rcore_drm software renderering
This commit is contained in:
parent
e2d10420a7
commit
954cde5b60
|
|
@ -64,12 +64,17 @@
|
|||
// so the enum KEY_F12 from raylib is used
|
||||
#undef KEY_F12
|
||||
|
||||
#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include <xf86drm.h> // Direct Rendering Manager user-level library interface
|
||||
#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
#else
|
||||
#include <sys/mman.h> // For mmap when copying to the dumb buffer
|
||||
#include <errno.h> // For the conversion of certain error messages
|
||||
#endif
|
||||
|
||||
#ifndef EGL_OPENGL_ES3_BIT
|
||||
#define EGL_OPENGL_ES3_BIT 0x40
|
||||
|
|
@ -96,15 +101,19 @@ typedef struct {
|
|||
drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
|
||||
drmModeCrtc *crtc; // CRT Controller
|
||||
int modeIndex; // Index of the used mode of connector->modes
|
||||
uint32_t prevFB; // Previous DRM framebufer (during frame swapping)
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
struct gbm_device *gbmDevice; // GBM device
|
||||
struct gbm_surface *gbmSurface; // GBM surface
|
||||
struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)
|
||||
uint32_t prevFB; // Previous GBM framebufer (during frame swapping)
|
||||
|
||||
EGLDisplay device; // Native display device (physical screen connection)
|
||||
EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
|
||||
EGLContext context; // Graphic context, mode in which drawing can be done
|
||||
EGLConfig config; // Graphic config
|
||||
#else
|
||||
uint32_t prevDumbHandle; // Handle to the previous dumb buffer (during frame swapping)
|
||||
#endif
|
||||
|
||||
// Keyboard data
|
||||
int defaultKeyboardMode; // Default keyboard mode
|
||||
|
|
@ -554,6 +563,8 @@ void DisableCursor(void)
|
|||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Hardware rendering buffer swap with EGL
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
|
||||
if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
|
|
@ -579,6 +590,209 @@ void SwapScreenBuffer(void)
|
|||
if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
|
||||
platform.prevBO = bo;
|
||||
#else
|
||||
// Software rendering buffer swap
|
||||
if ((-1 == platform.fd) || !platform.connector || (platform.modeIndex < 0))
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the software rendered color buffer
|
||||
int bufferWidth, bufferHeight;
|
||||
void *colorBuffer = swGetColorBuffer(&bufferWidth, &bufferHeight);
|
||||
if (!colorBuffer)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to get software color buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieving the dimensions of the display mode used
|
||||
drmModeModeInfo *mode = &platform.connector->modes[platform.modeIndex];
|
||||
uint32_t width = mode->hdisplay;
|
||||
uint32_t height = mode->vdisplay;
|
||||
|
||||
// Dumb buffers use a fixed format based on bpp
|
||||
#if SW_COLOR_BUFFER_BITS == 24
|
||||
const uint32_t bpp = 32; // 32 bits per pixel (XRGB8888 format)
|
||||
const uint32_t depth = 24; // Color depth, here only 24 bits, alpha is not used
|
||||
#else
|
||||
// REVIEW: Not sure how it will be interpreted (RGB or RGBA?)
|
||||
const uint32_t bpp = SW_COLOR_BUFFER_BITS;
|
||||
const uint32_t depth = SW_COLOR_BUFFER_BITS;
|
||||
#endif
|
||||
|
||||
// Create a dumb buffer for software rendering
|
||||
struct drm_mode_create_dumb creq = {0};
|
||||
creq.width = width;
|
||||
creq.height = height;
|
||||
creq.bpp = bpp;
|
||||
|
||||
int result = drmIoctl(platform.fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
|
||||
if (result < 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to create dumb buffer: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create framebuffer with the correct format
|
||||
uint32_t fb = 0;
|
||||
result = drmModeAddFB(platform.fd,
|
||||
width, height,
|
||||
depth, bpp, creq.pitch,
|
||||
creq.handle, &fb);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d (%s)", result, strerror(errno));
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map the dumb buffer to copy our software rendered buffer
|
||||
struct drm_mode_map_dumb mreq = {0};
|
||||
mreq.handle = creq.handle;
|
||||
result = drmIoctl(platform.fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to map dumb buffer: %s", strerror(errno));
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map the buffer into userspace
|
||||
void *dumbBuffer = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, platform.fd, mreq.offset);
|
||||
if (dumbBuffer == MAP_FAILED)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to mmap dumb buffer: %s", strerror(errno));
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the software rendered buffer to the dumb buffer with scaling if needed
|
||||
if (bufferWidth == width && bufferHeight == height)
|
||||
{
|
||||
// Direct copy if sizes match
|
||||
swCopyFramebuffer(0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scale the software buffer to match the display mode
|
||||
swBlitFramebuffer(0, 0, width, height, 0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
}
|
||||
|
||||
// Unmap the buffer
|
||||
munmap(dumbBuffer, creq.size);
|
||||
|
||||
// Find a CRTC compatible with the connector
|
||||
uint32_t crtcId = 0;
|
||||
if (platform.crtc)
|
||||
{
|
||||
crtcId = platform.crtc->crtc_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a CRTC that's compatible with this connector
|
||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources");
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check which CRTCs are compatible with this connector
|
||||
drmModeEncoder *encoder = NULL;
|
||||
if (platform.connector->encoder_id)
|
||||
{
|
||||
encoder = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
}
|
||||
|
||||
if (encoder && encoder->crtc_id)
|
||||
{
|
||||
crtcId = encoder->crtc_id;
|
||||
platform.crtc = drmModeGetCrtc(platform.fd, crtcId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a free CRTC
|
||||
for (int i = 0; i < res->count_crtcs; i++)
|
||||
{
|
||||
drmModeCrtc *crtc = drmModeGetCrtc(platform.fd, res->crtcs[i]);
|
||||
if (crtc && !crtc->buffer_id) // CRTC is free
|
||||
{
|
||||
crtcId = res->crtcs[i];
|
||||
if (platform.crtc) drmModeFreeCrtc(platform.crtc);
|
||||
platform.crtc = crtc;
|
||||
break;
|
||||
}
|
||||
if (crtc) drmModeFreeCrtc(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder) drmModeFreeEncoder(encoder);
|
||||
drmModeFreeResources(res);
|
||||
|
||||
if (!crtcId)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found");
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set CRTC with better error handling
|
||||
result = drmModeSetCrtc(platform.fd, crtcId, fb, 0, 0,
|
||||
&platform.connector->connector_id, 1,
|
||||
mode);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d (%s)", result, strerror(errno));
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: CRTC ID: %u, FB ID: %u, Connector ID: %u", crtcId, fb, platform.connector->connector_id);
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
||||
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up previous framebuffer
|
||||
if (platform.prevFB)
|
||||
{
|
||||
result = drmModeRmFB(platform.fd, platform.prevFB);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
platform.prevFB = fb;
|
||||
|
||||
// Clean up previous dumb buffer
|
||||
if (platform.prevDumbHandle)
|
||||
{
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = platform.prevDumbHandle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
}
|
||||
|
||||
platform.prevDumbHandle = creq.handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -723,10 +937,15 @@ int InitPlatform(void)
|
|||
platform.connector = NULL;
|
||||
platform.modeIndex = -1;
|
||||
platform.crtc = NULL;
|
||||
platform.prevFB = 0;
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
platform.gbmDevice = NULL;
|
||||
platform.gbmSurface = NULL;
|
||||
platform.prevBO = NULL;
|
||||
platform.prevFB = 0;
|
||||
#else
|
||||
platform.prevDumbHandle = 0;
|
||||
#endif
|
||||
|
||||
// Initialize graphic device: display/window and graphic context
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -743,6 +962,7 @@ int InitPlatform(void)
|
|||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open platform-gpu-card, trying card1");
|
||||
platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card1 opened successfully");
|
||||
|
|
@ -750,10 +970,19 @@ int InitPlatform(void)
|
|||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card1, trying card0");
|
||||
platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card0 opened successfully");
|
||||
}
|
||||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card0, trying card2");
|
||||
platform.fd = open("/dev/dri/card2", O_RDWR);
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card2 opened successfully");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platform.fd == -1)
|
||||
|
|
@ -766,29 +995,57 @@ int InitPlatform(void)
|
|||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
|
||||
|
||||
// Connector detection
|
||||
for (size_t i = 0; i < res->count_connectors; i++)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);
|
||||
|
||||
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
||||
|
||||
// In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected.
|
||||
// This might be a hardware or software limitation like on Raspberry Pi Zero with composite output.
|
||||
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id))
|
||||
if (!con)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get connector %i", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes);
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
|
||||
(con->connection == DRM_MODE_CONNECTED) ? "CONNECTED" :
|
||||
(con->connection == DRM_MODE_DISCONNECTED) ? "DISCONNECTED" :
|
||||
(con->connection == DRM_MODE_UNKNOWNCONNECTION) ? "UNKNOWN" : "OTHER");
|
||||
|
||||
// Accept CONNECTED, UNKNOWN and even those without encoder_id connectors for software mode
|
||||
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) &&
|
||||
(con->count_modes > 0))
|
||||
{
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// For hardware rendering, we need an encoder_id
|
||||
if (con->encoder_id)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected with encoder", i);
|
||||
platform.connector = con;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode NOT connected (deleting)");
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected but no encoder", i);
|
||||
}
|
||||
#else
|
||||
// For software rendering, we can accept even without encoder_id
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i suitable for software rendering", i);
|
||||
platform.connector = con;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!platform.connector)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i NOT suitable (deleting)", i);
|
||||
drmModeFreeConnector(con);
|
||||
}
|
||||
}
|
||||
|
|
@ -797,14 +1054,18 @@ int InitPlatform(void)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
if (!enc)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -813,7 +1074,9 @@ int InitPlatform(void)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -828,7 +1091,9 @@ int InitPlatform(void)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -856,7 +1121,9 @@ int InitPlatform(void)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -868,16 +1135,42 @@ int InitPlatform(void)
|
|||
(platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
|
||||
platform.connector->modes[platform.modeIndex].vrefresh);
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
#else
|
||||
// For software rendering, the first available mode can be used
|
||||
if (platform.connector->count_modes > 0)
|
||||
{
|
||||
platform.modeIndex = 0;
|
||||
CORE.Window.display.width = platform.connector->modes[0].hdisplay;
|
||||
CORE.Window.display.height = platform.connector->modes[0].vdisplay;
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u) for software rendering",
|
||||
platform.connector->modes[0].name,
|
||||
platform.connector->modes[0].hdisplay,
|
||||
platform.connector->modes[0].vdisplay,
|
||||
(platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
|
||||
platform.connector->modes[0].vrefresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No modes available for connector");
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use the width and height of the surface for render
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
|
||||
drmModeFreeResources(res);
|
||||
res = NULL;
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Hardware rendering initialization with EGL
|
||||
platform.gbmDevice = gbm_create_device(platform.fd);
|
||||
if (!platform.gbmDevice)
|
||||
{
|
||||
|
|
@ -1046,6 +1339,32 @@ int InitPlatform(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
#else
|
||||
// At this point we need to manage render size vs screen size
|
||||
// NOTE: This function use and modify global module variables:
|
||||
// -> CORE.Window.screen.width/CORE.Window.screen.height
|
||||
// -> CORE.Window.render.width/CORE.Window.render.height
|
||||
// -> CORE.Window.screenScale
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
// Setup window ready state for software rendering
|
||||
CORE.Window.ready = true;
|
||||
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
CORE.Window.currentFbo.width = CORE.Window.render.width;
|
||||
CORE.Window.currentFbo.height = CORE.Window.render.height;
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully (Software Rendering)");
|
||||
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
||||
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
||||
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
||||
#endif
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
|
|
@ -1058,12 +1377,8 @@ int InitPlatform(void)
|
|||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize timming system
|
||||
// Initialize timing system
|
||||
//----------------------------------------------------------------------------
|
||||
// NOTE: timming system must be initialized before the input events system
|
||||
InitTimer();
|
||||
|
|
@ -1097,6 +1412,7 @@ void ClosePlatform(void)
|
|||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
|
|
@ -1114,6 +1430,7 @@ void ClosePlatform(void)
|
|||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
|
|
@ -1135,6 +1452,7 @@ void ClosePlatform(void)
|
|||
platform.fd = -1;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
|
|
@ -1153,6 +1471,7 @@ void ClosePlatform(void)
|
|||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user