From df54c288c88fb4cf2cf81be32901f6a991a9446a Mon Sep 17 00:00:00 2001 From: brooksytech Date: Tue, 27 Sep 2022 14:09:30 -0700 Subject: [PATCH] Fix DolphinSA Hotkeys --- .../dolphinsa/config/handheld/GCPadNew.ini | 1 + packages/games/emulators/dolphinsa/package.mk | 3 +- .../dolphinsa/patches/new/002-egldrm.patch | 7495 ----------------- .../patches/new/002-x11-hotkeys.patch | 129 + .../patches/new/003-drm-hotkeys.patch | 118 - .../patches/new/003-drm-resolution.patch | 56 - .../dolphinsa/patches/new/007-drm-conn.patch | 48 - 7 files changed, 132 insertions(+), 7718 deletions(-) delete mode 100644 packages/games/emulators/dolphinsa/patches/new/002-egldrm.patch create mode 100644 packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch delete mode 100644 packages/games/emulators/dolphinsa/patches/new/003-drm-hotkeys.patch delete mode 100644 packages/games/emulators/dolphinsa/patches/new/003-drm-resolution.patch delete mode 100644 packages/games/emulators/dolphinsa/patches/new/007-drm-conn.patch diff --git a/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini b/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini index e2e99bf61..130cee4ce 100644 --- a/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini +++ b/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini @@ -6,6 +6,7 @@ Buttons/Start = Button 7 Buttons/X = Button 3 Buttons/Y = Button 2 Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 C-Stick/Dead Zone = 25.000000000000000 C-Stick/Down = Axis 4+ C-Stick/Left = Axis 3- diff --git a/packages/games/emulators/dolphinsa/package.mk b/packages/games/emulators/dolphinsa/package.mk index 3bcb4717b..aa506910e 100755 --- a/packages/games/emulators/dolphinsa/package.mk +++ b/packages/games/emulators/dolphinsa/package.mk @@ -58,7 +58,8 @@ PKG_CMAKE_OPTS_TARGET+=" -DENABLE_HEADLESS=ON \ -DENABLE_ANALYTICS=OFF \ -DENABLE_LTO=ON \ -DENABLE_QT=OFF \ - -DENCODE_FRAMEDUMPS=OFF" + -DENCODE_FRAMEDUMPS=OFF \ + -DENABLE_CLI_TOOL=OFF" makeinstall_target() { mkdir -p ${INSTALL}/usr/bin diff --git a/packages/games/emulators/dolphinsa/patches/new/002-egldrm.patch b/packages/games/emulators/dolphinsa/patches/new/002-egldrm.patch deleted file mode 100644 index 7d2213cf4..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/002-egldrm.patch +++ /dev/null @@ -1,7495 +0,0 @@ -From ddedd9b498cecb0a951e30868603ab7c3a46e2e7 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Thu, 6 Aug 2020 23:57:12 +0200 -Subject: [PATCH 01/25] Add support for EGL/DRM on dolphin-nogui - ---- - CMake/FindDRM.cmake | 41 + - Source/Core/Common/CMakeLists.txt | 17 +- - Source/Core/Common/GL/GLContext.cpp | 3 + - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 1483 ++++++++++++++++++ - Source/Core/Common/GL/GLInterface/EGLDRM.h | 59 + - Source/Core/Common/WindowSystemInfo.h | 1 + - Source/Core/DolphinNoGUI/CMakeLists.txt | 1 + - Source/Core/DolphinNoGUI/MainNoGUI.cpp | 5 +- - Source/Core/DolphinNoGUI/Platform.h | 1 + - Source/Core/DolphinNoGUI/PlatformDRM.cpp | 83 + - 10 files changed, 1691 insertions(+), 3 deletions(-) - create mode 100644 CMake/FindDRM.cmake - create mode 100644 Source/Core/Common/GL/GLInterface/EGLDRM.cpp - create mode 100644 Source/Core/Common/GL/GLInterface/EGLDRM.h - create mode 100644 Source/Core/DolphinNoGUI/PlatformDRM.cpp - -diff --git a/CMake/FindDRM.cmake b/CMake/FindDRM.cmake -new file mode 100644 -index 00000000000..10d554f0fcd ---- /dev/null -+++ b/CMake/FindDRM.cmake -@@ -0,0 +1,41 @@ -+# -+# Try to find DRM library and include path. -+# Once done this will define -+# -+# DRM_FOUND -+# DRM_INCLUDE_PATH -+# DRM_LIBRARY -+# -+ -+FIND_PATH(DRM_INCLUDE_PATH -+ NAMES -+ drm.h -+ PATHS -+ ${CMAKE_INCLUDE_PATH}/include/libdrm/ -+ ~/include/libdrm/ -+ /usr/include/libdrm/ -+ /usr/local/include/libdrm/ -+ /sw/include/libdrm/ -+ /opt/local/include/libdrm/ -+ DOC "The directory where drm.h resides") -+FIND_LIBRARY(DRM_LIBRARY -+ NAMES DRM drm -+ PATHS -+ ${CMAKE_LIBRARY_PATH}/lib/ -+ ~/lib/ -+ /usr/lib64 -+ /usr/lib -+ /usr/local/lib64 -+ /usr/local/lib -+ /sw/lib -+ /opt/local/lib -+ DOC "The DRM library") -+ -+IF(DRM_INCLUDE_PATH) -+ INCLUDE_DIRECTORIES(${DRM_INCLUDE_PATH}) -+ SET(DRM_FOUND 1 CACHE STRING "Set to 1 if DRM is found, 0 otherwise") -+ELSE(DRM_INCLUDE_PATH) -+ SET(DRM_FOUND 0 CACHE STRING "Set to 1 if DRM is found, 0 otherwise") -+ENDIF(DRM_INCLUDE_PATH) -+ -+MARK_AS_ADVANCED(DRM_FOUND) -diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt -index a805635af60..e4754f81400 100644 ---- a/Source/Core/Common/CMakeLists.txt -+++ b/Source/Core/Common/CMakeLists.txt -@@ -222,10 +222,18 @@ target_sources(common PRIVATE - ) - - if(ENABLE_EGL AND EGL_FOUND) -+ find_package(DRM MODULE QUIET) -+ - target_sources(common PRIVATE - GL/GLInterface/EGL.cpp - GL/GLInterface/EGL.h - ) -+ if (DRM_FOUND) -+ target_sources(common PRIVATE -+ GL/GLInterface/EGLDRM.cpp -+ GL/GLInterface/EGLDRM.h -+ ) -+ endif() - if(ANDROID) - target_sources(common PRIVATE - GL/GLInterface/EGLAndroid.cpp -@@ -237,8 +245,13 @@ if(ENABLE_EGL AND EGL_FOUND) - GL/GLInterface/EGLX11.h - ) - endif() -- target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS}) -- target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) -+ if (DRM_FOUND) -+ target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS} ${DRM_INCLUDE_DIRS}) -+ target_link_libraries(common PUBLIC ${EGL_LIBRARIES} ${DRM_LIBRARY}) -+ else() -+ target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS}) -+ target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) -+ endif() - endif() - - if(WIN32) -diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp -index d6969bcb55b..f5adaab71ab 100644 ---- a/Source/Core/Common/GL/GLContext.cpp -+++ b/Source/Core/Common/GL/GLContext.cpp -@@ -17,6 +17,7 @@ - #endif - #if HAVE_EGL - #include "Common/GL/GLInterface/EGL.h" -+#include "Common/GL/GLInterface/EGLDRM.h" - #if HAVE_X11 - #include "Common/GL/GLInterface/EGLX11.h" - #endif -@@ -110,6 +111,8 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s - #if HAVE_EGL - if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) - context = std::make_unique(); -+ else if (wsi.type == WindowSystemType::DRM) -+ context = std::make_unique(); - #endif - - if (!context) -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -new file mode 100644 -index 00000000000..3996178d045 ---- /dev/null -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -0,0 +1,1483 @@ -+/* RetroArch - A frontend for libretro. -+ * Copyright (c) 2011-2017 - Daniel De Matteis -+ * -+ * RetroArch is free software: you can redistribute it and/or modify it under the terms -+ * of the GNU General Public License as published by the Free Software Found- -+ * ation, either version 3 of the License, or (at your option) any later version. -+ * -+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -+ * PURPOSE. See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with RetroArch. -+ * If not, see . -+ */ -+ -+// Copyright 2012 Dolphin Emulator Project -+// Licensed under GPLv2+ -+// Refer to the license.txt file included. -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "Common/GL/GLInterface/EGLDRM.h" -+ -+#ifndef EGL_CONTEXT_FLAGS_KHR -+#define EGL_CONTEXT_FLAGS_KHR 0x30FC -+#endif -+ -+#ifndef EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR -+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 -+#endif -+ -+#ifndef EGL_OPENGL_ES3_BIT_KHR -+#define EGL_OPENGL_ES3_BIT_KHR 0x0040 -+#endif -+ -+#ifndef EGL_PLATFORM_GBM_KHR -+#define EGL_PLATFORM_GBM_KHR 0x31D7 -+#endif -+ -+extern uint32_t g_connector_id; -+extern int g_drm_fd; -+extern uint32_t g_crtc_id; -+ -+extern struct pollfd g_drm_fds; -+ -+extern drmModeConnector *g_drm_connector; -+extern drmModeModeInfo *g_drm_mode; -+extern drmModeCrtc *g_orig_crtc; -+ -+extern drmEventContext g_drm_evctx; -+ -+ -+void egl_report_error(void); -+ -+void egl_destroy(egl_ctx_data_t *egl); -+ -+void egl_terminate(EGLDisplay dpy); -+ -+void egl_swap_buffers(void *data); -+ -+void egl_set_swap_interval(egl_ctx_data_t *egl, int interval); -+ -+void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height); -+ -+typedef bool (*egl_accept_config_cb_t)(void *display_data, EGLDisplay dpy, EGLConfig config); -+ -+bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor); -+ -+bool egl_init_context_common( -+ egl_ctx_data_t *egl, EGLint *count, -+ const EGLint *attrib_ptr, -+ egl_accept_config_cb_t cb, -+ void *display_data); -+ -+bool egl_init_context(egl_ctx_data_t *egl, -+ EGLenum platform, -+ void *display_data, -+ EGLint *major, -+ EGLint *minor, -+ EGLint *n, -+ const EGLint *attrib_ptr, -+ egl_accept_config_cb_t cb); -+ -+bool egl_bind_api(EGLenum egl_api); -+ -+bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs); -+ -+bool egl_create_surface(egl_ctx_data_t *egl, void *native_window); -+ -+bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value); -+ -+bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, -+ EGLint attribute, EGLint *value); -+ -+bool egl_has_config(egl_ctx_data_t *egl); -+ -+#define _egl_query_surface(a, b, c, d) eglQuerySurface(a, b, c, d) -+#define _egl_get_proc_address(a) eglGetProcAddress(a) -+#define _egl_create_window_surface(a, b, c, d) eglCreateWindowSurface(a, b, c, d) -+#define _egl_create_context(a, b, c, d) eglCreateContext(a, b, c, d) -+#define _egl_get_configs(a, b, c, d) eglGetConfigs(a, b, c, d) -+#define _egl_get_display(a) eglGetDisplay(a) -+#define _egl_choose_config(a, b, c, d, e) eglChooseConfig(a, b, c, d, e) -+#define _egl_make_current(a, b, c, d) eglMakeCurrent(a, b, c, d) -+#define _egl_initialize(a, b, c) eglInitialize(a, b, c) -+#define _egl_destroy_surface(a, b) eglDestroySurface(a, b) -+#define _egl_destroy_context(a, b) eglDestroyContext(a, b) -+#define _egl_get_current_context() eglGetCurrentContext() -+#define _egl_get_error() eglGetError() -+#define _egl_terminate(dpy) eglTerminate(dpy) -+#define _egl_bind_api(a) eglBindAPI(a) -+#define _egl_query_string(a, b) eglQueryString(a, b) -+#define _egl_get_config_attrib(a, b, c, d) eglGetConfigAttrib(a, b, c, d) -+#define _egl_swap_buffers(a, b) eglSwapBuffers(a, b) -+#define _egl_swap_interval(a, b) eglSwapInterval(a, b) -+ -+void egl_report_error(void) -+{ -+ EGLint error = _egl_get_error(); -+ const char *str = NULL; -+ switch (error) -+ { -+ case EGL_SUCCESS: -+ str = "EGL_SUCCESS"; -+ break; -+ -+ case EGL_BAD_ACCESS: -+ str = "EGL_BAD_ACCESS"; -+ break; -+ -+ case EGL_BAD_ALLOC: -+ str = "EGL_BAD_ALLOC"; -+ break; -+ -+ case EGL_BAD_ATTRIBUTE: -+ str = "EGL_BAD_ATTRIBUTE"; -+ break; -+ -+ case EGL_BAD_CONFIG: -+ str = "EGL_BAD_CONFIG"; -+ break; -+ -+ case EGL_BAD_CONTEXT: -+ str = "EGL_BAD_CONTEXT"; -+ break; -+ -+ case EGL_BAD_CURRENT_SURFACE: -+ str = "EGL_BAD_CURRENT_SURFACE"; -+ break; -+ -+ case EGL_BAD_DISPLAY: -+ str = "EGL_BAD_DISPLAY"; -+ break; -+ -+ case EGL_BAD_MATCH: -+ str = "EGL_BAD_MATCH"; -+ break; -+ -+ case EGL_BAD_NATIVE_PIXMAP: -+ str = "EGL_BAD_NATIVE_PIXMAP"; -+ break; -+ -+ case EGL_BAD_NATIVE_WINDOW: -+ str = "EGL_BAD_NATIVE_WINDOW"; -+ break; -+ -+ case EGL_BAD_PARAMETER: -+ str = "EGL_BAD_PARAMETER"; -+ break; -+ -+ case EGL_BAD_SURFACE: -+ str = "EGL_BAD_SURFACE"; -+ break; -+ -+ default: -+ str = "Unknown"; -+ break; -+ } -+ -+ printf("[EGL]: #0x%x, %s\n", (unsigned)error, str); -+} -+ -+void egl_terminate(EGLDisplay dpy) -+{ -+ _egl_terminate(dpy); -+} -+ -+bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, -+ EGLint *value) -+{ -+ return _egl_get_config_attrib(dpy, config, attribute, value); -+} -+ -+bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) -+{ -+ return _egl_initialize(dpy, major, minor); -+} -+ -+bool egl_bind_api(EGLenum egl_api) -+{ -+ return _egl_bind_api(egl_api); -+} -+ -+void egl_destroy(egl_ctx_data_t *egl) -+{ -+ if (egl->dpy) -+ { -+ _egl_make_current(egl->dpy, -+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (egl->ctx != EGL_NO_CONTEXT) -+ _egl_destroy_context(egl->dpy, egl->ctx); -+ -+ if (egl->surf != EGL_NO_SURFACE) -+ _egl_destroy_surface(egl->dpy, egl->surf); -+ egl_terminate(egl->dpy); -+ } -+ -+ /* Be as careful as possible in deinit. -+ * If we screw up, any TTY will not restore. -+ */ -+ -+ egl->ctx = EGL_NO_CONTEXT; -+ egl->surf = EGL_NO_SURFACE; -+ egl->dpy = EGL_NO_DISPLAY; -+ egl->config = 0; -+} -+ -+void egl_swap_buffers(void *data) -+{ -+ egl_ctx_data_t *egl = (egl_ctx_data_t*)data; -+ if ( egl && -+ egl->dpy != EGL_NO_DISPLAY && -+ egl->surf != EGL_NO_SURFACE -+ ) -+ { -+ _egl_swap_buffers(egl->dpy, egl->surf); -+ } -+ else -+ printf("\nSWAP FAILED"); -+} -+ -+void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) -+{ -+ /* Can be called before initialization. -+ * Some contexts require that swap interval -+ * is known at startup time. -+ */ -+ egl->interval = interval; -+ -+ if (egl->dpy == EGL_NO_DISPLAY) -+ return; -+ if (!_egl_get_current_context()) -+ return; -+ -+ printf("[EGL]: eglSwapInterval(%u)\n", interval); -+ if (!_egl_swap_interval(egl->dpy, interval)) -+ { -+ printf("[EGL]: eglSwapInterval() failed.\n"); -+ egl_report_error(); -+ } -+} -+ -+void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height) -+{ -+ *width = 0; -+ *height = 0; -+ -+ if (egl->dpy != EGL_NO_DISPLAY && egl->surf != EGL_NO_SURFACE) -+ { -+ EGLint gl_width, gl_height; -+ -+ _egl_query_surface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width); -+ _egl_query_surface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height); -+ *width = gl_width; -+ *height = gl_height; -+ } -+} -+ -+bool check_egl_version(int minMajorVersion, int minMinorVersion) -+{ -+ int count; -+ int major, minor; -+ const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_VERSION); -+ -+ if (!str) -+ return false; -+ -+ count = sscanf(str, "%d.%d", &major, &minor); -+ if (count != 2) -+ return false; -+ -+ if (major < minMajorVersion) -+ return false; -+ -+ if (major > minMajorVersion) -+ return true; -+ -+ if (minor >= minMinorVersion) -+ return true; -+ -+ return false; -+} -+ -+bool check_egl_client_extension(const char *name) -+{ -+ size_t nameLen; -+ const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_EXTENSIONS); -+ -+ /* The EGL implementation doesn't support client extensions at all. */ -+ if (!str) -+ return false; -+ -+ nameLen = strlen(name); -+ while (*str != '\0') -+ { -+ /* Use strspn and strcspn to find the start position and length of each -+ * token in the extension string. Using strtok could also work, but -+ * that would require allocating a copy of the string. */ -+ size_t len = strcspn(str, " "); -+ if (len == nameLen && strncmp(str, name, nameLen) == 0) -+ return true; -+ str += len; -+ str += strspn(str, " "); -+ } -+ -+ return false; -+} -+ -+static EGLDisplay get_egl_display(EGLenum platform, void *native) -+{ -+ if (platform != EGL_NONE) -+ { -+ /* If the client library supports at least EGL 1.5, then we can call -+ * eglGetPlatformDisplay. Otherwise, see if eglGetPlatformDisplayEXT -+ * is available. */ -+#if defined(EGL_VERSION_1_5) -+ if (check_egl_version(1, 5)) -+ { -+ typedef EGLDisplay (EGLAPIENTRY * pfn_eglGetPlatformDisplay) -+ (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); -+ pfn_eglGetPlatformDisplay ptr_eglGetPlatformDisplay; -+ -+ printf("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); -+ ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay) -+ _egl_get_proc_address("eglGetPlatformDisplay"); -+ -+ if (ptr_eglGetPlatformDisplay) -+ { -+ EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL); -+ if (dpy != EGL_NO_DISPLAY) -+ return dpy; -+ } -+ } -+#endif /* defined(EGL_VERSION_1_5) */ -+ -+#if defined(EGL_EXT_platform_base) -+ if (check_egl_client_extension("EGL_EXT_platform_base")) -+ { -+ PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT; -+ -+ printf("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); -+ ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) -+ _egl_get_proc_address("eglGetPlatformDisplayEXT"); -+ -+ if (ptr_eglGetPlatformDisplayEXT) -+ { -+ EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL); -+ if (dpy != EGL_NO_DISPLAY) -+ return dpy; -+ } -+ } -+#endif /* defined(EGL_EXT_platform_base) */ -+ } -+ -+ /* Either the caller didn't provide a platform type, or the EGL -+ * implementation doesn't support eglGetPlatformDisplay. In this case, try -+ * eglGetDisplay and hope for the best. */ -+ printf("[EGL] Falling back to eglGetDisplay\n"); -+ return _egl_get_display((EGLNativeDisplayType) native); -+} -+ -+bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) -+{ -+ if (!egl_get_config_attrib(egl->dpy, egl->config, -+ EGL_NATIVE_VISUAL_ID, value)) -+ { -+ printf("[EGL]: egl_get_native_visual_id failed.\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool egl_init_context_common( -+ egl_ctx_data_t *egl, EGLint *count, -+ const EGLint *attrib_ptr, -+ egl_accept_config_cb_t cb, -+ void *display_data) -+{ -+ EGLint i; -+ EGLint matched = 0; -+ EGLConfig *configs = NULL; -+ if (!egl) -+ return false; -+ -+ if (!_egl_get_configs(egl->dpy, NULL, 0, count) || *count < 1) -+ { -+ printf("[EGL]: No configs to choose from.\n"); -+ return false; -+ } -+ -+ configs = (EGLConfig*)malloc(*count * sizeof(*configs)); -+ if (!configs) -+ return false; -+ -+ if (!_egl_choose_config(egl->dpy, attrib_ptr, -+ configs, *count, &matched) || !matched) -+ { -+ printf("[EGL]: No EGL configs with appropriate attributes.\n"); -+ return false; -+ } -+ -+ for (i = 0; i < *count; i++) -+ { -+ if (!cb || cb(display_data, egl->dpy, configs[i])) -+ { -+ egl->config = configs[i]; -+ break; -+ } -+ } -+ -+ free(configs); -+ -+ if (i == *count) -+ { -+ printf("[EGL]: No EGL config found which satifies requirements.\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+bool egl_init_context(egl_ctx_data_t *egl, -+ EGLenum platform, -+ void *display_data, -+ EGLint *major, EGLint *minor, -+ EGLint *count, const EGLint *attrib_ptr, -+ egl_accept_config_cb_t cb) -+{ -+ EGLDisplay dpy = get_egl_display(platform, display_data); -+ -+ if (dpy == EGL_NO_DISPLAY) -+ { -+ printf("[EGL]: Couldn't get EGL display.\n"); -+ return false; -+ } -+ -+ egl->dpy = dpy; -+ -+ if (!egl_initialize(egl->dpy, major, minor)) -+ return false; -+ -+ printf("[EGL]: EGL version: %d.%d\n", *major, *minor); -+ -+ return egl_init_context_common(egl, count, attrib_ptr, cb, -+ display_data); -+} -+ -+bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs) -+{ -+ EGLContext ctx = _egl_create_context(egl->dpy, egl->config, EGL_NO_CONTEXT, -+ egl_attribs); -+ -+ if (ctx == EGL_NO_CONTEXT) -+ return false; -+ -+ egl->ctx = ctx; -+ -+ return true; -+} -+ -+bool egl_create_surface(egl_ctx_data_t *egl, void *native_window) -+{ -+ EGLint window_attribs[] = { -+ EGL_RENDER_BUFFER, EGL_BACK_BUFFER, -+ EGL_NONE, -+ }; -+ -+ egl->surf = _egl_create_window_surface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs); -+ -+ if (egl->surf == EGL_NO_SURFACE) -+ return false; -+ -+ /* Connect the context to the surface. */ -+ if (!_egl_make_current(egl->dpy, egl->surf, egl->surf, egl->ctx)) -+ return false; -+ -+ printf("[EGL]: Current context: %p.\n", (void*)_egl_get_current_context()); -+ -+ return true; -+} -+ -+bool egl_has_config(egl_ctx_data_t *egl) -+{ -+ if (!egl->config) -+ { -+ printf("[EGL]: No EGL configurations available.\n"); -+ return false; -+ } -+ return true; -+} -+ -+ -+ -+bool drm_get_encoder(int fd); -+ -+/* Restore the original CRTC. */ -+void drm_restore_crtc(void); -+ -+bool drm_get_resources(int fd); -+ -+void drm_setup(int fd); -+ -+void drm_free(void); -+ -+bool drm_get_connector(int fd); -+ -+float drm_get_refresh_rate(void *data); -+ -+static bool drm_wait_flip(int timeout) -+{ -+ g_drm_fds.revents = 0; -+ -+ if (poll(&g_drm_fds, 1, timeout) < 0) -+ return false; -+ -+ if (g_drm_fds.revents & (POLLHUP | POLLERR)) -+ return false; -+ -+ if (g_drm_fds.revents & POLLIN) -+ { -+ drmHandleEvent(g_drm_fd, &g_drm_evctx); -+ return true; -+ } -+ -+ return false; -+} -+ -+/* TODO/FIXME - globals */ -+drmEventContext g_drm_evctx; -+struct pollfd g_drm_fds; -+uint32_t g_connector_id = 0; -+int g_drm_fd = 0; -+uint32_t g_crtc_id = 0; -+drmModeCrtc *g_orig_crtc = NULL; -+drmModeConnector *g_drm_connector = NULL; -+drmModeModeInfo *g_drm_mode = NULL; -+ -+/* TODO/FIXME - static globals */ -+static drmModeRes *g_drm_resources = NULL; -+static drmModeEncoder *g_drm_encoder = NULL; -+ -+/* Restore the original CRTC. */ -+void drm_restore_crtc(void) -+{ -+ if (!g_orig_crtc) -+ return; -+ -+ drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, -+ g_orig_crtc->buffer_id, -+ g_orig_crtc->x, -+ g_orig_crtc->y, -+ &g_connector_id, 1, &g_orig_crtc->mode); -+ -+ drmModeFreeCrtc(g_orig_crtc); -+ g_orig_crtc = NULL; -+} -+ -+bool drm_get_resources(int fd) -+{ -+ g_drm_resources = drmModeGetResources(fd); -+ if (!g_drm_resources) -+ { -+ printf("[DRM]: Couldn't get device resources.\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool drm_get_connector(int fd) -+{ -+ unsigned i; -+ unsigned monitor_index_count = 0; -+ unsigned monitor = 1; -+ -+ /* Enumerate all connectors. */ -+ -+ printf("[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); -+ -+ for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ { -+ drmModeConnectorPtr conn = drmModeGetConnector( -+ fd, g_drm_resources->connectors[i]); -+ -+ if (conn) -+ { -+ bool connected = conn->connection == DRM_MODE_CONNECTED; -+ printf("[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no"); -+ printf("[DRM]: Connector %d has %d modes.\n", i, conn->count_modes); -+ if (connected && conn->count_modes > 0) -+ { -+ monitor_index_count++; -+ printf("[DRM]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index_count); -+ } -+ drmModeFreeConnector(conn); -+ } -+ } -+ -+ monitor_index_count = 0; -+ -+ for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ { -+ g_drm_connector = drmModeGetConnector(fd, -+ g_drm_resources->connectors[i]); -+ -+ if (!g_drm_connector) -+ continue; -+ if (g_drm_connector->connection == DRM_MODE_CONNECTED -+ && g_drm_connector->count_modes > 0) -+ { -+ monitor_index_count++; -+ if (monitor_index_count == monitor) -+ { -+ printf("\n[DRM]: Matched monitor / connector\n"); -+ break; -+ } -+ } -+ -+ drmModeFreeConnector(g_drm_connector); -+ g_drm_connector = NULL; -+ } -+ -+ if (!g_drm_connector) -+ { -+ printf("[DRM]: Couldn't get device connector.\n"); -+ return false; -+ } -+ return true; -+} -+ -+bool drm_get_encoder(int fd) -+{ -+ unsigned i; -+ -+ for (i = 0; (int)i < g_drm_resources->count_encoders; i++) -+ { -+ g_drm_encoder = drmModeGetEncoder(fd, g_drm_resources->encoders[i]); -+ -+ if (!g_drm_encoder) -+ continue; -+ -+ if (g_drm_encoder->encoder_id == g_drm_connector->encoder_id) -+ break; -+ -+ drmModeFreeEncoder(g_drm_encoder); -+ g_drm_encoder = NULL; -+ } -+ -+ if (!g_drm_encoder) -+ { -+ printf("[DRM]: Couldn't find DRM encoder.\n"); -+ return false; -+ } -+ -+ for (i = 0; (int)i < g_drm_connector->count_modes; i++) -+ { -+ printf("[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", -+ i, -+ g_drm_connector->modes[i].name, -+ g_drm_connector->modes[i].hdisplay, -+ g_drm_connector->modes[i].vdisplay, -+ g_drm_connector->modes[i].vrefresh); -+ } -+ -+ return true; -+} -+ -+void drm_setup(int fd) -+{ -+ g_crtc_id = g_drm_encoder->crtc_id; -+ g_connector_id = g_drm_connector->connector_id; -+ g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); -+ if (!g_orig_crtc) -+ printf("[DRM]: Cannot find original CRTC.\n"); -+} -+ -+float drm_get_refresh_rate(void *data) -+{ -+ float refresh_rate = 0.0f; -+ -+ if (g_drm_mode) -+ { -+ refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal; -+ } -+ -+ return refresh_rate; -+} -+ -+void drm_free(void) -+{ -+ if (g_drm_encoder) -+ drmModeFreeEncoder(g_drm_encoder); -+ if (g_drm_connector) -+ drmModeFreeConnector(g_drm_connector); -+ if (g_drm_resources) -+ drmModeFreeResources(g_drm_resources); -+ -+ memset(&g_drm_fds, 0, sizeof(struct pollfd)); -+ memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -+ -+ g_drm_encoder = NULL; -+ g_drm_connector = NULL; -+ g_drm_resources = NULL; -+} -+ -+typedef struct gfx_ctx_drm_data -+{ -+ egl_ctx_data_t egl; -+ int fd; -+ int interval; -+ unsigned fb_width; -+ unsigned fb_height; -+ -+ bool core_hw_context_enable; -+ bool waiting_for_flip; -+ struct gbm_bo *bo; -+ struct gbm_bo *next_bo; -+ struct gbm_surface *gbm_surface; -+ struct gbm_device *gbm_dev; -+} gfx_ctx_drm_data_t; -+ -+static gfx_ctx_drm_data* g_drm; -+ -+struct drm_fb -+{ -+ struct gbm_bo *bo; -+ uint32_t fb_id; -+}; -+ -+static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) -+{ -+ struct drm_fb *fb = (struct drm_fb*)data; -+ -+ if (fb && fb->fb_id) -+ drmModeRmFB(g_drm_fd, fb->fb_id); -+ -+ free(fb); -+} -+ -+static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) -+{ -+ int ret; -+ unsigned width, height, stride, handle; -+ struct drm_fb *fb = (struct drm_fb*)calloc(1, sizeof(*fb)); -+ -+ fb->bo = bo; -+ -+ width = gbm_bo_get_width(bo); -+ height = gbm_bo_get_height(bo); -+ stride = gbm_bo_get_stride(bo); -+ handle = gbm_bo_get_handle(bo).u32; -+ -+ printf("[KMS]: New FB: %ux%u (stride: %u).\n", -+ width, height, stride); -+ -+ ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, -+ stride, handle, &fb->fb_id); -+ if (ret < 0) -+ goto error; -+ -+ gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback); -+ return fb; -+ -+error: -+ printf("[KMS]: Failed to create FB: %s\n", strerror(errno)); -+ free(fb); -+ return NULL; -+} -+ -+static void gfx_ctx_drm_swap_interval(void *data, int interval) -+{ -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ drm->interval = interval; -+ -+ if (interval > 1) -+ printf("[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); -+} -+ -+static void drm_flip_handler(int fd, unsigned frame, -+ unsigned sec, unsigned usec, void *data) -+{ -+#if 0 -+ static unsigned first_page_flip; -+ static unsigned last_page_flip; -+ -+ if (!first_page_flip) -+ first_page_flip = frame; -+ -+ if (last_page_flip) -+ { -+ unsigned missed = frame - last_page_flip - 1; -+ if (missed) -+ printf("[KMS]: Missed %u VBlank(s) (Frame: %u, DRM frame: %u).\n", -+ missed, frame - first_page_flip, frame); -+ } -+ -+ last_page_flip = frame; -+#endif -+ -+ *(bool*)data = false; -+} -+ -+static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t *drm, bool block) -+{ -+ int timeout = 0; -+ -+ if (!drm->waiting_for_flip) -+ return false; -+ -+ if (block) -+ timeout = -1; -+ -+ while (drm->waiting_for_flip) -+ { -+ if (!drm_wait_flip(timeout)) -+ break; -+ } -+ -+ if (drm->waiting_for_flip) -+ { printf("\nwait flip 2"); return true; } -+ -+ /* Page flip has taken place. */ -+ -+ /* This buffer is not on-screen anymore. Release it to GBM. */ -+ gbm_surface_release_buffer(drm->gbm_surface, drm->bo); -+ /* This buffer is being shown now. */ -+ drm->bo = drm->next_bo; -+ return false; -+} -+ -+static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t *drm) -+{ -+ struct drm_fb *fb = NULL; -+ -+ drm->next_bo = gbm_surface_lock_front_buffer(drm->gbm_surface); -+ fb = (struct drm_fb*)gbm_bo_get_user_data(drm->next_bo); -+ -+ if (!fb) -+ fb = (struct drm_fb*)drm_fb_get_from_bo(drm->next_bo); -+ -+ if (drmModePageFlip(g_drm_fd, g_crtc_id, fb->fb_id, -+ DRM_MODE_PAGE_FLIP_EVENT, &drm->waiting_for_flip) == 0) -+ return true; -+ -+ /* Failed to queue page flip. */ -+ printf("\nFailed to queue page flip\n"); -+ return false; -+} -+ -+static void gfx_ctx_drm_swap_buffers(void *data) -+{ -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ unsigned max_swapchain_images = 3; //settings->uints.video_max_swapchain_images; -+ -+ egl_swap_buffers(&drm->egl); -+ -+ /* I guess we have to wait for flip to have taken -+ * place before another flip can be queued up. -+ * -+ * If true, we are still waiting for a flip -+ * (nonblocking mode, so just drop the frame). */ -+ if (gfx_ctx_drm_wait_flip(drm, drm->interval)) -+ { printf("\nwait flip"); return; } -+ -+ drm->waiting_for_flip = gfx_ctx_drm_queue_flip(drm); -+ -+ /* Triple-buffered page flips */ -+ if (max_swapchain_images >= 3 && -+ gbm_surface_has_free_buffers(drm->gbm_surface)) -+ return; -+ -+ gfx_ctx_drm_wait_flip(drm, true); -+} -+ -+static void gfx_ctx_drm_get_video_size(void *data, -+ unsigned *width, unsigned *height) -+{ -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ -+ if (!drm) -+ { -+ printf("\nCannot get drm video size\n"); -+ return; -+ } -+ -+ *width = drm->fb_width; -+ *height = drm->fb_height; -+} -+ -+static void free_drm_resources(gfx_ctx_drm_data_t *drm) -+{ -+ if (!drm) -+ return; -+ -+ /* Restore original CRTC. */ -+ drm_restore_crtc(); -+ -+ if (drm->gbm_surface) -+ gbm_surface_destroy(drm->gbm_surface); -+ -+ if (drm->gbm_dev) -+ gbm_device_destroy(drm->gbm_dev); -+ -+ drm_free(); -+ -+ if (drm->fd >= 0) -+ { -+ if (g_drm_fd >= 0) -+ { -+ drmDropMaster(g_drm_fd); -+ close(drm->fd); -+ } -+ } -+ -+ drm->gbm_surface = NULL; -+ drm->gbm_dev = NULL; -+ g_drm_fd = -1; -+} -+ -+static void gfx_ctx_drm_destroy_resources(gfx_ctx_drm_data_t *drm) -+{ -+ if (!drm) -+ return; -+ -+ /* Make sure we acknowledge all page-flips. */ -+ gfx_ctx_drm_wait_flip(drm, true); -+ -+ egl_destroy(&drm->egl); -+ -+ free_drm_resources(drm); -+ -+ g_drm_mode = NULL; -+ g_crtc_id = 0; -+ g_connector_id = 0; -+ -+ drm->fb_width = 0; -+ drm->fb_height = 0; -+ -+ drm->bo = NULL; -+ drm->next_bo = NULL; -+} -+ -+static void *gfx_ctx_drm_init() -+{ -+ int fd, i; -+ unsigned monitor_index; -+ unsigned gpu_index = 0; -+ const char *gpu = NULL; -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)calloc(1, sizeof(gfx_ctx_drm_data_t)); -+ -+ if (!drm) -+ return NULL; -+ drm->fd = -1; -+ -+ free_drm_resources(drm); -+ -+ drm->fd = open("/dev/dri/card0", O_RDWR); -+ if (drm->fd < 0) -+ { -+ printf("[KMS]: Couldn't open DRM device.\n"); -+ return nullptr; -+ } -+ -+ fd = drm->fd; -+ -+ if (!drm_get_resources(fd)) -+ { -+ printf("[KMS]: drm_get_resources failed\n"); -+ return nullptr; -+ } -+ -+ if (!drm_get_connector(fd)) -+ { -+ printf("[KMS]: drm_get_connector failed\n"); -+ return nullptr; -+ } -+ -+ if (!drm_get_encoder(fd)) -+ { -+ printf("[KMS]: drm_get_encoder failed\n"); -+ return nullptr; -+ } -+ -+ drm_setup(fd); -+ -+ /* Choose the optimal video mode for get_video_size(): -+ - the current video mode from the CRTC -+ - otherwise pick first connector mode */ -+ if (g_orig_crtc->mode_valid) -+ { -+ drm->fb_width = g_orig_crtc->mode.hdisplay; -+ drm->fb_height = g_orig_crtc->mode.vdisplay; -+ } -+ else -+ { -+ drm->fb_width = g_drm_connector->modes[0].hdisplay; -+ drm->fb_height = g_drm_connector->modes[0].vdisplay; -+ } -+ -+ drmSetMaster(g_drm_fd); -+ -+ drm->gbm_dev = gbm_create_device(fd); -+ -+ if (!drm->gbm_dev) -+ { -+ printf("[KMS]: Couldn't create GBM device.\n"); -+ return nullptr; -+ } -+ -+ /* Setup the flip handler. */ -+ g_drm_fds.fd = fd; -+ g_drm_fds.events = POLLIN; -+ g_drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; -+ g_drm_evctx.page_flip_handler = drm_flip_handler; -+ -+ g_drm_fd = fd; -+ -+ return drm; -+ -+error: -+ gfx_ctx_drm_destroy_resources(drm); -+ -+ if (drm) -+ free(drm); -+ -+ return NULL; -+} -+ -+static EGLint *gfx_ctx_drm_egl_fill_attribs( -+ gfx_ctx_drm_data_t *drm, EGLint *attr) -+{ -+ *attr++ = EGL_CONTEXT_CLIENT_VERSION; -+ *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; -+#ifdef EGL_KHR_create_context -+ if (drm->egl.minor > 0) -+ { -+ *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; -+ *attr++ = drm->egl.minor; -+ } -+#endif -+ -+ *attr = EGL_NONE; -+ return attr; -+} -+ -+static bool gbm_choose_xrgb8888_cb(void *display_data, EGLDisplay dpy, EGLConfig config) -+{ -+ EGLint r, g, b, id; -+ (void)display_data; -+ -+ /* Makes sure we have 8 bit color. */ -+ if (!egl_get_config_attrib(dpy, config, EGL_RED_SIZE, &r)) -+ return false; -+ if (!egl_get_config_attrib(dpy, config, EGL_GREEN_SIZE, &g)) -+ return false; -+ if (!egl_get_config_attrib(dpy, config, EGL_BLUE_SIZE, &b)) -+ return false; -+ -+ if (r != 8 || g != 8 || b != 8) -+ return false; -+ -+ if (!egl_get_config_attrib(dpy, config, EGL_NATIVE_VISUAL_ID, &id)) -+ return false; -+ -+ return id == GBM_FORMAT_XRGB8888; -+} -+ -+#define DRM_EGL_ATTRIBS_BASE \ -+ EGL_SURFACE_TYPE, 0/*EGL_WINDOW_BIT*/, \ -+ EGL_RED_SIZE, 8, \ -+ EGL_GREEN_SIZE, 8, \ -+ EGL_BLUE_SIZE, 8, \ -+ EGL_ALPHA_SIZE, 0, \ -+ EGL_DEPTH_SIZE, 0 -+ -+#ifdef EGL_KHR_create_context -+ static const EGLint egl_attribs_gles3[] = { -+ DRM_EGL_ATTRIBS_BASE, -+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, -+ EGL_NONE, -+ }; -+#endif -+ -+static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) -+{ -+ const EGLint *attrib_ptr = NULL; -+ EGLint major; -+ EGLint minor; -+ EGLint n; -+ EGLint egl_attribs[16]; -+ EGLint *egl_attribs_ptr = NULL; -+ EGLint *attr = NULL; -+ -+ attrib_ptr = egl_attribs_gles3; -+ -+ if (!egl_init_context(&drm->egl, EGL_PLATFORM_GBM_KHR, -+ (EGLNativeDisplayType)drm->gbm_dev, &major, -+ &minor, &n, attrib_ptr, gbm_choose_xrgb8888_cb)) -+ { -+ printf("\n[EGL] Cannot init context"); -+ goto error; -+ } -+ attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); -+ egl_attribs_ptr = &egl_attribs[0]; -+ -+ if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) -+ ? egl_attribs_ptr : NULL)) -+ { -+ printf("\n[EGL] Cannot create context"); -+ goto error; -+ } -+ -+ if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface)) -+ { -+ printf("\n[EGL] Cannot create context"); -+ return false; -+ } -+ -+ egl_swap_buffers(&drm->egl); -+ -+ return true; -+ -+error: -+ egl_report_error(); -+ return false; -+} -+ -+static bool gfx_ctx_drm_set_video_mode(void *data, -+ unsigned width, unsigned height, -+ bool fullscreen) -+{ -+ float refresh_mod; -+ int i, ret = 0; -+ struct drm_fb *fb = NULL; -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ bool black_frame_insertion = false; //settings->bools.video_black_frame_insertion; -+ float video_refresh_rate = 60; //settings->floats.video_refresh_rate; -+ -+ if (!drm) -+ return false; -+ -+ /* If we use black frame insertion, -+ * we fake a 60 Hz monitor for 120 Hz one, -+ * etc, so try to match that. */ -+ refresh_mod = black_frame_insertion -+ ? 0.5f : 1.0f; -+ -+ /* Find desired video mode, and use that. -+ * If not fullscreen, we get desired windowed size, -+ * which is not appropriate. */ -+ if ((width == 0 && height == 0) || !fullscreen) -+ g_drm_mode = &g_drm_connector->modes[0]; -+ else -+ { -+ /* Try to match refresh_rate as closely as possible. -+ * -+ * Lower resolutions tend to have multiple supported -+ * refresh rates as well. -+ */ -+ float minimum_fps_diff = 0.0f; -+ -+ /* Find best match. */ -+ for (i = 0; i < g_drm_connector->count_modes; i++) -+ { -+ float diff; -+ if (width != g_drm_connector->modes[i].hdisplay || -+ height != g_drm_connector->modes[i].vdisplay) -+ continue; -+ -+ diff = fabsf(refresh_mod * g_drm_connector->modes[i].vrefresh -+ - video_refresh_rate); -+ -+ if (!g_drm_mode || diff < minimum_fps_diff) -+ { -+ g_drm_mode = &g_drm_connector->modes[i]; -+ minimum_fps_diff = diff; -+ } -+ } -+ } -+ -+ if (!g_drm_mode) -+ { -+ printf("[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", -+ width, height); -+ goto error; -+ } -+ -+ drm->fb_width = g_drm_mode->hdisplay; -+ drm->fb_height = g_drm_mode->vdisplay; -+ -+ /* Create GBM surface. */ -+ drm->gbm_surface = gbm_surface_create( -+ drm->gbm_dev, -+ drm->fb_width, -+ drm->fb_height, -+ GBM_FORMAT_XRGB8888, -+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); -+ -+ if (!drm->gbm_surface) -+ { -+ printf("[KMS/EGL]: Couldn't create GBM surface.\n"); -+ goto error; -+ } -+ -+ if (!gfx_ctx_drm_egl_set_video_mode(drm)) -+ { -+ printf("[KMS/EGL]: Couldn't set EGL video mode.\n"); -+ goto error; -+ } -+ -+ drm->bo = gbm_surface_lock_front_buffer(drm->gbm_surface); -+ -+ fb = (struct drm_fb*)gbm_bo_get_user_data(drm->bo); -+ -+ if (!fb) -+ fb = drm_fb_get_from_bo(drm->bo); -+ -+ ret = drmModeSetCrtc(g_drm_fd, -+ g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode); -+ if (ret < 0) -+ { -+ printf("[KMS/EGL]: drmModeSetCrtc failed\n"); -+ goto error; -+ } -+ return true; -+ -+error: -+ gfx_ctx_drm_destroy_resources(drm); -+ -+ if (drm) -+ free(drm); -+ -+ return false; -+} -+ -+static void gfx_ctx_drm_destroy(void *data) -+{ -+ gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ -+ if (!drm) -+ return; -+ -+ gfx_ctx_drm_destroy_resources(drm); -+ free(drm); -+} -+ -+#ifndef EGL_KHR_create_context -+#define EGL_KHR_create_context 1 -+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF -+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -+#endif /* EGL_KHR_create_context */ -+ -+GLContextEGLDRM::~GLContextEGLDRM() -+{ -+ DestroyWindowSurface(); -+ DestroyContext(); -+} -+ -+bool GLContextEGLDRM::IsHeadless() const -+{ -+ return false; -+} -+ -+void GLContextEGLDRM::Swap() -+{ -+ gfx_ctx_drm_swap_buffers(g_drm); -+} -+void GLContextEGLDRM::SwapInterval(int interval) -+{ -+ gfx_ctx_drm_swap_interval(g_drm, interval); -+ egl_set_swap_interval(m_egl, interval); -+} -+ -+void* GLContextEGLDRM::GetFuncAddress(const std::string& name) -+{ -+ return (void*)eglGetProcAddress(name.c_str()); -+} -+ -+// Create rendering window. -+// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -+bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) -+{ -+ EGLint egl_major, egl_minor; -+ bool supports_core_profile = false; -+ -+ g_drm = (gfx_ctx_drm_data_t*)gfx_ctx_drm_init(); -+ egl_bind_api(EGL_OPENGL_ES_API); -+ gfx_ctx_drm_set_video_mode(g_drm, 1920, 1080, true); -+ m_backbuffer_width = 1920; -+ m_backbuffer_height = 1080; -+ -+ m_egl = &g_drm->egl; -+ m_opengl_mode = Mode::OpenGLES; -+ -+ m_supports_surfaceless = false; -+ const char* ext = eglQueryString(m_egl->dpy, EGL_EXTENSIONS); -+ if (strstr(ext, "EGL_KHR_surfaceless_context")) -+ { -+ printf("\nFound EGL_KHR_surfaceless_context\n"); -+ m_supports_surfaceless =true; -+ } -+ eglBindAPI(EGL_OPENGL_ES_API); -+ -+ return MakeCurrent(); -+} -+ -+std::unique_ptr GLContextEGLDRM::CreateSharedContext() -+{ -+ printf("\nvoid GLContextEGLDRM::CreateSharedContext"); -+ std::unique_ptr new_context = std::make_unique(); -+ new_context->m_egl = (egl_ctx_data_t*)malloc(sizeof(egl_ctx_data_t)); -+ memcpy(new_context->m_egl, m_egl, sizeof(egl_ctx_data_t)); -+ -+ eglBindAPI(EGL_OPENGL_ES_API); -+ EGLint egl_attribs[16]; -+ EGLint *egl_attribs_ptr = NULL; -+ const EGLint *attrib_ptr = egl_attribs_gles3; -+ EGLint* attr = gfx_ctx_drm_egl_fill_attribs(g_drm, egl_attribs); -+ egl_attribs_ptr = &egl_attribs[0]; -+ new_context->m_egl->ctx = eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); -+ if (!new_context->m_egl->ctx) -+ { -+ printf("\nError: eglCreateContext failed\n"); -+ egl_report_error(); -+ return nullptr; -+ } -+ eglBindAPI(EGL_OPENGL_ES_API); -+ new_context->m_opengl_mode = Mode::OpenGLES; -+ new_context->m_supports_surfaceless = m_supports_surfaceless; -+ new_context->m_is_shared = true; -+ if (!new_context->CreateWindowSurface()) -+ { -+ printf("\nError: CreateWindowSurface failed\n"); -+ egl_report_error(); -+ return nullptr; -+ } -+ return new_context; -+} -+ -+bool GLContextEGLDRM::CreateWindowSurface() -+{ -+ EGLint attrib_list[] = { EGL_NONE, }; -+ printf("\nvoid GLContextEGLDRM::CreateWindowSurface"); -+ if (m_supports_surfaceless) -+ { -+ m_egl->surf = EGL_NO_SURFACE; -+ printf("\nCreated surfaceless context\n"); -+ return true; -+ } -+ -+ if (!IsHeadless()) -+ { -+ if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) -+ { -+ printf("\negl_create_surface failed, trying pbuffer\n"); -+ egl_report_error(); -+ goto pbuffer; -+ } -+ printf("\nm_egl_surface=0x%x",m_egl->surf); -+ // Get dimensions from the surface. -+ EGLint surface_width = 1, surface_height = 1; -+ if (!eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_WIDTH, &surface_width) || -+ !eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_HEIGHT, &surface_height)) -+ { -+ printf("Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); -+ } -+ m_backbuffer_width = static_cast(surface_width); -+ m_backbuffer_height = static_cast(surface_height); -+ return true; -+ } -+ -+pbuffer: -+ m_egl->surf = eglCreatePbufferSurface(m_egl->dpy, m_egl->config, attrib_list); -+ if (!m_egl->surf) -+ { -+ printf("\nError: eglCreatePbufferSurface failed\n"); -+ egl_report_error(); -+ return false; -+ } -+ return true; -+} -+ -+void GLContextEGLDRM::DestroyWindowSurface() -+{ -+ printf("\nvoid GLContextEGLDRM::DestroyWindowSurface"); -+ if (m_egl->surf == EGL_NO_SURFACE) -+ return; -+ -+ if (eglGetCurrentSurface(EGL_DRAW) == m_egl->surf) -+ eglMakeCurrent(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (!eglDestroySurface(m_egl->dpy, m_egl->surf)) -+ printf("\nCould not destroy window surface."); -+ m_egl->surf = EGL_NO_SURFACE; -+} -+ -+bool GLContextEGLDRM::MakeCurrent() -+{ -+ printf("\nvoid GLContextEGLDRM::MakeCurrent()"); -+ return _egl_make_current(m_egl->dpy, g_drm->egl.surf, g_drm->egl.surf, m_egl->ctx); -+} -+ -+void GLContextEGLDRM::UpdateSurface(void* window_handle) -+{ -+ printf("\nvoid GLContextEGLDRM::UpdateSurface(void* window_handle)"); -+ ClearCurrent(); -+ DestroyWindowSurface(); -+ CreateWindowSurface(); -+ MakeCurrent(); -+} -+ -+bool GLContextEGLDRM::ClearCurrent() -+{ -+ printf("\nvoid GLContextEGLDRM::ClearCurrent()"); -+ return _egl_make_current(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+} -+ -+// Close backend -+void GLContextEGLDRM::DestroyContext() -+{ -+ printf("\nGLContextEGLDRM::DestroyContext()"); -+if (!m_egl->ctx) -+ return; -+ -+ if (eglGetCurrentContext() == m_egl->ctx) -+ eglMakeCurrent(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (!eglDestroyContext(m_egl->dpy, m_egl->ctx)) -+ printf("\nCould not destroy drawing context."); -+ if (!m_is_shared && !eglTerminate(m_egl->dpy)) -+ printf("\nCould not destroy display connection."); -+ m_egl->ctx = EGL_NO_CONTEXT; -+ m_egl->dpy = EGL_NO_DISPLAY; -+} -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -new file mode 100644 -index 00000000000..b8615cf7e67 ---- /dev/null -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -0,0 +1,59 @@ -+// Copyright 2008 Dolphin Emulator Project -+// Licensed under GPLv2+ -+// Refer to the license.txt file included. -+ -+#pragma once -+ -+#include -+#include -+#include -+#include -+ -+#include "Common/GL/GLContext.h" -+ -+typedef struct -+{ -+ EGLContext ctx; -+ EGLSurface surf; -+ EGLDisplay dpy; -+ EGLConfig config; -+ int interval; -+ -+ unsigned major; -+ unsigned minor; -+ -+} egl_ctx_data_t; -+ -+class GLContextEGLDRM : public GLContext -+{ -+public: -+ virtual ~GLContextEGLDRM() override; -+ -+ bool IsHeadless() const override; -+ -+ std::unique_ptr CreateSharedContext() override; -+ -+ bool MakeCurrent() override; -+ bool ClearCurrent() override; -+ -+ void UpdateSurface(void* window_handle) override; -+ -+ void Swap() override; -+ void SwapInterval(int interval) override; -+ -+ void* GetFuncAddress(const std::string& name) override; -+ -+protected: -+ bool Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) override; -+ -+ bool CreateWindowSurface(); -+ void DestroyWindowSurface(); -+ void DestroyContext(); -+ -+ WindowSystemInfo m_wsi = {}; -+ -+ bool m_supports_surfaceless = false; -+ std::vector m_attribs; -+ -+ egl_ctx_data_t* m_egl; -+}; ---- a/Source/Core/Common/WindowSystemInfo.h 2021-02-21 20:51:42.393957185 +0100 -+++ b/Source/Core/Common/WindowSystemInfo.h 2021-02-21 20:51:50.440623503 +0100 -@@ -14,6 +14,7 @@ - Wayland, - FBDev, - Haiku, -+ DRM - }; - - struct WindowSystemInfo -diff --git a/Source/Core/DolphinNoGUI/CMakeLists.txt b/Source/Core/DolphinNoGUI/CMakeLists.txt -index 3943582ad20..d534eb9522f 100644 ---- a/Source/Core/DolphinNoGUI/CMakeLists.txt -+++ b/Source/Core/DolphinNoGUI/CMakeLists.txt -@@ -15,6 +15,7 @@ endif() - - if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp) -+ target_sources(dolphin-nogui PRIVATE PlatformDRM.cpp) - endif() - - set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) -diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -index 0bf4df23b87..9faf1152de2 100644 ---- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp -+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -@@ -118,6 +118,8 @@ static std::unique_ptr GetPlatform(const optparse::Values& options) - #ifdef __linux__ - if (platform_name == "fbdev" || platform_name.empty()) - return Platform::CreateFBDevPlatform(); -+ if (platform_name == "drm" || platform_name.empty()) -+ return Platform::CreateDRMPlatform(); - #endif - - #ifdef _WIN32 -@@ -141,7 +143,8 @@ int main(int argc, char* argv[]) - "headless" - #ifdef __linux__ - , -- "fbdev" -+ "fbdev", -+ "drm" - #endif - #if HAVE_X11 - , -diff --git a/Source/Core/DolphinNoGUI/Platform.h b/Source/Core/DolphinNoGUI/Platform.h -index b0d98e58bef..bc8c57a3cef 100644 ---- a/Source/Core/DolphinNoGUI/Platform.h -+++ b/Source/Core/DolphinNoGUI/Platform.h -@@ -38,6 +38,7 @@ class Platform - - #ifdef __linux__ - static std::unique_ptr CreateFBDevPlatform(); -+ static std::unique_ptr CreateDRMPlatform(); - #endif - - #ifdef _WIN32 -diff --git a/Source/Core/DolphinNoGUI/PlatformDRM.cpp b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -new file mode 100644 -index 00000000000..1784aaae4f8 ---- /dev/null -+++ b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -@@ -0,0 +1,83 @@ -+// Copyright 2020 Dolphin Emulator Project -+// Licensed under GPLv2+ -+// Refer to the license.txt file included. -+ -+#include -+ -+#include "DolphinNoGUI/Platform.h" -+ -+#include "Common/MsgHandler.h" -+#include "Core/ConfigManager.h" -+#include "Core/Core.h" -+#include "Core/State.h" -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "VideoCommon/RenderBase.h" -+ -+namespace -+{ -+class PlatformDRM : public Platform -+{ -+public: -+ ~PlatformDRM() override; -+ -+ bool Init() override; -+ void SetTitle(const std::string& string) override; -+ void MainLoop() override; -+ -+ WindowSystemInfo GetWindowSystemInfo() const override; -+ -+private: -+}; -+ -+PlatformDRM::~PlatformDRM() -+{ -+} -+ -+bool PlatformDRM::Init() -+{ -+ return true; -+} -+ -+void PlatformDRM::SetTitle(const std::string& string) -+{ -+ std::fprintf(stdout, "%s\n", string.c_str()); -+} -+ -+void PlatformDRM::MainLoop() -+{ -+ while (IsRunning()) -+ { -+ UpdateRunningFlag(); -+ Core::HostDispatchJobs(); -+ -+ // TODO: Is this sleep appropriate? -+ std::this_thread::sleep_for(std::chrono::milliseconds(1)); -+ } -+} -+ -+WindowSystemInfo PlatformDRM::GetWindowSystemInfo() const -+{ -+ WindowSystemInfo wsi; -+ wsi.type = WindowSystemType::DRM; -+ wsi.display_connection = nullptr; // EGL_DEFAULT_DISPLAY -+ wsi.render_window = nullptr; -+ wsi.render_surface = nullptr; -+ return wsi; -+} -+} // namespace -+ -+std::unique_ptr Platform::CreateDRMPlatform() -+{ -+ return std::make_unique(); -+} - -From 0f2be8f1a2d9162ac3f02bfebc2a0674b149667b Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 00:27:27 +0200 -Subject: [PATCH 02/25] Fix missing Cmake modules and code required to properly - detect and link libdrm and libgbm - ---- - CMake/FindDRM.cmake | 41 --------------------------- - CMake/FindLibdrm.cmake | 45 ++++++++++++++++++++++++++++++ - CMake/FindLibgbm.cmake | 46 +++++++++++++++++++++++++++++++ - Source/Core/Common/CMakeLists.txt | 21 ++++++++------ - 4 files changed, 103 insertions(+), 50 deletions(-) - delete mode 100644 CMake/FindDRM.cmake - create mode 100644 CMake/FindLibdrm.cmake - create mode 100644 CMake/FindLibgbm.cmake - -diff --git a/CMake/FindDRM.cmake b/CMake/FindDRM.cmake -deleted file mode 100644 -index 10d554f0fcd..00000000000 ---- a/CMake/FindDRM.cmake -+++ /dev/null -@@ -1,41 +0,0 @@ --# --# Try to find DRM library and include path. --# Once done this will define --# --# DRM_FOUND --# DRM_INCLUDE_PATH --# DRM_LIBRARY --# -- --FIND_PATH(DRM_INCLUDE_PATH -- NAMES -- drm.h -- PATHS -- ${CMAKE_INCLUDE_PATH}/include/libdrm/ -- ~/include/libdrm/ -- /usr/include/libdrm/ -- /usr/local/include/libdrm/ -- /sw/include/libdrm/ -- /opt/local/include/libdrm/ -- DOC "The directory where drm.h resides") --FIND_LIBRARY(DRM_LIBRARY -- NAMES DRM drm -- PATHS -- ${CMAKE_LIBRARY_PATH}/lib/ -- ~/lib/ -- /usr/lib64 -- /usr/lib -- /usr/local/lib64 -- /usr/local/lib -- /sw/lib -- /opt/local/lib -- DOC "The DRM library") -- --IF(DRM_INCLUDE_PATH) -- INCLUDE_DIRECTORIES(${DRM_INCLUDE_PATH}) -- SET(DRM_FOUND 1 CACHE STRING "Set to 1 if DRM is found, 0 otherwise") --ELSE(DRM_INCLUDE_PATH) -- SET(DRM_FOUND 0 CACHE STRING "Set to 1 if DRM is found, 0 otherwise") --ENDIF(DRM_INCLUDE_PATH) -- --MARK_AS_ADVANCED(DRM_FOUND) -diff --git a/CMake/FindLibdrm.cmake b/CMake/FindLibdrm.cmake -new file mode 100644 -index 00000000000..4b39de31e9b ---- /dev/null -+++ b/CMake/FindLibdrm.cmake -@@ -0,0 +1,45 @@ -+#.rst: -+# FindLibDRM -+# ---------- -+# Finds the LibDRM library -+# -+# This will define the following variables:: -+# -+# LIBDRM_FOUND - system has LibDRM -+# LIBDRM_INCLUDE_DIRS - the LibDRM include directory -+# LIBDRM_LIBRARIES - the LibDRM libraries -+# -+# and the following imported targets:: -+# -+# LibDRM::LibDRM - The LibDRM library -+ -+if(PKG_CONFIG_FOUND) -+ pkg_check_modules(PC_LIBDRM libdrm>=2.4.82 QUIET) -+endif() -+ -+find_path(LIBDRM_INCLUDE_DIR NAMES drm.h -+ PATH_SUFFIXES libdrm drm -+ PATHS ${PC_LIBDRM_INCLUDEDIR}) -+find_library(LIBDRM_LIBRARY NAMES drm -+ PATHS ${PC_LIBDRM_LIBDIR}) -+ -+set(LIBDRM_VERSION ${PC_LIBDRM_VERSION}) -+ -+include(FindPackageHandleStandardArgs) -+find_package_handle_standard_args(LibDRM -+ REQUIRED_VARS LIBDRM_LIBRARY LIBDRM_INCLUDE_DIR -+ VERSION_VAR LIBDRM_VERSION) -+ -+if(LIBDRM_FOUND) -+ set(LIBDRM_LIBRARIES ${LIBDRM_LIBRARY}) -+ set(LIBDRM_INCLUDE_DIRS ${LIBDRM_INCLUDE_DIR}) -+ -+ if(NOT TARGET LIBDRM::LIBDRM) -+ add_library(LIBDRM::LIBDRM UNKNOWN IMPORTED) -+ set_target_properties(LIBDRM::LIBDRM PROPERTIES -+ IMPORTED_LOCATION "${LIBDRM_LIBRARY}" -+ INTERFACE_INCLUDE_DIRECTORIES "${LIBDRM_INCLUDE_DIR}") -+ endif() -+endif() -+ -+mark_as_advanced(LIBDRM_INCLUDE_DIR LIBDRM_LIBRARY) -diff --git a/CMake/FindLibgbm.cmake b/CMake/FindLibgbm.cmake -new file mode 100644 -index 00000000000..d2091cbfb42 ---- /dev/null -+++ b/CMake/FindLibgbm.cmake -@@ -0,0 +1,46 @@ -+# - Try to find gbm. -+# Once done, this will define -+# -+# LIBGBM_INCLUDE_DIRS - the gbm include directories -+# LIBGBM_LIBRARIES - link these to use gbm. -+# -+# Copyright (C) 2015 Igalia S.L. -+# -+# Redistribution and use in source and binary forms, with or without -+# modification, are permitted provided that the following conditions -+# are met: -+# 1. Redistributions of source code must retain the above copyright -+# notice, this list of conditions and the following disclaimer. -+# 2. Redistributions in binary form must reproduce the above copyright -+# notice, this list of conditions and the following disclaimer in the -+# documentation and/or other materials provided with the distribution. -+# -+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS -+# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS -+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ -+find_package(PkgConfig) -+pkg_check_modules(PC_LIBGBM gbm) -+ -+find_path(LIBGBM_INCLUDE_DIRS -+ NAMES gbm.h -+ HINTS ${PC_LIBGBM_INCLUDE_DIRS} ${PC_LIBGBM_INCUDEDIR} -+) -+ -+find_library(LIBGBM_LIBRARIES -+ NAMES gbm -+ HINTS ${PC_LIBGBM_LIBRARY_DIRS} ${PC_LIBGBM_LIBDIR} -+) -+ -+include(FindPackageHandleStandardArgs) -+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGBM DEFAULT_MSG LIBGBM_LIBRARIES) -+ -+mark_as_advanced(LIBGBM_INCLUDE_DIRS LIBGBM_LIBRARIES) -diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt -index e4754f81400..6e220d9047b 100644 ---- a/Source/Core/Common/CMakeLists.txt -+++ b/Source/Core/Common/CMakeLists.txt -@@ -222,17 +222,20 @@ target_sources(common PRIVATE - ) - - if(ENABLE_EGL AND EGL_FOUND) -- find_package(DRM MODULE QUIET) -- -- target_sources(common PRIVATE -+ find_package(Libdrm) -+ find_package(Libgbm) -+ if (LIBDRM_FOUND AND LIBGBM_FOUND) -+ target_sources(common PRIVATE - GL/GLInterface/EGL.cpp - GL/GLInterface/EGL.h -- ) -- if (DRM_FOUND) -- target_sources(common PRIVATE - GL/GLInterface/EGLDRM.cpp - GL/GLInterface/EGLDRM.h - ) -+ else() -+ target_sources(common PRIVATE -+ GL/GLInterface/EGL.cpp -+ GL/GLInterface/EGL.h -+ ) - endif() - if(ANDROID) - target_sources(common PRIVATE -@@ -245,9 +248,9 @@ if(ENABLE_EGL AND EGL_FOUND) - GL/GLInterface/EGLX11.h - ) - endif() -- if (DRM_FOUND) -- target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS} ${DRM_INCLUDE_DIRS}) -- target_link_libraries(common PUBLIC ${EGL_LIBRARIES} ${DRM_LIBRARY}) -+ if (LIBDRM_FOUND AND LIBGBM_FOUND) -+ target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS} ${LIBDRM_INCLUDE_DIRS} ${LIBGBM_INCLUDE_DIRS}) -+ target_link_libraries(common PUBLIC ${EGL_LIBRARIES} ${LIBDRM_LIBRARIES} ${LIBGBM_LIBRARIES}) - else() - target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS}) - target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) - -From 1fa6fbc5387ecffcd18887a4894c3c3db84bd80a Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 10:35:28 +0200 -Subject: [PATCH 03/25] Tidy up EGLDRM - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 430 +++++-------------- - Source/Core/Common/GL/GLInterface/EGLDRM.h | 4 - - 2 files changed, 107 insertions(+), 327 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 3996178d045..4b4ed1668e8 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -1,3 +1,9 @@ -+// Copyright 2020 Dolphin Emulator Project -+// Licensed under GPLv2+ -+// Refer to the license.txt file included. -+ -+// EGL DRM GBM code based on RetroArch, RetroArch licenses follows -+ - /* RetroArch - A frontend for libretro. - * Copyright (c) 2011-2017 - Daniel De Matteis - * -@@ -13,10 +19,6 @@ - * If not, see . - */ - --// Copyright 2012 Dolphin Emulator Project --// Licensed under GPLv2+ --// Refer to the license.txt file included. -- - #include - #include - #include -@@ -58,182 +60,82 @@ - #define EGL_PLATFORM_GBM_KHR 0x31D7 - #endif - --extern uint32_t g_connector_id; --extern int g_drm_fd; --extern uint32_t g_crtc_id; -- --extern struct pollfd g_drm_fds; -- --extern drmModeConnector *g_drm_connector; --extern drmModeModeInfo *g_drm_mode; --extern drmModeCrtc *g_orig_crtc; -- --extern drmEventContext g_drm_evctx; -- -- --void egl_report_error(void); -- --void egl_destroy(egl_ctx_data_t *egl); -- --void egl_terminate(EGLDisplay dpy); -- --void egl_swap_buffers(void *data); -- --void egl_set_swap_interval(egl_ctx_data_t *egl, int interval); -- --void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height); -+#ifndef EGL_KHR_create_context -+#define EGL_KHR_create_context 1 -+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF -+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -+#endif /* EGL_KHR_create_context */ - - typedef bool (*egl_accept_config_cb_t)(void *display_data, EGLDisplay dpy, EGLConfig config); - --bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor); -- --bool egl_init_context_common( -- egl_ctx_data_t *egl, EGLint *count, -- const EGLint *attrib_ptr, -- egl_accept_config_cb_t cb, -- void *display_data); -- --bool egl_init_context(egl_ctx_data_t *egl, -- EGLenum platform, -- void *display_data, -- EGLint *major, -- EGLint *minor, -- EGLint *n, -- const EGLint *attrib_ptr, -- egl_accept_config_cb_t cb); -- --bool egl_bind_api(EGLenum egl_api); -- --bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs); -- --bool egl_create_surface(egl_ctx_data_t *egl, void *native_window); -- --bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value); -- --bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, -- EGLint attribute, EGLint *value); -- --bool egl_has_config(egl_ctx_data_t *egl); -- --#define _egl_query_surface(a, b, c, d) eglQuerySurface(a, b, c, d) --#define _egl_get_proc_address(a) eglGetProcAddress(a) --#define _egl_create_window_surface(a, b, c, d) eglCreateWindowSurface(a, b, c, d) --#define _egl_create_context(a, b, c, d) eglCreateContext(a, b, c, d) --#define _egl_get_configs(a, b, c, d) eglGetConfigs(a, b, c, d) --#define _egl_get_display(a) eglGetDisplay(a) --#define _egl_choose_config(a, b, c, d, e) eglChooseConfig(a, b, c, d, e) --#define _egl_make_current(a, b, c, d) eglMakeCurrent(a, b, c, d) --#define _egl_initialize(a, b, c) eglInitialize(a, b, c) --#define _egl_destroy_surface(a, b) eglDestroySurface(a, b) --#define _egl_destroy_context(a, b) eglDestroyContext(a, b) --#define _egl_get_current_context() eglGetCurrentContext() --#define _egl_get_error() eglGetError() --#define _egl_terminate(dpy) eglTerminate(dpy) --#define _egl_bind_api(a) eglBindAPI(a) --#define _egl_query_string(a, b) eglQueryString(a, b) --#define _egl_get_config_attrib(a, b, c, d) eglGetConfigAttrib(a, b, c, d) --#define _egl_swap_buffers(a, b) eglSwapBuffers(a, b) --#define _egl_swap_interval(a, b) eglSwapInterval(a, b) -- --void egl_report_error(void) -+typedef struct gfx_ctx_drm_data - { -- EGLint error = _egl_get_error(); -- const char *str = NULL; -- switch (error) -- { -- case EGL_SUCCESS: -- str = "EGL_SUCCESS"; -- break; -- -- case EGL_BAD_ACCESS: -- str = "EGL_BAD_ACCESS"; -- break; -- -- case EGL_BAD_ALLOC: -- str = "EGL_BAD_ALLOC"; -- break; -- -- case EGL_BAD_ATTRIBUTE: -- str = "EGL_BAD_ATTRIBUTE"; -- break; -- -- case EGL_BAD_CONFIG: -- str = "EGL_BAD_CONFIG"; -- break; -- -- case EGL_BAD_CONTEXT: -- str = "EGL_BAD_CONTEXT"; -- break; -- -- case EGL_BAD_CURRENT_SURFACE: -- str = "EGL_BAD_CURRENT_SURFACE"; -- break; -- -- case EGL_BAD_DISPLAY: -- str = "EGL_BAD_DISPLAY"; -- break; -- -- case EGL_BAD_MATCH: -- str = "EGL_BAD_MATCH"; -- break; -- -- case EGL_BAD_NATIVE_PIXMAP: -- str = "EGL_BAD_NATIVE_PIXMAP"; -- break; -- -- case EGL_BAD_NATIVE_WINDOW: -- str = "EGL_BAD_NATIVE_WINDOW"; -- break; -- -- case EGL_BAD_PARAMETER: -- str = "EGL_BAD_PARAMETER"; -- break; -+ egl_ctx_data_t egl; -+ int fd; -+ int interval; -+ unsigned fb_width; -+ unsigned fb_height; - -- case EGL_BAD_SURFACE: -- str = "EGL_BAD_SURFACE"; -- break; -+ bool core_hw_context_enable; -+ bool waiting_for_flip; -+ struct gbm_bo *bo; -+ struct gbm_bo *next_bo; -+ struct gbm_surface *gbm_surface; -+ struct gbm_device *gbm_dev; -+} gfx_ctx_drm_data_t; - -- default: -- str = "Unknown"; -- break; -- } -+struct drm_fb -+{ -+ struct gbm_bo *bo; -+ uint32_t fb_id; -+}; - -- printf("[EGL]: #0x%x, %s\n", (unsigned)error, str); --} -+/* TODO/FIXME - globals */ -+static drmEventContext g_drm_evctx; -+static struct pollfd g_drm_fds; -+static uint32_t g_connector_id = 0; -+static int g_drm_fd = 0; -+static uint32_t g_crtc_id = 0; -+static drmModeCrtc *g_orig_crtc = NULL; -+static drmModeConnector *g_drm_connector = NULL; -+static drmModeModeInfo *g_drm_mode = NULL; - --void egl_terminate(EGLDisplay dpy) --{ -- _egl_terminate(dpy); --} -+/* TODO/FIXME - static globals */ -+static drmModeRes *g_drm_resources = NULL; -+static drmModeEncoder *g_drm_encoder = NULL; - --bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, -- EGLint *value) --{ -- return _egl_get_config_attrib(dpy, config, attribute, value); --} -+static gfx_ctx_drm_data* g_drm = NULL; - --bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) --{ -- return _egl_initialize(dpy, major, minor); --} -+bool drm_get_encoder(int fd); - --bool egl_bind_api(EGLenum egl_api) --{ -- return _egl_bind_api(egl_api); --} -+/* Restore the original CRTC. */ -+void drm_restore_crtc(void); -+bool drm_get_resources(int fd); -+void drm_setup(int fd); -+void drm_free(void); -+bool drm_get_connector(int fd); -+float drm_get_refresh_rate(void *data); - --void egl_destroy(egl_ctx_data_t *egl) -+static void egl_destroy(egl_ctx_data_t *egl) - { - if (egl->dpy) - { -- _egl_make_current(egl->dpy, -+ eglMakeCurrent(egl->dpy, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (egl->ctx != EGL_NO_CONTEXT) -- _egl_destroy_context(egl->dpy, egl->ctx); -+ eglDestroyContext(egl->dpy, egl->ctx); - - if (egl->surf != EGL_NO_SURFACE) -- _egl_destroy_surface(egl->dpy, egl->surf); -- egl_terminate(egl->dpy); -+ eglDestroySurface(egl->dpy, egl->surf); -+ eglTerminate(egl->dpy); - } - - /* Be as careful as possible in deinit. -@@ -246,7 +148,7 @@ void egl_destroy(egl_ctx_data_t *egl) - egl->config = 0; - } - --void egl_swap_buffers(void *data) -+static void egl_swap_buffers(void *data) - { - egl_ctx_data_t *egl = (egl_ctx_data_t*)data; - if ( egl && -@@ -254,13 +156,11 @@ void egl_swap_buffers(void *data) - egl->surf != EGL_NO_SURFACE - ) - { -- _egl_swap_buffers(egl->dpy, egl->surf); -+ eglSwapBuffers(egl->dpy, egl->surf); - } -- else -- printf("\nSWAP FAILED"); - } - --void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) -+static void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) - { - /* Can be called before initialization. - * Some contexts require that swap interval -@@ -270,38 +170,21 @@ void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) - - if (egl->dpy == EGL_NO_DISPLAY) - return; -- if (!_egl_get_current_context()) -+ if (!eglGetCurrentContext()) - return; - - printf("[EGL]: eglSwapInterval(%u)\n", interval); -- if (!_egl_swap_interval(egl->dpy, interval)) -+ if (!eglSwapInterval(egl->dpy, interval)) - { -- printf("[EGL]: eglSwapInterval() failed.\n"); -- egl_report_error(); -+ printf("[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); - } - } - --void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height) --{ -- *width = 0; -- *height = 0; -- -- if (egl->dpy != EGL_NO_DISPLAY && egl->surf != EGL_NO_SURFACE) -- { -- EGLint gl_width, gl_height; -- -- _egl_query_surface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width); -- _egl_query_surface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height); -- *width = gl_width; -- *height = gl_height; -- } --} -- --bool check_egl_version(int minMajorVersion, int minMinorVersion) -+static bool check_egl_version(int minMajorVersion, int minMinorVersion) - { - int count; - int major, minor; -- const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_VERSION); -+ const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION); - - if (!str) - return false; -@@ -322,10 +205,10 @@ bool check_egl_version(int minMajorVersion, int minMinorVersion) - return false; - } - --bool check_egl_client_extension(const char *name) -+static bool check_egl_client_extension(const char *name) - { - size_t nameLen; -- const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_EXTENSIONS); -+ const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - - /* The EGL implementation doesn't support client extensions at all. */ - if (!str) -@@ -363,7 +246,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - - printf("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); - ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay) -- _egl_get_proc_address("eglGetPlatformDisplay"); -+ eglGetProcAddress("eglGetPlatformDisplay"); - - if (ptr_eglGetPlatformDisplay) - { -@@ -381,7 +264,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - - printf("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); - ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) -- _egl_get_proc_address("eglGetPlatformDisplayEXT"); -+ eglGetProcAddress("eglGetPlatformDisplayEXT"); - - if (ptr_eglGetPlatformDisplayEXT) - { -@@ -397,12 +280,12 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - * implementation doesn't support eglGetPlatformDisplay. In this case, try - * eglGetDisplay and hope for the best. */ - printf("[EGL] Falling back to eglGetDisplay\n"); -- return _egl_get_display((EGLNativeDisplayType) native); -+ return eglGetDisplay((EGLNativeDisplayType) native); - } - --bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) -+static bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) - { -- if (!egl_get_config_attrib(egl->dpy, egl->config, -+ if (!eglGetConfigAttrib(egl->dpy, egl->config, - EGL_NATIVE_VISUAL_ID, value)) - { - printf("[EGL]: egl_get_native_visual_id failed.\n"); -@@ -412,7 +295,7 @@ bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) - return true; - } - --bool egl_init_context_common( -+static bool egl_init_context_common( - egl_ctx_data_t *egl, EGLint *count, - const EGLint *attrib_ptr, - egl_accept_config_cb_t cb, -@@ -424,7 +307,7 @@ bool egl_init_context_common( - if (!egl) - return false; - -- if (!_egl_get_configs(egl->dpy, NULL, 0, count) || *count < 1) -+ if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1) - { - printf("[EGL]: No configs to choose from.\n"); - return false; -@@ -434,7 +317,7 @@ bool egl_init_context_common( - if (!configs) - return false; - -- if (!_egl_choose_config(egl->dpy, attrib_ptr, -+ if (!eglChooseConfig(egl->dpy, attrib_ptr, - configs, *count, &matched) || !matched) - { - printf("[EGL]: No EGL configs with appropriate attributes.\n"); -@@ -462,7 +345,7 @@ bool egl_init_context_common( - } - - --bool egl_init_context(egl_ctx_data_t *egl, -+static bool egl_init_context(egl_ctx_data_t *egl, - EGLenum platform, - void *display_data, - EGLint *major, EGLint *minor, -@@ -479,7 +362,7 @@ bool egl_init_context(egl_ctx_data_t *egl, - - egl->dpy = dpy; - -- if (!egl_initialize(egl->dpy, major, minor)) -+ if (!eglInitialize(egl->dpy, major, minor)) - return false; - - printf("[EGL]: EGL version: %d.%d\n", *major, *minor); -@@ -488,9 +371,9 @@ bool egl_init_context(egl_ctx_data_t *egl, - display_data); - } - --bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs) -+static bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs) - { -- EGLContext ctx = _egl_create_context(egl->dpy, egl->config, EGL_NO_CONTEXT, -+ EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT, - egl_attribs); - - if (ctx == EGL_NO_CONTEXT) -@@ -501,54 +384,27 @@ bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs) - return true; - } - --bool egl_create_surface(egl_ctx_data_t *egl, void *native_window) -+static bool egl_create_surface(egl_ctx_data_t *egl, void *native_window) - { - EGLint window_attribs[] = { - EGL_RENDER_BUFFER, EGL_BACK_BUFFER, - EGL_NONE, - }; - -- egl->surf = _egl_create_window_surface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs); -+ egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs); - - if (egl->surf == EGL_NO_SURFACE) - return false; - - /* Connect the context to the surface. */ -- if (!_egl_make_current(egl->dpy, egl->surf, egl->surf, egl->ctx)) -+ if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx)) - return false; - -- printf("[EGL]: Current context: %p.\n", (void*)_egl_get_current_context()); -+ printf("[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); - - return true; - } - --bool egl_has_config(egl_ctx_data_t *egl) --{ -- if (!egl->config) -- { -- printf("[EGL]: No EGL configurations available.\n"); -- return false; -- } -- return true; --} -- -- -- --bool drm_get_encoder(int fd); -- --/* Restore the original CRTC. */ --void drm_restore_crtc(void); -- --bool drm_get_resources(int fd); -- --void drm_setup(int fd); -- --void drm_free(void); -- --bool drm_get_connector(int fd); -- --float drm_get_refresh_rate(void *data); -- - static bool drm_wait_flip(int timeout) - { - g_drm_fds.revents = 0; -@@ -568,20 +424,6 @@ static bool drm_wait_flip(int timeout) - return false; - } - --/* TODO/FIXME - globals */ --drmEventContext g_drm_evctx; --struct pollfd g_drm_fds; --uint32_t g_connector_id = 0; --int g_drm_fd = 0; --uint32_t g_crtc_id = 0; --drmModeCrtc *g_orig_crtc = NULL; --drmModeConnector *g_drm_connector = NULL; --drmModeModeInfo *g_drm_mode = NULL; -- --/* TODO/FIXME - static globals */ --static drmModeRes *g_drm_resources = NULL; --static drmModeEncoder *g_drm_encoder = NULL; -- - /* Restore the original CRTC. */ - void drm_restore_crtc(void) - { -@@ -653,10 +495,7 @@ bool drm_get_connector(int fd) - { - monitor_index_count++; - if (monitor_index_count == monitor) -- { -- printf("\n[DRM]: Matched monitor / connector\n"); - break; -- } - } - - drmModeFreeConnector(g_drm_connector); -@@ -746,30 +585,6 @@ void drm_free(void) - g_drm_resources = NULL; - } - --typedef struct gfx_ctx_drm_data --{ -- egl_ctx_data_t egl; -- int fd; -- int interval; -- unsigned fb_width; -- unsigned fb_height; -- -- bool core_hw_context_enable; -- bool waiting_for_flip; -- struct gbm_bo *bo; -- struct gbm_bo *next_bo; -- struct gbm_surface *gbm_surface; -- struct gbm_device *gbm_dev; --} gfx_ctx_drm_data_t; -- --static gfx_ctx_drm_data* g_drm; -- --struct drm_fb --{ -- struct gbm_bo *bo; -- uint32_t fb_id; --}; -- - static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) - { - struct drm_fb *fb = (struct drm_fb*)data; -@@ -1092,17 +907,17 @@ static bool gbm_choose_xrgb8888_cb(void *display_data, EGLDisplay dpy, EGLConfig - (void)display_data; - - /* Makes sure we have 8 bit color. */ -- if (!egl_get_config_attrib(dpy, config, EGL_RED_SIZE, &r)) -+ if (!eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r)) - return false; -- if (!egl_get_config_attrib(dpy, config, EGL_GREEN_SIZE, &g)) -+ if (!eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g)) - return false; -- if (!egl_get_config_attrib(dpy, config, EGL_BLUE_SIZE, &b)) -+ if (!eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b)) - return false; - - if (r != 8 || g != 8 || b != 8) - return false; - -- if (!egl_get_config_attrib(dpy, config, EGL_NATIVE_VISUAL_ID, &id)) -+ if (!eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &id)) - return false; - - return id == GBM_FORMAT_XRGB8888; -@@ -1140,7 +955,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) - (EGLNativeDisplayType)drm->gbm_dev, &major, - &minor, &n, attrib_ptr, gbm_choose_xrgb8888_cb)) - { -- printf("\n[EGL] Cannot init context"); -+ printf("\n[EGL] Cannot init context error 0x%x",eglGetError()); - goto error; - } - attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); -@@ -1149,13 +964,13 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) - if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) - ? egl_attribs_ptr : NULL)) - { -- printf("\n[EGL] Cannot create context"); -+ printf("\n[EGL] Cannot create context error 0x%x",eglGetError()); - goto error; - } - - if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface)) - { -- printf("\n[EGL] Cannot create context"); -+ printf("\n[EGL] Cannot create context error 0x%x",eglGetError()); - return false; - } - -@@ -1164,7 +979,6 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) - return true; - - error: -- egl_report_error(); - return false; - } - -@@ -1287,24 +1101,12 @@ static void gfx_ctx_drm_destroy(void *data) - free(drm); - } - --#ifndef EGL_KHR_create_context --#define EGL_KHR_create_context 1 --#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 --#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB --#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD --#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD --#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE --#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF --#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 --#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 --#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 --#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 --#endif /* EGL_KHR_create_context */ - - GLContextEGLDRM::~GLContextEGLDRM() - { - DestroyWindowSurface(); - DestroyContext(); -+ gfx_ctx_drm_destroy(g_drm); - } - - bool GLContextEGLDRM::IsHeadless() const -@@ -1331,25 +1133,18 @@ void* GLContextEGLDRM::GetFuncAddress(const std::string& name) - // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() - bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) - { -- EGLint egl_major, egl_minor; -- bool supports_core_profile = false; -- - g_drm = (gfx_ctx_drm_data_t*)gfx_ctx_drm_init(); -- egl_bind_api(EGL_OPENGL_ES_API); -+ -+ eglBindAPI(EGL_OPENGL_ES_API); -+ - gfx_ctx_drm_set_video_mode(g_drm, 1920, 1080, true); - m_backbuffer_width = 1920; - m_backbuffer_height = 1080; - - m_egl = &g_drm->egl; - m_opengl_mode = Mode::OpenGLES; -+ m_supports_surfaceless = check_egl_client_extension("EGL_KHR_surfaceless_context"); - -- m_supports_surfaceless = false; -- const char* ext = eglQueryString(m_egl->dpy, EGL_EXTENSIONS); -- if (strstr(ext, "EGL_KHR_surfaceless_context")) -- { -- printf("\nFound EGL_KHR_surfaceless_context\n"); -- m_supports_surfaceless =true; -- } - eglBindAPI(EGL_OPENGL_ES_API); - - return MakeCurrent(); -@@ -1357,7 +1152,6 @@ bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool - - std::unique_ptr GLContextEGLDRM::CreateSharedContext() - { -- printf("\nvoid GLContextEGLDRM::CreateSharedContext"); - std::unique_ptr new_context = std::make_unique(); - new_context->m_egl = (egl_ctx_data_t*)malloc(sizeof(egl_ctx_data_t)); - memcpy(new_context->m_egl, m_egl, sizeof(egl_ctx_data_t)); -@@ -1371,8 +1165,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_egl->ctx = eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); - if (!new_context->m_egl->ctx) - { -- printf("\nError: eglCreateContext failed\n"); -- egl_report_error(); -+ printf("\nError: eglCreateContext failed 0x%x\n", eglGetError()); - return nullptr; - } - eglBindAPI(EGL_OPENGL_ES_API); -@@ -1381,8 +1174,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_is_shared = true; - if (!new_context->CreateWindowSurface()) - { -- printf("\nError: CreateWindowSurface failed\n"); -- egl_report_error(); -+ printf("\nError: CreateWindowSurface failed 0x%x\n", eglGetError()); - return nullptr; - } - return new_context; -@@ -1391,7 +1183,6 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - bool GLContextEGLDRM::CreateWindowSurface() - { - EGLint attrib_list[] = { EGL_NONE, }; -- printf("\nvoid GLContextEGLDRM::CreateWindowSurface"); - if (m_supports_surfaceless) - { - m_egl->surf = EGL_NO_SURFACE; -@@ -1403,8 +1194,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - { - if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) - { -- printf("\negl_create_surface failed, trying pbuffer\n"); -- egl_report_error(); -+ printf("\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); - goto pbuffer; - } - printf("\nm_egl_surface=0x%x",m_egl->surf); -@@ -1424,8 +1214,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - m_egl->surf = eglCreatePbufferSurface(m_egl->dpy, m_egl->config, attrib_list); - if (!m_egl->surf) - { -- printf("\nError: eglCreatePbufferSurface failed\n"); -- egl_report_error(); -+ printf("\nError: eglCreatePbufferSurface failed 0x%x\n", eglGetError()); - return false; - } - return true; -@@ -1433,7 +1222,6 @@ bool GLContextEGLDRM::CreateWindowSurface() - - void GLContextEGLDRM::DestroyWindowSurface() - { -- printf("\nvoid GLContextEGLDRM::DestroyWindowSurface"); - if (m_egl->surf == EGL_NO_SURFACE) - return; - -@@ -1446,13 +1234,11 @@ void GLContextEGLDRM::DestroyWindowSurface() - - bool GLContextEGLDRM::MakeCurrent() - { -- printf("\nvoid GLContextEGLDRM::MakeCurrent()"); -- return _egl_make_current(m_egl->dpy, g_drm->egl.surf, g_drm->egl.surf, m_egl->ctx); -+ return eglMakeCurrent(m_egl->dpy, g_drm->egl.surf, g_drm->egl.surf, m_egl->ctx); - } - - void GLContextEGLDRM::UpdateSurface(void* window_handle) - { -- printf("\nvoid GLContextEGLDRM::UpdateSurface(void* window_handle)"); - ClearCurrent(); - DestroyWindowSurface(); - CreateWindowSurface(); -@@ -1461,14 +1247,12 @@ void GLContextEGLDRM::UpdateSurface(void* window_handle) - - bool GLContextEGLDRM::ClearCurrent() - { -- printf("\nvoid GLContextEGLDRM::ClearCurrent()"); -- return _egl_make_current(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ return eglMakeCurrent(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - - // Close backend - void GLContextEGLDRM::DestroyContext() - { -- printf("\nGLContextEGLDRM::DestroyContext()"); - if (!m_egl->ctx) - return; - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -index b8615cf7e67..b03dfea0622 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.h -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -50,10 +50,6 @@ class GLContextEGLDRM : public GLContext - void DestroyWindowSurface(); - void DestroyContext(); - -- WindowSystemInfo m_wsi = {}; -- - bool m_supports_surfaceless = false; -- std::vector m_attribs; -- - egl_ctx_data_t* m_egl; - }; - -From bd3159621277b4ad13a030e55e071cead9bc186d Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 11:30:04 +0200 -Subject: [PATCH 04/25] Use Dolphin logging system - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 134 +++++++++++-------- - 1 file changed, 81 insertions(+), 53 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 4b4ed1668e8..baebf998c4a 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -43,6 +43,7 @@ - #include - - #include "Common/GL/GLInterface/EGLDRM.h" -+#include "Common/Logging/Log.h" - - #ifndef EGL_CONTEXT_FLAGS_KHR - #define EGL_CONTEXT_FLAGS_KHR 0x30FC -@@ -173,10 +174,10 @@ static void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) - if (!eglGetCurrentContext()) - return; - -- printf("[EGL]: eglSwapInterval(%u)\n", interval); -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval(%u)\n", interval); - if (!eglSwapInterval(egl->dpy, interval)) - { -- printf("[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); - } - } - -@@ -209,7 +210,6 @@ static bool check_egl_client_extension(const char *name) - { - size_t nameLen; - const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); -- - /* The EGL implementation doesn't support client extensions at all. */ - if (!str) - return false; -@@ -230,6 +230,34 @@ static bool check_egl_client_extension(const char *name) - return false; - } - -+static bool check_egl_display_extension(void* data, const char *name) -+{ -+ size_t nameLen; -+ egl_ctx_data_t *egl = (egl_ctx_data_t*)data; -+ if (!egl || egl->dpy == EGL_NO_DISPLAY) -+ return false; -+ -+ const char *str = eglQueryString(egl->dpy, EGL_EXTENSIONS); -+ /* The EGL implementation doesn't support extensions at all. */ -+ if (!str) -+ return false; -+ -+ nameLen = strlen(name); -+ while (*str != '\0') -+ { -+ /* Use strspn and strcspn to find the start position and length of each -+ * token in the extension string. Using strtok could also work, but -+ * that would require allocating a copy of the string. */ -+ size_t len = strcspn(str, " "); -+ if (len == nameLen && strncmp(str, name, nameLen) == 0) -+ return true; -+ str += len; -+ str += strspn(str, " "); -+ } -+ -+ return false; -+} -+ - static EGLDisplay get_egl_display(EGLenum platform, void *native) - { - if (platform != EGL_NONE) -@@ -244,7 +272,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); - pfn_eglGetPlatformDisplay ptr_eglGetPlatformDisplay; - -- printf("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); -+ INFO_LOG(VIDEO, "[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); - ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay) - eglGetProcAddress("eglGetPlatformDisplay"); - -@@ -262,7 +290,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT; - -- printf("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); -+ INFO_LOG(VIDEO, "[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); - ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) - eglGetProcAddress("eglGetPlatformDisplayEXT"); - -@@ -279,7 +307,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native) - /* Either the caller didn't provide a platform type, or the EGL - * implementation doesn't support eglGetPlatformDisplay. In this case, try - * eglGetDisplay and hope for the best. */ -- printf("[EGL] Falling back to eglGetDisplay\n"); -+ INFO_LOG(VIDEO, "[EGL] Falling back to eglGetDisplay\n"); - return eglGetDisplay((EGLNativeDisplayType) native); - } - -@@ -288,7 +316,7 @@ static bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) - if (!eglGetConfigAttrib(egl->dpy, egl->config, - EGL_NATIVE_VISUAL_ID, value)) - { -- printf("[EGL]: egl_get_native_visual_id failed.\n"); -+ INFO_LOG(VIDEO, "[EGL]: egl_get_native_visual_id failed.\n"); - return false; - } - -@@ -309,7 +337,7 @@ static bool egl_init_context_common( - - if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1) - { -- printf("[EGL]: No configs to choose from.\n"); -+ INFO_LOG(VIDEO, "[EGL]: No configs to choose from.\n"); - return false; - } - -@@ -320,7 +348,7 @@ static bool egl_init_context_common( - if (!eglChooseConfig(egl->dpy, attrib_ptr, - configs, *count, &matched) || !matched) - { -- printf("[EGL]: No EGL configs with appropriate attributes.\n"); -+ INFO_LOG(VIDEO, "[EGL]: No EGL configs with appropriate attributes.\n"); - return false; - } - -@@ -337,7 +365,7 @@ static bool egl_init_context_common( - - if (i == *count) - { -- printf("[EGL]: No EGL config found which satifies requirements.\n"); -+ INFO_LOG(VIDEO, "[EGL]: No EGL config found which satifies requirements.\n"); - return false; - } - -@@ -356,7 +384,7 @@ static bool egl_init_context(egl_ctx_data_t *egl, - - if (dpy == EGL_NO_DISPLAY) - { -- printf("[EGL]: Couldn't get EGL display.\n"); -+ INFO_LOG(VIDEO, "[EGL]: Couldn't get EGL display.\n"); - return false; - } - -@@ -365,7 +393,7 @@ static bool egl_init_context(egl_ctx_data_t *egl, - if (!eglInitialize(egl->dpy, major, minor)) - return false; - -- printf("[EGL]: EGL version: %d.%d\n", *major, *minor); -+ INFO_LOG(VIDEO, "[EGL]: EGL version: %d.%d\n", *major, *minor); - - return egl_init_context_common(egl, count, attrib_ptr, cb, - display_data); -@@ -400,7 +428,7 @@ static bool egl_create_surface(egl_ctx_data_t *egl, void *native_window) - if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx)) - return false; - -- printf("[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); -+ INFO_LOG(VIDEO, "[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); - - return true; - } -@@ -445,7 +473,7 @@ bool drm_get_resources(int fd) - g_drm_resources = drmModeGetResources(fd); - if (!g_drm_resources) - { -- printf("[DRM]: Couldn't get device resources.\n"); -+ INFO_LOG(VIDEO, "[DRM]: Couldn't get device resources.\n"); - return false; - } - -@@ -460,7 +488,7 @@ bool drm_get_connector(int fd) - - /* Enumerate all connectors. */ - -- printf("[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); -+ INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); - - for (i = 0; (int)i < g_drm_resources->count_connectors; i++) - { -@@ -470,12 +498,12 @@ bool drm_get_connector(int fd) - if (conn) - { - bool connected = conn->connection == DRM_MODE_CONNECTED; -- printf("[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no"); -- printf("[DRM]: Connector %d has %d modes.\n", i, conn->count_modes); -+ INFO_LOG(VIDEO, "[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no"); -+ INFO_LOG(VIDEO, "[DRM]: Connector %d has %d modes.\n", i, conn->count_modes); - if (connected && conn->count_modes > 0) - { - monitor_index_count++; -- printf("[DRM]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index_count); -+ INFO_LOG(VIDEO, "[DRM]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index_count); - } - drmModeFreeConnector(conn); - } -@@ -504,7 +532,7 @@ bool drm_get_connector(int fd) - - if (!g_drm_connector) - { -- printf("[DRM]: Couldn't get device connector.\n"); -+ INFO_LOG(VIDEO, "[DRM]: Couldn't get device connector.\n"); - return false; - } - return true; -@@ -530,13 +558,13 @@ bool drm_get_encoder(int fd) - - if (!g_drm_encoder) - { -- printf("[DRM]: Couldn't find DRM encoder.\n"); -+ INFO_LOG(VIDEO, "[DRM]: Couldn't find DRM encoder.\n"); - return false; - } - - for (i = 0; (int)i < g_drm_connector->count_modes; i++) - { -- printf("[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", -+ INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", - i, - g_drm_connector->modes[i].name, - g_drm_connector->modes[i].hdisplay, -@@ -553,7 +581,7 @@ void drm_setup(int fd) - g_connector_id = g_drm_connector->connector_id; - g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); - if (!g_orig_crtc) -- printf("[DRM]: Cannot find original CRTC.\n"); -+ INFO_LOG(VIDEO, "[DRM]: Cannot find original CRTC.\n"); - } - - float drm_get_refresh_rate(void *data) -@@ -608,7 +636,7 @@ static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) - stride = gbm_bo_get_stride(bo); - handle = gbm_bo_get_handle(bo).u32; - -- printf("[KMS]: New FB: %ux%u (stride: %u).\n", -+ INFO_LOG(VIDEO, "[KMS]: New FB: %ux%u (stride: %u).\n", - width, height, stride); - - ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, -@@ -620,7 +648,7 @@ static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) - return fb; - - error: -- printf("[KMS]: Failed to create FB: %s\n", strerror(errno)); -+ INFO_LOG(VIDEO, "[KMS]: Failed to create FB: %s\n", strerror(errno)); - free(fb); - return NULL; - } -@@ -631,7 +659,7 @@ static void gfx_ctx_drm_swap_interval(void *data, int interval) - drm->interval = interval; - - if (interval > 1) -- printf("[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); -+ INFO_LOG(VIDEO, "[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); - } - - static void drm_flip_handler(int fd, unsigned frame, -@@ -648,7 +676,7 @@ static void drm_flip_handler(int fd, unsigned frame, - { - unsigned missed = frame - last_page_flip - 1; - if (missed) -- printf("[KMS]: Missed %u VBlank(s) (Frame: %u, DRM frame: %u).\n", -+ INFO_LOG(VIDEO, "[KMS]: Missed %u VBlank(s) (Frame: %u, DRM frame: %u).\n", - missed, frame - first_page_flip, frame); - } - -@@ -675,7 +703,7 @@ static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t *drm, bool block) - } - - if (drm->waiting_for_flip) -- { printf("\nwait flip 2"); return true; } -+ { INFO_LOG(VIDEO, "\nwait flip 2"); return true; } - - /* Page flip has taken place. */ - -@@ -701,7 +729,7 @@ static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t *drm) - return true; - - /* Failed to queue page flip. */ -- printf("\nFailed to queue page flip\n"); -+ INFO_LOG(VIDEO, "\nFailed to queue page flip\n"); - return false; - } - -@@ -718,7 +746,7 @@ static void gfx_ctx_drm_swap_buffers(void *data) - * If true, we are still waiting for a flip - * (nonblocking mode, so just drop the frame). */ - if (gfx_ctx_drm_wait_flip(drm, drm->interval)) -- { printf("\nwait flip"); return; } -+ { INFO_LOG(VIDEO, "\nwait flip"); return; } - - drm->waiting_for_flip = gfx_ctx_drm_queue_flip(drm); - -@@ -737,7 +765,7 @@ static void gfx_ctx_drm_get_video_size(void *data, - - if (!drm) - { -- printf("\nCannot get drm video size\n"); -+ INFO_LOG(VIDEO, "\nCannot get drm video size\n"); - return; - } - -@@ -815,7 +843,7 @@ static void *gfx_ctx_drm_init() - drm->fd = open("/dev/dri/card0", O_RDWR); - if (drm->fd < 0) - { -- printf("[KMS]: Couldn't open DRM device.\n"); -+ INFO_LOG(VIDEO, "[KMS]: Couldn't open DRM device.\n"); - return nullptr; - } - -@@ -823,19 +851,19 @@ static void *gfx_ctx_drm_init() - - if (!drm_get_resources(fd)) - { -- printf("[KMS]: drm_get_resources failed\n"); -+ INFO_LOG(VIDEO, "[KMS]: drm_get_resources failed\n"); - return nullptr; - } - - if (!drm_get_connector(fd)) - { -- printf("[KMS]: drm_get_connector failed\n"); -+ INFO_LOG(VIDEO, "[KMS]: drm_get_connector failed\n"); - return nullptr; - } - - if (!drm_get_encoder(fd)) - { -- printf("[KMS]: drm_get_encoder failed\n"); -+ INFO_LOG(VIDEO, "[KMS]: drm_get_encoder failed\n"); - return nullptr; - } - -@@ -861,7 +889,7 @@ static void *gfx_ctx_drm_init() - - if (!drm->gbm_dev) - { -- printf("[KMS]: Couldn't create GBM device.\n"); -+ INFO_LOG(VIDEO, "[KMS]: Couldn't create GBM device.\n"); - return nullptr; - } - -@@ -955,7 +983,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) - (EGLNativeDisplayType)drm->gbm_dev, &major, - &minor, &n, attrib_ptr, gbm_choose_xrgb8888_cb)) - { -- printf("\n[EGL] Cannot init context error 0x%x",eglGetError()); -+ INFO_LOG(VIDEO, "\n[EGL] Cannot init context error 0x%x",eglGetError()); - goto error; - } - attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); -@@ -964,13 +992,13 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) - if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) - ? egl_attribs_ptr : NULL)) - { -- printf("\n[EGL] Cannot create context error 0x%x",eglGetError()); -+ INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x",eglGetError()); - goto error; - } - - if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface)) - { -- printf("\n[EGL] Cannot create context error 0x%x",eglGetError()); -+ INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x",eglGetError()); - return false; - } - -@@ -1037,7 +1065,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data, - - if (!g_drm_mode) - { -- printf("[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", -+ INFO_LOG(VIDEO, "[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", - width, height); - goto error; - } -@@ -1055,13 +1083,13 @@ static bool gfx_ctx_drm_set_video_mode(void *data, - - if (!drm->gbm_surface) - { -- printf("[KMS/EGL]: Couldn't create GBM surface.\n"); -+ INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't create GBM surface.\n"); - goto error; - } - - if (!gfx_ctx_drm_egl_set_video_mode(drm)) - { -- printf("[KMS/EGL]: Couldn't set EGL video mode.\n"); -+ INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't set EGL video mode.\n"); - goto error; - } - -@@ -1076,7 +1104,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data, - g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode); - if (ret < 0) - { -- printf("[KMS/EGL]: drmModeSetCrtc failed\n"); -+ INFO_LOG(VIDEO, "[KMS/EGL]: drmModeSetCrtc failed\n"); - goto error; - } - return true; -@@ -1143,7 +1171,7 @@ bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool - - m_egl = &g_drm->egl; - m_opengl_mode = Mode::OpenGLES; -- m_supports_surfaceless = check_egl_client_extension("EGL_KHR_surfaceless_context"); -+ m_supports_surfaceless = check_egl_display_extension(m_egl,"EGL_KHR_surfaceless_context"); - - eglBindAPI(EGL_OPENGL_ES_API); - -@@ -1165,7 +1193,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_egl->ctx = eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); - if (!new_context->m_egl->ctx) - { -- printf("\nError: eglCreateContext failed 0x%x\n", eglGetError()); -+ INFO_LOG(VIDEO, "\nError: eglCreateContext failed 0x%x\n", eglGetError()); - return nullptr; - } - eglBindAPI(EGL_OPENGL_ES_API); -@@ -1174,7 +1202,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_is_shared = true; - if (!new_context->CreateWindowSurface()) - { -- printf("\nError: CreateWindowSurface failed 0x%x\n", eglGetError()); -+ INFO_LOG(VIDEO, "\nError: CreateWindowSurface failed 0x%x\n", eglGetError()); - return nullptr; - } - return new_context; -@@ -1186,7 +1214,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - if (m_supports_surfaceless) - { - m_egl->surf = EGL_NO_SURFACE; -- printf("\nCreated surfaceless context\n"); -+ INFO_LOG(VIDEO, "\nCreated surfaceless context\n"); - return true; - } - -@@ -1194,16 +1222,16 @@ bool GLContextEGLDRM::CreateWindowSurface() - { - if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) - { -- printf("\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); -+ INFO_LOG(VIDEO, "\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); - goto pbuffer; - } -- printf("\nm_egl_surface=0x%x",m_egl->surf); -+ INFO_LOG(VIDEO, "\nm_egl_surface=0x%x",m_egl->surf); - // Get dimensions from the surface. - EGLint surface_width = 1, surface_height = 1; - if (!eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_WIDTH, &surface_width) || - !eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_HEIGHT, &surface_height)) - { -- printf("Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); -+ INFO_LOG(VIDEO, "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); - } - m_backbuffer_width = static_cast(surface_width); - m_backbuffer_height = static_cast(surface_height); -@@ -1214,7 +1242,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - m_egl->surf = eglCreatePbufferSurface(m_egl->dpy, m_egl->config, attrib_list); - if (!m_egl->surf) - { -- printf("\nError: eglCreatePbufferSurface failed 0x%x\n", eglGetError()); -+ INFO_LOG(VIDEO, "\nError: eglCreatePbufferSurface failed 0x%x\n", eglGetError()); - return false; - } - return true; -@@ -1228,7 +1256,7 @@ void GLContextEGLDRM::DestroyWindowSurface() - if (eglGetCurrentSurface(EGL_DRAW) == m_egl->surf) - eglMakeCurrent(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (!eglDestroySurface(m_egl->dpy, m_egl->surf)) -- printf("\nCould not destroy window surface."); -+ INFO_LOG(VIDEO, "\nCould not destroy window surface."); - m_egl->surf = EGL_NO_SURFACE; - } - -@@ -1259,9 +1287,9 @@ if (!m_egl->ctx) - if (eglGetCurrentContext() == m_egl->ctx) - eglMakeCurrent(m_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (!eglDestroyContext(m_egl->dpy, m_egl->ctx)) -- printf("\nCould not destroy drawing context."); -+ INFO_LOG(VIDEO, "\nCould not destroy drawing context."); - if (!m_is_shared && !eglTerminate(m_egl->dpy)) -- printf("\nCould not destroy display connection."); -+ INFO_LOG(VIDEO, "\nCould not destroy display connection."); - m_egl->ctx = EGL_NO_CONTEXT; - m_egl->dpy = EGL_NO_DISPLAY; - } - -From 0a05a524bd770d51359fa40e416d2b16a52057d1 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 13:11:03 +0200 -Subject: [PATCH 05/25] Remove hardcoded video mode, try to match native game - rate - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 26 +++++++------------- - 1 file changed, 9 insertions(+), 17 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index baebf998c4a..e617592e677 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -44,6 +44,7 @@ - - #include "Common/GL/GLInterface/EGLDRM.h" - #include "Common/Logging/Log.h" -+#include "Core/HW/VideoInterface.h" //for TargetRefreshRate - - #ifndef EGL_CONTEXT_FLAGS_KHR - #define EGL_CONTEXT_FLAGS_KHR 0x30FC -@@ -1014,22 +1015,14 @@ static bool gfx_ctx_drm_set_video_mode(void *data, - unsigned width, unsigned height, - bool fullscreen) - { -- float refresh_mod; - int i, ret = 0; - struct drm_fb *fb = NULL; - gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -- bool black_frame_insertion = false; //settings->bools.video_black_frame_insertion; -- float video_refresh_rate = 60; //settings->floats.video_refresh_rate; -+ float video_refresh_rate = (float)VideoInterface::GetTargetRefreshRate(); - - if (!drm) - return false; - -- /* If we use black frame insertion, -- * we fake a 60 Hz monitor for 120 Hz one, -- * etc, so try to match that. */ -- refresh_mod = black_frame_insertion -- ? 0.5f : 1.0f; -- - /* Find desired video mode, and use that. - * If not fullscreen, we get desired windowed size, - * which is not appropriate. */ -@@ -1052,8 +1045,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data, - height != g_drm_connector->modes[i].vdisplay) - continue; - -- diff = fabsf(refresh_mod * g_drm_connector->modes[i].vrefresh -- - video_refresh_rate); -+ diff = fabsf(g_drm_connector->modes[i].vrefresh - video_refresh_rate); - - if (!g_drm_mode || diff < minimum_fps_diff) - { -@@ -1165,9 +1157,10 @@ bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool - - eglBindAPI(EGL_OPENGL_ES_API); - -- gfx_ctx_drm_set_video_mode(g_drm, 1920, 1080, true); -- m_backbuffer_width = 1920; -- m_backbuffer_height = 1080; -+ // Use current video mode, do not switch -+ gfx_ctx_drm_set_video_mode(g_drm, 0, 0, false); -+ m_backbuffer_width = g_drm->fb_width; -+ m_backbuffer_height = g_drm->fb_height; - - m_egl = &g_drm->egl; - m_opengl_mode = Mode::OpenGLES; -@@ -1193,7 +1186,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_egl->ctx = eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); - if (!new_context->m_egl->ctx) - { -- INFO_LOG(VIDEO, "\nError: eglCreateContext failed 0x%x\n", eglGetError()); -+ ERROR_LOG(VIDEO, "\nError: eglCreateContext failed 0x%x\n", eglGetError()); - return nullptr; - } - eglBindAPI(EGL_OPENGL_ES_API); -@@ -1202,7 +1195,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - new_context->m_is_shared = true; - if (!new_context->CreateWindowSurface()) - { -- INFO_LOG(VIDEO, "\nError: CreateWindowSurface failed 0x%x\n", eglGetError()); -+ ERROR_LOG(VIDEO, "\nError: CreateWindowSurface failed 0x%x\n", eglGetError()); - return nullptr; - } - return new_context; -@@ -1225,7 +1218,6 @@ bool GLContextEGLDRM::CreateWindowSurface() - INFO_LOG(VIDEO, "\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); - goto pbuffer; - } -- INFO_LOG(VIDEO, "\nm_egl_surface=0x%x",m_egl->surf); - // Get dimensions from the surface. - EGLint surface_width = 1, surface_height = 1; - if (!eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_WIDTH, &surface_width) || - -From 56b39ef782efdeaf6aac2dd4926ca042ba189e8d Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 14:25:28 +0200 -Subject: [PATCH 06/25] Fix lint checks - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.h | 16 ++++++++-------- - Source/Core/DolphinNoGUI/MainNoGUI.cpp | 3 +-- - 2 files changed, 9 insertions(+), 10 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -index b03dfea0622..61bb6a7cfe2 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.h -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -13,14 +13,14 @@ - - typedef struct - { -- EGLContext ctx; -- EGLSurface surf; -- EGLDisplay dpy; -- EGLConfig config; -- int interval; -- -- unsigned major; -- unsigned minor; -+ EGLContext ctx; -+ EGLSurface surf; -+ EGLDisplay dpy; -+ EGLConfig config; -+ int interval; -+ -+ unsigned major; -+ unsigned minor; - - } egl_ctx_data_t; - -diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -index 9faf1152de2..143d059d04c 100644 ---- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp -+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -@@ -143,8 +143,7 @@ int main(int argc, char* argv[]) - "headless" - #ifdef __linux__ - , -- "fbdev", -- "drm" -+ "fbdev", "drm" - #endif - #if HAVE_X11 - , - -From 0c523614eabd043b51d6addbb34cb0d6a85ec7e1 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 14:55:22 +0200 -Subject: [PATCH 07/25] Update Source/Core/Common/GL/GLInterface/EGLDRM.h - -Co-authored-by: LC ---- - Source/Core/Common/GL/GLInterface/EGLDRM.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -index 61bb6a7cfe2..9b38f00900c 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.h -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -27,7 +27,7 @@ typedef struct - class GLContextEGLDRM : public GLContext - { - public: -- virtual ~GLContextEGLDRM() override; -+ ~GLContextEGLDRM() override; - - bool IsHeadless() const override; - - -From 0404543372cbf6da890ccb7bdaa36fc0e135e430 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 14:55:33 +0200 -Subject: [PATCH 08/25] Update Source/Core/Common/GL/GLInterface/EGLDRM.cpp - -Co-authored-by: LC ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index e617592e677..d341d26f8bc 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -76,7 +76,7 @@ - #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 - #endif /* EGL_KHR_create_context */ - --typedef bool (*egl_accept_config_cb_t)(void *display_data, EGLDisplay dpy, EGLConfig config); -+using EGLAcceptConfigCB = bool (*)(void *display_data, EGLDisplay dpy, EGLConfig config); - - typedef struct gfx_ctx_drm_data - { - -From b66346be056d5b46068b577f227bab54fa6bdaf9 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 14:55:49 +0200 -Subject: [PATCH 09/25] Update Source/Core/DolphinNoGUI/PlatformDRM.cpp - -Co-authored-by: LC ---- - Source/Core/DolphinNoGUI/PlatformDRM.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Source/Core/DolphinNoGUI/PlatformDRM.cpp b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -index 1784aaae4f8..255888ad4cc 100644 ---- a/Source/Core/DolphinNoGUI/PlatformDRM.cpp -+++ b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -@@ -40,7 +40,7 @@ class PlatformDRM : public Platform - private: - }; - --PlatformDRM::~PlatformDRM() -+PlatformDRM::~PlatformDRM() = default; - { - } - - -From 8a6e26d483df52358d563190274f312a6d5eebbf Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:02:21 +0200 -Subject: [PATCH 10/25] Run clang-format on EGLDRM - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 1481 +++++++++--------- - 1 file changed, 726 insertions(+), 755 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index d341d26f8bc..100e60d1c78 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -19,28 +19,28 @@ - * If not, see . - */ - --#include --#include - #include --#include --#include -+#include - #include -+#include - #include -+#include -+#include -+#include -+#include - #include - #include --#include --#include --#include -+#include - - #include - #include - #include -+#include -+#include - #include - #include --#include - #include - #include --#include - - #include "Common/GL/GLInterface/EGLDRM.h" - #include "Common/Logging/Log.h" -@@ -76,43 +76,43 @@ - #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 - #endif /* EGL_KHR_create_context */ - --using EGLAcceptConfigCB = bool (*)(void *display_data, EGLDisplay dpy, EGLConfig config); -+using EGLAcceptConfigCB = bool (*)(void* display_data, EGLDisplay dpy, EGLConfig config); - - typedef struct gfx_ctx_drm_data - { -- egl_ctx_data_t egl; -- int fd; -- int interval; -- unsigned fb_width; -- unsigned fb_height; -- -- bool core_hw_context_enable; -- bool waiting_for_flip; -- struct gbm_bo *bo; -- struct gbm_bo *next_bo; -- struct gbm_surface *gbm_surface; -- struct gbm_device *gbm_dev; -+ egl_ctx_data_t egl; -+ int fd; -+ int interval; -+ unsigned fb_width; -+ unsigned fb_height; -+ -+ bool core_hw_context_enable; -+ bool waiting_for_flip; -+ struct gbm_bo* bo; -+ struct gbm_bo* next_bo; -+ struct gbm_surface* gbm_surface; -+ struct gbm_device* gbm_dev; - } gfx_ctx_drm_data_t; - - struct drm_fb - { -- struct gbm_bo *bo; -- uint32_t fb_id; -+ struct gbm_bo* bo; -+ uint32_t fb_id; - }; - - /* TODO/FIXME - globals */ - static drmEventContext g_drm_evctx; - static struct pollfd g_drm_fds; --static uint32_t g_connector_id = 0; --static int g_drm_fd = 0; --static uint32_t g_crtc_id = 0; --static drmModeCrtc *g_orig_crtc = NULL; --static drmModeConnector *g_drm_connector = NULL; --static drmModeModeInfo *g_drm_mode = NULL; -+static uint32_t g_connector_id = 0; -+static int g_drm_fd = 0; -+static uint32_t g_crtc_id = 0; -+static drmModeCrtc* g_orig_crtc = NULL; -+static drmModeConnector* g_drm_connector = NULL; -+static drmModeModeInfo* g_drm_mode = NULL; - - /* TODO/FIXME - static globals */ --static drmModeRes *g_drm_resources = NULL; --static drmModeEncoder *g_drm_encoder = NULL; -+static drmModeRes* g_drm_resources = NULL; -+static drmModeEncoder* g_drm_encoder = NULL; - - static gfx_ctx_drm_data* g_drm = NULL; - -@@ -124,547 +124,524 @@ bool drm_get_resources(int fd); - void drm_setup(int fd); - void drm_free(void); - bool drm_get_connector(int fd); --float drm_get_refresh_rate(void *data); -+float drm_get_refresh_rate(void* data); - --static void egl_destroy(egl_ctx_data_t *egl) -+static void egl_destroy(egl_ctx_data_t* egl) - { -- if (egl->dpy) -- { -- eglMakeCurrent(egl->dpy, -- EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -- if (egl->ctx != EGL_NO_CONTEXT) -- eglDestroyContext(egl->dpy, egl->ctx); -- -- if (egl->surf != EGL_NO_SURFACE) -- eglDestroySurface(egl->dpy, egl->surf); -- eglTerminate(egl->dpy); -- } -+ if (egl->dpy) -+ { -+ eglMakeCurrent(egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (egl->ctx != EGL_NO_CONTEXT) -+ eglDestroyContext(egl->dpy, egl->ctx); - -- /* Be as careful as possible in deinit. -- * If we screw up, any TTY will not restore. -- */ -+ if (egl->surf != EGL_NO_SURFACE) -+ eglDestroySurface(egl->dpy, egl->surf); -+ eglTerminate(egl->dpy); -+ } -+ -+ /* Be as careful as possible in deinit. -+ * If we screw up, any TTY will not restore. -+ */ - -- egl->ctx = EGL_NO_CONTEXT; -- egl->surf = EGL_NO_SURFACE; -- egl->dpy = EGL_NO_DISPLAY; -- egl->config = 0; -+ egl->ctx = EGL_NO_CONTEXT; -+ egl->surf = EGL_NO_SURFACE; -+ egl->dpy = EGL_NO_DISPLAY; -+ egl->config = 0; - } - --static void egl_swap_buffers(void *data) -+static void egl_swap_buffers(void* data) - { -- egl_ctx_data_t *egl = (egl_ctx_data_t*)data; -- if ( egl && -- egl->dpy != EGL_NO_DISPLAY && -- egl->surf != EGL_NO_SURFACE -- ) -- { -- eglSwapBuffers(egl->dpy, egl->surf); -- } -+ egl_ctx_data_t* egl = (egl_ctx_data_t*)data; -+ if (egl && egl->dpy != EGL_NO_DISPLAY && egl->surf != EGL_NO_SURFACE) -+ { -+ eglSwapBuffers(egl->dpy, egl->surf); -+ } - } - --static void egl_set_swap_interval(egl_ctx_data_t *egl, int interval) -+static void egl_set_swap_interval(egl_ctx_data_t* egl, int interval) - { -- /* Can be called before initialization. -- * Some contexts require that swap interval -- * is known at startup time. -- */ -- egl->interval = interval; -- -- if (egl->dpy == EGL_NO_DISPLAY) -- return; -- if (!eglGetCurrentContext()) -- return; -- -- INFO_LOG(VIDEO, "[EGL]: eglSwapInterval(%u)\n", interval); -- if (!eglSwapInterval(egl->dpy, interval)) -- { -- INFO_LOG(VIDEO, "[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); -- } -+ /* Can be called before initialization. -+ * Some contexts require that swap interval -+ * is known at startup time. -+ */ -+ egl->interval = interval; -+ -+ if (egl->dpy == EGL_NO_DISPLAY) -+ return; -+ if (!eglGetCurrentContext()) -+ return; -+ -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval(%u)\n", interval); -+ if (!eglSwapInterval(egl->dpy, interval)) -+ { -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); -+ } - } - - static bool check_egl_version(int minMajorVersion, int minMinorVersion) - { -- int count; -- int major, minor; -- const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION); -+ int count; -+ int major, minor; -+ const char* str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION); - -- if (!str) -- return false; -+ if (!str) -+ return false; - -- count = sscanf(str, "%d.%d", &major, &minor); -- if (count != 2) -- return false; -+ count = sscanf(str, "%d.%d", &major, &minor); -+ if (count != 2) -+ return false; - -- if (major < minMajorVersion) -- return false; -+ if (major < minMajorVersion) -+ return false; - -- if (major > minMajorVersion) -- return true; -+ if (major > minMajorVersion) -+ return true; - -- if (minor >= minMinorVersion) -- return true; -+ if (minor >= minMinorVersion) -+ return true; - -- return false; -+ return false; - } - --static bool check_egl_client_extension(const char *name) -+static bool check_egl_client_extension(const char* name) - { -- size_t nameLen; -- const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); -- /* The EGL implementation doesn't support client extensions at all. */ -- if (!str) -- return false; -- -- nameLen = strlen(name); -- while (*str != '\0') -- { -- /* Use strspn and strcspn to find the start position and length of each -- * token in the extension string. Using strtok could also work, but -- * that would require allocating a copy of the string. */ -- size_t len = strcspn(str, " "); -- if (len == nameLen && strncmp(str, name, nameLen) == 0) -- return true; -- str += len; -- str += strspn(str, " "); -- } -+ size_t nameLen; -+ const char* str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); -+ /* The EGL implementation doesn't support client extensions at all. */ -+ if (!str) -+ return false; -+ -+ nameLen = strlen(name); -+ while (*str != '\0') -+ { -+ /* Use strspn and strcspn to find the start position and length of each -+ * token in the extension string. Using strtok could also work, but -+ * that would require allocating a copy of the string. */ -+ size_t len = strcspn(str, " "); -+ if (len == nameLen && strncmp(str, name, nameLen) == 0) -+ return true; -+ str += len; -+ str += strspn(str, " "); -+ } - -- return false; -+ return false; - } - --static bool check_egl_display_extension(void* data, const char *name) -+static bool check_egl_display_extension(void* data, const char* name) - { -- size_t nameLen; -- egl_ctx_data_t *egl = (egl_ctx_data_t*)data; -- if (!egl || egl->dpy == EGL_NO_DISPLAY) -- return false; -- -- const char *str = eglQueryString(egl->dpy, EGL_EXTENSIONS); -- /* The EGL implementation doesn't support extensions at all. */ -- if (!str) -- return false; -- -- nameLen = strlen(name); -- while (*str != '\0') -- { -- /* Use strspn and strcspn to find the start position and length of each -- * token in the extension string. Using strtok could also work, but -- * that would require allocating a copy of the string. */ -- size_t len = strcspn(str, " "); -- if (len == nameLen && strncmp(str, name, nameLen) == 0) -- return true; -- str += len; -- str += strspn(str, " "); -- } -+ size_t nameLen; -+ egl_ctx_data_t* egl = (egl_ctx_data_t*)data; -+ if (!egl || egl->dpy == EGL_NO_DISPLAY) -+ return false; -+ -+ const char* str = eglQueryString(egl->dpy, EGL_EXTENSIONS); -+ /* The EGL implementation doesn't support extensions at all. */ -+ if (!str) -+ return false; -+ -+ nameLen = strlen(name); -+ while (*str != '\0') -+ { -+ /* Use strspn and strcspn to find the start position and length of each -+ * token in the extension string. Using strtok could also work, but -+ * that would require allocating a copy of the string. */ -+ size_t len = strcspn(str, " "); -+ if (len == nameLen && strncmp(str, name, nameLen) == 0) -+ return true; -+ str += len; -+ str += strspn(str, " "); -+ } - -- return false; -+ return false; - } - --static EGLDisplay get_egl_display(EGLenum platform, void *native) -+static EGLDisplay get_egl_display(EGLenum platform, void* native) - { -- if (platform != EGL_NONE) -- { -- /* If the client library supports at least EGL 1.5, then we can call -- * eglGetPlatformDisplay. Otherwise, see if eglGetPlatformDisplayEXT -- * is available. */ -+ if (platform != EGL_NONE) -+ { -+ /* If the client library supports at least EGL 1.5, then we can call -+ * eglGetPlatformDisplay. Otherwise, see if eglGetPlatformDisplayEXT -+ * is available. */ - #if defined(EGL_VERSION_1_5) -- if (check_egl_version(1, 5)) -+ if (check_egl_version(1, 5)) -+ { -+ typedef EGLDisplay(EGLAPIENTRY * pfn_eglGetPlatformDisplay)( -+ EGLenum platform, void* native_display, const EGLAttrib* attrib_list); -+ pfn_eglGetPlatformDisplay ptr_eglGetPlatformDisplay; -+ -+ INFO_LOG(VIDEO, "[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); -+ ptr_eglGetPlatformDisplay = -+ (pfn_eglGetPlatformDisplay)eglGetProcAddress("eglGetPlatformDisplay"); -+ -+ if (ptr_eglGetPlatformDisplay) - { -- typedef EGLDisplay (EGLAPIENTRY * pfn_eglGetPlatformDisplay) -- (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); -- pfn_eglGetPlatformDisplay ptr_eglGetPlatformDisplay; -- -- INFO_LOG(VIDEO, "[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n"); -- ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay) -- eglGetProcAddress("eglGetPlatformDisplay"); -- -- if (ptr_eglGetPlatformDisplay) -- { -- EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL); -- if (dpy != EGL_NO_DISPLAY) -- return dpy; -- } -+ EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL); -+ if (dpy != EGL_NO_DISPLAY) -+ return dpy; - } -+ } - #endif /* defined(EGL_VERSION_1_5) */ - - #if defined(EGL_EXT_platform_base) -- if (check_egl_client_extension("EGL_EXT_platform_base")) -+ if (check_egl_client_extension("EGL_EXT_platform_base")) -+ { -+ PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT; -+ -+ INFO_LOG(VIDEO, "[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); -+ ptr_eglGetPlatformDisplayEXT = -+ (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); -+ -+ if (ptr_eglGetPlatformDisplayEXT) - { -- PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT; -- -- INFO_LOG(VIDEO, "[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n"); -- ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) -- eglGetProcAddress("eglGetPlatformDisplayEXT"); -- -- if (ptr_eglGetPlatformDisplayEXT) -- { -- EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL); -- if (dpy != EGL_NO_DISPLAY) -- return dpy; -- } -+ EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL); -+ if (dpy != EGL_NO_DISPLAY) -+ return dpy; - } -+ } - #endif /* defined(EGL_EXT_platform_base) */ -- } -+ } - -- /* Either the caller didn't provide a platform type, or the EGL -- * implementation doesn't support eglGetPlatformDisplay. In this case, try -- * eglGetDisplay and hope for the best. */ -- INFO_LOG(VIDEO, "[EGL] Falling back to eglGetDisplay\n"); -- return eglGetDisplay((EGLNativeDisplayType) native); -+ /* Either the caller didn't provide a platform type, or the EGL -+ * implementation doesn't support eglGetPlatformDisplay. In this case, try -+ * eglGetDisplay and hope for the best. */ -+ INFO_LOG(VIDEO, "[EGL] Falling back to eglGetDisplay\n"); -+ return eglGetDisplay((EGLNativeDisplayType)native); - } - --static bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value) -+static bool egl_get_native_visual_id(egl_ctx_data_t* egl, EGLint* value) - { -- if (!eglGetConfigAttrib(egl->dpy, egl->config, -- EGL_NATIVE_VISUAL_ID, value)) -- { -- INFO_LOG(VIDEO, "[EGL]: egl_get_native_visual_id failed.\n"); -- return false; -- } -+ if (!eglGetConfigAttrib(egl->dpy, egl->config, EGL_NATIVE_VISUAL_ID, value)) -+ { -+ INFO_LOG(VIDEO, "[EGL]: egl_get_native_visual_id failed.\n"); -+ return false; -+ } - -- return true; -+ return true; - } - --static bool egl_init_context_common( -- egl_ctx_data_t *egl, EGLint *count, -- const EGLint *attrib_ptr, -- egl_accept_config_cb_t cb, -- void *display_data) -+static bool egl_init_context_common(egl_ctx_data_t* egl, EGLint* count, const EGLint* attrib_ptr, -+ egl_accept_config_cb_t cb, void* display_data) - { -- EGLint i; -- EGLint matched = 0; -- EGLConfig *configs = NULL; -- if (!egl) -- return false; -+ EGLint i; -+ EGLint matched = 0; -+ EGLConfig* configs = NULL; -+ if (!egl) -+ return false; - -- if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1) -- { -- INFO_LOG(VIDEO, "[EGL]: No configs to choose from.\n"); -- return false; -- } -+ if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1) -+ { -+ INFO_LOG(VIDEO, "[EGL]: No configs to choose from.\n"); -+ return false; -+ } - -- configs = (EGLConfig*)malloc(*count * sizeof(*configs)); -- if (!configs) -- return false; -+ configs = (EGLConfig*)malloc(*count * sizeof(*configs)); -+ if (!configs) -+ return false; - -- if (!eglChooseConfig(egl->dpy, attrib_ptr, -- configs, *count, &matched) || !matched) -- { -- INFO_LOG(VIDEO, "[EGL]: No EGL configs with appropriate attributes.\n"); -- return false; -- } -+ if (!eglChooseConfig(egl->dpy, attrib_ptr, configs, *count, &matched) || !matched) -+ { -+ INFO_LOG(VIDEO, "[EGL]: No EGL configs with appropriate attributes.\n"); -+ return false; -+ } - -- for (i = 0; i < *count; i++) -- { -- if (!cb || cb(display_data, egl->dpy, configs[i])) -- { -- egl->config = configs[i]; -- break; -- } -- } -+ for (i = 0; i < *count; i++) -+ { -+ if (!cb || cb(display_data, egl->dpy, configs[i])) -+ { -+ egl->config = configs[i]; -+ break; -+ } -+ } - -- free(configs); -+ free(configs); - -- if (i == *count) -- { -- INFO_LOG(VIDEO, "[EGL]: No EGL config found which satifies requirements.\n"); -- return false; -- } -+ if (i == *count) -+ { -+ INFO_LOG(VIDEO, "[EGL]: No EGL config found which satifies requirements.\n"); -+ return false; -+ } - -- return true; -+ return true; - } - -- --static bool egl_init_context(egl_ctx_data_t *egl, -- EGLenum platform, -- void *display_data, -- EGLint *major, EGLint *minor, -- EGLint *count, const EGLint *attrib_ptr, -- egl_accept_config_cb_t cb) -+static bool egl_init_context(egl_ctx_data_t* egl, EGLenum platform, void* display_data, -+ EGLint* major, EGLint* minor, EGLint* count, const EGLint* attrib_ptr, -+ egl_accept_config_cb_t cb) - { -- EGLDisplay dpy = get_egl_display(platform, display_data); -+ EGLDisplay dpy = get_egl_display(platform, display_data); - -- if (dpy == EGL_NO_DISPLAY) -- { -- INFO_LOG(VIDEO, "[EGL]: Couldn't get EGL display.\n"); -- return false; -- } -+ if (dpy == EGL_NO_DISPLAY) -+ { -+ INFO_LOG(VIDEO, "[EGL]: Couldn't get EGL display.\n"); -+ return false; -+ } - -- egl->dpy = dpy; -+ egl->dpy = dpy; - -- if (!eglInitialize(egl->dpy, major, minor)) -- return false; -+ if (!eglInitialize(egl->dpy, major, minor)) -+ return false; - -- INFO_LOG(VIDEO, "[EGL]: EGL version: %d.%d\n", *major, *minor); -+ INFO_LOG(VIDEO, "[EGL]: EGL version: %d.%d\n", *major, *minor); - -- return egl_init_context_common(egl, count, attrib_ptr, cb, -- display_data); -+ return egl_init_context_common(egl, count, attrib_ptr, cb, display_data); - } - --static bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs) -+static bool egl_create_context(egl_ctx_data_t* egl, const EGLint* egl_attribs) - { -- EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT, -- egl_attribs); -+ EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT, egl_attribs); - -- if (ctx == EGL_NO_CONTEXT) -- return false; -+ if (ctx == EGL_NO_CONTEXT) -+ return false; - -- egl->ctx = ctx; -+ egl->ctx = ctx; - -- return true; -+ return true; - } - --static bool egl_create_surface(egl_ctx_data_t *egl, void *native_window) -+static bool egl_create_surface(egl_ctx_data_t* egl, void* native_window) - { -- EGLint window_attribs[] = { -- EGL_RENDER_BUFFER, EGL_BACK_BUFFER, -- EGL_NONE, -- }; -+ EGLint window_attribs[] = { -+ EGL_RENDER_BUFFER, -+ EGL_BACK_BUFFER, -+ EGL_NONE, -+ }; - -- egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs); -+ egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, (NativeWindowType)native_window, -+ window_attribs); - -- if (egl->surf == EGL_NO_SURFACE) -- return false; -+ if (egl->surf == EGL_NO_SURFACE) -+ return false; - -- /* Connect the context to the surface. */ -- if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx)) -- return false; -+ /* Connect the context to the surface. */ -+ if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx)) -+ return false; - -- INFO_LOG(VIDEO, "[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); -+ INFO_LOG(VIDEO, "[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); - -- return true; -+ return true; - } - - static bool drm_wait_flip(int timeout) - { -- g_drm_fds.revents = 0; -+ g_drm_fds.revents = 0; - -- if (poll(&g_drm_fds, 1, timeout) < 0) -- return false; -+ if (poll(&g_drm_fds, 1, timeout) < 0) -+ return false; - -- if (g_drm_fds.revents & (POLLHUP | POLLERR)) -- return false; -+ if (g_drm_fds.revents & (POLLHUP | POLLERR)) -+ return false; - -- if (g_drm_fds.revents & POLLIN) -- { -- drmHandleEvent(g_drm_fd, &g_drm_evctx); -- return true; -- } -+ if (g_drm_fds.revents & POLLIN) -+ { -+ drmHandleEvent(g_drm_fd, &g_drm_evctx); -+ return true; -+ } - -- return false; -+ return false; - } - - /* Restore the original CRTC. */ - void drm_restore_crtc(void) - { -- if (!g_orig_crtc) -- return; -+ if (!g_orig_crtc) -+ return; - -- drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, -- g_orig_crtc->buffer_id, -- g_orig_crtc->x, -- g_orig_crtc->y, -- &g_connector_id, 1, &g_orig_crtc->mode); -+ drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, g_orig_crtc->buffer_id, g_orig_crtc->x, -+ g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); - -- drmModeFreeCrtc(g_orig_crtc); -- g_orig_crtc = NULL; -+ drmModeFreeCrtc(g_orig_crtc); -+ g_orig_crtc = NULL; - } - - bool drm_get_resources(int fd) - { -- g_drm_resources = drmModeGetResources(fd); -- if (!g_drm_resources) -- { -- INFO_LOG(VIDEO, "[DRM]: Couldn't get device resources.\n"); -- return false; -- } -+ g_drm_resources = drmModeGetResources(fd); -+ if (!g_drm_resources) -+ { -+ INFO_LOG(VIDEO, "[DRM]: Couldn't get device resources.\n"); -+ return false; -+ } - -- return true; -+ return true; - } - - bool drm_get_connector(int fd) - { -- unsigned i; -- unsigned monitor_index_count = 0; -- unsigned monitor = 1; -+ unsigned i; -+ unsigned monitor_index_count = 0; -+ unsigned monitor = 1; - -- /* Enumerate all connectors. */ -+ /* Enumerate all connectors. */ - -- INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); -+ INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); - -- for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -- { -- drmModeConnectorPtr conn = drmModeGetConnector( -- fd, g_drm_resources->connectors[i]); -+ for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ { -+ drmModeConnectorPtr conn = drmModeGetConnector(fd, g_drm_resources->connectors[i]); - -- if (conn) -+ if (conn) -+ { -+ bool connected = conn->connection == DRM_MODE_CONNECTED; -+ INFO_LOG(VIDEO, "[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no"); -+ INFO_LOG(VIDEO, "[DRM]: Connector %d has %d modes.\n", i, conn->count_modes); -+ if (connected && conn->count_modes > 0) - { -- bool connected = conn->connection == DRM_MODE_CONNECTED; -- INFO_LOG(VIDEO, "[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no"); -- INFO_LOG(VIDEO, "[DRM]: Connector %d has %d modes.\n", i, conn->count_modes); -- if (connected && conn->count_modes > 0) -- { -- monitor_index_count++; -- INFO_LOG(VIDEO, "[DRM]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index_count); -- } -- drmModeFreeConnector(conn); -+ monitor_index_count++; -+ INFO_LOG(VIDEO, "[DRM]: Connector %d assigned to monitor index: #%u.\n", i, -+ monitor_index_count); - } -- } -+ drmModeFreeConnector(conn); -+ } -+ } - -- monitor_index_count = 0; -+ monitor_index_count = 0; - -- for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -- { -- g_drm_connector = drmModeGetConnector(fd, -- g_drm_resources->connectors[i]); -+ for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ { -+ g_drm_connector = drmModeGetConnector(fd, g_drm_resources->connectors[i]); - -- if (!g_drm_connector) -- continue; -- if (g_drm_connector->connection == DRM_MODE_CONNECTED -- && g_drm_connector->count_modes > 0) -- { -- monitor_index_count++; -- if (monitor_index_count == monitor) -- break; -- } -+ if (!g_drm_connector) -+ continue; -+ if (g_drm_connector->connection == DRM_MODE_CONNECTED && g_drm_connector->count_modes > 0) -+ { -+ monitor_index_count++; -+ if (monitor_index_count == monitor) -+ break; -+ } - -- drmModeFreeConnector(g_drm_connector); -- g_drm_connector = NULL; -- } -+ drmModeFreeConnector(g_drm_connector); -+ g_drm_connector = NULL; -+ } - -- if (!g_drm_connector) -- { -- INFO_LOG(VIDEO, "[DRM]: Couldn't get device connector.\n"); -- return false; -- } -- return true; -+ if (!g_drm_connector) -+ { -+ INFO_LOG(VIDEO, "[DRM]: Couldn't get device connector.\n"); -+ return false; -+ } -+ return true; - } - - bool drm_get_encoder(int fd) - { -- unsigned i; -+ unsigned i; - -- for (i = 0; (int)i < g_drm_resources->count_encoders; i++) -- { -- g_drm_encoder = drmModeGetEncoder(fd, g_drm_resources->encoders[i]); -+ for (i = 0; (int)i < g_drm_resources->count_encoders; i++) -+ { -+ g_drm_encoder = drmModeGetEncoder(fd, g_drm_resources->encoders[i]); - -- if (!g_drm_encoder) -- continue; -+ if (!g_drm_encoder) -+ continue; - -- if (g_drm_encoder->encoder_id == g_drm_connector->encoder_id) -- break; -+ if (g_drm_encoder->encoder_id == g_drm_connector->encoder_id) -+ break; - -- drmModeFreeEncoder(g_drm_encoder); -- g_drm_encoder = NULL; -- } -+ drmModeFreeEncoder(g_drm_encoder); -+ g_drm_encoder = NULL; -+ } - -- if (!g_drm_encoder) -- { -- INFO_LOG(VIDEO, "[DRM]: Couldn't find DRM encoder.\n"); -- return false; -- } -+ if (!g_drm_encoder) -+ { -+ INFO_LOG(VIDEO, "[DRM]: Couldn't find DRM encoder.\n"); -+ return false; -+ } - -- for (i = 0; (int)i < g_drm_connector->count_modes; i++) -- { -- INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", -- i, -- g_drm_connector->modes[i].name, -- g_drm_connector->modes[i].hdisplay, -- g_drm_connector->modes[i].vdisplay, -- g_drm_connector->modes[i].vrefresh); -- } -+ for (i = 0; (int)i < g_drm_connector->count_modes; i++) -+ { -+ INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", i, g_drm_connector->modes[i].name, -+ g_drm_connector->modes[i].hdisplay, g_drm_connector->modes[i].vdisplay, -+ g_drm_connector->modes[i].vrefresh); -+ } - -- return true; -+ return true; - } - - void drm_setup(int fd) - { -- g_crtc_id = g_drm_encoder->crtc_id; -- g_connector_id = g_drm_connector->connector_id; -- g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); -- if (!g_orig_crtc) -- INFO_LOG(VIDEO, "[DRM]: Cannot find original CRTC.\n"); -+ g_crtc_id = g_drm_encoder->crtc_id; -+ g_connector_id = g_drm_connector->connector_id; -+ g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); -+ if (!g_orig_crtc) -+ INFO_LOG(VIDEO, "[DRM]: Cannot find original CRTC.\n"); - } - --float drm_get_refresh_rate(void *data) -+float drm_get_refresh_rate(void* data) - { -- float refresh_rate = 0.0f; -+ float refresh_rate = 0.0f; - -- if (g_drm_mode) -- { -- refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal; -- } -+ if (g_drm_mode) -+ { -+ refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal; -+ } - -- return refresh_rate; -+ return refresh_rate; - } - - void drm_free(void) - { -- if (g_drm_encoder) -- drmModeFreeEncoder(g_drm_encoder); -- if (g_drm_connector) -- drmModeFreeConnector(g_drm_connector); -- if (g_drm_resources) -- drmModeFreeResources(g_drm_resources); -- -- memset(&g_drm_fds, 0, sizeof(struct pollfd)); -- memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -- -- g_drm_encoder = NULL; -- g_drm_connector = NULL; -- g_drm_resources = NULL; -+ if (g_drm_encoder) -+ drmModeFreeEncoder(g_drm_encoder); -+ if (g_drm_connector) -+ drmModeFreeConnector(g_drm_connector); -+ if (g_drm_resources) -+ drmModeFreeResources(g_drm_resources); -+ -+ memset(&g_drm_fds, 0, sizeof(struct pollfd)); -+ memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -+ -+ g_drm_encoder = NULL; -+ g_drm_connector = NULL; -+ g_drm_resources = NULL; - } - --static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) -+static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data) - { -- struct drm_fb *fb = (struct drm_fb*)data; -+ struct drm_fb* fb = (struct drm_fb*)data; - -- if (fb && fb->fb_id) -- drmModeRmFB(g_drm_fd, fb->fb_id); -+ if (fb && fb->fb_id) -+ drmModeRmFB(g_drm_fd, fb->fb_id); - -- free(fb); -+ free(fb); - } - --static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) -+static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - { -- int ret; -- unsigned width, height, stride, handle; -- struct drm_fb *fb = (struct drm_fb*)calloc(1, sizeof(*fb)); -+ int ret; -+ unsigned width, height, stride, handle; -+ struct drm_fb* fb = (struct drm_fb*)calloc(1, sizeof(*fb)); - -- fb->bo = bo; -+ fb->bo = bo; - -- width = gbm_bo_get_width(bo); -- height = gbm_bo_get_height(bo); -- stride = gbm_bo_get_stride(bo); -- handle = gbm_bo_get_handle(bo).u32; -+ width = gbm_bo_get_width(bo); -+ height = gbm_bo_get_height(bo); -+ stride = gbm_bo_get_stride(bo); -+ handle = gbm_bo_get_handle(bo).u32; - -- INFO_LOG(VIDEO, "[KMS]: New FB: %ux%u (stride: %u).\n", -- width, height, stride); -+ INFO_LOG(VIDEO, "[KMS]: New FB: %ux%u (stride: %u).\n", width, height, stride); - -- ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, -- stride, handle, &fb->fb_id); -- if (ret < 0) -- goto error; -+ ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); -+ if (ret < 0) -+ goto error; - -- gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback); -- return fb; -+ gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback); -+ return fb; - - error: -- INFO_LOG(VIDEO, "[KMS]: Failed to create FB: %s\n", strerror(errno)); -- free(fb); -- return NULL; -+ INFO_LOG(VIDEO, "[KMS]: Failed to create FB: %s\n", strerror(errno)); -+ free(fb); -+ return NULL; - } - --static void gfx_ctx_drm_swap_interval(void *data, int interval) -+static void gfx_ctx_drm_swap_interval(void* data, int interval) - { -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -- drm->interval = interval; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ drm->interval = interval; - -- if (interval > 1) -- INFO_LOG(VIDEO, "[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); -+ if (interval > 1) -+ INFO_LOG(VIDEO, -+ "[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); - } - --static void drm_flip_handler(int fd, unsigned frame, -- unsigned sec, unsigned usec, void *data) -+static void drm_flip_handler(int fd, unsigned frame, unsigned sec, unsigned usec, void* data) - { - #if 0 - static unsigned first_page_flip; -@@ -684,444 +661,434 @@ static void drm_flip_handler(int fd, unsigned frame, - last_page_flip = frame; - #endif - -- *(bool*)data = false; -+ *(bool*)data = false; - } - --static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t *drm, bool block) -+static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t* drm, bool block) - { -- int timeout = 0; -+ int timeout = 0; - -- if (!drm->waiting_for_flip) -- return false; -+ if (!drm->waiting_for_flip) -+ return false; - -- if (block) -- timeout = -1; -+ if (block) -+ timeout = -1; - -- while (drm->waiting_for_flip) -- { -- if (!drm_wait_flip(timeout)) -- break; -- } -+ while (drm->waiting_for_flip) -+ { -+ if (!drm_wait_flip(timeout)) -+ break; -+ } - -- if (drm->waiting_for_flip) -- { INFO_LOG(VIDEO, "\nwait flip 2"); return true; } -+ if (drm->waiting_for_flip) -+ { -+ INFO_LOG(VIDEO, "\nwait flip 2"); -+ return true; -+ } - -- /* Page flip has taken place. */ -+ /* Page flip has taken place. */ - -- /* This buffer is not on-screen anymore. Release it to GBM. */ -- gbm_surface_release_buffer(drm->gbm_surface, drm->bo); -- /* This buffer is being shown now. */ -- drm->bo = drm->next_bo; -- return false; -+ /* This buffer is not on-screen anymore. Release it to GBM. */ -+ gbm_surface_release_buffer(drm->gbm_surface, drm->bo); -+ /* This buffer is being shown now. */ -+ drm->bo = drm->next_bo; -+ return false; - } - --static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t *drm) -+static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t* drm) - { -- struct drm_fb *fb = NULL; -+ struct drm_fb* fb = NULL; - -- drm->next_bo = gbm_surface_lock_front_buffer(drm->gbm_surface); -- fb = (struct drm_fb*)gbm_bo_get_user_data(drm->next_bo); -+ drm->next_bo = gbm_surface_lock_front_buffer(drm->gbm_surface); -+ fb = (struct drm_fb*)gbm_bo_get_user_data(drm->next_bo); - -- if (!fb) -- fb = (struct drm_fb*)drm_fb_get_from_bo(drm->next_bo); -+ if (!fb) -+ fb = (struct drm_fb*)drm_fb_get_from_bo(drm->next_bo); - -- if (drmModePageFlip(g_drm_fd, g_crtc_id, fb->fb_id, -- DRM_MODE_PAGE_FLIP_EVENT, &drm->waiting_for_flip) == 0) -- return true; -+ if (drmModePageFlip(g_drm_fd, g_crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, -+ &drm->waiting_for_flip) == 0) -+ return true; - -- /* Failed to queue page flip. */ -- INFO_LOG(VIDEO, "\nFailed to queue page flip\n"); -- return false; -+ /* Failed to queue page flip. */ -+ INFO_LOG(VIDEO, "\nFailed to queue page flip\n"); -+ return false; - } - --static void gfx_ctx_drm_swap_buffers(void *data) -+static void gfx_ctx_drm_swap_buffers(void* data) - { -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -- unsigned max_swapchain_images = 3; //settings->uints.video_max_swapchain_images; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ unsigned max_swapchain_images = 3; // settings->uints.video_max_swapchain_images; - -- egl_swap_buffers(&drm->egl); -+ egl_swap_buffers(&drm->egl); - -- /* I guess we have to wait for flip to have taken -- * place before another flip can be queued up. -- * -- * If true, we are still waiting for a flip -- * (nonblocking mode, so just drop the frame). */ -- if (gfx_ctx_drm_wait_flip(drm, drm->interval)) -- { INFO_LOG(VIDEO, "\nwait flip"); return; } -+ /* I guess we have to wait for flip to have taken -+ * place before another flip can be queued up. -+ * -+ * If true, we are still waiting for a flip -+ * (nonblocking mode, so just drop the frame). */ -+ if (gfx_ctx_drm_wait_flip(drm, drm->interval)) -+ { -+ INFO_LOG(VIDEO, "\nwait flip"); -+ return; -+ } - -- drm->waiting_for_flip = gfx_ctx_drm_queue_flip(drm); -+ drm->waiting_for_flip = gfx_ctx_drm_queue_flip(drm); - -- /* Triple-buffered page flips */ -- if (max_swapchain_images >= 3 && -- gbm_surface_has_free_buffers(drm->gbm_surface)) -- return; -+ /* Triple-buffered page flips */ -+ if (max_swapchain_images >= 3 && gbm_surface_has_free_buffers(drm->gbm_surface)) -+ return; - -- gfx_ctx_drm_wait_flip(drm, true); -+ gfx_ctx_drm_wait_flip(drm, true); - } - --static void gfx_ctx_drm_get_video_size(void *data, -- unsigned *width, unsigned *height) -+static void gfx_ctx_drm_get_video_size(void* data, unsigned* width, unsigned* height) - { -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; - -- if (!drm) -- { -- INFO_LOG(VIDEO, "\nCannot get drm video size\n"); -- return; -- } -+ if (!drm) -+ { -+ INFO_LOG(VIDEO, "\nCannot get drm video size\n"); -+ return; -+ } - -- *width = drm->fb_width; -- *height = drm->fb_height; -+ *width = drm->fb_width; -+ *height = drm->fb_height; - } - --static void free_drm_resources(gfx_ctx_drm_data_t *drm) -+static void free_drm_resources(gfx_ctx_drm_data_t* drm) - { -- if (!drm) -- return; -+ if (!drm) -+ return; - -- /* Restore original CRTC. */ -- drm_restore_crtc(); -+ /* Restore original CRTC. */ -+ drm_restore_crtc(); - -- if (drm->gbm_surface) -- gbm_surface_destroy(drm->gbm_surface); -+ if (drm->gbm_surface) -+ gbm_surface_destroy(drm->gbm_surface); - -- if (drm->gbm_dev) -- gbm_device_destroy(drm->gbm_dev); -+ if (drm->gbm_dev) -+ gbm_device_destroy(drm->gbm_dev); - -- drm_free(); -+ drm_free(); - -- if (drm->fd >= 0) -- { -- if (g_drm_fd >= 0) -- { -- drmDropMaster(g_drm_fd); -- close(drm->fd); -- } -- } -+ if (drm->fd >= 0) -+ { -+ if (g_drm_fd >= 0) -+ { -+ drmDropMaster(g_drm_fd); -+ close(drm->fd); -+ } -+ } - -- drm->gbm_surface = NULL; -- drm->gbm_dev = NULL; -- g_drm_fd = -1; -+ drm->gbm_surface = NULL; -+ drm->gbm_dev = NULL; -+ g_drm_fd = -1; - } - --static void gfx_ctx_drm_destroy_resources(gfx_ctx_drm_data_t *drm) -+static void gfx_ctx_drm_destroy_resources(gfx_ctx_drm_data_t* drm) - { -- if (!drm) -- return; -+ if (!drm) -+ return; - -- /* Make sure we acknowledge all page-flips. */ -- gfx_ctx_drm_wait_flip(drm, true); -+ /* Make sure we acknowledge all page-flips. */ -+ gfx_ctx_drm_wait_flip(drm, true); - -- egl_destroy(&drm->egl); -+ egl_destroy(&drm->egl); - -- free_drm_resources(drm); -+ free_drm_resources(drm); - -- g_drm_mode = NULL; -- g_crtc_id = 0; -- g_connector_id = 0; -+ g_drm_mode = NULL; -+ g_crtc_id = 0; -+ g_connector_id = 0; - -- drm->fb_width = 0; -- drm->fb_height = 0; -+ drm->fb_width = 0; -+ drm->fb_height = 0; - -- drm->bo = NULL; -- drm->next_bo = NULL; -+ drm->bo = NULL; -+ drm->next_bo = NULL; - } - --static void *gfx_ctx_drm_init() -+static void* gfx_ctx_drm_init() - { -- int fd, i; -- unsigned monitor_index; -- unsigned gpu_index = 0; -- const char *gpu = NULL; -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)calloc(1, sizeof(gfx_ctx_drm_data_t)); -+ int fd, i; -+ unsigned monitor_index; -+ unsigned gpu_index = 0; -+ const char* gpu = NULL; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)calloc(1, sizeof(gfx_ctx_drm_data_t)); - -- if (!drm) -- return NULL; -- drm->fd = -1; -+ if (!drm) -+ return NULL; -+ drm->fd = -1; - -- free_drm_resources(drm); -+ free_drm_resources(drm); - -- drm->fd = open("/dev/dri/card0", O_RDWR); -- if (drm->fd < 0) -- { -- INFO_LOG(VIDEO, "[KMS]: Couldn't open DRM device.\n"); -- return nullptr; -- } -+ drm->fd = open("/dev/dri/card0", O_RDWR); -+ if (drm->fd < 0) -+ { -+ INFO_LOG(VIDEO, "[KMS]: Couldn't open DRM device.\n"); -+ return nullptr; -+ } - -- fd = drm->fd; -+ fd = drm->fd; - -- if (!drm_get_resources(fd)) -- { -- INFO_LOG(VIDEO, "[KMS]: drm_get_resources failed\n"); -- return nullptr; -- } -+ if (!drm_get_resources(fd)) -+ { -+ INFO_LOG(VIDEO, "[KMS]: drm_get_resources failed\n"); -+ return nullptr; -+ } - -- if (!drm_get_connector(fd)) -- { -- INFO_LOG(VIDEO, "[KMS]: drm_get_connector failed\n"); -- return nullptr; -- } -+ if (!drm_get_connector(fd)) -+ { -+ INFO_LOG(VIDEO, "[KMS]: drm_get_connector failed\n"); -+ return nullptr; -+ } - -- if (!drm_get_encoder(fd)) -- { -- INFO_LOG(VIDEO, "[KMS]: drm_get_encoder failed\n"); -- return nullptr; -- } -+ if (!drm_get_encoder(fd)) -+ { -+ INFO_LOG(VIDEO, "[KMS]: drm_get_encoder failed\n"); -+ return nullptr; -+ } - -- drm_setup(fd); -+ drm_setup(fd); - -- /* Choose the optimal video mode for get_video_size(): -- - the current video mode from the CRTC -- - otherwise pick first connector mode */ -- if (g_orig_crtc->mode_valid) -- { -- drm->fb_width = g_orig_crtc->mode.hdisplay; -- drm->fb_height = g_orig_crtc->mode.vdisplay; -- } -- else -- { -- drm->fb_width = g_drm_connector->modes[0].hdisplay; -- drm->fb_height = g_drm_connector->modes[0].vdisplay; -- } -+ /* Choose the optimal video mode for get_video_size(): -+ - the current video mode from the CRTC -+ - otherwise pick first connector mode */ -+ if (g_orig_crtc->mode_valid) -+ { -+ drm->fb_width = g_orig_crtc->mode.hdisplay; -+ drm->fb_height = g_orig_crtc->mode.vdisplay; -+ } -+ else -+ { -+ drm->fb_width = g_drm_connector->modes[0].hdisplay; -+ drm->fb_height = g_drm_connector->modes[0].vdisplay; -+ } - -- drmSetMaster(g_drm_fd); -+ drmSetMaster(g_drm_fd); - -- drm->gbm_dev = gbm_create_device(fd); -+ drm->gbm_dev = gbm_create_device(fd); - -- if (!drm->gbm_dev) -- { -- INFO_LOG(VIDEO, "[KMS]: Couldn't create GBM device.\n"); -- return nullptr; -- } -+ if (!drm->gbm_dev) -+ { -+ INFO_LOG(VIDEO, "[KMS]: Couldn't create GBM device.\n"); -+ return nullptr; -+ } - -- /* Setup the flip handler. */ -- g_drm_fds.fd = fd; -- g_drm_fds.events = POLLIN; -- g_drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; -- g_drm_evctx.page_flip_handler = drm_flip_handler; -+ /* Setup the flip handler. */ -+ g_drm_fds.fd = fd; -+ g_drm_fds.events = POLLIN; -+ g_drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; -+ g_drm_evctx.page_flip_handler = drm_flip_handler; - -- g_drm_fd = fd; -+ g_drm_fd = fd; - -- return drm; -+ return drm; - - error: -- gfx_ctx_drm_destroy_resources(drm); -+ gfx_ctx_drm_destroy_resources(drm); - -- if (drm) -- free(drm); -+ if (drm) -+ free(drm); - -- return NULL; -+ return NULL; - } - --static EGLint *gfx_ctx_drm_egl_fill_attribs( -- gfx_ctx_drm_data_t *drm, EGLint *attr) -+static EGLint* gfx_ctx_drm_egl_fill_attribs(gfx_ctx_drm_data_t* drm, EGLint* attr) - { -- *attr++ = EGL_CONTEXT_CLIENT_VERSION; -- *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; -+ *attr++ = EGL_CONTEXT_CLIENT_VERSION; -+ *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; - #ifdef EGL_KHR_create_context -- if (drm->egl.minor > 0) -- { -- *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; -- *attr++ = drm->egl.minor; -- } -+ if (drm->egl.minor > 0) -+ { -+ *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; -+ *attr++ = drm->egl.minor; -+ } - #endif - -- *attr = EGL_NONE; -- return attr; -+ *attr = EGL_NONE; -+ return attr; - } - --static bool gbm_choose_xrgb8888_cb(void *display_data, EGLDisplay dpy, EGLConfig config) -+static bool gbm_choose_xrgb8888_cb(void* display_data, EGLDisplay dpy, EGLConfig config) - { -- EGLint r, g, b, id; -- (void)display_data; -+ EGLint r, g, b, id; -+ (void)display_data; - -- /* Makes sure we have 8 bit color. */ -- if (!eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r)) -- return false; -- if (!eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g)) -- return false; -- if (!eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b)) -- return false; -+ /* Makes sure we have 8 bit color. */ -+ if (!eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r)) -+ return false; -+ if (!eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g)) -+ return false; -+ if (!eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b)) -+ return false; - -- if (r != 8 || g != 8 || b != 8) -- return false; -+ if (r != 8 || g != 8 || b != 8) -+ return false; - -- if (!eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &id)) -- return false; -+ if (!eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &id)) -+ return false; - -- return id == GBM_FORMAT_XRGB8888; -+ return id == GBM_FORMAT_XRGB8888; - } - --#define DRM_EGL_ATTRIBS_BASE \ -- EGL_SURFACE_TYPE, 0/*EGL_WINDOW_BIT*/, \ -- EGL_RED_SIZE, 8, \ -- EGL_GREEN_SIZE, 8, \ -- EGL_BLUE_SIZE, 8, \ -- EGL_ALPHA_SIZE, 0, \ -- EGL_DEPTH_SIZE, 0 -+#define DRM_EGL_ATTRIBS_BASE \ -+ EGL_SURFACE_TYPE, 0 /*EGL_WINDOW_BIT*/, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, \ -+ EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 0 - - #ifdef EGL_KHR_create_context -- static const EGLint egl_attribs_gles3[] = { -- DRM_EGL_ATTRIBS_BASE, -- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, -- EGL_NONE, -- }; -+static const EGLint egl_attribs_gles3[] = { -+ DRM_EGL_ATTRIBS_BASE, -+ EGL_RENDERABLE_TYPE, -+ EGL_OPENGL_ES3_BIT_KHR, -+ EGL_NONE, -+}; - #endif - --static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) -+static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t* drm) - { -- const EGLint *attrib_ptr = NULL; -- EGLint major; -- EGLint minor; -- EGLint n; -- EGLint egl_attribs[16]; -- EGLint *egl_attribs_ptr = NULL; -- EGLint *attr = NULL; -- -- attrib_ptr = egl_attribs_gles3; -- -- if (!egl_init_context(&drm->egl, EGL_PLATFORM_GBM_KHR, -- (EGLNativeDisplayType)drm->gbm_dev, &major, -- &minor, &n, attrib_ptr, gbm_choose_xrgb8888_cb)) -- { -- INFO_LOG(VIDEO, "\n[EGL] Cannot init context error 0x%x",eglGetError()); -- goto error; -- } -- attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); -- egl_attribs_ptr = &egl_attribs[0]; -+ const EGLint* attrib_ptr = NULL; -+ EGLint major; -+ EGLint minor; -+ EGLint n; -+ EGLint egl_attribs[16]; -+ EGLint* egl_attribs_ptr = NULL; -+ EGLint* attr = NULL; - -- if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) -- ? egl_attribs_ptr : NULL)) -- { -- INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x",eglGetError()); -- goto error; -- } -+ attrib_ptr = egl_attribs_gles3; - -- if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface)) -- { -- INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x",eglGetError()); -- return false; -- } -+ if (!egl_init_context(&drm->egl, EGL_PLATFORM_GBM_KHR, (EGLNativeDisplayType)drm->gbm_dev, &major, -+ &minor, &n, attrib_ptr, gbm_choose_xrgb8888_cb)) -+ { -+ INFO_LOG(VIDEO, "\n[EGL] Cannot init context error 0x%x", eglGetError()); -+ goto error; -+ } -+ attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); -+ egl_attribs_ptr = &egl_attribs[0]; -+ -+ if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) -+ { -+ INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x", eglGetError()); -+ goto error; -+ } - -- egl_swap_buffers(&drm->egl); -+ if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface)) -+ { -+ INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x", eglGetError()); -+ return false; -+ } - -- return true; -+ egl_swap_buffers(&drm->egl); -+ -+ return true; - - error: -- return false; -+ return false; - } - --static bool gfx_ctx_drm_set_video_mode(void *data, -- unsigned width, unsigned height, -- bool fullscreen) -+static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned height, bool fullscreen) - { -- int i, ret = 0; -- struct drm_fb *fb = NULL; -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -- float video_refresh_rate = (float)VideoInterface::GetTargetRefreshRate(); -- -- if (!drm) -- return false; -- -- /* Find desired video mode, and use that. -- * If not fullscreen, we get desired windowed size, -- * which is not appropriate. */ -- if ((width == 0 && height == 0) || !fullscreen) -- g_drm_mode = &g_drm_connector->modes[0]; -- else -- { -- /* Try to match refresh_rate as closely as possible. -- * -- * Lower resolutions tend to have multiple supported -- * refresh rates as well. -- */ -- float minimum_fps_diff = 0.0f; -- -- /* Find best match. */ -- for (i = 0; i < g_drm_connector->count_modes; i++) -+ int i, ret = 0; -+ struct drm_fb* fb = NULL; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ float video_refresh_rate = (float)VideoInterface::GetTargetRefreshRate(); -+ -+ if (!drm) -+ return false; -+ -+ /* Find desired video mode, and use that. -+ * If not fullscreen, we get desired windowed size, -+ * which is not appropriate. */ -+ if ((width == 0 && height == 0) || !fullscreen) -+ g_drm_mode = &g_drm_connector->modes[0]; -+ else -+ { -+ /* Try to match refresh_rate as closely as possible. -+ * -+ * Lower resolutions tend to have multiple supported -+ * refresh rates as well. -+ */ -+ float minimum_fps_diff = 0.0f; -+ -+ /* Find best match. */ -+ for (i = 0; i < g_drm_connector->count_modes; i++) -+ { -+ float diff; -+ if (width != g_drm_connector->modes[i].hdisplay || -+ height != g_drm_connector->modes[i].vdisplay) -+ continue; -+ -+ diff = fabsf(g_drm_connector->modes[i].vrefresh - video_refresh_rate); -+ -+ if (!g_drm_mode || diff < minimum_fps_diff) - { -- float diff; -- if (width != g_drm_connector->modes[i].hdisplay || -- height != g_drm_connector->modes[i].vdisplay) -- continue; -- -- diff = fabsf(g_drm_connector->modes[i].vrefresh - video_refresh_rate); -- -- if (!g_drm_mode || diff < minimum_fps_diff) -- { -- g_drm_mode = &g_drm_connector->modes[i]; -- minimum_fps_diff = diff; -- } -+ g_drm_mode = &g_drm_connector->modes[i]; -+ minimum_fps_diff = diff; - } -- } -+ } -+ } - -- if (!g_drm_mode) -- { -- INFO_LOG(VIDEO, "[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", -- width, height); -- goto error; -- } -+ if (!g_drm_mode) -+ { -+ INFO_LOG(VIDEO, "[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", width, height); -+ goto error; -+ } - -- drm->fb_width = g_drm_mode->hdisplay; -- drm->fb_height = g_drm_mode->vdisplay; -+ drm->fb_width = g_drm_mode->hdisplay; -+ drm->fb_height = g_drm_mode->vdisplay; - -- /* Create GBM surface. */ -- drm->gbm_surface = gbm_surface_create( -- drm->gbm_dev, -- drm->fb_width, -- drm->fb_height, -- GBM_FORMAT_XRGB8888, -- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); -+ /* Create GBM surface. */ -+ drm->gbm_surface = -+ gbm_surface_create(drm->gbm_dev, drm->fb_width, drm->fb_height, GBM_FORMAT_XRGB8888, -+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - -- if (!drm->gbm_surface) -- { -- INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't create GBM surface.\n"); -- goto error; -- } -+ if (!drm->gbm_surface) -+ { -+ INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't create GBM surface.\n"); -+ goto error; -+ } - -- if (!gfx_ctx_drm_egl_set_video_mode(drm)) -- { -- INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't set EGL video mode.\n"); -- goto error; -- } -+ if (!gfx_ctx_drm_egl_set_video_mode(drm)) -+ { -+ INFO_LOG(VIDEO, "[KMS/EGL]: Couldn't set EGL video mode.\n"); -+ goto error; -+ } - -- drm->bo = gbm_surface_lock_front_buffer(drm->gbm_surface); -+ drm->bo = gbm_surface_lock_front_buffer(drm->gbm_surface); - -- fb = (struct drm_fb*)gbm_bo_get_user_data(drm->bo); -+ fb = (struct drm_fb*)gbm_bo_get_user_data(drm->bo); - -- if (!fb) -- fb = drm_fb_get_from_bo(drm->bo); -+ if (!fb) -+ fb = drm_fb_get_from_bo(drm->bo); - -- ret = drmModeSetCrtc(g_drm_fd, -- g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode); -- if (ret < 0) -- { -- INFO_LOG(VIDEO, "[KMS/EGL]: drmModeSetCrtc failed\n"); -- goto error; -- } -- return true; -+ ret = drmModeSetCrtc(g_drm_fd, g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode); -+ if (ret < 0) -+ { -+ INFO_LOG(VIDEO, "[KMS/EGL]: drmModeSetCrtc failed\n"); -+ goto error; -+ } -+ return true; - - error: -- gfx_ctx_drm_destroy_resources(drm); -+ gfx_ctx_drm_destroy_resources(drm); - -- if (drm) -- free(drm); -+ if (drm) -+ free(drm); - -- return false; -+ return false; - } - --static void gfx_ctx_drm_destroy(void *data) -+static void gfx_ctx_drm_destroy(void* data) - { -- gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; -+ gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; - -- if (!drm) -- return; -+ if (!drm) -+ return; - -- gfx_ctx_drm_destroy_resources(drm); -- free(drm); -+ gfx_ctx_drm_destroy_resources(drm); -+ free(drm); - } - -- - GLContextEGLDRM::~GLContextEGLDRM() - { - DestroyWindowSurface(); -@@ -1136,12 +1103,12 @@ bool GLContextEGLDRM::IsHeadless() const - - void GLContextEGLDRM::Swap() - { -- gfx_ctx_drm_swap_buffers(g_drm); -+ gfx_ctx_drm_swap_buffers(g_drm); - } - void GLContextEGLDRM::SwapInterval(int interval) - { -- gfx_ctx_drm_swap_interval(g_drm, interval); -- egl_set_swap_interval(m_egl, interval); -+ gfx_ctx_drm_swap_interval(g_drm, interval); -+ egl_set_swap_interval(m_egl, interval); - } - - void* GLContextEGLDRM::GetFuncAddress(const std::string& name) -@@ -1159,12 +1126,12 @@ bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool - - // Use current video mode, do not switch - gfx_ctx_drm_set_video_mode(g_drm, 0, 0, false); -- m_backbuffer_width = g_drm->fb_width; -+ m_backbuffer_width = g_drm->fb_width; - m_backbuffer_height = g_drm->fb_height; - - m_egl = &g_drm->egl; - m_opengl_mode = Mode::OpenGLES; -- m_supports_surfaceless = check_egl_display_extension(m_egl,"EGL_KHR_surfaceless_context"); -+ m_supports_surfaceless = check_egl_display_extension(m_egl, "EGL_KHR_surfaceless_context"); - - eglBindAPI(EGL_OPENGL_ES_API); - -@@ -1179,11 +1146,12 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - - eglBindAPI(EGL_OPENGL_ES_API); - EGLint egl_attribs[16]; -- EGLint *egl_attribs_ptr = NULL; -- const EGLint *attrib_ptr = egl_attribs_gles3; -+ EGLint* egl_attribs_ptr = NULL; -+ const EGLint* attrib_ptr = egl_attribs_gles3; - EGLint* attr = gfx_ctx_drm_egl_fill_attribs(g_drm, egl_attribs); - egl_attribs_ptr = &egl_attribs[0]; -- new_context->m_egl->ctx = eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); -+ new_context->m_egl->ctx = -+ eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); - if (!new_context->m_egl->ctx) - { - ERROR_LOG(VIDEO, "\nError: eglCreateContext failed 0x%x\n", eglGetError()); -@@ -1203,7 +1171,9 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - - bool GLContextEGLDRM::CreateWindowSurface() - { -- EGLint attrib_list[] = { EGL_NONE, }; -+ EGLint attrib_list[] = { -+ EGL_NONE, -+ }; - if (m_supports_surfaceless) - { - m_egl->surf = EGL_NO_SURFACE; -@@ -1213,17 +1183,18 @@ bool GLContextEGLDRM::CreateWindowSurface() - - if (!IsHeadless()) - { -- if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) -- { -+ if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) -+ { - INFO_LOG(VIDEO, "\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); - goto pbuffer; -- } -+ } - // Get dimensions from the surface. - EGLint surface_width = 1, surface_height = 1; - if (!eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_WIDTH, &surface_width) || - !eglQuerySurface(m_egl->dpy, m_egl->surf, EGL_HEIGHT, &surface_height)) - { -- INFO_LOG(VIDEO, "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); -+ INFO_LOG(VIDEO, -+ "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); - } - m_backbuffer_width = static_cast(surface_width); - m_backbuffer_height = static_cast(surface_height); -@@ -1231,13 +1202,13 @@ bool GLContextEGLDRM::CreateWindowSurface() - } - - pbuffer: -- m_egl->surf = eglCreatePbufferSurface(m_egl->dpy, m_egl->config, attrib_list); -- if (!m_egl->surf) -- { -- INFO_LOG(VIDEO, "\nError: eglCreatePbufferSurface failed 0x%x\n", eglGetError()); -- return false; -- } -- return true; -+ m_egl->surf = eglCreatePbufferSurface(m_egl->dpy, m_egl->config, attrib_list); -+ if (!m_egl->surf) -+ { -+ INFO_LOG(VIDEO, "\nError: eglCreatePbufferSurface failed 0x%x\n", eglGetError()); -+ return false; -+ } -+ return true; - } - - void GLContextEGLDRM::DestroyWindowSurface() -@@ -1273,7 +1244,7 @@ bool GLContextEGLDRM::ClearCurrent() - // Close backend - void GLContextEGLDRM::DestroyContext() - { --if (!m_egl->ctx) -+ if (!m_egl->ctx) - return; - - if (eglGetCurrentContext() == m_egl->ctx) - -From 414cb0ec131cad6667f229c7b5b8b16969d42772 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:04:56 +0200 -Subject: [PATCH 11/25] Indent properly Source/Core/Common/CMakeLists.txt - ---- - Source/Core/Common/CMakeLists.txt | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt -index 6e220d9047b..6e7574b7c8d 100644 ---- a/Source/Core/Common/CMakeLists.txt -+++ b/Source/Core/Common/CMakeLists.txt -@@ -226,16 +226,16 @@ if(ENABLE_EGL AND EGL_FOUND) - find_package(Libgbm) - if (LIBDRM_FOUND AND LIBGBM_FOUND) - target_sources(common PRIVATE -- GL/GLInterface/EGL.cpp -- GL/GLInterface/EGL.h -- GL/GLInterface/EGLDRM.cpp -- GL/GLInterface/EGLDRM.h -+ GL/GLInterface/EGL.cpp -+ GL/GLInterface/EGL.h -+ GL/GLInterface/EGLDRM.cpp -+ GL/GLInterface/EGLDRM.h - ) - else() -- target_sources(common PRIVATE -- GL/GLInterface/EGL.cpp -- GL/GLInterface/EGL.h -- ) -+ target_sources(common PRIVATE -+ GL/GLInterface/EGL.cpp -+ GL/GLInterface/EGL.h -+ ) - endif() - if(ANDROID) - target_sources(common PRIVATE - -From c55dc590e461bc7e9d647ad0cb8e0d7ff50044ae Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:08:56 +0200 -Subject: [PATCH 12/25] Fix headers order / C++ compliance and move to - EGLContextData struct - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 45 ++++++++++---------- - Source/Core/Common/GL/GLInterface/EGLDRM.h | 6 +-- - 2 files changed, 26 insertions(+), 25 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 100e60d1c78..ff1b13967cd 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -19,26 +19,27 @@ - * If not, see . - */ - --#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ - #include --#include - #include - #include --#include --#include --#include - #include - #include - #include - #include - --#include --#include --#include - #include - #include --#include --#include - #include - #include - -@@ -80,7 +81,7 @@ using EGLAcceptConfigCB = bool (*)(void* display_data, EGLDisplay dpy, EGLConfig - - typedef struct gfx_ctx_drm_data - { -- egl_ctx_data_t egl; -+ EGLContextData egl; - int fd; - int interval; - unsigned fb_width; -@@ -126,7 +127,7 @@ void drm_free(void); - bool drm_get_connector(int fd); - float drm_get_refresh_rate(void* data); - --static void egl_destroy(egl_ctx_data_t* egl) -+static void egl_destroy(EGLContextData* egl) - { - if (egl->dpy) - { -@@ -151,14 +152,14 @@ static void egl_destroy(egl_ctx_data_t* egl) - - static void egl_swap_buffers(void* data) - { -- egl_ctx_data_t* egl = (egl_ctx_data_t*)data; -+ EGLContextData* egl = (EGLContextData*)data; - if (egl && egl->dpy != EGL_NO_DISPLAY && egl->surf != EGL_NO_SURFACE) - { - eglSwapBuffers(egl->dpy, egl->surf); - } - } - --static void egl_set_swap_interval(egl_ctx_data_t* egl, int interval) -+static void egl_set_swap_interval(EGLContextData* egl, int interval) - { - /* Can be called before initialization. - * Some contexts require that swap interval -@@ -230,7 +231,7 @@ static bool check_egl_client_extension(const char* name) - static bool check_egl_display_extension(void* data, const char* name) - { - size_t nameLen; -- egl_ctx_data_t* egl = (egl_ctx_data_t*)data; -+ EGLContextData* egl = (EGLContextData*)data; - if (!egl || egl->dpy == EGL_NO_DISPLAY) - return false; - -@@ -308,7 +309,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void* native) - return eglGetDisplay((EGLNativeDisplayType)native); - } - --static bool egl_get_native_visual_id(egl_ctx_data_t* egl, EGLint* value) -+static bool egl_get_native_visual_id(EGLContextData* egl, EGLint* value) - { - if (!eglGetConfigAttrib(egl->dpy, egl->config, EGL_NATIVE_VISUAL_ID, value)) - { -@@ -319,7 +320,7 @@ static bool egl_get_native_visual_id(egl_ctx_data_t* egl, EGLint* value) - return true; - } - --static bool egl_init_context_common(egl_ctx_data_t* egl, EGLint* count, const EGLint* attrib_ptr, -+static bool egl_init_context_common(EGLContextData* egl, EGLint* count, const EGLint* attrib_ptr, - egl_accept_config_cb_t cb, void* display_data) - { - EGLint i; -@@ -364,7 +365,7 @@ static bool egl_init_context_common(egl_ctx_data_t* egl, EGLint* count, const EG - return true; - } - --static bool egl_init_context(egl_ctx_data_t* egl, EGLenum platform, void* display_data, -+static bool egl_init_context(EGLContextData* egl, EGLenum platform, void* display_data, - EGLint* major, EGLint* minor, EGLint* count, const EGLint* attrib_ptr, - egl_accept_config_cb_t cb) - { -@@ -386,7 +387,7 @@ static bool egl_init_context(egl_ctx_data_t* egl, EGLenum platform, void* displa - return egl_init_context_common(egl, count, attrib_ptr, cb, display_data); - } - --static bool egl_create_context(egl_ctx_data_t* egl, const EGLint* egl_attribs) -+static bool egl_create_context(EGLContextData* egl, const EGLint* egl_attribs) - { - EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT, egl_attribs); - -@@ -398,7 +399,7 @@ static bool egl_create_context(egl_ctx_data_t* egl, const EGLint* egl_attribs) - return true; - } - --static bool egl_create_surface(egl_ctx_data_t* egl, void* native_window) -+static bool egl_create_surface(EGLContextData* egl, void* native_window) - { - EGLint window_attribs[] = { - EGL_RENDER_BUFFER, -@@ -1141,8 +1142,8 @@ bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool - std::unique_ptr GLContextEGLDRM::CreateSharedContext() - { - std::unique_ptr new_context = std::make_unique(); -- new_context->m_egl = (egl_ctx_data_t*)malloc(sizeof(egl_ctx_data_t)); -- memcpy(new_context->m_egl, m_egl, sizeof(egl_ctx_data_t)); -+ new_context->m_egl = (EGLContextData*)malloc(sizeof(EGLContextData)); -+ memcpy(new_context->m_egl, m_egl, sizeof(EGLContextData)); - - eglBindAPI(EGL_OPENGL_ES_API); - EGLint egl_attribs[16]; -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -index 9b38f00900c..46d361a3a14 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.h -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -11,7 +11,7 @@ - - #include "Common/GL/GLContext.h" - --typedef struct -+struct EGLContextData - { - EGLContext ctx; - EGLSurface surf; -@@ -22,7 +22,7 @@ typedef struct - unsigned major; - unsigned minor; - --} egl_ctx_data_t; -+}; - - class GLContextEGLDRM : public GLContext - { -@@ -51,5 +51,5 @@ class GLContextEGLDRM : public GLContext - void DestroyContext(); - - bool m_supports_surfaceless = false; -- egl_ctx_data_t* m_egl; -+ EGLContextData* m_egl; - }; - -From 02575c2cbfa074043668d7d3b41b0bd122e9e664 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:11:49 +0200 -Subject: [PATCH 13/25] Move gfx_ctx_drm_data_t to GFXContextDRMData - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 30 ++++++++++---------- - 1 file changed, 15 insertions(+), 15 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index ff1b13967cd..f252fb09170 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -79,7 +79,7 @@ - - using EGLAcceptConfigCB = bool (*)(void* display_data, EGLDisplay dpy, EGLConfig config); - --typedef struct gfx_ctx_drm_data -+struct GFXContextDRMData - { - EGLContextData egl; - int fd; -@@ -93,7 +93,7 @@ typedef struct gfx_ctx_drm_data - struct gbm_bo* next_bo; - struct gbm_surface* gbm_surface; - struct gbm_device* gbm_dev; --} gfx_ctx_drm_data_t; -+}; - - struct drm_fb - { -@@ -634,7 +634,7 @@ static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - - static void gfx_ctx_drm_swap_interval(void* data, int interval) - { -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ GFXContextDRMData* drm = (GFXContextDRMData*)data; - drm->interval = interval; - - if (interval > 1) -@@ -665,7 +665,7 @@ static void drm_flip_handler(int fd, unsigned frame, unsigned sec, unsigned usec - *(bool*)data = false; - } - --static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t* drm, bool block) -+static bool gfx_ctx_drm_wait_flip(GFXContextDRMData* drm, bool block) - { - int timeout = 0; - -@@ -696,7 +696,7 @@ static bool gfx_ctx_drm_wait_flip(gfx_ctx_drm_data_t* drm, bool block) - return false; - } - --static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t* drm) -+static bool gfx_ctx_drm_queue_flip(GFXContextDRMData* drm) - { - struct drm_fb* fb = NULL; - -@@ -717,7 +717,7 @@ static bool gfx_ctx_drm_queue_flip(gfx_ctx_drm_data_t* drm) - - static void gfx_ctx_drm_swap_buffers(void* data) - { -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ GFXContextDRMData* drm = (GFXContextDRMData*)data; - unsigned max_swapchain_images = 3; // settings->uints.video_max_swapchain_images; - - egl_swap_buffers(&drm->egl); -@@ -744,7 +744,7 @@ static void gfx_ctx_drm_swap_buffers(void* data) - - static void gfx_ctx_drm_get_video_size(void* data, unsigned* width, unsigned* height) - { -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ GFXContextDRMData* drm = (GFXContextDRMData*)data; - - if (!drm) - { -@@ -756,7 +756,7 @@ static void gfx_ctx_drm_get_video_size(void* data, unsigned* width, unsigned* he - *height = drm->fb_height; - } - --static void free_drm_resources(gfx_ctx_drm_data_t* drm) -+static void free_drm_resources(GFXContextDRMData* drm) - { - if (!drm) - return; -@@ -786,7 +786,7 @@ static void free_drm_resources(gfx_ctx_drm_data_t* drm) - g_drm_fd = -1; - } - --static void gfx_ctx_drm_destroy_resources(gfx_ctx_drm_data_t* drm) -+static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) - { - if (!drm) - return; -@@ -815,7 +815,7 @@ static void* gfx_ctx_drm_init() - unsigned monitor_index; - unsigned gpu_index = 0; - const char* gpu = NULL; -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)calloc(1, sizeof(gfx_ctx_drm_data_t)); -+ GFXContextDRMData* drm = (GFXContextDRMData*)calloc(1, sizeof(GFXContextDRMData)); - - if (!drm) - return NULL; -@@ -895,7 +895,7 @@ static void* gfx_ctx_drm_init() - return NULL; - } - --static EGLint* gfx_ctx_drm_egl_fill_attribs(gfx_ctx_drm_data_t* drm, EGLint* attr) -+static EGLint* gfx_ctx_drm_egl_fill_attribs(GFXContextDRMData* drm, EGLint* attr) - { - *attr++ = EGL_CONTEXT_CLIENT_VERSION; - *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; -@@ -946,7 +946,7 @@ static const EGLint egl_attribs_gles3[] = { - }; - #endif - --static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t* drm) -+static bool gfx_ctx_drm_egl_set_video_mode(GFXContextDRMData* drm) - { - const EGLint* attrib_ptr = NULL; - EGLint major; -@@ -991,7 +991,7 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - { - int i, ret = 0; - struct drm_fb* fb = NULL; -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ GFXContextDRMData* drm = (GFXContextDRMData*)data; - float video_refresh_rate = (float)VideoInterface::GetTargetRefreshRate(); - - if (!drm) -@@ -1081,7 +1081,7 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - - static void gfx_ctx_drm_destroy(void* data) - { -- gfx_ctx_drm_data_t* drm = (gfx_ctx_drm_data_t*)data; -+ GFXContextDRMData* drm = (GFXContextDRMData*)data; - - if (!drm) - return; -@@ -1121,7 +1121,7 @@ void* GLContextEGLDRM::GetFuncAddress(const std::string& name) - // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() - bool GLContextEGLDRM::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) - { -- g_drm = (gfx_ctx_drm_data_t*)gfx_ctx_drm_init(); -+ g_drm = (GFXContextDRMData*)gfx_ctx_drm_init(); - - eglBindAPI(EGL_OPENGL_ES_API); - - -From 67cb42244209095b64022b3616000c7686859655 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:15:39 +0200 -Subject: [PATCH 14/25] Remove useless "private:" declaration in - PlatformDRM.cpp - ---- - Source/Core/DolphinNoGUI/PlatformDRM.cpp | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/Source/Core/DolphinNoGUI/PlatformDRM.cpp b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -index 255888ad4cc..6e4dc08eedf 100644 ---- a/Source/Core/DolphinNoGUI/PlatformDRM.cpp -+++ b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -@@ -36,8 +36,6 @@ class PlatformDRM : public Platform - void MainLoop() override; - - WindowSystemInfo GetWindowSystemInfo() const override; -- --private: - }; - - PlatformDRM::~PlatformDRM() = default; - -From dcabf7a330cfeb8db857ceced4e40034b3731877 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:17:41 +0200 -Subject: [PATCH 15/25] Harmonize NULL to nullptr in EGLDRM.cpp - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 64 ++++++++++---------- - 1 file changed, 32 insertions(+), 32 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index f252fb09170..79992127006 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -107,15 +107,15 @@ static struct pollfd g_drm_fds; - static uint32_t g_connector_id = 0; - static int g_drm_fd = 0; - static uint32_t g_crtc_id = 0; --static drmModeCrtc* g_orig_crtc = NULL; --static drmModeConnector* g_drm_connector = NULL; --static drmModeModeInfo* g_drm_mode = NULL; -+static drmModeCrtc* g_orig_crtc = nullptr; -+static drmModeConnector* g_drm_connector = nullptr; -+static drmModeModeInfo* g_drm_mode = nullptr; - - /* TODO/FIXME - static globals */ --static drmModeRes* g_drm_resources = NULL; --static drmModeEncoder* g_drm_encoder = NULL; -+static drmModeRes* g_drm_resources = nullptr; -+static drmModeEncoder* g_drm_encoder = nullptr; - --static gfx_ctx_drm_data* g_drm = NULL; -+static gfx_ctx_drm_data* g_drm = nullptr; - - bool drm_get_encoder(int fd); - -@@ -276,7 +276,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void* native) - - if (ptr_eglGetPlatformDisplay) - { -- EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL); -+ EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, nullptr); - if (dpy != EGL_NO_DISPLAY) - return dpy; - } -@@ -294,7 +294,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void* native) - - if (ptr_eglGetPlatformDisplayEXT) - { -- EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL); -+ EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, nullptr); - if (dpy != EGL_NO_DISPLAY) - return dpy; - } -@@ -325,11 +325,11 @@ static bool egl_init_context_common(EGLContextData* egl, EGLint* count, const EG - { - EGLint i; - EGLint matched = 0; -- EGLConfig* configs = NULL; -+ EGLConfig* configs = nullptr; - if (!egl) - return false; - -- if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1) -+ if (!eglGetConfigs(egl->dpy, nullptr, 0, count) || *count < 1) - { - INFO_LOG(VIDEO, "[EGL]: No configs to choose from.\n"); - return false; -@@ -451,7 +451,7 @@ void drm_restore_crtc(void) - g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); - - drmModeFreeCrtc(g_orig_crtc); -- g_orig_crtc = NULL; -+ g_orig_crtc = nullptr; - } - - bool drm_get_resources(int fd) -@@ -511,7 +511,7 @@ bool drm_get_connector(int fd) - } - - drmModeFreeConnector(g_drm_connector); -- g_drm_connector = NULL; -+ g_drm_connector = nullptr; - } - - if (!g_drm_connector) -@@ -537,7 +537,7 @@ bool drm_get_encoder(int fd) - break; - - drmModeFreeEncoder(g_drm_encoder); -- g_drm_encoder = NULL; -+ g_drm_encoder = nullptr; - } - - if (!g_drm_encoder) -@@ -589,9 +589,9 @@ void drm_free(void) - memset(&g_drm_fds, 0, sizeof(struct pollfd)); - memset(&g_drm_evctx, 0, sizeof(drmEventContext)); - -- g_drm_encoder = NULL; -- g_drm_connector = NULL; -- g_drm_resources = NULL; -+ g_drm_encoder = nullptr; -+ g_drm_connector = nullptr; -+ g_drm_resources = nullptr; - } - - static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data) -@@ -629,7 +629,7 @@ static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - error: - INFO_LOG(VIDEO, "[KMS]: Failed to create FB: %s\n", strerror(errno)); - free(fb); -- return NULL; -+ return nullptr; - } - - static void gfx_ctx_drm_swap_interval(void* data, int interval) -@@ -698,7 +698,7 @@ static bool gfx_ctx_drm_wait_flip(GFXContextDRMData* drm, bool block) - - static bool gfx_ctx_drm_queue_flip(GFXContextDRMData* drm) - { -- struct drm_fb* fb = NULL; -+ struct drm_fb* fb = nullptr; - - drm->next_bo = gbm_surface_lock_front_buffer(drm->gbm_surface); - fb = (struct drm_fb*)gbm_bo_get_user_data(drm->next_bo); -@@ -781,8 +781,8 @@ static void free_drm_resources(GFXContextDRMData* drm) - } - } - -- drm->gbm_surface = NULL; -- drm->gbm_dev = NULL; -+ drm->gbm_surface = nullptr; -+ drm->gbm_dev = nullptr; - g_drm_fd = -1; - } - -@@ -798,15 +798,15 @@ static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) - - free_drm_resources(drm); - -- g_drm_mode = NULL; -+ g_drm_mode = nullptr; - g_crtc_id = 0; - g_connector_id = 0; - - drm->fb_width = 0; - drm->fb_height = 0; - -- drm->bo = NULL; -- drm->next_bo = NULL; -+ drm->bo = nullptr; -+ drm->next_bo = nullptr; - } - - static void* gfx_ctx_drm_init() -@@ -814,11 +814,11 @@ static void* gfx_ctx_drm_init() - int fd, i; - unsigned monitor_index; - unsigned gpu_index = 0; -- const char* gpu = NULL; -+ const char* gpu = nullptr; - GFXContextDRMData* drm = (GFXContextDRMData*)calloc(1, sizeof(GFXContextDRMData)); - - if (!drm) -- return NULL; -+ return nullptr; - drm->fd = -1; - - free_drm_resources(drm); -@@ -892,7 +892,7 @@ static void* gfx_ctx_drm_init() - if (drm) - free(drm); - -- return NULL; -+ return nullptr; - } - - static EGLint* gfx_ctx_drm_egl_fill_attribs(GFXContextDRMData* drm, EGLint* attr) -@@ -948,13 +948,13 @@ static const EGLint egl_attribs_gles3[] = { - - static bool gfx_ctx_drm_egl_set_video_mode(GFXContextDRMData* drm) - { -- const EGLint* attrib_ptr = NULL; -+ const EGLint* attrib_ptr = nullptr; - EGLint major; - EGLint minor; - EGLint n; - EGLint egl_attribs[16]; -- EGLint* egl_attribs_ptr = NULL; -- EGLint* attr = NULL; -+ EGLint* egl_attribs_ptr = nullptr; -+ EGLint* attr = nullptr; - - attrib_ptr = egl_attribs_gles3; - -@@ -967,7 +967,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(GFXContextDRMData* drm) - attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); - egl_attribs_ptr = &egl_attribs[0]; - -- if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) -+ if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) ? egl_attribs_ptr : nullptr)) - { - INFO_LOG(VIDEO, "\n[EGL] Cannot create context error 0x%x", eglGetError()); - goto error; -@@ -990,7 +990,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(GFXContextDRMData* drm) - static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned height, bool fullscreen) - { - int i, ret = 0; -- struct drm_fb* fb = NULL; -+ struct drm_fb* fb = nullptr; - GFXContextDRMData* drm = (GFXContextDRMData*)data; - float video_refresh_rate = (float)VideoInterface::GetTargetRefreshRate(); - -@@ -1147,7 +1147,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - - eglBindAPI(EGL_OPENGL_ES_API); - EGLint egl_attribs[16]; -- EGLint* egl_attribs_ptr = NULL; -+ EGLint* egl_attribs_ptr = nullptr; - const EGLint* attrib_ptr = egl_attribs_gles3; - EGLint* attr = gfx_ctx_drm_egl_fill_attribs(g_drm, egl_attribs); - egl_attribs_ptr = &egl_attribs[0]; - -From 810f2240390b6f55314c319a2917bafe498d8ba4 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:28:31 +0200 -Subject: [PATCH 16/25] Fix build following PR changes - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 6 +++--- - Source/Core/DolphinNoGUI/PlatformDRM.cpp | 2 -- - 2 files changed, 3 insertions(+), 5 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 79992127006..ec5113d5660 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -115,7 +115,7 @@ static drmModeModeInfo* g_drm_mode = nullptr; - static drmModeRes* g_drm_resources = nullptr; - static drmModeEncoder* g_drm_encoder = nullptr; - --static gfx_ctx_drm_data* g_drm = nullptr; -+static GFXContextDRMData* g_drm = nullptr; - - bool drm_get_encoder(int fd); - -@@ -321,7 +321,7 @@ static bool egl_get_native_visual_id(EGLContextData* egl, EGLint* value) - } - - static bool egl_init_context_common(EGLContextData* egl, EGLint* count, const EGLint* attrib_ptr, -- egl_accept_config_cb_t cb, void* display_data) -+ EGLAcceptConfigCB cb, void* display_data) - { - EGLint i; - EGLint matched = 0; -@@ -367,7 +367,7 @@ static bool egl_init_context_common(EGLContextData* egl, EGLint* count, const EG - - static bool egl_init_context(EGLContextData* egl, EGLenum platform, void* display_data, - EGLint* major, EGLint* minor, EGLint* count, const EGLint* attrib_ptr, -- egl_accept_config_cb_t cb) -+ EGLAcceptConfigCB cb) - { - EGLDisplay dpy = get_egl_display(platform, display_data); - -diff --git a/Source/Core/DolphinNoGUI/PlatformDRM.cpp b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -index 6e4dc08eedf..b210cea1599 100644 ---- a/Source/Core/DolphinNoGUI/PlatformDRM.cpp -+++ b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -@@ -39,8 +39,6 @@ class PlatformDRM : public Platform - }; - - PlatformDRM::~PlatformDRM() = default; --{ --} - - bool PlatformDRM::Init() - { - -From c72d6fede67631ebba59bb28c5f9ad495474b676 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:36:44 +0200 -Subject: [PATCH 17/25] Fix warnings and unused stuff - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 41 +------------------- - 1 file changed, 2 insertions(+), 39 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index ec5113d5660..0414072170c 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -309,17 +309,6 @@ static EGLDisplay get_egl_display(EGLenum platform, void* native) - return eglGetDisplay((EGLNativeDisplayType)native); - } - --static bool egl_get_native_visual_id(EGLContextData* egl, EGLint* value) --{ -- if (!eglGetConfigAttrib(egl->dpy, egl->config, EGL_NATIVE_VISUAL_ID, value)) -- { -- INFO_LOG(VIDEO, "[EGL]: egl_get_native_visual_id failed.\n"); -- return false; -- } -- -- return true; --} -- - static bool egl_init_context_common(EGLContextData* egl, EGLint* count, const EGLint* attrib_ptr, - EGLAcceptConfigCB cb, void* display_data) - { -@@ -742,20 +731,6 @@ static void gfx_ctx_drm_swap_buffers(void* data) - gfx_ctx_drm_wait_flip(drm, true); - } - --static void gfx_ctx_drm_get_video_size(void* data, unsigned* width, unsigned* height) --{ -- GFXContextDRMData* drm = (GFXContextDRMData*)data; -- -- if (!drm) -- { -- INFO_LOG(VIDEO, "\nCannot get drm video size\n"); -- return; -- } -- -- *width = drm->fb_width; -- *height = drm->fb_height; --} -- - static void free_drm_resources(GFXContextDRMData* drm) - { - if (!drm) -@@ -811,10 +786,7 @@ static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) - - static void* gfx_ctx_drm_init() - { -- int fd, i; -- unsigned monitor_index; -- unsigned gpu_index = 0; -- const char* gpu = nullptr; -+ int fd; - GFXContextDRMData* drm = (GFXContextDRMData*)calloc(1, sizeof(GFXContextDRMData)); - - if (!drm) -@@ -885,14 +857,6 @@ static void* gfx_ctx_drm_init() - g_drm_fd = fd; - - return drm; -- --error: -- gfx_ctx_drm_destroy_resources(drm); -- -- if (drm) -- free(drm); -- -- return nullptr; - } - - static EGLint* gfx_ctx_drm_egl_fill_attribs(GFXContextDRMData* drm, EGLint* attr) -@@ -1148,8 +1112,7 @@ std::unique_ptr GLContextEGLDRM::CreateSharedContext() - eglBindAPI(EGL_OPENGL_ES_API); - EGLint egl_attribs[16]; - EGLint* egl_attribs_ptr = nullptr; -- const EGLint* attrib_ptr = egl_attribs_gles3; -- EGLint* attr = gfx_ctx_drm_egl_fill_attribs(g_drm, egl_attribs); -+ gfx_ctx_drm_egl_fill_attribs(g_drm, egl_attribs); - egl_attribs_ptr = &egl_attribs[0]; - new_context->m_egl->ctx = - eglCreateContext(m_egl->dpy, m_egl->config, m_egl->ctx, egl_attribs_ptr); - -From de60407f2f907d174079b162a178bcb94b18d6d6 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 16:49:51 +0200 -Subject: [PATCH 18/25] Refactor #1 - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 100 ++++++++----------- - 1 file changed, 41 insertions(+), 59 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 0414072170c..8bf87db2270 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -123,7 +123,6 @@ bool drm_get_encoder(int fd); - void drm_restore_crtc(void); - bool drm_get_resources(int fd); - void drm_setup(int fd); --void drm_free(void); - bool drm_get_connector(int fd); - float drm_get_refresh_rate(void* data); - -@@ -566,23 +565,6 @@ float drm_get_refresh_rate(void* data) - return refresh_rate; - } - --void drm_free(void) --{ -- if (g_drm_encoder) -- drmModeFreeEncoder(g_drm_encoder); -- if (g_drm_connector) -- drmModeFreeConnector(g_drm_connector); -- if (g_drm_resources) -- drmModeFreeResources(g_drm_resources); -- -- memset(&g_drm_fds, 0, sizeof(struct pollfd)); -- memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -- -- g_drm_encoder = nullptr; -- g_drm_connector = nullptr; -- g_drm_resources = nullptr; --} -- - static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data) - { - struct drm_fb* fb = (struct drm_fb*)data; -@@ -704,33 +686,6 @@ static bool gfx_ctx_drm_queue_flip(GFXContextDRMData* drm) - return false; - } - --static void gfx_ctx_drm_swap_buffers(void* data) --{ -- GFXContextDRMData* drm = (GFXContextDRMData*)data; -- unsigned max_swapchain_images = 3; // settings->uints.video_max_swapchain_images; -- -- egl_swap_buffers(&drm->egl); -- -- /* I guess we have to wait for flip to have taken -- * place before another flip can be queued up. -- * -- * If true, we are still waiting for a flip -- * (nonblocking mode, so just drop the frame). */ -- if (gfx_ctx_drm_wait_flip(drm, drm->interval)) -- { -- INFO_LOG(VIDEO, "\nwait flip"); -- return; -- } -- -- drm->waiting_for_flip = gfx_ctx_drm_queue_flip(drm); -- -- /* Triple-buffered page flips */ -- if (max_swapchain_images >= 3 && gbm_surface_has_free_buffers(drm->gbm_surface)) -- return; -- -- gfx_ctx_drm_wait_flip(drm, true); --} -- - static void free_drm_resources(GFXContextDRMData* drm) - { - if (!drm) -@@ -745,7 +700,19 @@ static void free_drm_resources(GFXContextDRMData* drm) - if (drm->gbm_dev) - gbm_device_destroy(drm->gbm_dev); - -- drm_free(); -+ if (g_drm_encoder) -+ drmModeFreeEncoder(g_drm_encoder); -+ if (g_drm_connector) -+ drmModeFreeConnector(g_drm_connector); -+ if (g_drm_resources) -+ drmModeFreeResources(g_drm_resources); -+ -+ memset(&g_drm_fds, 0, sizeof(struct pollfd)); -+ memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -+ -+ g_drm_encoder = nullptr; -+ g_drm_connector = nullptr; -+ g_drm_resources = nullptr; - - if (drm->fd >= 0) - { -@@ -1043,22 +1010,16 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - return false; - } - --static void gfx_ctx_drm_destroy(void* data) --{ -- GFXContextDRMData* drm = (GFXContextDRMData*)data; -- -- if (!drm) -- return; -- -- gfx_ctx_drm_destroy_resources(drm); -- free(drm); --} -- - GLContextEGLDRM::~GLContextEGLDRM() - { - DestroyWindowSurface(); - DestroyContext(); -- gfx_ctx_drm_destroy(g_drm); -+ -+ if (!g_drm) -+ return; -+ -+ gfx_ctx_drm_destroy_resources(g_drm); -+ free(g_drm); - } - - bool GLContextEGLDRM::IsHeadless() const -@@ -1068,7 +1029,28 @@ bool GLContextEGLDRM::IsHeadless() const - - void GLContextEGLDRM::Swap() - { -- gfx_ctx_drm_swap_buffers(g_drm); -+ unsigned max_swapchain_images = 3; // double-buffering -+ -+ egl_swap_buffers(&g_drm->egl); -+ -+ /* I guess we have to wait for flip to have taken -+ * place before another flip can be queued up. -+ * -+ * If true, we are still waiting for a flip -+ * (nonblocking mode, so just drop the frame). */ -+ if (gfx_ctx_drm_wait_flip(g_drm, g_drm->interval)) -+ { -+ INFO_LOG(VIDEO, "\nwait flip"); -+ return; -+ } -+ -+ g_drm->waiting_for_flip = gfx_ctx_drm_queue_flip(g_drm); -+ -+ /* Triple-buffered page flips */ -+ if (max_swapchain_images >= 3 && gbm_surface_has_free_buffers(g_drm->gbm_surface)) -+ return; -+ -+ gfx_ctx_drm_wait_flip(g_drm, true); - } - void GLContextEGLDRM::SwapInterval(int interval) - { - -From 32ac53b784fb38b60bb6d38f62e5065499ca815f Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 18:47:07 +0200 -Subject: [PATCH 19/25] Refactor (2) - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 258 +++++++------------ - 1 file changed, 96 insertions(+), 162 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 8bf87db2270..14c7f45b7b1 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -67,14 +67,6 @@ - #define EGL_KHR_create_context 1 - #define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 - #define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB --#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD --#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD --#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE --#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF --#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 --#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 --#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 --#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 - #endif /* EGL_KHR_create_context */ - - using EGLAcceptConfigCB = bool (*)(void* display_data, EGLDisplay dpy, EGLConfig config); -@@ -87,12 +79,23 @@ struct GFXContextDRMData - unsigned fb_width; - unsigned fb_height; - -- bool core_hw_context_enable; - bool waiting_for_flip; - struct gbm_bo* bo; - struct gbm_bo* next_bo; - struct gbm_surface* gbm_surface; - struct gbm_device* gbm_dev; -+ -+ drmEventContext drm_evctx; -+ struct pollfd drm_fds; -+ uint32_t connector_id = 0; -+ int drm_fd = 0; -+ uint32_t crtc_id = 0; -+ drmModeCrtc* orig_crtc = nullptr; -+ drmModeConnector* drm_connector = nullptr; -+ drmModeModeInfo* drm_mode = nullptr; -+ -+ drmModeRes* drm_resources = nullptr; -+ drmModeEncoder* drm_encoder = nullptr; - }; - - struct drm_fb -@@ -101,30 +104,13 @@ struct drm_fb - uint32_t fb_id; - }; - --/* TODO/FIXME - globals */ --static drmEventContext g_drm_evctx; --static struct pollfd g_drm_fds; --static uint32_t g_connector_id = 0; --static int g_drm_fd = 0; --static uint32_t g_crtc_id = 0; --static drmModeCrtc* g_orig_crtc = nullptr; --static drmModeConnector* g_drm_connector = nullptr; --static drmModeModeInfo* g_drm_mode = nullptr; -- - /* TODO/FIXME - static globals */ --static drmModeRes* g_drm_resources = nullptr; --static drmModeEncoder* g_drm_encoder = nullptr; -- - static GFXContextDRMData* g_drm = nullptr; - - bool drm_get_encoder(int fd); - - /* Restore the original CRTC. */ --void drm_restore_crtc(void); --bool drm_get_resources(int fd); --void drm_setup(int fd); - bool drm_get_connector(int fd); --float drm_get_refresh_rate(void* data); - - static void egl_destroy(EGLContextData* egl) - { -@@ -412,48 +398,23 @@ static bool egl_create_surface(EGLContextData* egl, void* native_window) - - static bool drm_wait_flip(int timeout) - { -- g_drm_fds.revents = 0; -+ g_drm->drm_fds.revents = 0; - -- if (poll(&g_drm_fds, 1, timeout) < 0) -+ if (poll(&g_drm->drm_fds, 1, timeout) < 0) - return false; - -- if (g_drm_fds.revents & (POLLHUP | POLLERR)) -+ if (g_drm->drm_fds.revents & (POLLHUP | POLLERR)) - return false; - -- if (g_drm_fds.revents & POLLIN) -+ if (g_drm->drm_fds.revents & POLLIN) - { -- drmHandleEvent(g_drm_fd, &g_drm_evctx); -+ drmHandleEvent(g_drm->drm_fd, &g_drm->drm_evctx); - return true; - } - - return false; - } - --/* Restore the original CRTC. */ --void drm_restore_crtc(void) --{ -- if (!g_orig_crtc) -- return; -- -- drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, g_orig_crtc->buffer_id, g_orig_crtc->x, -- g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); -- -- drmModeFreeCrtc(g_orig_crtc); -- g_orig_crtc = nullptr; --} -- --bool drm_get_resources(int fd) --{ -- g_drm_resources = drmModeGetResources(fd); -- if (!g_drm_resources) -- { -- INFO_LOG(VIDEO, "[DRM]: Couldn't get device resources.\n"); -- return false; -- } -- -- return true; --} -- - bool drm_get_connector(int fd) - { - unsigned i; -@@ -462,11 +423,11 @@ bool drm_get_connector(int fd) - - /* Enumerate all connectors. */ - -- INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors); -+ INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm->drm_resources->count_connectors); - -- for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ for (i = 0; (int)i < g_drm->drm_resources->count_connectors; i++) - { -- drmModeConnectorPtr conn = drmModeGetConnector(fd, g_drm_resources->connectors[i]); -+ drmModeConnectorPtr conn = drmModeGetConnector(fd, g_drm->drm_resources->connectors[i]); - - if (conn) - { -@@ -485,24 +446,24 @@ bool drm_get_connector(int fd) - - monitor_index_count = 0; - -- for (i = 0; (int)i < g_drm_resources->count_connectors; i++) -+ for (i = 0; (int)i < g_drm->drm_resources->count_connectors; i++) - { -- g_drm_connector = drmModeGetConnector(fd, g_drm_resources->connectors[i]); -+ g_drm->drm_connector = drmModeGetConnector(fd, g_drm->drm_resources->connectors[i]); - -- if (!g_drm_connector) -+ if (!g_drm->drm_connector) - continue; -- if (g_drm_connector->connection == DRM_MODE_CONNECTED && g_drm_connector->count_modes > 0) -+ if (g_drm->drm_connector->connection == DRM_MODE_CONNECTED && g_drm->drm_connector->count_modes > 0) - { - monitor_index_count++; - if (monitor_index_count == monitor) - break; - } - -- drmModeFreeConnector(g_drm_connector); -- g_drm_connector = nullptr; -+ drmModeFreeConnector(g_drm->drm_connector); -+ g_drm->drm_connector = nullptr; - } - -- if (!g_drm_connector) -+ if (!g_drm->drm_connector) - { - INFO_LOG(VIDEO, "[DRM]: Couldn't get device connector.\n"); - return false; -@@ -514,63 +475,42 @@ bool drm_get_encoder(int fd) - { - unsigned i; - -- for (i = 0; (int)i < g_drm_resources->count_encoders; i++) -+ for (i = 0; (int)i < g_drm->drm_resources->count_encoders; i++) - { -- g_drm_encoder = drmModeGetEncoder(fd, g_drm_resources->encoders[i]); -+ g_drm->drm_encoder = drmModeGetEncoder(fd, g_drm->drm_resources->encoders[i]); - -- if (!g_drm_encoder) -+ if (!g_drm->drm_encoder) - continue; - -- if (g_drm_encoder->encoder_id == g_drm_connector->encoder_id) -+ if (g_drm->drm_encoder->encoder_id == g_drm->drm_connector->encoder_id) - break; - -- drmModeFreeEncoder(g_drm_encoder); -- g_drm_encoder = nullptr; -+ drmModeFreeEncoder(g_drm->drm_encoder); -+ g_drm->drm_encoder = nullptr; - } - -- if (!g_drm_encoder) -+ if (!g_drm->drm_encoder) - { - INFO_LOG(VIDEO, "[DRM]: Couldn't find DRM encoder.\n"); - return false; - } - -- for (i = 0; (int)i < g_drm_connector->count_modes; i++) -+ for (i = 0; (int)i < g_drm->drm_connector->count_modes; i++) - { -- INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", i, g_drm_connector->modes[i].name, -- g_drm_connector->modes[i].hdisplay, g_drm_connector->modes[i].vdisplay, -- g_drm_connector->modes[i].vrefresh); -+ INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", i, g_drm->drm_connector->modes[i].name, -+ g_drm->drm_connector->modes[i].hdisplay, g_drm->drm_connector->modes[i].vdisplay, -+ g_drm->drm_connector->modes[i].vrefresh); - } - - return true; - } - --void drm_setup(int fd) --{ -- g_crtc_id = g_drm_encoder->crtc_id; -- g_connector_id = g_drm_connector->connector_id; -- g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); -- if (!g_orig_crtc) -- INFO_LOG(VIDEO, "[DRM]: Cannot find original CRTC.\n"); --} -- --float drm_get_refresh_rate(void* data) --{ -- float refresh_rate = 0.0f; -- -- if (g_drm_mode) -- { -- refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal; -- } -- -- return refresh_rate; --} -- - static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data) - { - struct drm_fb* fb = (struct drm_fb*)data; - - if (fb && fb->fb_id) -- drmModeRmFB(g_drm_fd, fb->fb_id); -+ drmModeRmFB(g_drm->drm_fd, fb->fb_id); - - free(fb); - } -@@ -590,7 +530,7 @@ static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - - INFO_LOG(VIDEO, "[KMS]: New FB: %ux%u (stride: %u).\n", width, height, stride); - -- ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); -+ ret = drmModeAddFB(g_drm->drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); - if (ret < 0) - goto error; - -@@ -615,24 +555,6 @@ static void gfx_ctx_drm_swap_interval(void* data, int interval) - - static void drm_flip_handler(int fd, unsigned frame, unsigned sec, unsigned usec, void* data) - { --#if 0 -- static unsigned first_page_flip; -- static unsigned last_page_flip; -- -- if (!first_page_flip) -- first_page_flip = frame; -- -- if (last_page_flip) -- { -- unsigned missed = frame - last_page_flip - 1; -- if (missed) -- INFO_LOG(VIDEO, "[KMS]: Missed %u VBlank(s) (Frame: %u, DRM frame: %u).\n", -- missed, frame - first_page_flip, frame); -- } -- -- last_page_flip = frame; --#endif -- - *(bool*)data = false; - } - -@@ -677,7 +599,7 @@ static bool gfx_ctx_drm_queue_flip(GFXContextDRMData* drm) - if (!fb) - fb = (struct drm_fb*)drm_fb_get_from_bo(drm->next_bo); - -- if (drmModePageFlip(g_drm_fd, g_crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, -+ if (drmModePageFlip(g_drm->drm_fd, g_drm->crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - &drm->waiting_for_flip) == 0) - return true; - -@@ -692,7 +614,14 @@ static void free_drm_resources(GFXContextDRMData* drm) - return; - - /* Restore original CRTC. */ -- drm_restore_crtc(); -+ if (drm->orig_crtc) -+ { -+ drmModeSetCrtc(drm->drm_fd, drm->orig_crtc->crtc_id, drm->orig_crtc->buffer_id, drm->orig_crtc->x, -+ drm->orig_crtc->y, &drm->connector_id, 1, &drm->orig_crtc->mode); -+ -+ drmModeFreeCrtc(drm->orig_crtc); -+ drm->orig_crtc = nullptr; -+ } - - if (drm->gbm_surface) - gbm_surface_destroy(drm->gbm_surface); -@@ -700,32 +629,32 @@ static void free_drm_resources(GFXContextDRMData* drm) - if (drm->gbm_dev) - gbm_device_destroy(drm->gbm_dev); - -- if (g_drm_encoder) -- drmModeFreeEncoder(g_drm_encoder); -- if (g_drm_connector) -- drmModeFreeConnector(g_drm_connector); -- if (g_drm_resources) -- drmModeFreeResources(g_drm_resources); -+ if (drm->drm_encoder) -+ drmModeFreeEncoder(drm->drm_encoder); -+ if (drm->drm_connector) -+ drmModeFreeConnector(drm->drm_connector); -+ if (drm->drm_resources) -+ drmModeFreeResources(drm->drm_resources); - -- memset(&g_drm_fds, 0, sizeof(struct pollfd)); -- memset(&g_drm_evctx, 0, sizeof(drmEventContext)); -+ memset(&drm->drm_fds, 0, sizeof(struct pollfd)); -+ memset(&drm->drm_evctx, 0, sizeof(drmEventContext)); - -- g_drm_encoder = nullptr; -- g_drm_connector = nullptr; -- g_drm_resources = nullptr; -+ drm->drm_encoder = nullptr; -+ drm->drm_connector = nullptr; -+ drm->drm_resources = nullptr; - - if (drm->fd >= 0) - { -- if (g_drm_fd >= 0) -+ if (drm->drm_fd >= 0) - { -- drmDropMaster(g_drm_fd); -+ drmDropMaster(drm->drm_fd); - close(drm->fd); - } - } - - drm->gbm_surface = nullptr; - drm->gbm_dev = nullptr; -- g_drm_fd = -1; -+ drm->drm_fd = -1; - } - - static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) -@@ -740,9 +669,9 @@ static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) - - free_drm_resources(drm); - -- g_drm_mode = nullptr; -- g_crtc_id = 0; -- g_connector_id = 0; -+ drm->drm_mode = nullptr; -+ drm->crtc_id = 0; -+ drm->connector_id = 0; - - drm->fb_width = 0; - drm->fb_height = 0; -@@ -771,9 +700,10 @@ static void* gfx_ctx_drm_init() - - fd = drm->fd; - -- if (!drm_get_resources(fd)) -+ drm->drm_resources = drmModeGetResources(fd); -+ if (!drm->drm_resources) - { -- INFO_LOG(VIDEO, "[KMS]: drm_get_resources failed\n"); -+ INFO_LOG(VIDEO, "[KMS]: Couldn't get DRM device resources.\n"); - return nullptr; - } - -@@ -789,23 +719,27 @@ static void* gfx_ctx_drm_init() - return nullptr; - } - -- drm_setup(fd); -+ drm->crtc_id = drm->drm_encoder->crtc_id; -+ drm->connector_id = drm->drm_connector->connector_id; -+ drm->orig_crtc = drmModeGetCrtc(fd, drm->crtc_id); -+ if (!drm->orig_crtc) -+ INFO_LOG(VIDEO, "[DRM]: Cannot find original CRTC.\n"); - - /* Choose the optimal video mode for get_video_size(): - - the current video mode from the CRTC - - otherwise pick first connector mode */ -- if (g_orig_crtc->mode_valid) -+ if (drm->orig_crtc->mode_valid) - { -- drm->fb_width = g_orig_crtc->mode.hdisplay; -- drm->fb_height = g_orig_crtc->mode.vdisplay; -+ drm->fb_width = drm->orig_crtc->mode.hdisplay; -+ drm->fb_height = drm->orig_crtc->mode.vdisplay; - } - else - { -- drm->fb_width = g_drm_connector->modes[0].hdisplay; -- drm->fb_height = g_drm_connector->modes[0].vdisplay; -+ drm->fb_width = drm->drm_connector->modes[0].hdisplay; -+ drm->fb_height = drm->drm_connector->modes[0].vdisplay; - } - -- drmSetMaster(g_drm_fd); -+ drmSetMaster(drm->drm_fd); - - drm->gbm_dev = gbm_create_device(fd); - -@@ -816,12 +750,12 @@ static void* gfx_ctx_drm_init() - } - - /* Setup the flip handler. */ -- g_drm_fds.fd = fd; -- g_drm_fds.events = POLLIN; -- g_drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; -- g_drm_evctx.page_flip_handler = drm_flip_handler; -+ drm->drm_fds.fd = fd; -+ drm->drm_fds.events = POLLIN; -+ drm->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; -+ drm->drm_evctx.page_flip_handler = drm_flip_handler; - -- g_drm_fd = fd; -+ drm->drm_fd = fd; - - return drm; - } -@@ -932,7 +866,7 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - * If not fullscreen, we get desired windowed size, - * which is not appropriate. */ - if ((width == 0 && height == 0) || !fullscreen) -- g_drm_mode = &g_drm_connector->modes[0]; -+ drm->drm_mode = &drm->drm_connector->modes[0]; - else - { - /* Try to match refresh_rate as closely as possible. -@@ -943,31 +877,31 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - float minimum_fps_diff = 0.0f; - - /* Find best match. */ -- for (i = 0; i < g_drm_connector->count_modes; i++) -+ for (i = 0; i < drm->drm_connector->count_modes; i++) - { - float diff; -- if (width != g_drm_connector->modes[i].hdisplay || -- height != g_drm_connector->modes[i].vdisplay) -+ if (width != drm->drm_connector->modes[i].hdisplay || -+ height != drm->drm_connector->modes[i].vdisplay) - continue; - -- diff = fabsf(g_drm_connector->modes[i].vrefresh - video_refresh_rate); -+ diff = fabsf(drm->drm_connector->modes[i].vrefresh - video_refresh_rate); - -- if (!g_drm_mode || diff < minimum_fps_diff) -+ if (!drm->drm_mode || diff < minimum_fps_diff) - { -- g_drm_mode = &g_drm_connector->modes[i]; -+ drm->drm_mode = &drm->drm_connector->modes[i]; - minimum_fps_diff = diff; - } - } - } - -- if (!g_drm_mode) -+ if (!drm->drm_mode) - { - INFO_LOG(VIDEO, "[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", width, height); - goto error; - } - -- drm->fb_width = g_drm_mode->hdisplay; -- drm->fb_height = g_drm_mode->vdisplay; -+ drm->fb_width = drm->drm_mode->hdisplay; -+ drm->fb_height = drm->drm_mode->vdisplay; - - /* Create GBM surface. */ - drm->gbm_surface = -@@ -993,7 +927,7 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - if (!fb) - fb = drm_fb_get_from_bo(drm->bo); - -- ret = drmModeSetCrtc(g_drm_fd, g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode); -+ ret = drmModeSetCrtc(drm->drm_fd, drm->crtc_id, fb->fb_id, 0, 0, &drm->connector_id, 1, drm->drm_mode); - if (ret < 0) - { - INFO_LOG(VIDEO, "[KMS/EGL]: drmModeSetCrtc failed\n"); - -From c6a374bae4c0b1c990d06acb4266ca60358b9419 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 19:03:32 +0200 -Subject: [PATCH 20/25] Refactor (3) - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 106 ++++++++----------- - 1 file changed, 44 insertions(+), 62 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 14c7f45b7b1..726c68a95a5 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -107,34 +107,9 @@ struct drm_fb - /* TODO/FIXME - static globals */ - static GFXContextDRMData* g_drm = nullptr; - --bool drm_get_encoder(int fd); -- - /* Restore the original CRTC. */ - bool drm_get_connector(int fd); - --static void egl_destroy(EGLContextData* egl) --{ -- if (egl->dpy) -- { -- eglMakeCurrent(egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -- if (egl->ctx != EGL_NO_CONTEXT) -- eglDestroyContext(egl->dpy, egl->ctx); -- -- if (egl->surf != EGL_NO_SURFACE) -- eglDestroySurface(egl->dpy, egl->surf); -- eglTerminate(egl->dpy); -- } -- -- /* Be as careful as possible in deinit. -- * If we screw up, any TTY will not restore. -- */ -- -- egl->ctx = EGL_NO_CONTEXT; -- egl->surf = EGL_NO_SURFACE; -- egl->dpy = EGL_NO_DISPLAY; -- egl->config = 0; --} -- - static void egl_swap_buffers(void* data) - { - EGLContextData* egl = (EGLContextData*)data; -@@ -144,26 +119,6 @@ static void egl_swap_buffers(void* data) - } - } - --static void egl_set_swap_interval(EGLContextData* egl, int interval) --{ -- /* Can be called before initialization. -- * Some contexts require that swap interval -- * is known at startup time. -- */ -- egl->interval = interval; -- -- if (egl->dpy == EGL_NO_DISPLAY) -- return; -- if (!eglGetCurrentContext()) -- return; -- -- INFO_LOG(VIDEO, "[EGL]: eglSwapInterval(%u)\n", interval); -- if (!eglSwapInterval(egl->dpy, interval)) -- { -- INFO_LOG(VIDEO, "[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); -- } --} -- - static bool check_egl_version(int minMajorVersion, int minMinorVersion) - { - int count; -@@ -213,10 +168,9 @@ static bool check_egl_client_extension(const char* name) - return false; - } - --static bool check_egl_display_extension(void* data, const char* name) -+static bool check_egl_display_extension(EGLContextData* egl, const char* name) - { - size_t nameLen; -- EGLContextData* egl = (EGLContextData*)data; - if (!egl || egl->dpy == EGL_NO_DISPLAY) - return false; - -@@ -543,16 +497,6 @@ static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - return nullptr; - } - --static void gfx_ctx_drm_swap_interval(void* data, int interval) --{ -- GFXContextDRMData* drm = (GFXContextDRMData*)data; -- drm->interval = interval; -- -- if (interval > 1) -- INFO_LOG(VIDEO, -- "[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); --} -- - static void drm_flip_handler(int fd, unsigned frame, unsigned sec, unsigned usec, void* data) - { - *(bool*)data = false; -@@ -665,7 +609,25 @@ static void gfx_ctx_drm_destroy_resources(GFXContextDRMData* drm) - /* Make sure we acknowledge all page-flips. */ - gfx_ctx_drm_wait_flip(drm, true); - -- egl_destroy(&drm->egl); -+ if (drm->egl.dpy) -+ { -+ eglMakeCurrent(drm->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (drm->egl.ctx != EGL_NO_CONTEXT) -+ eglDestroyContext(drm->egl.dpy, drm->egl.ctx); -+ -+ if (drm->egl.surf != EGL_NO_SURFACE) -+ eglDestroySurface(drm->egl.dpy, drm->egl.surf); -+ eglTerminate(drm->egl.dpy); -+ } -+ -+ /* Be as careful as possible in deinit. -+ * If we screw up, any TTY will not restore. -+ */ -+ -+ drm->egl.ctx = EGL_NO_CONTEXT; -+ drm->egl.surf = EGL_NO_SURFACE; -+ drm->egl.dpy = EGL_NO_DISPLAY; -+ drm->egl.config = 0; - - free_drm_resources(drm); - -@@ -986,10 +948,30 @@ void GLContextEGLDRM::Swap() - - gfx_ctx_drm_wait_flip(g_drm, true); - } -+ - void GLContextEGLDRM::SwapInterval(int interval) - { -- gfx_ctx_drm_swap_interval(g_drm, interval); -- egl_set_swap_interval(m_egl, interval); -+ g_drm->interval = interval; -+ if (interval > 1) -+ INFO_LOG(VIDEO, -+ "[KMS]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); -+ -+ /* Can be called before initialization. -+ * Some contexts require that swap interval -+ * is known at startup time. -+ */ -+ m_egl->interval = interval; -+ -+ if (m_egl->dpy == EGL_NO_DISPLAY) -+ return; -+ if (!eglGetCurrentContext()) -+ return; -+ -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval(%u)\n", interval); -+ if (!eglSwapInterval(m_egl->dpy, interval)) -+ { -+ INFO_LOG(VIDEO, "[EGL]: eglSwapInterval() failed 0x%x.\n", eglGetError()); -+ } - } - - void* GLContextEGLDRM::GetFuncAddress(const std::string& name) -@@ -1057,7 +1039,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - if (m_supports_surfaceless) - { - m_egl->surf = EGL_NO_SURFACE; -- INFO_LOG(VIDEO, "\nCreated surfaceless context\n"); -+ INFO_LOG(VIDEO, "\nCreated surfaceless EGL shared context\n"); - return true; - } - -@@ -1065,7 +1047,7 @@ bool GLContextEGLDRM::CreateWindowSurface() - { - if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) - { -- INFO_LOG(VIDEO, "\negl_create_surface failed, trying pbuffer failed 0x%x\n", eglGetError()); -+ INFO_LOG(VIDEO, "\negl_create_surface failed (error 0x%x), trying pbuffer instead...\n", eglGetError()); - goto pbuffer; - } - // Get dimensions from the surface. - -From c9c4e4341c496ce351af0a0c65a6068c46f01af3 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 19:25:36 +0200 -Subject: [PATCH 21/25] Move helper functions to static - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 726c68a95a5..a7ae0a6dbfb 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -107,9 +107,6 @@ struct drm_fb - /* TODO/FIXME - static globals */ - static GFXContextDRMData* g_drm = nullptr; - --/* Restore the original CRTC. */ --bool drm_get_connector(int fd); -- - static void egl_swap_buffers(void* data) - { - EGLContextData* egl = (EGLContextData*)data; -@@ -369,7 +366,7 @@ static bool drm_wait_flip(int timeout) - return false; - } - --bool drm_get_connector(int fd) -+static bool drm_get_connector(int fd) - { - unsigned i; - unsigned monitor_index_count = 0; -@@ -425,7 +422,7 @@ bool drm_get_connector(int fd) - return true; - } - --bool drm_get_encoder(int fd) -+static bool drm_get_encoder(int fd) - { - unsigned i; - - -From d6fbe009dc0fa3ea29d8dd6b12cf7712154dc3ca Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 20:58:50 +0200 -Subject: [PATCH 22/25] Better conditional compilation support for EGL/DRM - (should pass Dolphin CI) - ---- - CMakeLists.txt | 6 ++++++ - Source/Core/Common/CMakeLists.txt | 2 -- - Source/Core/Common/GL/GLContext.cpp | 2 ++ - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 26484938a32..91d8341bd58 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -456,6 +456,12 @@ if(ENABLE_EGL) - if(EGL_FOUND) - add_definitions(-DHAVE_EGL=1) - message(STATUS "EGL OpenGL interface enabled") -+ find_package(Libdrm) -+ find_package(Libgbm) -+ if(LIBDRM_FOUND AND LIBGBM_FOUND) -+ add_definitions(-DHAVE_DRM=1) -+ message(STATUS "EGL/DRM/GBM support enabled") -+ endif() - else() - message(WARNING "EGL support enabled but not found. This build will not support EGL.") - endif() -diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt -index 6e7574b7c8d..f40dff90a59 100644 ---- a/Source/Core/Common/CMakeLists.txt -+++ b/Source/Core/Common/CMakeLists.txt -@@ -222,8 +222,6 @@ target_sources(common PRIVATE - ) - - if(ENABLE_EGL AND EGL_FOUND) -- find_package(Libdrm) -- find_package(Libgbm) - if (LIBDRM_FOUND AND LIBGBM_FOUND) - target_sources(common PRIVATE - GL/GLInterface/EGL.cpp -diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp -index f5adaab71ab..25ff342d6ca 100644 ---- a/Source/Core/Common/GL/GLContext.cpp -+++ b/Source/Core/Common/GL/GLContext.cpp -@@ -17,7 +17,9 @@ - #endif - #if HAVE_EGL - #include "Common/GL/GLInterface/EGL.h" -+#if HAVE_DRM - #include "Common/GL/GLInterface/EGLDRM.h" -+#endif - #if HAVE_X11 - #include "Common/GL/GLInterface/EGLX11.h" - #endif - -From b9eaa05b0b4111658005fabba05f93a4bac475e6 Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 21:09:56 +0200 -Subject: [PATCH 23/25] Fix missing #ifdef - ---- - Source/Core/Common/GL/GLContext.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp -index 25ff342d6ca..9d33b1cff78 100644 ---- a/Source/Core/Common/GL/GLContext.cpp -+++ b/Source/Core/Common/GL/GLContext.cpp -@@ -113,8 +113,10 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s - #if HAVE_EGL - if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) - context = std::make_unique(); -+#if HAVE_DRM - else if (wsi.type == WindowSystemType::DRM) - context = std::make_unique(); -+#endif - #endif - - if (!context) - -From 1eea311b76ca66b8742c12dd9e16875f0502078c Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Fri, 7 Aug 2020 21:11:38 +0200 -Subject: [PATCH 24/25] Fix lint checks - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 16 ++++++++++------ - Source/Core/Common/GL/GLInterface/EGLDRM.h | 1 - - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index a7ae0a6dbfb..367e875371f 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -403,7 +403,8 @@ static bool drm_get_connector(int fd) - - if (!g_drm->drm_connector) - continue; -- if (g_drm->drm_connector->connection == DRM_MODE_CONNECTED && g_drm->drm_connector->count_modes > 0) -+ if (g_drm->drm_connector->connection == DRM_MODE_CONNECTED && -+ g_drm->drm_connector->count_modes > 0) - { - monitor_index_count++; - if (monitor_index_count == monitor) -@@ -557,8 +558,9 @@ static void free_drm_resources(GFXContextDRMData* drm) - /* Restore original CRTC. */ - if (drm->orig_crtc) - { -- drmModeSetCrtc(drm->drm_fd, drm->orig_crtc->crtc_id, drm->orig_crtc->buffer_id, drm->orig_crtc->x, -- drm->orig_crtc->y, &drm->connector_id, 1, &drm->orig_crtc->mode); -+ drmModeSetCrtc(drm->drm_fd, drm->orig_crtc->crtc_id, drm->orig_crtc->buffer_id, -+ drm->orig_crtc->x, drm->orig_crtc->y, &drm->connector_id, 1, -+ &drm->orig_crtc->mode); - - drmModeFreeCrtc(drm->orig_crtc); - drm->orig_crtc = nullptr; -@@ -886,7 +888,8 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - if (!fb) - fb = drm_fb_get_from_bo(drm->bo); - -- ret = drmModeSetCrtc(drm->drm_fd, drm->crtc_id, fb->fb_id, 0, 0, &drm->connector_id, 1, drm->drm_mode); -+ ret = drmModeSetCrtc(drm->drm_fd, drm->crtc_id, fb->fb_id, 0, 0, &drm->connector_id, 1, -+ drm->drm_mode); - if (ret < 0) - { - INFO_LOG(VIDEO, "[KMS/EGL]: drmModeSetCrtc failed\n"); -@@ -922,7 +925,7 @@ bool GLContextEGLDRM::IsHeadless() const - - void GLContextEGLDRM::Swap() - { -- unsigned max_swapchain_images = 3; // double-buffering -+ unsigned max_swapchain_images = 3; // double-buffering - - egl_swap_buffers(&g_drm->egl); - -@@ -1044,7 +1047,8 @@ bool GLContextEGLDRM::CreateWindowSurface() - { - if (!egl_create_surface(m_egl, (EGLNativeWindowType)g_drm->gbm_surface)) - { -- INFO_LOG(VIDEO, "\negl_create_surface failed (error 0x%x), trying pbuffer instead...\n", eglGetError()); -+ INFO_LOG(VIDEO, "\negl_create_surface failed (error 0x%x), trying pbuffer instead...\n", -+ eglGetError()); - goto pbuffer; - } - // Get dimensions from the surface. -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.h b/Source/Core/Common/GL/GLInterface/EGLDRM.h -index 46d361a3a14..ffa6c7af329 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.h -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.h -@@ -21,7 +21,6 @@ struct EGLContextData - - unsigned major; - unsigned minor; -- - }; - - class GLContextEGLDRM : public GLContext - -From 1294d4d6b807cd2775693f742068bdad0c45c35b Mon Sep 17 00:00:00 2001 -From: Romain TISSERAND -Date: Sat, 8 Aug 2020 11:33:04 +0200 -Subject: [PATCH 25/25] Fix crash following refactoring - ---- - Source/Core/Common/GL/GLInterface/EGLDRM.cpp | 86 ++++++++++---------- - 1 file changed, 41 insertions(+), 45 deletions(-) - -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 367e875371f..f8487619809 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -98,15 +98,15 @@ struct GFXContextDRMData - drmModeEncoder* drm_encoder = nullptr; - }; - -+/* TODO/FIXME - static globals */ -+static GFXContextDRMData* g_drm = nullptr; -+ - struct drm_fb - { - struct gbm_bo* bo; - uint32_t fb_id; - }; - --/* TODO/FIXME - static globals */ --static GFXContextDRMData* g_drm = nullptr; -- - static void egl_swap_buffers(void* data) - { - EGLContextData* egl = (EGLContextData*)data; -@@ -347,26 +347,26 @@ static bool egl_create_surface(EGLContextData* egl, void* native_window) - return true; - } - --static bool drm_wait_flip(int timeout) -+static bool drm_wait_flip(GFXContextDRMData* drm, int timeout) - { -- g_drm->drm_fds.revents = 0; -+ drm->drm_fds.revents = 0; - -- if (poll(&g_drm->drm_fds, 1, timeout) < 0) -+ if (poll(&drm->drm_fds, 1, timeout) < 0) - return false; - -- if (g_drm->drm_fds.revents & (POLLHUP | POLLERR)) -+ if (drm->drm_fds.revents & (POLLHUP | POLLERR)) - return false; - -- if (g_drm->drm_fds.revents & POLLIN) -+ if (drm->drm_fds.revents & POLLIN) - { -- drmHandleEvent(g_drm->drm_fd, &g_drm->drm_evctx); -+ drmHandleEvent(drm->drm_fd, &drm->drm_evctx); - return true; - } - - return false; - } - --static bool drm_get_connector(int fd) -+static bool drm_get_connector(GFXContextDRMData* drm, int fd) - { - unsigned i; - unsigned monitor_index_count = 0; -@@ -374,11 +374,11 @@ static bool drm_get_connector(int fd) - - /* Enumerate all connectors. */ - -- INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", g_drm->drm_resources->count_connectors); -+ INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", drm->drm_resources->count_connectors); - -- for (i = 0; (int)i < g_drm->drm_resources->count_connectors; i++) -+ for (i = 0; (int)i < drm->drm_resources->count_connectors; i++) - { -- drmModeConnectorPtr conn = drmModeGetConnector(fd, g_drm->drm_resources->connectors[i]); -+ drmModeConnectorPtr conn = drmModeGetConnector(fd, drm->drm_resources->connectors[i]); - - if (conn) - { -@@ -397,25 +397,24 @@ static bool drm_get_connector(int fd) - - monitor_index_count = 0; - -- for (i = 0; (int)i < g_drm->drm_resources->count_connectors; i++) -+ for (i = 0; (int)i < drm->drm_resources->count_connectors; i++) - { -- g_drm->drm_connector = drmModeGetConnector(fd, g_drm->drm_resources->connectors[i]); -+ drm->drm_connector = drmModeGetConnector(fd, drm->drm_resources->connectors[i]); - -- if (!g_drm->drm_connector) -+ if (!drm->drm_connector) - continue; -- if (g_drm->drm_connector->connection == DRM_MODE_CONNECTED && -- g_drm->drm_connector->count_modes > 0) -+ if (drm->drm_connector->connection == DRM_MODE_CONNECTED && drm->drm_connector->count_modes > 0) - { - monitor_index_count++; - if (monitor_index_count == monitor) - break; - } - -- drmModeFreeConnector(g_drm->drm_connector); -- g_drm->drm_connector = nullptr; -+ drmModeFreeConnector(drm->drm_connector); -+ drm->drm_connector = nullptr; - } - -- if (!g_drm->drm_connector) -+ if (!drm->drm_connector) - { - INFO_LOG(VIDEO, "[DRM]: Couldn't get device connector.\n"); - return false; -@@ -423,35 +422,35 @@ static bool drm_get_connector(int fd) - return true; - } - --static bool drm_get_encoder(int fd) -+static bool drm_get_encoder(GFXContextDRMData* drm, int fd) - { - unsigned i; - -- for (i = 0; (int)i < g_drm->drm_resources->count_encoders; i++) -+ for (i = 0; (int)i < drm->drm_resources->count_encoders; i++) - { -- g_drm->drm_encoder = drmModeGetEncoder(fd, g_drm->drm_resources->encoders[i]); -+ drm->drm_encoder = drmModeGetEncoder(fd, drm->drm_resources->encoders[i]); - -- if (!g_drm->drm_encoder) -+ if (!drm->drm_encoder) - continue; - -- if (g_drm->drm_encoder->encoder_id == g_drm->drm_connector->encoder_id) -+ if (drm->drm_encoder->encoder_id == drm->drm_connector->encoder_id) - break; - -- drmModeFreeEncoder(g_drm->drm_encoder); -- g_drm->drm_encoder = nullptr; -+ drmModeFreeEncoder(drm->drm_encoder); -+ drm->drm_encoder = nullptr; - } - -- if (!g_drm->drm_encoder) -+ if (!drm->drm_encoder) - { - INFO_LOG(VIDEO, "[DRM]: Couldn't find DRM encoder.\n"); - return false; - } - -- for (i = 0; (int)i < g_drm->drm_connector->count_modes; i++) -+ for (i = 0; (int)i < drm->drm_connector->count_modes; i++) - { -- INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", i, g_drm->drm_connector->modes[i].name, -- g_drm->drm_connector->modes[i].hdisplay, g_drm->drm_connector->modes[i].vdisplay, -- g_drm->drm_connector->modes[i].vrefresh); -+ INFO_LOG(VIDEO, "[DRM]: Mode %d: (%s) %d x %d, %u Hz\n", i, drm->drm_connector->modes[i].name, -+ drm->drm_connector->modes[i].hdisplay, drm->drm_connector->modes[i].vdisplay, -+ drm->drm_connector->modes[i].vrefresh); - } - - return true; -@@ -461,13 +460,13 @@ static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data) - { - struct drm_fb* fb = (struct drm_fb*)data; - -- if (fb && fb->fb_id) -+ if (fb && fb->fb_id && g_drm) - drmModeRmFB(g_drm->drm_fd, fb->fb_id); - - free(fb); - } - --static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) -+static struct drm_fb* drm_fb_get_from_bo(GFXContextDRMData* drm, struct gbm_bo* bo) - { - int ret; - unsigned width, height, stride, handle; -@@ -482,7 +481,7 @@ static struct drm_fb* drm_fb_get_from_bo(struct gbm_bo* bo) - - INFO_LOG(VIDEO, "[KMS]: New FB: %ux%u (stride: %u).\n", width, height, stride); - -- ret = drmModeAddFB(g_drm->drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); -+ ret = drmModeAddFB(drm->drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); - if (ret < 0) - goto error; - -@@ -512,15 +511,12 @@ static bool gfx_ctx_drm_wait_flip(GFXContextDRMData* drm, bool block) - - while (drm->waiting_for_flip) - { -- if (!drm_wait_flip(timeout)) -+ if (!drm_wait_flip(drm, timeout)) - break; - } - - if (drm->waiting_for_flip) -- { -- INFO_LOG(VIDEO, "\nwait flip 2"); - return true; -- } - - /* Page flip has taken place. */ - -@@ -539,9 +535,9 @@ static bool gfx_ctx_drm_queue_flip(GFXContextDRMData* drm) - fb = (struct drm_fb*)gbm_bo_get_user_data(drm->next_bo); - - if (!fb) -- fb = (struct drm_fb*)drm_fb_get_from_bo(drm->next_bo); -+ fb = (struct drm_fb*)drm_fb_get_from_bo(drm, drm->next_bo); - -- if (drmModePageFlip(g_drm->drm_fd, g_drm->crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, -+ if (drmModePageFlip(drm->drm_fd, drm->crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - &drm->waiting_for_flip) == 0) - return true; - -@@ -668,13 +664,13 @@ static void* gfx_ctx_drm_init() - return nullptr; - } - -- if (!drm_get_connector(fd)) -+ if (!drm_get_connector(drm, fd)) - { - INFO_LOG(VIDEO, "[KMS]: drm_get_connector failed\n"); - return nullptr; - } - -- if (!drm_get_encoder(fd)) -+ if (!drm_get_encoder(drm, fd)) - { - INFO_LOG(VIDEO, "[KMS]: drm_get_encoder failed\n"); - return nullptr; -@@ -886,7 +882,7 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - fb = (struct drm_fb*)gbm_bo_get_user_data(drm->bo); - - if (!fb) -- fb = drm_fb_get_from_bo(drm->bo); -+ fb = drm_fb_get_from_bo(drm, drm->bo); - - ret = drmModeSetCrtc(drm->drm_fd, drm->crtc_id, fb->fb_id, 0, 0, &drm->connector_id, 1, - drm->drm_mode); diff --git a/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch b/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch new file mode 100644 index 000000000..013782b07 --- /dev/null +++ b/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch @@ -0,0 +1,129 @@ +diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp +index c8e7016..fb089c4 100644 +--- a/Source/Core/Core/HW/GCPadEmu.cpp ++++ b/Source/Core/Core/HW/GCPadEmu.cpp +@@ -26,6 +26,7 @@ static const u16 button_bitmasks[] = { + PAD_BUTTON_Y, + PAD_TRIGGER_Z, + PAD_BUTTON_START, ++ PAD_BUTTON_HOTKEY, + 0 // MIC HAX + }; + +@@ -37,7 +38,7 @@ static const u16 trigger_bitmasks[] = { + static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, + PAD_BUTTON_RIGHT}; + +-static const char* const named_buttons[] = {"A", "B", "X", "Y", "Z", "Start"}; ++static const char* const named_buttons[] = {"A", "B", "X", "Y", "Z", "Start", "Hotkey"}; + + static const char* const named_triggers[] = { + // i18n: The left trigger button (labeled L on real controllers) +diff --git a/Source/Core/DolphinNoGUI/PlatformX11.cpp b/Source/Core/DolphinNoGUI/PlatformX11.cpp +index 8dcd93bf52..5d7386da38 100644 +--- a/Source/Core/DolphinNoGUI/PlatformX11.cpp ++++ b/Source/Core/DolphinNoGUI/PlatformX11.cpp +@@ -16,6 +16,12 @@ static constexpr auto X_None = None; + #include "Core/Core.h" + #include "Core/State.h" + ++#include "Core/HW/GCPad.h" ++#include "InputCommon/GCPadStatus.h" ++#include ++#include "Core/Config/GraphicsSettings.h" ++#include "VideoCommon/VideoConfig.h" ++ + #include + #include + #include +@@ -149,11 +155,78 @@ void PlatformX11::MainLoop() + { + while (IsRunning()) + { ++ static int hotkey = 0; ++ static int slot = 0; ++ static int fps = 0; ++ static int aspect = 0; ++ + UpdateRunningFlag(); + Core::HostDispatchJobs(); + ProcessEvents(); + UpdateWindowPosition(); + ++ if(Pad::IsInitialized()) { ++ GCPadStatus x = Pad::GetStatus(0); ++ ++ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed ++ if(hotkey == 1) { ++ hotkey = 2; ++ } ++ } else { ++ hotkey = 1; // assure hotkey is released between actions ++ } ++ ++ if(hotkey == 2) { // hotkey pressed ++ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { ++ RequestShutdown(); ++ hotkey = 0; ++ } ++ ++ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { ++ State::Load(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { ++ State::Save(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { ++ if(slot > 0) slot--; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { ++ if(slot < 10) slot++; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { ++ Core::SaveScreenShot(); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { ++ if(fps == 0) { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, True); ++ fps = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, False); ++ fps = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { ++ if(aspect == 0) { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); ++ aspect = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); ++ aspect = 0; ++ } ++ hotkey = 0; ++ } ++ } ++ } ++ + // TODO: Is this sleep appropriate? + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h +index 7da1bbd..57d294d 100644 +--- a/Source/Core/InputCommon/GCPadStatus.h ++++ b/Source/Core/InputCommon/GCPadStatus.h +@@ -27,6 +27,7 @@ enum PadButton + PAD_BUTTON_X = 0x0400, + PAD_BUTTON_Y = 0x0800, + PAD_BUTTON_START = 0x1000, ++ PAD_BUTTON_HOTKEY = 0x2000, + }; + + struct GCPadStatus diff --git a/packages/games/emulators/dolphinsa/patches/new/003-drm-hotkeys.patch b/packages/games/emulators/dolphinsa/patches/new/003-drm-hotkeys.patch deleted file mode 100644 index f4a3859ef..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/003-drm-hotkeys.patch +++ /dev/null @@ -1,118 +0,0 @@ -diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp -index c8e7016..fb089c4 100644 ---- a/Source/Core/Core/HW/GCPadEmu.cpp -+++ b/Source/Core/Core/HW/GCPadEmu.cpp -@@ -26,6 +26,7 @@ static const u16 button_bitmasks[] = { - PAD_BUTTON_Y, - PAD_TRIGGER_Z, - PAD_BUTTON_START, -+ PAD_BUTTON_HOTKEY, - 0 // MIC HAX - }; - -@@ -37,7 +38,7 @@ static const u16 trigger_bitmasks[] = { - static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, - PAD_BUTTON_RIGHT}; - --static const char* const named_buttons[] = {"A", "B", "X", "Y", "Z", "Start"}; -+static const char* const named_buttons[] = {"A", "B", "X", "Y", "Z", "Start", "Hotkey"}; - - static const char* const named_triggers[] = { - // i18n: The left trigger button (labeled L on real controllers) -diff --git a/Source/Core/DolphinNoGUI/PlatformDRM.cpp b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -index b210cea..77d4e86 100644 ---- a/Source/Core/DolphinNoGUI/PlatformDRM.cpp -+++ b/Source/Core/DolphinNoGUI/PlatformDRM.cpp -@@ -11,6 +11,12 @@ - #include "Core/Core.h" - #include "Core/State.h" - -+#include "Core/HW/GCPad.h" -+#include "InputCommon/GCPadStatus.h" -+#include -+#include "Core/Config/GraphicsSettings.h" -+#include "VideoCommon/VideoConfig.h" -+ - #include - #include - -@@ -54,9 +60,67 @@ void PlatformDRM::MainLoop() - { - while (IsRunning()) - { -+ static int hotkey = 0; -+ static int slot = 0; -+ static int stereo = 0; -+ - UpdateRunningFlag(); - Core::HostDispatchJobs(); - -+ if(Pad::IsInitialized()) { -+ GCPadStatus x = Pad::GetStatus(0); -+ -+ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed -+ if(hotkey == 1) { -+ hotkey = 2; -+ } -+ } else { -+ hotkey = 1; // assure hotkey is released between actions -+ } -+ -+ if(hotkey == 2) { // hotkey pressed -+ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { -+ RequestShutdown(); -+ hotkey = 0; -+ } -+ -+ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { -+ State::Load(slot); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_B) == PAD_BUTTON_B) { -+ State::Save(slot); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { -+ if(slot > 0) slot--; -+ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { -+ if(slot < 10) slot++; -+ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { -+ Core::SaveScreenShot(); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { -+ if(stereo == 0) { -+ Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::SBS); -+ stereo = 1; -+ } else { -+ Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Off); -+ stereo = 0; -+ } -+ hotkey = 0; -+ } -+ } -+ -+ } -+ // -+ - // TODO: Is this sleep appropriate? - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } -diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h -index 7da1bbd..57d294d 100644 ---- a/Source/Core/InputCommon/GCPadStatus.h -+++ b/Source/Core/InputCommon/GCPadStatus.h -@@ -27,6 +27,7 @@ enum PadButton - PAD_BUTTON_X = 0x0400, - PAD_BUTTON_Y = 0x0800, - PAD_BUTTON_START = 0x1000, -+ PAD_BUTTON_HOTKEY = 0x2000, - }; - - struct GCPadStatus diff --git a/packages/games/emulators/dolphinsa/patches/new/003-drm-resolution.patch b/packages/games/emulators/dolphinsa/patches/new/003-drm-resolution.patch deleted file mode 100644 index b98f82961..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/003-drm-resolution.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index f848761..676c886 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -819,37 +819,24 @@ static bool gfx_ctx_drm_set_video_mode(void* data, unsigned width, unsigned heig - if (!drm) - return false; - -- /* Find desired video mode, and use that. -- * If not fullscreen, we get desired windowed size, -- * which is not appropriate. */ -- if ((width == 0 && height == 0) || !fullscreen) -- drm->drm_mode = &drm->drm_connector->modes[0]; -- else -+ // batocera - set resolution - { -- /* Try to match refresh_rate as closely as possible. -- * -- * Lower resolutions tend to have multiple supported -- * refresh rates as well. -- */ -- float minimum_fps_diff = 0.0f; -- -- /* Find best match. */ -- for (i = 0; i < drm->drm_connector->count_modes; i++) -- { -- float diff; -- if (width != drm->drm_connector->modes[i].hdisplay || -- height != drm->drm_connector->modes[i].vdisplay) -- continue; -- -- diff = fabsf(drm->drm_connector->modes[i].vrefresh - video_refresh_rate); -- -- if (!drm->drm_mode || diff < minimum_fps_diff) -- { -- drm->drm_mode = &drm->drm_connector->modes[i]; -- minimum_fps_diff = diff; -+ FILE* fdDrmMode; -+ int drmMode; -+ if((fdDrmMode = fopen("/var/run/drmMode", "r")) != NULL) { -+ if(fscanf(fdDrmMode, "%i", &drmMode) == 1) { -+ if(drmMode>=0 && drmModedrm_connector->count_modes) { -+ drmModeCrtc *pcrtc = drmModeGetCrtc(drm->drm_fd, drm->drm_encoder->crtc_id); -+ if(pcrtc != NULL) { -+ drmModeSetCrtc(drm->drm_fd, pcrtc->crtc_id, pcrtc->buffer_id, 0, 0, &drm->drm_connector->connector_id, 1, &drm->drm_connector->modes[drmMode]); -+ drm->drm_mode = &drm->drm_connector->modes[drmMode]; -+ } -+ } - } -+ fclose(fdDrmMode); - } - } -+ // - - if (!drm->drm_mode) - { diff --git a/packages/games/emulators/dolphinsa/patches/new/007-drm-conn.patch b/packages/games/emulators/dolphinsa/patches/new/007-drm-conn.patch deleted file mode 100644 index f3b59c788..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/007-drm-conn.patch +++ /dev/null @@ -1,48 +0,0 @@ -diff --git a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -index 55efc47..b96768f 100644 ---- a/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -+++ b/Source/Core/Common/GL/GLInterface/EGLDRM.cpp -@@ -371,14 +371,33 @@ static bool drm_get_connector(GFXContextDRMData* drm, int fd) - unsigned i; - unsigned monitor_index_count = 0; - unsigned monitor = 1; -+ int drmConn = 0; - - /* Enumerate all connectors. */ - - INFO_LOG(VIDEO, "[DRM]: Found %d connectors.\n", drm->drm_resources->count_connectors); - -+ // batocera -+ { -+ FILE* fdDrmConn; -+ int drmConnRead; -+ if((fdDrmConn = fopen("/var/run/drmConn", "r")) != NULL) { -+ if(fscanf(fdDrmConn, "%i", &drmConnRead) == 1) { -+ if(drmConnRead>=0 && drmConndrm_resources->count_connectors) { -+ drmConn = drmConnRead; -+ } -+ } -+ } -+ } -+ // -+ - for (i = 0; (int)i < drm->drm_resources->count_connectors; i++) - { -- drmModeConnectorPtr conn = drmModeGetConnector(fd, drm->drm_resources->connectors[i]); -+ drmModeConnectorPtr conn; -+ -+ if(i != drmConn) continue; -+ -+ conn = drmModeGetConnector(fd, drm->drm_resources->connectors[i]); - - if (conn) - { -@@ -399,6 +418,8 @@ static bool drm_get_connector(GFXContextDRMData* drm, int fd) - - for (i = 0; (int)i < drm->drm_resources->count_connectors; i++) - { -+ if(i != drmConn) continue; -+ - drm->drm_connector = drmModeGetConnector(fd, drm->drm_resources->connectors[i]); - - if (!drm->drm_connector)