[Cogl] [PATCH] wayland: Add a convenience function to update a region from SHM buffer
Robert Bragg
robert at sixbynine.org
Wed Nov 27 11:43:39 PST 2013
This patch looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
Robert
On Mon, Nov 25, 2013 at 5:04 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Here is a proposed replacement for the following patch which was
> pushed onto the 1.18 branch without first going through the master
> branch. If we go with this patch then we can revert the patch on the
> 1.18 branch and cherry-pick this one from master.
>
> https://git.gnome.org/browse/cogl/commit/?id=af480a2b8b5450148ca4b9
>
> The changes from that patch are that it is no longer specific to
> CoglTexture2D and its arguments more closely match those from
> cogl_texture_set_region on the master branch. This includes a
> parameter for the mipmap level and separate arguments for the src and
> dst offsets. It also includes a patch to cogland to take advantage of
> the function.
>
> ------- >8 --------------- (use git am --scissors to automatically chop here)
>
> 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.
> ---
> cogl/cogl-texture-2d.c | 96 ++++++++++++++++++++++++++++++++++------------
> cogl/cogl-wayland-server.h | 44 +++++++++++++++++++++
> examples/cogland.c | 44 +++++----------------
> 3 files changed, 125 insertions(+), 59 deletions(-)
>
> diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
> index 07a9a3c..5023378 100644
> --- a/cogl/cogl-texture-2d.c
> +++ b/cogl/cogl-texture-2d.c
> @@ -292,6 +292,75 @@ _cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
> #endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
>
> #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 *
> cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
> struct wl_resource *buffer,
> @@ -304,34 +373,11 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
> if (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 height = wl_shm_buffer_get_height (shm_buffer);
> + CoglPixelFormat format, internal_format;
>
> - 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;
> - }
> + shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &internal_format);
>
> return cogl_texture_2d_new_from_data (ctx,
> width, height,
> diff --git a/cogl/cogl-wayland-server.h b/cogl/cogl-wayland-server.h
> index e56f5bd..9eded9b 100644
> --- a/cogl/cogl-wayland-server.h
> +++ b/cogl/cogl-wayland-server.h
> @@ -79,6 +79,50 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
> struct wl_resource *buffer,
> 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
>
> #endif /* __COGL_WAYLAND_SERVER_H */
> diff --git a/examples/cogland.c b/examples/cogland.c
> index 82876c2..819605e 100644
> --- a/examples/cogland.c
> +++ b/examples/cogland.c
> @@ -447,40 +447,16 @@ surface_damaged (CoglandSurface *surface,
>
> if (shm_buffer)
> {
> - CoglPixelFormat format;
> - int stride = wl_shm_buffer_get_stride (shm_buffer);
> - const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
> -
> - 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;
> - 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 (COGL_TEXTURE (surface->texture),
> - width, height,
> - format,
> - stride,
> - data + x * 4 + y * stride,
> - x, y, /* dst_x/y */
> - 0, /* level */
> - NULL /* error */);
> + CoglTexture *texture = COGL_TEXTURE (surface->texture);
> +
> + cogl_wayland_texture_set_region_from_shm_buffer (texture,
> + x, y,
> + width,
> + height,
> + shm_buffer,
> + x, y,
> + 0, /* level */
> + NULL);
> }
> }
>
> --
> 1.8.3.1
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list