summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2013-11-25 17:04:16 +0000
committerNeil Roberts <neil@linux.intel.com>2013-11-28 13:51:49 +0000
commitc76c1d136d2cac7f3d1331a4d1dc0dd0f06e812c (patch)
tree825222d06729600326c8b54fc560d0467a1dfba6
parentd94cb984e3c93630f3c2e6e3be9d189672aa20f3 (diff)
downloadcogl-c76c1d136d2cac7f3d1331a4d1dc0dd0f06e812c.tar.gz
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>
-rw-r--r--cogl/cogl-texture-2d.c96
-rw-r--r--cogl/cogl-wayland-server.h44
-rw-r--r--examples/cogland.c44
3 files changed, 123 insertions, 61 deletions
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 835254ec..a238097a 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 26b30dc8..a28f6a35 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 eb23e784..f2082110 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);