mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 11:30:45 -05:00
wayland-buffer: Use MetaFormatInfo to find supported formats
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3280>
This commit is contained in:
parent
dbdc821ca7
commit
97c1d19017
@ -56,6 +56,8 @@
|
||||
#include "meta/util.h"
|
||||
#include "wayland/meta-wayland-dma-buf.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "common/meta-cogl-drm-formats.h"
|
||||
#include "compositor/meta-multi-texture-format-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||
@ -64,6 +66,8 @@
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#define META_WAYLAND_SHM_MAX_PLANES 4
|
||||
|
||||
enum
|
||||
{
|
||||
RESOURCE_DESTROYED,
|
||||
@ -75,6 +79,9 @@ guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandBuffer, meta_wayland_buffer, G_TYPE_OBJECT);
|
||||
|
||||
MetaFormatInfo supported_shm_formats[G_N_ELEMENTS (meta_format_info)];
|
||||
size_t n_supported_shm_formats = 0;
|
||||
|
||||
static void
|
||||
meta_wayland_buffer_destroy_handler (struct wl_listener *listener,
|
||||
void *data)
|
||||
@ -205,123 +212,43 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shm_format_to_cogl_pixel_format (enum wl_shm_format shm_format,
|
||||
CoglPixelFormat *format_out)
|
||||
static uint32_t
|
||||
shm_to_drm_format (enum wl_shm_format format)
|
||||
{
|
||||
CoglPixelFormat format;
|
||||
if (format == WL_SHM_FORMAT_ARGB8888)
|
||||
return DRM_FORMAT_ARGB8888;
|
||||
if (format == WL_SHM_FORMAT_XRGB8888)
|
||||
return DRM_FORMAT_XRGB8888;
|
||||
|
||||
switch (shm_format)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
format = COGL_PIXEL_FORMAT_XRGB_8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XBGR8888:
|
||||
format = COGL_PIXEL_FORMAT_XBGR_8888;
|
||||
case WL_SHM_FORMAT_ABGR8888:
|
||||
format = COGL_PIXEL_FORMAT_ABGR_8888_PRE;
|
||||
break;
|
||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
case WL_SHM_FORMAT_RGB565:
|
||||
format = COGL_PIXEL_FORMAT_RGB_565;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
format = COGL_PIXEL_FORMAT_BGRX_8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XBGR8888:
|
||||
format = COGL_PIXEL_FORMAT_RGBX_8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ABGR8888:
|
||||
format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB2101010:
|
||||
format = COGL_PIXEL_FORMAT_XRGB_2101010;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ARGB2101010:
|
||||
format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XBGR2101010:
|
||||
format = COGL_PIXEL_FORMAT_XBGR_2101010;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ABGR2101010:
|
||||
format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB16161616F:
|
||||
format = COGL_PIXEL_FORMAT_BGRX_FP_16161616;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ARGB16161616F:
|
||||
format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XBGR16161616F:
|
||||
format = COGL_PIXEL_FORMAT_RGBX_FP_16161616;
|
||||
break;
|
||||
case WL_SHM_FORMAT_ABGR16161616F:
|
||||
format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (format_out)
|
||||
*format_out = format;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shm_buffer_get_cogl_pixel_format (MetaWaylandBuffer *buffer,
|
||||
struct wl_shm_buffer *shm_buffer,
|
||||
CoglPixelFormat *format_out)
|
||||
{
|
||||
MetaContext *context =
|
||||
meta_wayland_compositor_get_context (buffer->compositor);
|
||||
MetaBackend *backend = meta_context_get_backend (context);
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
CoglPixelFormat cogl_format;
|
||||
|
||||
if (!shm_format_to_cogl_pixel_format (wl_shm_buffer_get_format (shm_buffer),
|
||||
&cogl_format))
|
||||
return FALSE;
|
||||
|
||||
if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
|
||||
return FALSE;
|
||||
|
||||
if (format_out)
|
||||
*format_out = cogl_format;
|
||||
|
||||
return TRUE;
|
||||
/* all other wayland shm formats are the same as the drm format */
|
||||
return format;
|
||||
}
|
||||
|
||||
static const char *
|
||||
shm_format_to_string (MetaDrmFormatBuf *format_buf,
|
||||
uint32_t shm_format)
|
||||
shm_format_to_string (MetaDrmFormatBuf *format_buf,
|
||||
enum wl_shm_format shm_format)
|
||||
{
|
||||
const char *result;
|
||||
uint32_t drm_format;
|
||||
|
||||
switch (shm_format)
|
||||
drm_format = shm_to_drm_format (shm_format);
|
||||
return meta_drm_format_to_string (format_buf, drm_format);
|
||||
}
|
||||
|
||||
static const MetaFormatInfo *
|
||||
get_supported_shm_format_info (uint32_t shm_format)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n_supported_shm_formats; i++)
|
||||
{
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
result = "ARGB8888";
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
result = "XRGB8888";
|
||||
break;
|
||||
default:
|
||||
result = meta_drm_format_to_string (format_buf, shm_format);
|
||||
break;
|
||||
uint32_t drm_format;
|
||||
|
||||
drm_format = shm_to_drm_format (shm_format);
|
||||
if (supported_shm_formats[i].drm_format == drm_format)
|
||||
return &supported_shm_formats[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -340,23 +267,30 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
CoglBitmap *bitmap;
|
||||
CoglTexture *new_cogl_tex;
|
||||
MetaDrmFormatBuf format_buf;
|
||||
uint32_t shm_format;
|
||||
const MetaFormatInfo *format_info;
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
width = wl_shm_buffer_get_width (shm_buffer);
|
||||
height = wl_shm_buffer_get_height (shm_buffer);
|
||||
if (!shm_buffer_get_cogl_pixel_format (buffer, shm_buffer, &format))
|
||||
shm_format = wl_shm_buffer_get_format (shm_buffer);
|
||||
|
||||
format_info = get_supported_shm_format_info (shm_format);
|
||||
if (!format_info)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid shm pixel format");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_assert (format_info->multi_texture_format == META_MULTI_TEXTURE_FORMAT_SIMPLE);
|
||||
format = format_info->cogl_format;
|
||||
|
||||
meta_topic (META_DEBUG_WAYLAND,
|
||||
"[wl-shm] wl_buffer@%u wl_shm_format %s -> CoglPixelFormat %s",
|
||||
wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
|
||||
shm_format_to_string (&format_buf,
|
||||
wl_shm_buffer_get_format (shm_buffer)),
|
||||
shm_format_to_string (&format_buf, shm_format),
|
||||
cogl_pixel_format_to_string (format));
|
||||
|
||||
if (*texture &&
|
||||
@ -683,12 +617,20 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
|
||||
gboolean set_texture_failed = FALSE;
|
||||
CoglPixelFormat format;
|
||||
CoglTexture *cogl_texture;
|
||||
uint32_t shm_format;
|
||||
const MetaFormatInfo *format_info;
|
||||
|
||||
n_rectangles = mtk_region_num_rectangles (region);
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
|
||||
shm_buffer_get_cogl_pixel_format (buffer, shm_buffer, &format);
|
||||
shm_format = wl_shm_buffer_get_format (shm_buffer);
|
||||
|
||||
format_info = get_supported_shm_format_info (shm_format);
|
||||
g_assert (format_info != NULL);
|
||||
g_assert (format_info->multi_texture_format == META_MULTI_TEXTURE_FORMAT_SIMPLE);
|
||||
format = format_info->cogl_format;
|
||||
|
||||
g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
|
||||
cogl_texture = meta_multi_texture_get_plane (texture, 0);
|
||||
|
||||
@ -912,6 +854,35 @@ meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass)
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
context_supports_format (CoglContext *cogl_context,
|
||||
const MetaFormatInfo *format_info)
|
||||
{
|
||||
const MetaMultiTextureFormatInfo *mt_format_info;
|
||||
size_t i;
|
||||
|
||||
if (format_info->multi_texture_format == META_MULTI_TEXTURE_FORMAT_INVALID)
|
||||
return FALSE;
|
||||
|
||||
if (format_info->multi_texture_format == META_MULTI_TEXTURE_FORMAT_SIMPLE)
|
||||
{
|
||||
return cogl_context_format_supports_upload (cogl_context,
|
||||
format_info->cogl_format);
|
||||
}
|
||||
|
||||
mt_format_info =
|
||||
meta_multi_texture_format_get_info (format_info->multi_texture_format);
|
||||
|
||||
for (i = 0; i < mt_format_info->n_planes; i++)
|
||||
{
|
||||
if (!cogl_context_format_supports_upload (cogl_context,
|
||||
mt_format_info->subformats[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_init_shm (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
@ -920,11 +891,13 @@ meta_wayland_init_shm (MetaWaylandCompositor *compositor)
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
int i;
|
||||
|
||||
static const enum wl_shm_format shm_formats[] = {
|
||||
static const enum wl_shm_format possible_formats[] = {
|
||||
WL_SHM_FORMAT_ARGB8888,
|
||||
WL_SHM_FORMAT_XRGB8888,
|
||||
WL_SHM_FORMAT_ABGR8888,
|
||||
WL_SHM_FORMAT_XBGR8888,
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
WL_SHM_FORMAT_RGB565,
|
||||
WL_SHM_FORMAT_ARGB2101010,
|
||||
WL_SHM_FORMAT_XRGB2101010,
|
||||
@ -934,22 +907,31 @@ meta_wayland_init_shm (MetaWaylandCompositor *compositor)
|
||||
WL_SHM_FORMAT_XRGB16161616F,
|
||||
WL_SHM_FORMAT_ABGR16161616F,
|
||||
WL_SHM_FORMAT_XBGR16161616F,
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
|
||||
wl_display_init_shm (compositor->wayland_display);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (shm_formats); i++)
|
||||
n_supported_shm_formats = 0;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (possible_formats); i++)
|
||||
{
|
||||
CoglPixelFormat cogl_format;
|
||||
const MetaFormatInfo *format_info;
|
||||
uint32_t drm_format;
|
||||
|
||||
if (!shm_format_to_cogl_pixel_format (shm_formats[i], &cogl_format))
|
||||
drm_format = shm_to_drm_format (possible_formats[i]);
|
||||
format_info = meta_format_info_from_drm_format (drm_format);
|
||||
g_assert (format_info);
|
||||
|
||||
if (!context_supports_format (cogl_context, format_info))
|
||||
continue;
|
||||
|
||||
if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
|
||||
continue;
|
||||
supported_shm_formats[n_supported_shm_formats++] = *format_info;
|
||||
|
||||
wl_display_add_shm_format (compositor->wayland_display, shm_formats[i]);
|
||||
if (possible_formats[i] != WL_SHM_FORMAT_ARGB8888 &&
|
||||
possible_formats[i] != WL_SHM_FORMAT_XRGB8888)
|
||||
{
|
||||
wl_display_add_shm_format (compositor->wayland_display,
|
||||
possible_formats[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user