diff options
| author | Kaido Kert <kaidokert@gmail.com> | 2024-11-29 04:47:25 +0000 |
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2024-12-09 12:35:38 +0200 |
| commit | aaab406251540429522c5ef7808ee049c65a06d2 (patch) | |
| tree | 65b6681f3dab077e5341d9cb386f2e71220d12af | |
| parent | 6cf6e88715ac034f568603bce9a1b8f4a30c12ce (diff) | |
Implement native visual matching
Implement matching GBM buffer format to EGL NATIVE_VISUAL_ID.
eglChooseConfig cannot match on NATIVE_VISUAL_ID, but GBM/EGL
requires matching formats. Similar logic is implemented in
kmscube code in match_config_to_visual.
X11, Wayland and Null cube demos remain unchanged.
Tested on Raspi-4 and VirtualBox/Ubuntu
| -rw-r--r-- | kmscube/cube-egl.cpp | 34 | ||||
| -rw-r--r-- | kmscube/cube-egl.h | 3 | ||||
| -rw-r--r-- | kmscube/cube-gbm.cpp | 8 |
3 files changed, 34 insertions, 11 deletions
diff --git a/kmscube/cube-egl.cpp b/kmscube/cube-egl.cpp index 9551793..372c978 100644 --- a/kmscube/cube-egl.cpp +++ b/kmscube/cube-egl.cpp @@ -22,7 +22,10 @@ static void print_egl_config(EGLDisplay dpy, EGLConfig cfg) getconf(EGL_NATIVE_VISUAL_TYPE)); } -EglState::EglState(void* native_display) +EglState::EglState(void* native_display) : EglState(native_display, 0) {} + +EglState::EglState(void* native_display, EGLint native_visual_id) + : m_native_visual_id(native_visual_id) { EGLBoolean b; EGLint major, minor, n; @@ -60,11 +63,11 @@ EglState::EglState(void* native_display) b = eglBindAPI(EGL_OPENGL_ES_API); FAIL_IF(!b, "failed to bind api EGL_OPENGL_ES_API"); - if (s_verbose) { - EGLint numConfigs; - b = eglGetConfigs(m_display, nullptr, 0, &numConfigs); - FAIL_IF(!b, "failed to get number of configs"); + EGLint numConfigs; + b = eglGetConfigs(m_display, nullptr, 0, &numConfigs); + FAIL_IF(!b, "failed to get number of configs"); + if (s_verbose) { EGLConfig configs[numConfigs]; b = eglGetConfigs(m_display, configs, numConfigs, &numConfigs); FAIL_IF(!b, "failed to get configs"); @@ -75,8 +78,25 @@ EglState::EglState(void* native_display) print_egl_config(m_display, configs[i]); } - b = eglChooseConfig(m_display, config_attribs, &m_config, 1, &n); - FAIL_IF(!b || n != 1, "failed to choose config"); + std::vector<EGLConfig> configs(numConfigs); + b = eglChooseConfig(m_display, config_attribs, configs.data(), numConfigs, &n); + FAIL_IF(!b || n < 1, "failed to choose config"); + + // elgChooseConfig does implement matching by EGL_NATIVE_VISUAL_ID, do a manual + // loop. Picks the first returned if native_visual_id is not set. + for (const auto& config : configs) { + EGLint id; + b = eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &id); + if (!b) { + printf("failed to get native visual id\n"); + continue; + } + + if (id == native_visual_id || !native_visual_id) { + m_config = config; + break; + } + } if (s_verbose) { printf("Chosen config:\n"); diff --git a/kmscube/cube-egl.h b/kmscube/cube-egl.h index f492d07..73e3ab1 100644 --- a/kmscube/cube-egl.h +++ b/kmscube/cube-egl.h @@ -6,16 +6,19 @@ class EglState { public: EglState(void* native_display); + EglState(void* native_display, EGLint native_visual_id); ~EglState(); EGLDisplay display() const { return m_display; } EGLConfig config() const { return m_config; } EGLContext context() const { return m_context; } + EGLint native_visual_id() const { return m_native_visual_id; } private: EGLDisplay m_display; EGLConfig m_config; EGLContext m_context; + EGLint m_native_visual_id; }; class EglSurface diff --git a/kmscube/cube-gbm.cpp b/kmscube/cube-gbm.cpp index 034ae8a..69930ee 100644 --- a/kmscube/cube-gbm.cpp +++ b/kmscube/cube-gbm.cpp @@ -49,10 +49,10 @@ private: class GbmSurface { public: - GbmSurface(GbmDevice& gdev, int width, int height) + GbmSurface(GbmDevice& gdev, int width, int height, uint32_t format) { m_surface = gbm_surface_create(gdev.handle(), width, height, - GBM_FORMAT_XRGB8888, + format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); FAIL_IF(!m_surface, "failed to create gbm surface"); } @@ -93,7 +93,7 @@ public: : card(card), egl(egl), m_width(width), m_height(height), bo_prev(0), bo_next(0) { - gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height)); + gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height, egl.native_visual_id())); esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL); FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface"); } @@ -319,7 +319,7 @@ void main_gbm() FAIL_IF(!card.has_atomic(), "No atomic modesetting"); GbmDevice gdev(card); - EglState egl(gdev.handle()); + EglState egl(gdev.handle(), GBM_FORMAT_XRGB8888); ResourceManager resman(card); |
