diff options
Diffstat (limited to 'src/rcore_drm.c')
| -rw-r--r-- | src/rcore_drm.c | 352 |
1 files changed, 171 insertions, 181 deletions
diff --git a/src/rcore_drm.c b/src/rcore_drm.c index 2644c5e7..213f2c54 100644 --- a/src/rcore_drm.c +++ b/src/rcore_drm.c @@ -140,21 +140,22 @@ static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- -static bool InitGraphicsDevice(int width, int height); // Initialize graphics device +static int InitPlatform(void); // Initialize platform (graphics, inputs and more) +static void ClosePlatform(void); // Close platform -static void InitKeyboard(void); // Initialize raw keyboard system -static void RestoreKeyboard(void); // Restore keyboard system +static void InitKeyboard(void); // Initialize raw keyboard system +static void RestoreKeyboard(void); // Restore keyboard system #if defined(SUPPORT_SSH_KEYBOARD_RPI) -static void ProcessKeyboard(void); // Process keyboard events +static void ProcessKeyboard(void); // Process keyboard events #endif -static void InitEvdevInput(void); // Initialize evdev inputs -static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate -static void PollKeyboardEvents(void); // Process evdev keyboard events -static void *EventThread(void *arg); // Input device events reading thread +static void InitEvdevInput(void); // Initialize evdev inputs +static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate +static void PollKeyboardEvents(void); // Process evdev keyboard events +static void *EventThread(void *arg); // Input device events reading thread -static void InitGamepad(void); // Initialize raw gamepad input -static void *GamepadThread(void *arg); // Mouse reading thread +static void InitGamepad(void); // Initialize raw gamepad input +static void *GamepadThread(void *arg); // Mouse reading thread static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list @@ -204,49 +205,31 @@ void InitWindow(int width, int height, const char *title) TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)"); #endif - // NOTE: Keep internal pointer to input title string (no copy) + // Initialize window data + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + CORE.Window.eventWaiting = false; + CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title; // Initialize global input state - memset(&CORE.Input, 0, sizeof(CORE.Input)); + memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0 CORE.Input.Keyboard.exitKey = KEY_ESCAPE; - CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f}; + CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; - CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN - CORE.Window.eventWaiting = false; - - - // Platform specific init window - //-------------------------------------------------------------- - // Initialize graphics device (display device and OpenGL context) - // NOTE: returns true if window and graphic device has been initialized successfully - CORE.Window.ready = InitGraphicsDevice(width, height); - - // If graphic device is no properly initialized, we end program - if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; } - else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2); - - // Set some default window flags - CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false - - // Initialize hi-res timer - InitTimer(); - - // Initialize base path for storage - CORE.Storage.basePath = GetWorkingDirectory(); - - // Initialize raw input system - InitEvdevInput(); // Evdev inputs initialization - InitGamepad(); // Gamepad init - InitKeyboard(); // Keyboard init (stdin) + CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; + + // Initialize platform + //-------------------------------------------------------------- + InitPlatform(); //-------------------------------------------------------------- + + // Initialize rlgl default data (buffers and shaders) + // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl + rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - - // Initialize random seed - SetRandomSeed((unsigned int)time(NULL)); + // Setup default viewport + SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); #if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) // Load default font @@ -289,7 +272,10 @@ void InitWindow(int width, int height, const char *title) events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent)); CORE.Time.frameCounter = 0; #endif - + + // Initialize random seed + SetRandomSeed((unsigned int)time(NULL)); + TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully"); } @@ -315,93 +301,9 @@ void CloseWindow(void) timeEndPeriod(1); // Restore time period #endif - // Platform specific close window - //-------------------------------------------------------------- - if (platform.prevFB) - { - drmModeRmFB(platform.fd, platform.prevFB); - platform.prevFB = 0; - } - - if (platform.prevBO) - { - gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO); - platform.prevBO = NULL; - } - - if (platform.gbmSurface) - { - gbm_surface_destroy(platform.gbmSurface); - platform.gbmSurface = NULL; - } - - if (platform.gbmDevice) - { - gbm_device_destroy(platform.gbmDevice); - platform.gbmDevice = NULL; - } - - if (platform.crtc) - { - if (platform.connector) - { - drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id, - platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode); - drmModeFreeConnector(platform.connector); - platform.connector = NULL; - } - - drmModeFreeCrtc(platform.crtc); - platform.crtc = NULL; - } - - if (platform.fd != -1) - { - close(platform.fd); - platform.fd = -1; - } - - // Close surface, context and display - if (platform.device != EGL_NO_DISPLAY) - { - if (platform.surface != EGL_NO_SURFACE) - { - eglDestroySurface(platform.device, platform.surface); - platform.surface = EGL_NO_SURFACE; - } - - if (platform.context != EGL_NO_CONTEXT) - { - eglDestroyContext(platform.device, platform.context); - platform.context = EGL_NO_CONTEXT; - } - - eglTerminate(platform.device); - platform.device = EGL_NO_DISPLAY; - } - - // Wait for mouse and gamepad threads to finish before closing - // NOTE: Those threads should already have finished at this point - // because they are controlled by CORE.Window.shouldClose variable - - CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called - - // Close the evdev keyboard - if (platform.keyboardFd != -1) - { - close(platform.keyboardFd); - platform.keyboardFd = -1; - } - - for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) - { - if (platform.eventWorker[i].threadId) - { - pthread_join(platform.eventWorker[i].threadId, NULL); - } - } - - if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL); + // De-initialize platform + //-------------------------------------------------------------- + ClosePlatform(); //-------------------------------------------------------------- #if defined(SUPPORT_EVENTS_AUTOMATION) @@ -808,28 +710,9 @@ void PollInputEvents(void) // Module Internal Functions Definition //---------------------------------------------------------------------------------- -// Initialize display device and framebuffer -// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size -// If width or height are 0, default display size will be used for framebuffer size -// NOTE: returns false in case graphic device could not be created -static bool InitGraphicsDevice(int width, int height) +// Initialize platform: graphics, inputs and more +static int InitPlatform(void) { - CORE.Window.screen.width = width; // User desired width - CORE.Window.screen.height = height; // User desired height - CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default - - // Set the window minimum and maximum default values to 0 - CORE.Window.screenMin.width = 0; - CORE.Window.screenMin.height = 0; - CORE.Window.screenMax.width = 0; - CORE.Window.screenMax.height = 0; - - // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars... - // ...in top-down or left-right to match display aspect ratio (no weird scaling) - - CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; - platform.fd = -1; platform.connector = NULL; platform.modeIndex = -1; @@ -838,6 +721,9 @@ static bool InitGraphicsDevice(int width, int height) platform.gbmSurface = NULL; platform.prevBO = NULL; platform.prevFB = 0; + + CORE.Window.fullscreen = true; + CORE.Window.flags |= FLAG_FULLSCREEN_MODE; #if defined(DEFAULT_GRAPHIC_DEVICE_DRM) platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR); @@ -861,14 +747,14 @@ static bool InitGraphicsDevice(int width, int height) if (platform.fd == -1) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card"); - return false; + return -1; } drmModeRes *res = drmModeGetResources(platform.fd); if (!res) { TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources"); - return false; + return -1; } TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors); @@ -897,7 +783,7 @@ static bool InitGraphicsDevice(int width, int height) { TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found"); drmModeFreeResources(res); - return false; + return -1; } drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id); @@ -905,7 +791,7 @@ static bool InitGraphicsDevice(int width, int height) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder"); drmModeFreeResources(res); - return false; + return -1; } platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id); @@ -914,7 +800,7 @@ static bool InitGraphicsDevice(int width, int height) TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc"); drmModeFreeEncoder(enc); drmModeFreeResources(res); - return false; + return -1; } // If InitWindow should use the current mode find it in the connector's mode list @@ -929,7 +815,7 @@ static bool InitGraphicsDevice(int width, int height) TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found"); drmModeFreeEncoder(enc); drmModeFreeResources(res); - return false; + return -1; } CORE.Window.screen.width = CORE.Window.display.width; @@ -957,7 +843,7 @@ static bool InitGraphicsDevice(int width, int height) TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode"); drmModeFreeEncoder(enc); drmModeFreeResources(res); - return false; + return -1; } CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay; @@ -982,7 +868,7 @@ static bool InitGraphicsDevice(int width, int height) if (!platform.gbmDevice) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device"); - return false; + return -1; } platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay, @@ -990,7 +876,7 @@ static bool InitGraphicsDevice(int width, int height) if (!platform.gbmSurface) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface"); - return false; + return -1; } EGLint samples = 0; @@ -1030,7 +916,7 @@ static bool InitGraphicsDevice(int width, int height) if (platform.device == EGL_NO_DISPLAY) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); - return false; + return -1; } // Initialize the EGL device connection @@ -1038,13 +924,13 @@ static bool InitGraphicsDevice(int width, int height) { // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); - return false; + return -1; } if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs)) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError()); - return false; + return -1; } TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs); @@ -1053,7 +939,7 @@ static bool InitGraphicsDevice(int width, int height) if (!configs) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs"); - return false; + return -1; } EGLint matchingNumConfigs = 0; @@ -1061,7 +947,7 @@ static bool InitGraphicsDevice(int width, int height) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError()); free(configs); - return false; + return -1; } TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs); @@ -1091,7 +977,7 @@ static bool InitGraphicsDevice(int width, int height) if (!found) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config"); - return false; + return -1; } // Set rendering API @@ -1102,7 +988,7 @@ static bool InitGraphicsDevice(int width, int height) if (platform.context == EGL_NO_CONTEXT) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context"); - return false; + return -1; } // Create an EGL window surface @@ -1111,7 +997,7 @@ static bool InitGraphicsDevice(int width, int height) if (EGL_NO_SURFACE == platform.surface) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError()); - return false; + return -1; } // At this point we need to manage render size vs screen size @@ -1127,7 +1013,7 @@ static bool InitGraphicsDevice(int width, int height) if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface"); - return false; + return -1; } else { @@ -1147,19 +1033,123 @@ static bool InitGraphicsDevice(int width, int height) // NOTE: GL procedures address loader is required to load extensions rlLoadExtensions(eglGetProcAddress); - // Initialize OpenGL context (states and resources) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl - rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + + // If graphic device is no properly initialized, we end program + if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } + else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2); - // Setup default viewport - // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); + // Set some default window flags + CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false + CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false + CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true + CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + // Initialize hi-res timer + InitTimer(); - return true; + // Initialize base path for storage + CORE.Storage.basePath = GetWorkingDirectory(); + + // Initialize raw input system + InitEvdevInput(); // Evdev inputs initialization + InitGamepad(); // Gamepad init + InitKeyboard(); // Keyboard init (stdin) + + return 0; } +// Close platform +static void ClosePlatform(void) +{ + if (platform.prevFB) + { + drmModeRmFB(platform.fd, platform.prevFB); + platform.prevFB = 0; + } + + if (platform.prevBO) + { + gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO); + platform.prevBO = NULL; + } + + if (platform.gbmSurface) + { + gbm_surface_destroy(platform.gbmSurface); + platform.gbmSurface = NULL; + } + + if (platform.gbmDevice) + { + gbm_device_destroy(platform.gbmDevice); + platform.gbmDevice = NULL; + } + + if (platform.crtc) + { + if (platform.connector) + { + drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id, + platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode); + drmModeFreeConnector(platform.connector); + platform.connector = NULL; + } + + drmModeFreeCrtc(platform.crtc); + platform.crtc = NULL; + } + + if (platform.fd != -1) + { + close(platform.fd); + platform.fd = -1; + } + + // Close surface, context and display + if (platform.device != EGL_NO_DISPLAY) + { + if (platform.surface != EGL_NO_SURFACE) + { + eglDestroySurface(platform.device, platform.surface); + platform.surface = EGL_NO_SURFACE; + } + + if (platform.context != EGL_NO_CONTEXT) + { + eglDestroyContext(platform.device, platform.context); + platform.context = EGL_NO_CONTEXT; + } + + eglTerminate(platform.device); + platform.device = EGL_NO_DISPLAY; + } + + // Wait for mouse and gamepad threads to finish before closing + // NOTE: Those threads should already have finished at this point + // because they are controlled by CORE.Window.shouldClose variable + + CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called + + // Close the evdev keyboard + if (platform.keyboardFd != -1) + { + close(platform.keyboardFd); + platform.keyboardFd = -1; + } + + for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i) + { + if (platform.eventWorker[i].threadId) + { + pthread_join(platform.eventWorker[i].threadId, NULL); + } + } + + if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL); +} + + // Initialize Keyboard system (using standard input) static void InitKeyboard(void) { |
