#define DRM_FORMAT_MOD_LINEAR 0
#endif
-enum wl_drm_format_flags {
- HAS_ARGB8888 = 1,
- HAS_XRGB8888 = 2,
- HAS_RGB565 = 4,
- HAS_ARGB2101010 = 8,
- HAS_XRGB2101010 = 16,
-};
-
-static const struct {
+/*
+ * The index of entries in this table is used as a bitmask in
+ * dri2_dpy->formats, which tracks the formats supported by our server.
+ */
+static const struct dri2_wl_visual {
const char *format_name;
- enum wl_drm_format_flags has_format;
uint32_t wl_drm_format;
uint32_t wl_shm_format;
int dri_image_format;
+ int bpp;
unsigned int rgba_masks[4];
} dri2_wl_visuals[] = {
{
- "XRGB2101010", HAS_XRGB2101010,
+ "XRGB2101010",
WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
- __DRI_IMAGE_FORMAT_XRGB2101010,
+ __DRI_IMAGE_FORMAT_XRGB2101010, 32,
{ 0x3ff00000, 0x000ffc00, 0x000003ff, 0x00000000 }
},
{
- "ARGB2101010", HAS_ARGB2101010,
+ "ARGB2101010",
WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
- __DRI_IMAGE_FORMAT_ARGB2101010,
+ __DRI_IMAGE_FORMAT_ARGB2101010, 32,
{ 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }
},
{
- "XRGB8888", HAS_XRGB8888,
+ "XRGB8888",
WL_DRM_FORMAT_XRGB8888, WL_SHM_FORMAT_XRGB8888,
- __DRI_IMAGE_FORMAT_XRGB8888,
+ __DRI_IMAGE_FORMAT_XRGB8888, 32,
{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }
},
{
- "ARGB8888", HAS_ARGB8888,
+ "ARGB8888",
WL_DRM_FORMAT_ARGB8888, WL_SHM_FORMAT_ARGB8888,
- __DRI_IMAGE_FORMAT_ARGB8888,
+ __DRI_IMAGE_FORMAT_ARGB8888, 32,
{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }
},
{
- "RGB565", HAS_RGB565,
+ "RGB565",
WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
- __DRI_IMAGE_FORMAT_RGB565,
+ __DRI_IMAGE_FORMAT_RGB565, 16,
{ 0xf800, 0x07e0, 0x001f, 0x0000 }
},
};
+static int
+dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy,
+ const __DRIconfig *config)
+{
+ unsigned int red, green, blue, alpha;
+
+ dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK, &red);
+ dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK, &green);
+ dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK, &blue);
+ dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK, &alpha);
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+ const struct dri2_wl_visual *wl_visual = &dri2_wl_visuals[i];
+
+ if (red == wl_visual->rgba_masks[0] &&
+ green == wl_visual->rgba_masks[1] &&
+ blue == wl_visual->rgba_masks[2] &&
+ alpha == wl_visual->rgba_masks[3]) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_fourcc(uint32_t fourcc)
+{
+ for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+ /* wl_drm format codes overlap with DRIImage FourCC codes for all formats
+ * we support. */
+ if (dri2_wl_visuals[i].wl_drm_format == fourcc)
+ return i;
+ }
+
+ return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_dri_image_format(uint32_t dri_image_format)
+{
+ for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+ if (dri2_wl_visuals[i].dri_image_format == dri_image_format)
+ return i;
+ }
+
+ return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_shm_format(uint32_t shm_format)
+{
+ for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+ if (dri2_wl_visuals[i].wl_shm_format == shm_format)
+ return i;
+ }
+
+ return -1;
+}
+
static int
roundtrip(struct dri2_egl_display *dri2_dpy)
{
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct wl_egl_window *window = native_window;
struct dri2_egl_surface *dri2_surf;
+ int visual_idx;
const __DRIconfig *config;
dri2_surf = calloc(1, sizeof *dri2_surf);
return NULL;
}
- if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list, false))
+ if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
+ attrib_list, false))
goto cleanup_surf;
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+ visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config);
+ assert(visual_idx != -1);
+
if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
- if (conf->RedSize == 5)
- dri2_surf->format = WL_DRM_FORMAT_RGB565;
- else if (conf->RedSize == 8 && conf->AlphaSize == 0)
- dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
- else if (conf->RedSize == 8)
- dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
- else if (conf->RedSize == 10 && conf->AlphaSize == 0)
- dri2_surf->format = WL_DRM_FORMAT_XRGB2101010;
- else if (conf->RedSize == 10)
- dri2_surf->format = WL_DRM_FORMAT_ARGB2101010;
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format;
} else {
assert(dri2_dpy->wl_shm);
- if (conf->RedSize == 5)
- dri2_surf->format = WL_SHM_FORMAT_RGB565;
- else if (conf->RedSize == 8 && conf->AlphaSize == 0)
- dri2_surf->format = WL_SHM_FORMAT_XRGB8888;
- else if (conf->RedSize == 8)
- dri2_surf->format = WL_SHM_FORMAT_ARGB8888;
- else if (conf->RedSize == 10 && conf->AlphaSize == 0)
- dri2_surf->format = WL_SHM_FORMAT_XRGB2101010;
- else if (conf->RedSize == 10)
- dri2_surf->format = WL_SHM_FORMAT_ARGB2101010;
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_shm_format;
}
dri2_surf->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
if (dri2_dpy->flush)
dri2_surf->wl_win->resize_callback = resize_callback;
- config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
- dri2_surf->base.GLColorspace);
-
if (dri2_dpy->image_driver)
createNewDrawable = dri2_dpy->image_driver->createNewDrawable;
else if (dri2_dpy->dri2)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
int use_flags;
+ int visual_idx;
unsigned int dri_image_format;
uint64_t *modifiers;
int num_modifiers;
- /* currently supports five WL DRM formats,
- * WL_DRM_FORMAT_ARGB2101010, WL_DRM_FORMAT_XRGB2101010,
- * WL_DRM_FORMAT_ARGB8888, WL_DRM_FORMAT_XRGB8888,
- * and WL_DRM_FORMAT_RGB565
- */
- switch (dri2_surf->format) {
- case WL_DRM_FORMAT_ARGB2101010:
- dri_image_format = __DRI_IMAGE_FORMAT_ARGB2101010;
- modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.argb2101010);
- num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.argb2101010);
- break;
- case WL_DRM_FORMAT_XRGB2101010:
- dri_image_format = __DRI_IMAGE_FORMAT_XRGB2101010;
- modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.xrgb2101010);
- num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.xrgb2101010);
- break;
- case WL_DRM_FORMAT_ARGB8888:
- dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888;
- modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.argb8888);
- num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.argb8888);
- break;
- case WL_DRM_FORMAT_XRGB8888:
- dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888;
- modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.xrgb8888);
- num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.xrgb8888);
- break;
- case WL_DRM_FORMAT_RGB565:
- dri_image_format = __DRI_IMAGE_FORMAT_RGB565;
- modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.rgb565);
- num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.rgb565);
- break;
- default:
- /* format is not supported */
- return -1;
- }
+ visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+ assert(visual_idx != -1);
+ dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
+ modifiers = u_vector_tail(&dri2_dpy->wl_modifiers[visual_idx]);
+ num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers[visual_idx]);
/* There might be a buffer release already queued that wasn't processed */
wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue);
struct dri2_egl_surface *dri2_surf = loaderPrivate;
unsigned int *attachments_with_format;
__DRIbuffer *buffer;
- unsigned int bpp;
-
- switch (dri2_surf->format) {
- case WL_DRM_FORMAT_ARGB2101010:
- case WL_DRM_FORMAT_XRGB2101010:
- case WL_DRM_FORMAT_ARGB8888:
- case WL_DRM_FORMAT_XRGB8888:
- bpp = 32;
- break;
- case WL_DRM_FORMAT_RGB565:
- bpp = 16;
- break;
- default:
- /* format is not supported */
+ int visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+
+ if (visual_idx == -1)
return NULL;
- }
attachments_with_format = calloc(count, 2 * sizeof(unsigned int));
if (!attachments_with_format) {
for (int i = 0; i < count; ++i) {
attachments_with_format[2*i] = attachments[i];
- attachments_with_format[2*i + 1] = bpp;
+ attachments_with_format[2*i + 1] = dri2_wl_visuals[visual_idx].bpp;
}
buffer =
{
EGLBoolean query;
int dri_format;
+ int visual_idx;
query = dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FOURCC,
fourcc);
if (!query)
return false;
- switch (dri_format) {
- case __DRI_IMAGE_FORMAT_ARGB8888:
- *fourcc = __DRI_IMAGE_FOURCC_ARGB8888;
- return true;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- *fourcc = __DRI_IMAGE_FOURCC_XRGB8888;
- return true;
- default:
+ visual_idx = dri2_wl_visual_idx_from_dri_image_format(dri_format);
+ if (visual_idx == -1)
return false;
- }
+
+ *fourcc = dri2_wl_visuals[visual_idx].wl_drm_format;
+ return true;
}
static struct wl_buffer *
int stride, offset;
int fd = -1;
- if (i == 0)
- p_image = image;
- else
- p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
+ p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
if (!p_image) {
- zwp_linux_buffer_params_v1_destroy(params);
- return NULL;
+ assert(i == 0);
+ p_image = image;
}
query = dri2_dpy->image->queryImage(p_image,
struct dri2_egl_image *dri2_img = dri2_egl_image(img);
__DRIimage *image = dri2_img->dri_image;
struct wl_buffer *buffer;
- int format;
+ int format, visual_idx;
+ /* Check the upstream display supports this buffer's format. */
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
- switch (format) {
- case __DRI_IMAGE_FORMAT_ARGB2101010:
- if (!(dri2_dpy->formats & HAS_ARGB2101010))
- goto bad_format;
- break;
- case __DRI_IMAGE_FORMAT_XRGB2101010:
- if (!(dri2_dpy->formats & HAS_XRGB2101010))
- goto bad_format;
- break;
- case __DRI_IMAGE_FORMAT_ARGB8888:
- if (!(dri2_dpy->formats & HAS_ARGB8888))
- goto bad_format;
- break;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- if (!(dri2_dpy->formats & HAS_XRGB8888))
- goto bad_format;
- break;
- default:
+ visual_idx = dri2_wl_visual_idx_from_dri_image_format(format);
+ if (visual_idx == -1)
+ goto bad_format;
+
+ if (!(dri2_dpy->formats & (1 << visual_idx)))
goto bad_format;
- }
buffer = create_wl_buffer(dri2_dpy, NULL, image);
drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
struct dri2_egl_display *dri2_dpy = data;
+ int visual_idx = dri2_wl_visual_idx_from_fourcc(format);
- switch (format) {
- case WL_DRM_FORMAT_ARGB2101010:
- dri2_dpy->formats |= HAS_ARGB2101010;
- break;
- case WL_DRM_FORMAT_XRGB2101010:
- dri2_dpy->formats |= HAS_XRGB2101010;
- break;
- 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;
- }
+ if (visual_idx == -1)
+ return;
+
+ dri2_dpy->formats |= (1 << visual_idx);
}
static void
uint32_t modifier_lo)
{
struct dri2_egl_display *dri2_dpy = data;
- uint64_t *mod = NULL;
+ int visual_idx = dri2_wl_visual_idx_from_fourcc(format);
+ uint64_t *mod;
+
+ if (visual_idx == -1)
+ return;
if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) &&
modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff))
return;
- switch (format) {
- case WL_DRM_FORMAT_ARGB2101010:
- mod = u_vector_add(&dri2_dpy->wl_modifiers.argb2101010);
- dri2_dpy->formats |= HAS_ARGB2101010;
- break;
- case WL_DRM_FORMAT_XRGB2101010:
- mod = u_vector_add(&dri2_dpy->wl_modifiers.xrgb2101010);
- dri2_dpy->formats |= HAS_XRGB2101010;
- break;
- case WL_DRM_FORMAT_ARGB8888:
- mod = u_vector_add(&dri2_dpy->wl_modifiers.argb8888);
- dri2_dpy->formats |= HAS_ARGB8888;
- break;
- case WL_DRM_FORMAT_XRGB8888:
- mod = u_vector_add(&dri2_dpy->wl_modifiers.xrgb8888);
- dri2_dpy->formats |= HAS_XRGB8888;
- break;
- case WL_DRM_FORMAT_RGB565:
- mod = u_vector_add(&dri2_dpy->wl_modifiers.rgb565);
- dri2_dpy->formats |= HAS_RGB565;
- break;
- default:
- break;
- }
-
- if (!mod)
- return;
+ dri2_dpy->formats |= (1 << visual_idx);
+ mod = u_vector_add(&dri2_dpy->wl_modifiers[visual_idx]);
*mod = (uint64_t) modifier_hi << 32;
*mod |= (uint64_t) (modifier_lo & 0xffffffff);
}
for (unsigned j = 0; j < ARRAY_SIZE(dri2_wl_visuals); j++) {
struct dri2_egl_config *dri2_conf;
- if (!(dri2_dpy->formats & dri2_wl_visuals[j].has_format))
+ if (!(dri2_dpy->formats & (1 << j)))
continue;
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
dri2_dpy->wl_dpy = disp->PlatformDisplay;
}
- if (!u_vector_init(&dri2_dpy->wl_modifiers.xrgb2101010, sizeof(uint64_t), 32) ||
- !u_vector_init(&dri2_dpy->wl_modifiers.argb2101010, sizeof(uint64_t), 32) ||
- !u_vector_init(&dri2_dpy->wl_modifiers.xrgb8888, sizeof(uint64_t), 32) ||
- !u_vector_init(&dri2_dpy->wl_modifiers.argb8888, sizeof(uint64_t), 32) ||
- !u_vector_init(&dri2_dpy->wl_modifiers.rgb565, sizeof(uint64_t), 32)) {
+ dri2_dpy->wl_modifiers =
+ calloc(ARRAY_SIZE(dri2_wl_visuals), sizeof(*dri2_dpy->wl_modifiers));
+ if (!dri2_dpy->wl_modifiers)
goto cleanup;
+ for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+ if (!u_vector_init(&dri2_dpy->wl_modifiers[i], sizeof(uint64_t), 32))
+ goto cleanup;
}
dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
static int
dri2_wl_swrast_get_stride_for_format(int format, int w)
{
- if (format == WL_SHM_FORMAT_RGB565)
- return 2 * w;
- else /* ARGB8888 || XRGB8888 || ARGB2101010 || XRGB2101010 */
- return 4 * w;
+ int visual_idx = dri2_wl_visual_idx_from_shm_format(format);
+
+ assume(visual_idx != -1);
+
+ return w * (dri2_wl_visuals[visual_idx].bpp / 8);
}
/*
shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
{
struct dri2_egl_display *dri2_dpy = data;
+ int visual_idx = dri2_wl_visual_idx_from_shm_format(format);
- switch (format) {
- case WL_SHM_FORMAT_ARGB2101010:
- dri2_dpy->formats |= HAS_ARGB2101010;
- break;
- case WL_SHM_FORMAT_XRGB2101010:
- dri2_dpy->formats |= HAS_XRGB2101010;
- break;
- case WL_SHM_FORMAT_ARGB8888:
- dri2_dpy->formats |= HAS_ARGB8888;
- break;
- case WL_SHM_FORMAT_XRGB8888:
- dri2_dpy->formats |= HAS_XRGB8888;
- break;
- case WL_SHM_FORMAT_RGB565:
- dri2_dpy->formats |= HAS_RGB565;
- break;
- }
+ if (visual_idx == -1)
+ return;
+
+ dri2_dpy->formats |= (1 << visual_idx);
}
static const struct wl_shm_listener shm_listener = {
wl_event_queue_destroy(dri2_dpy->wl_queue);
if (dri2_dpy->wl_dpy_wrapper)
wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper);
- u_vector_finish(&dri2_dpy->wl_modifiers.argb2101010);
- u_vector_finish(&dri2_dpy->wl_modifiers.xrgb2101010);
- u_vector_finish(&dri2_dpy->wl_modifiers.argb8888);
- u_vector_finish(&dri2_dpy->wl_modifiers.xrgb8888);
- u_vector_finish(&dri2_dpy->wl_modifiers.rgb565);
+
+ for (int i = 0; dri2_dpy->wl_modifiers && i < ARRAY_SIZE(dri2_wl_visuals); i++)
+ u_vector_finish(&dri2_dpy->wl_modifiers[i]);
+ free(dri2_dpy->wl_modifiers);
+
if (dri2_dpy->own_device)
wl_display_disconnect(dri2_dpy->wl_dpy);
}