[PATCH mesa 1/3] wayland: Keep track of the formats in a sorted array instead of flags
Neil Roberts
neil at linux.intel.com
Thu Feb 6 05:58:29 PST 2014
In order to support YUV formats in CreateWaylandBufferFromImageWL we need to
be able to check whether the compositor supports a larger number of formats so
storing them in flags is a bit awkard. Instead all of the formats are now
stored in a sorted array using wl_array. A binary search is used to check for
the format.
---
src/egl/drivers/dri2/egl_dri2.h | 2 +-
src/egl/drivers/dri2/platform_wayland.c | 85 ++++++++++++++++++++++++---------
2 files changed, 64 insertions(+), 23 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index dfc5927..3f90582 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -131,7 +131,7 @@ struct dri2_egl_display
struct wl_drm *wl_drm;
struct wl_event_queue *wl_queue;
int authenticated;
- int formats;
+ struct wl_array formats;
uint32_t capabilities;
#endif
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 50750a9..089ed62 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -41,12 +41,6 @@
#include <wayland-client.h>
#include "wayland-drm-client-protocol.h"
-enum wl_drm_format_flags {
- HAS_ARGB8888 = 1,
- HAS_XRGB8888 = 2,
- HAS_RGB565 = 4,
-};
-
static void
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
{
@@ -679,6 +673,31 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
return dri2_swap_buffers_with_damage (drv, disp, draw, NULL, 0);
}
+static EGLBoolean
+dri2_can_handle_format(struct dri2_egl_display *dri2_dpy,
+ enum wl_drm_format format)
+{
+ const enum wl_drm_format *formats;
+ int min, mid, max;
+
+ /* Binary search for the format */
+ min = 0;
+ max = dri2_dpy->formats.size / sizeof (enum wl_drm_format);
+ formats = dri2_dpy->formats.data;
+
+ while (max > min) {
+ mid = (max + min) / 2;
+ if (formats[mid] < format)
+ min = mid + 1;
+ else if (formats[mid] > format)
+ max = mid;
+ else
+ return EGL_TRUE;
+ }
+
+ return EGL_FALSE;
+}
+
static struct wl_buffer *
dri2_create_wayland_buffer_from_image_wl(_EGLDriver *drv,
_EGLDisplay *disp,
@@ -695,12 +714,12 @@ dri2_create_wayland_buffer_from_image_wl(_EGLDriver *drv,
switch (format) {
case __DRI_IMAGE_FORMAT_ARGB8888:
- if (!(dri2_dpy->formats & HAS_ARGB8888))
+ if (!dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_ARGB8888))
goto bad_format;
wl_format = WL_DRM_FORMAT_ARGB8888;
break;
case __DRI_IMAGE_FORMAT_XRGB8888:
- if (!(dri2_dpy->formats & HAS_XRGB8888))
+ if (!dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_XRGB8888))
goto bad_format;
wl_format = WL_DRM_FORMAT_XRGB8888;
break;
@@ -794,6 +813,7 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
wl_drm_destroy(dri2_dpy->wl_drm);
if (dri2_dpy->own_device)
wl_display_disconnect(dri2_dpy->wl_dpy);
+ wl_array_release(&dri2_dpy->formats);
free(dri2_dpy);
disp->DriverData = NULL;
@@ -834,18 +854,36 @@ static void
drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
struct dri2_egl_display *dri2_dpy = data;
-
- switch (format) {
- case WL_DRM_FORMAT_ARGB8888:
- dri2_dpy->formats |= HAS_ARGB8888;
- break;
- case WL_DRM_FORMAT_XRGB8888:
- dri2_dpy->formats |= HAS_XRGB8888;
- break;
- case WL_DRM_FORMAT_RGB565:
- dri2_dpy->formats |= HAS_RGB565;
- break;
+ enum wl_drm_format *formats = dri2_dpy->formats.data;
+ int n_formats;
+ int min, mid, max;
+
+ n_formats = dri2_dpy->formats.size / sizeof (enum wl_drm_format);
+
+ /* Search for the insert position to keep the format array sorted */
+ min = 0;
+ max = n_formats;
+
+ while (max > min) {
+ mid = (max + min) / 2;
+ if (formats[mid] < format)
+ min = mid + 1;
+ else if (formats[mid] > format)
+ max = mid;
+ else
+ return;
}
+
+ if (wl_array_add(&dri2_dpy->formats, sizeof (enum wl_drm_format)) == NULL)
+ return;
+
+ formats = dri2_dpy->formats.data;
+
+ /* Move the subsequent formats out of the way */
+ memmove(formats + min + 1,
+ formats + min,
+ (n_formats - min) * sizeof *formats);
+ formats[min] = format;
}
static void
@@ -980,6 +1018,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+ wl_array_init(&dri2_dpy->formats);
+
disp->DriverData = (void *) dri2_dpy;
if (disp->PlatformDisplay == NULL) {
dri2_dpy->wl_dpy = wl_display_connect(NULL);
@@ -1050,11 +1090,11 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
types = EGL_WINDOW_BIT;
for (i = 0; dri2_dpy->driver_configs[i]; i++) {
config = dri2_dpy->driver_configs[i];
- if (dri2_dpy->formats & HAS_XRGB8888)
+ if (dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_XRGB8888))
dri2_add_config(disp, config, i + 1, types, NULL, rgb_masks);
- if (dri2_dpy->formats & HAS_ARGB8888)
+ if (dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_ARGB8888))
dri2_add_config(disp, config, i + 1, types, NULL, argb_masks);
- if (dri2_dpy->formats & HAS_RGB565)
+ if (dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_RGB565))
dri2_add_config(disp, config, i + 1, types, NULL, rgb565_masks);
}
@@ -1081,6 +1121,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
free(dri2_dpy->device_name);
wl_drm_destroy(dri2_dpy->wl_drm);
cleanup_dpy:
+ wl_array_release(&dri2_dpy->formats);
free(dri2_dpy);
return EGL_FALSE;
--
1.8.5.3
More information about the wayland-devel
mailing list