[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