Skip to content

Commit

Permalink
Implement native visual matching
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kaidokert authored and tomba committed Dec 9, 2024
1 parent 6cf6e88 commit aaab406
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
34 changes: 27 additions & 7 deletions kmscube/cube-egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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");
Expand Down
3 changes: 3 additions & 0 deletions kmscube/cube-egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions kmscube/cube-gbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class GbmDevice
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");
}
Expand Down Expand Up @@ -93,7 +93,7 @@ class GbmEglSurface
: 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");
}
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit aaab406

Please sign in to comment.