mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -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 "meta/util.h"
|
||||||
#include "wayland/meta-wayland-dma-buf.h"
|
#include "wayland/meta-wayland-dma-buf.h"
|
||||||
#include "wayland/meta-wayland-private.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
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||||
@ -64,6 +66,8 @@
|
|||||||
#include "backends/native/meta-renderer-native.h"
|
#include "backends/native/meta-renderer-native.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define META_WAYLAND_SHM_MAX_PLANES 4
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RESOURCE_DESTROYED,
|
RESOURCE_DESTROYED,
|
||||||
@ -75,6 +79,9 @@ guint signals[LAST_SIGNAL];
|
|||||||
|
|
||||||
G_DEFINE_TYPE (MetaWaylandBuffer, meta_wayland_buffer, G_TYPE_OBJECT);
|
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
|
static void
|
||||||
meta_wayland_buffer_destroy_handler (struct wl_listener *listener,
|
meta_wayland_buffer_destroy_handler (struct wl_listener *listener,
|
||||||
void *data)
|
void *data)
|
||||||
@ -205,123 +212,43 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static uint32_t
|
||||||
shm_format_to_cogl_pixel_format (enum wl_shm_format shm_format,
|
shm_to_drm_format (enum wl_shm_format format)
|
||||||
CoglPixelFormat *format_out)
|
|
||||||
{
|
{
|
||||||
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)
|
/* all other wayland shm formats are the same as the drm format */
|
||||||
{
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
shm_format_to_string (MetaDrmFormatBuf *format_buf,
|
shm_format_to_string (MetaDrmFormatBuf *format_buf,
|
||||||
uint32_t shm_format)
|
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);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
static const MetaFormatInfo *
|
||||||
|
get_supported_shm_format_info (uint32_t shm_format)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_supported_shm_formats; i++)
|
||||||
|
{
|
||||||
|
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 NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -340,23 +267,30 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
CoglBitmap *bitmap;
|
CoglBitmap *bitmap;
|
||||||
CoglTexture *new_cogl_tex;
|
CoglTexture *new_cogl_tex;
|
||||||
MetaDrmFormatBuf format_buf;
|
MetaDrmFormatBuf format_buf;
|
||||||
|
uint32_t shm_format;
|
||||||
|
const MetaFormatInfo *format_info;
|
||||||
|
|
||||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||||
stride = wl_shm_buffer_get_stride (shm_buffer);
|
stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||||
width = wl_shm_buffer_get_width (shm_buffer);
|
width = wl_shm_buffer_get_width (shm_buffer);
|
||||||
height = wl_shm_buffer_get_height (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,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"Invalid shm pixel format");
|
"Invalid shm pixel format");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert (format_info->multi_texture_format == META_MULTI_TEXTURE_FORMAT_SIMPLE);
|
||||||
|
format = format_info->cogl_format;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WAYLAND,
|
meta_topic (META_DEBUG_WAYLAND,
|
||||||
"[wl-shm] wl_buffer@%u wl_shm_format %s -> CoglPixelFormat %s",
|
"[wl-shm] wl_buffer@%u wl_shm_format %s -> CoglPixelFormat %s",
|
||||||
wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
|
wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
|
||||||
shm_format_to_string (&format_buf,
|
shm_format_to_string (&format_buf, shm_format),
|
||||||
wl_shm_buffer_get_format (shm_buffer)),
|
|
||||||
cogl_pixel_format_to_string (format));
|
cogl_pixel_format_to_string (format));
|
||||||
|
|
||||||
if (*texture &&
|
if (*texture &&
|
||||||
@ -683,12 +617,20 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
|
|||||||
gboolean set_texture_failed = FALSE;
|
gboolean set_texture_failed = FALSE;
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat format;
|
||||||
CoglTexture *cogl_texture;
|
CoglTexture *cogl_texture;
|
||||||
|
uint32_t shm_format;
|
||||||
|
const MetaFormatInfo *format_info;
|
||||||
|
|
||||||
n_rectangles = mtk_region_num_rectangles (region);
|
n_rectangles = mtk_region_num_rectangles (region);
|
||||||
|
|
||||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
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);
|
g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
|
||||||
cogl_texture = meta_multi_texture_get_plane (texture, 0);
|
cogl_texture = meta_multi_texture_get_plane (texture, 0);
|
||||||
|
|
||||||
@ -912,6 +854,35 @@ meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass)
|
|||||||
G_TYPE_NONE, 0);
|
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
|
void
|
||||||
meta_wayland_init_shm (MetaWaylandCompositor *compositor)
|
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);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
CoglContext *cogl_context =
|
CoglContext *cogl_context =
|
||||||
clutter_backend_get_cogl_context (clutter_backend);
|
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_ABGR8888,
|
||||||
WL_SHM_FORMAT_XBGR8888,
|
WL_SHM_FORMAT_XBGR8888,
|
||||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
||||||
WL_SHM_FORMAT_RGB565,
|
WL_SHM_FORMAT_RGB565,
|
||||||
WL_SHM_FORMAT_ARGB2101010,
|
WL_SHM_FORMAT_ARGB2101010,
|
||||||
WL_SHM_FORMAT_XRGB2101010,
|
WL_SHM_FORMAT_XRGB2101010,
|
||||||
@ -934,22 +907,31 @@ meta_wayland_init_shm (MetaWaylandCompositor *compositor)
|
|||||||
WL_SHM_FORMAT_XRGB16161616F,
|
WL_SHM_FORMAT_XRGB16161616F,
|
||||||
WL_SHM_FORMAT_ABGR16161616F,
|
WL_SHM_FORMAT_ABGR16161616F,
|
||||||
WL_SHM_FORMAT_XBGR16161616F,
|
WL_SHM_FORMAT_XBGR16161616F,
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
int i;
|
|
||||||
|
|
||||||
wl_display_init_shm (compositor->wayland_display);
|
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;
|
continue;
|
||||||
|
|
||||||
if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
|
supported_shm_formats[n_supported_shm_formats++] = *format_info;
|
||||||
continue;
|
|
||||||
|
|
||||||
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