wayland: Add a convenience function to update a region from SHM buffer
Adds cogl_wayland_texture_set_region_from_shm_buffer which is a convenience wrapper around cogl_texture_set_region but it uses the correct format to copy the data from a Wayland SHM buffer. This will typically be used by compositors to update the texture for a surface when an SHM buffer is attached. The ordering of the arguments is based on cogl_texture_set_region_from_bitmap. Based on a patch by Jasper St. Pierre. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit c76c1d136d2cac7f3d1331a4d1dc0dd0f06e812c) Conflicts: examples/cogland.c
This commit is contained in:
parent
5ef1020e8a
commit
a29b8c475e
@ -293,6 +293,75 @@ _cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
|
|||||||
#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
|
#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
|
||||||
|
|
||||||
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
|
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
|
||||||
|
static void
|
||||||
|
shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
|
||||||
|
CoglPixelFormat *format_out,
|
||||||
|
CoglPixelFormat *internal_format_out)
|
||||||
|
{
|
||||||
|
CoglPixelFormat format;
|
||||||
|
CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||||
|
|
||||||
|
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||||
|
{
|
||||||
|
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||||
|
case WL_SHM_FORMAT_ARGB8888:
|
||||||
|
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_XRGB8888:
|
||||||
|
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||||
|
internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
||||||
|
break;
|
||||||
|
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||||
|
case WL_SHM_FORMAT_ARGB8888:
|
||||||
|
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_XRGB8888:
|
||||||
|
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||||
|
internal_format = COGL_PIXEL_FORMAT_BGR_888;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
g_warn_if_reached ();
|
||||||
|
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format_out)
|
||||||
|
*format_out = format;
|
||||||
|
if (internal_format_out)
|
||||||
|
*internal_format_out = internal_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglBool
|
||||||
|
cogl_wayland_texture_set_region_from_shm_buffer (CoglTexture *texture,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
struct wl_shm_buffer *
|
||||||
|
shm_buffer,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int level,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
|
||||||
|
int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||||
|
CoglPixelFormat format;
|
||||||
|
int bpp;
|
||||||
|
|
||||||
|
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
|
||||||
|
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
|
||||||
|
|
||||||
|
return _cogl_texture_set_region (COGL_TEXTURE (texture),
|
||||||
|
width, height,
|
||||||
|
format,
|
||||||
|
stride,
|
||||||
|
data + src_x * bpp + src_y * stride,
|
||||||
|
dst_x, dst_y,
|
||||||
|
level,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
|
cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
|
||||||
struct wl_resource *buffer,
|
struct wl_resource *buffer,
|
||||||
@ -305,34 +374,11 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
|
|||||||
if (shm_buffer)
|
if (shm_buffer)
|
||||||
{
|
{
|
||||||
int stride = wl_shm_buffer_get_stride (shm_buffer);
|
int stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||||
CoglPixelFormat format;
|
|
||||||
CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY;
|
|
||||||
int width = wl_shm_buffer_get_width (shm_buffer);
|
int width = wl_shm_buffer_get_width (shm_buffer);
|
||||||
int height = wl_shm_buffer_get_height (shm_buffer);
|
int height = wl_shm_buffer_get_height (shm_buffer);
|
||||||
|
CoglPixelFormat format, internal_format;
|
||||||
|
|
||||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &internal_format);
|
||||||
{
|
|
||||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
|
||||||
break;
|
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
|
||||||
internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
|
||||||
break;
|
|
||||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
|
||||||
break;
|
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
|
||||||
internal_format = COGL_PIXEL_FORMAT_BGR_888;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
g_warn_if_reached ();
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cogl_texture_2d_new_from_data (ctx,
|
return cogl_texture_2d_new_from_data (ctx,
|
||||||
width, height,
|
width, height,
|
||||||
|
@ -95,6 +95,50 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
|
|||||||
struct wl_resource *buffer,
|
struct wl_resource *buffer,
|
||||||
CoglError **error);
|
CoglError **error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_wayland_texture_set_region_from_shm_buffer:
|
||||||
|
* @texture: a #CoglTexture
|
||||||
|
* @width: The width of the region to copy
|
||||||
|
* @height: The height of the region to copy
|
||||||
|
* @shm_buffer: The source buffer
|
||||||
|
* @src_x: The X offset within the source bufer to copy from
|
||||||
|
* @src_y: The Y offset within the source bufer to copy from
|
||||||
|
* @dst_x: The X offset within the texture to copy to
|
||||||
|
* @dst_y: The Y offset within the texture to copy to
|
||||||
|
* @level: The mipmap level of the texture to copy to
|
||||||
|
* @error: A #CoglError to return exceptional errors
|
||||||
|
*
|
||||||
|
* Sets the pixels in a rectangular subregion of @texture from a
|
||||||
|
* Wayland SHM buffer. Generally this would be used in response to
|
||||||
|
* wl_surface.damage event in a compositor in order to update the
|
||||||
|
* texture with the damaged region. This is just a convenience wrapper
|
||||||
|
* around getting the SHM buffer pointer and calling
|
||||||
|
* cogl_texture_set_region(). See that function for a description of
|
||||||
|
* the level parameter.
|
||||||
|
*
|
||||||
|
* <note>Since the storage for a #CoglTexture is allocated lazily then
|
||||||
|
* if the given @texture has not previously been allocated then this
|
||||||
|
* api can return %FALSE and throw an exceptional @error if there is
|
||||||
|
* not enough memory to allocate storage for @texture.</note>
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the subregion upload was successful, and
|
||||||
|
* %FALSE otherwise
|
||||||
|
* Since: 1.18
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
CoglBool
|
||||||
|
cogl_wayland_texture_set_region_from_shm_buffer (CoglTexture *texture,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
struct wl_shm_buffer *
|
||||||
|
shm_buffer,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int level,
|
||||||
|
CoglError **error);
|
||||||
|
|
||||||
COGL_END_DECLS
|
COGL_END_DECLS
|
||||||
|
|
||||||
/* The gobject introspection scanner seems to parse public headers in
|
/* The gobject introspection scanner seems to parse public headers in
|
||||||
|
@ -445,42 +445,14 @@ surface_damaged (CoglandSurface *surface,
|
|||||||
wl_shm_buffer_get (surface->buffer_ref.buffer->resource);
|
wl_shm_buffer_get (surface->buffer_ref.buffer->resource);
|
||||||
|
|
||||||
if (shm_buffer)
|
if (shm_buffer)
|
||||||
{
|
cogl_wayland_texture_set_region_from_shm_buffer (surface->texture,
|
||||||
CoglPixelFormat format;
|
x, y,
|
||||||
int stride = wl_shm_buffer_get_stride (shm_buffer);
|
width,
|
||||||
const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
|
height,
|
||||||
|
shm_buffer,
|
||||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
x, y,
|
||||||
{
|
0, /* level */
|
||||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
NULL);
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
|
||||||
break;
|
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
|
||||||
break;
|
|
||||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
|
||||||
break;
|
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
|
||||||
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
g_warn_if_reached ();
|
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
|
||||||
}
|
|
||||||
|
|
||||||
cogl_texture_set_region (surface->texture,
|
|
||||||
x, y, /* src_x/y */
|
|
||||||
x, y, /* dst_x/y */
|
|
||||||
width, height, /* dst_width/height */
|
|
||||||
width, height, /* width/height */
|
|
||||||
format,
|
|
||||||
stride,
|
|
||||||
data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cogland_queue_redraw (surface->compositor);
|
cogland_queue_redraw (surface->compositor);
|
||||||
|
Loading…
Reference in New Issue
Block a user