[cogl] wayland: Add a convenience function to update a region from SHM buffer



commit c76c1d136d2cac7f3d1331a4d1dc0dd0f06e812c
Author: Neil Roberts <neil linux intel com>
Date:   Mon Nov 25 17:04:16 2013 +0000

    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>

 cogl/cogl-texture-2d.c     |   96 ++++++++++++++++++++++++++++++++-----------
 cogl/cogl-wayland-server.h |   44 ++++++++++++++++++++
 examples/cogland.c         |   44 ++++----------------
 3 files changed, 123 insertions(+), 61 deletions(-)
---
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 835254e..a238097 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -293,6 +293,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,
@@ -305,34 +374,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 26b30dc..a28f6a3 100644
--- a/cogl/cogl-wayland-server.h
+++ b/cogl/cogl-wayland-server.h
@@ -88,6 +88,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 eb23e78..f208211 100644
--- a/examples/cogland.c
+++ b/examples/cogland.c
@@ -445,42 +445,14 @@ surface_damaged (CoglandSurface *surface,
         wl_shm_buffer_get (surface->buffer_ref.buffer->resource);
 
       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 (surface->texture,
-                                   width, height,
-                                   format,
-                                   stride,
-                                   data + x * 4 + y * stride,
-                                   x, y, /* dst_x/y */
-                                   0, /* level */
-                                   NULL /* error */);
-        }
+        cogl_wayland_texture_set_region_from_shm_buffer (surface->texture,
+                                                         x, y,
+                                                         width,
+                                                         height,
+                                                         shm_buffer,
+                                                         x, y,
+                                                         0, /* level */
+                                                         NULL);
     }
 
   cogland_queue_redraw (surface->compositor);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]