[Mesa-dev] [PATCH kmscube v3] formats: use weston's egl config matching logic, centralize format

Ilia Mirkin imirkin at alum.mit.edu
Sat Feb 10 01:49:48 UTC 2018


The GBM surface format has to match the DRM mode. Both are used in a
couple of places, so unify it so that it's only set in one place. Note
that the GBM and DRM formats are identical.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Reviewed-by: Eric Engestrom <eric.engestrom at imgtec.com>
---

v2 -> v3:
 - get rid of format defines in common.h
 - use gbm format for drmModeAddFB2 as they're the same formats

 common.c     | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 common.h     |  1 +
 drm-common.c |  7 +++---
 3 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/common.c b/common.c
index b76c994..a092cdb 100644
--- a/common.c
+++ b/common.c
@@ -47,6 +47,7 @@ get_modifiers(uint64_t **mods)
 const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
 {
 	gbm.dev = gbm_create_device(drm_fd);
+	gbm.format = GBM_FORMAT_XRGB8888;
 
 #ifndef HAVE_GBM_MODIFIERS
 	if (modifier != DRM_FORMAT_MOD_INVALID) {
@@ -54,7 +55,7 @@ const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
 		return NULL;
 	}
 	gbm.surface = gbm_surface_create(gbm.dev, w, h,
-			GBM_FORMAT_XRGB8888,
+			gbm.format,
 			GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
 #else
 	uint64_t *mods;
@@ -66,7 +67,7 @@ const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
 		count = get_modifiers(&mods);
 	}
 	gbm.surface = gbm_surface_create_with_modifiers(gbm.dev, w, h,
-			GBM_FORMAT_XRGB8888, mods, count);
+			gbm.format, mods, count);
 #endif
 
 	if (!gbm.surface) {
@@ -100,9 +101,75 @@ static bool has_ext(const char *extension_list, const char *ext)
 	}
 }
 
+static int
+match_config_to_visual(EGLDisplay egl_display,
+		       EGLint visual_id,
+		       EGLConfig *configs,
+		       int count)
+{
+	int i;
+
+	for (i = 0; i < count; ++i) {
+		EGLint id;
+
+		if (!eglGetConfigAttrib(egl_display,
+				configs[i], EGL_NATIVE_VISUAL_ID,
+				&id))
+			continue;
+
+		if (id == visual_id)
+			return i;
+	}
+
+	return -1;
+}
+
+static bool
+egl_choose_config(EGLDisplay egl_display, const EGLint *attribs,
+                  EGLint visual_id, EGLConfig *config_out)
+{
+	EGLint count = 0;
+	EGLint matched = 0;
+	EGLConfig *configs;
+	int config_index = -1;
+
+	if (!eglGetConfigs(egl_display, NULL, 0, &count) || count < 1) {
+		printf("No EGL configs to choose from.\n");
+		return false;
+	}
+	configs = malloc(count * sizeof *configs);
+	if (!configs)
+		return false;
+
+	if (!eglChooseConfig(egl_display, attribs, configs,
+			      count, &matched) || !matched) {
+		printf("No EGL configs with appropriate attributes.\n");
+		goto out;
+	}
+
+	if (!visual_id)
+		config_index = 0;
+
+	if (config_index == -1)
+		config_index = match_config_to_visual(egl_display,
+						      visual_id,
+						      configs,
+						      matched);
+
+	if (config_index != -1)
+		*config_out = configs[config_index];
+
+out:
+	free(configs);
+	if (config_index == -1)
+		return false;
+
+	return true;
+}
+
 int init_egl(struct egl *egl, const struct gbm *gbm)
 {
-	EGLint major, minor, n;
+	EGLint major, minor;
 
 	static const EGLint context_attribs[] = {
 		EGL_CONTEXT_CLIENT_VERSION, 2,
@@ -174,8 +241,9 @@ int init_egl(struct egl *egl, const struct gbm *gbm)
 		return -1;
 	}
 
-	if (!eglChooseConfig(egl->display, config_attribs, &egl->config, 1, &n) || n != 1) {
-		printf("failed to choose config: %d\n", n);
+	if (!egl_choose_config(egl->display, config_attribs, gbm->format,
+                               &egl->config)) {
+		printf("failed to choose config\n");
 		return -1;
 	}
 
diff --git a/common.h b/common.h
index 11ec26e..dc87825 100644
--- a/common.h
+++ b/common.h
@@ -60,6 +60,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy,
 struct gbm {
 	struct gbm_device *dev;
 	struct gbm_surface *surface;
+	uint32_t format;
 	int width, height;
 };
 
diff --git a/drm-common.c b/drm-common.c
index 4b55745..1ec2820 100644
--- a/drm-common.c
+++ b/drm-common.c
@@ -47,7 +47,7 @@ struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo)
 {
 	int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
 	struct drm_fb *fb = gbm_bo_get_user_data(bo);
-	uint32_t width, height,
+	uint32_t width, height, format,
 		 strides[4] = {0}, handles[4] = {0},
 		 offsets[4] = {0}, flags = 0;
 	int ret = -1;
@@ -60,6 +60,7 @@ struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo)
 
 	width = gbm_bo_get_width(bo);
 	height = gbm_bo_get_height(bo);
+	format = gbm_bo_get_format(bo);
 
 #ifdef HAVE_GBM_MODIFIERS
 	uint64_t modifiers[4] = {0};
@@ -78,7 +79,7 @@ struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo)
 	}
 
 	ret = drmModeAddFB2WithModifiers(drm_fd, width, height,
-			DRM_FORMAT_XRGB8888, handles, strides, offsets,
+			format, handles, strides, offsets,
 			modifiers, &fb->fb_id, flags);
 #endif
 	if (ret) {
@@ -88,7 +89,7 @@ struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo)
 		memcpy(handles, (uint32_t [4]){gbm_bo_get_handle(bo).u32,0,0,0}, 16);
 		memcpy(strides, (uint32_t [4]){gbm_bo_get_stride(bo),0,0,0}, 16);
 		memset(offsets, 0, 16);
-		ret = drmModeAddFB2(drm_fd, width, height, DRM_FORMAT_XRGB8888,
+		ret = drmModeAddFB2(drm_fd, width, height, format,
 				handles, strides, offsets, &fb->fb_id, 0);
 	}
 
-- 
2.13.6



More information about the mesa-dev mailing list