[PATCH weston 1/7] compositor: add surface-shooting API

Pekka Paalanen ppaalanen at gmail.com
Fri Feb 13 02:02:19 PST 2015


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

This is an optional API that will be implemented by the renderers. It
allows to fetch the current contents of a surface, essentially the
buffer contents from a client buffer, converted to an RGBA format.

This is meant as a debugging API. The implementations may be heavy and
cause a stall, so they are not intended to be used often during normal
operations.

Renderers are expected to convert whatever data a surface has to a
single RGBA format.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 src/compositor.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/compositor.h |  23 +++++++++++
 2 files changed, 142 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index c2c975d..b56d2d5 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2012-2014 Collabora, Ltd.
+ * Copyright © 2012-2015 Collabora, Ltd.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
@@ -2882,6 +2882,124 @@ weston_surface_set_label_func(struct weston_surface *surface,
 	surface->timeline.force_refresh = 1;
 }
 
+/** Get the size of surface contents
+ *
+ * \param surface The surface to query.
+ * \param width Returns the width of raw contents.
+ * \param height Returns the height of raw contents.
+ *
+ * Retrieves the raw surface content size in pixels for the given surface.
+ * This is the whole content size in buffer pixels. If the surface
+ * has no content or the renderer does not implement this feature,
+ * zeroes are returned.
+ *
+ * This function is used to determine the buffer size needed for
+ * a weston_surface_copy_content() call.
+ */
+WL_EXPORT void
+weston_surface_get_content_size(struct weston_surface *surface,
+				int *width, int *height)
+{
+	struct weston_renderer *rer = surface->compositor->renderer;
+
+	if (!rer->surface_get_content_size) {
+		*width = 0;
+		*height = 0;
+		return;
+	}
+
+	rer->surface_get_content_size(surface, width, height);
+}
+
+/** Copy surface contents to system memory.
+ *
+ * \param surface The surface to copy from.
+ * \param target Pointer to the target memory buffer.
+ * \param stride Stride of the target buffer in bytes.
+ * \param size Size of the target buffer in bytes.
+ * \param src_x X location on contents to copy from.
+ * \param src_y Y location on contents to copy from.
+ * \param width Width in pixels of the area to copy.
+ * \param height Height in pixels of the area to copy.
+ * \param format The pixel format for the data to be
+ * written into target.
+ * \return 0 for success, -1 for failure.
+ *
+ * Surface contents are maintained by the renderer. They can be in a
+ * reserved weston_buffer or as a copy, e.g. a GL texture, or something
+ * else.
+ *
+ * Surface contents are copied into memory pointed to by target.
+ * The target memory layout is described by stride and size. Each
+ * copied pixel row will be stride bytes apart. The target memory
+ * may be larger than needed, but being smaller returns an error.
+ * The extra bytes in target, as a whole or per row, may or may not
+ * be written; their contents is unspecified.
+ *
+ * The image in the target memory will be arranged in rows from
+ * top to bottom, and pixels on a row from left to right.
+ *
+ * Parameters src_x and src_y define the upper-left corner in buffer
+ * coordinates (pixels) to copy from. Parameters width and height
+ * define the size of the area to copy in pixels. Parameter format
+ * defines the pixel format in the target memory.
+ *
+ * It is an error to provide inconsistent arguments. Size must be
+ * at least stride times height. Stride must be at least width times
+ * the bytes per pixel defined by format.
+ *
+ * The rectangle defined by src_x, src_y, width, height must fit in
+ * the surface contents. Otherwise an error is returned.
+ *
+ * Use surface_get_data_size to determine the content size; the
+ * needed target buffer size and rectangle limits.
+ *
+ * CURRENT IMPLEMENTATION RESTRICTIONS:
+ * - format must be PIXMAN_a8b8g8r8 (GL_RGBA, GL_UNSIGNED_BYTE).
+ * - the machine must be little-endian due to Pixman formats.
+ *
+ * NOTE: Pixman formats are premultiplied.
+ */
+WL_EXPORT int
+weston_surface_copy_content(struct weston_surface *surface,
+			    void *target, size_t stride, size_t size,
+			    int src_x, int src_y,
+			    int width, int height,
+			    pixman_format_code_t format)
+{
+	struct weston_renderer *rer = surface->compositor->renderer;
+	int cw, ch;
+	size_t bytespp;
+
+	if (!rer->surface_copy_content)
+		return -1;
+
+	weston_surface_get_content_size(surface, &cw, &ch);
+
+	if (src_x < 0 || src_y < 0)
+		return -1;
+
+	if (width <= 0 || height <= 0)
+		return -1;
+
+	if (src_x + width > cw || src_y + height > ch)
+		return -1;
+
+	switch (format) {
+	case PIXMAN_a8b8g8r8:
+		bytespp = 4;
+		break;
+	default:
+		return -1;
+	}
+
+	if (width * bytespp > stride || stride * height > size)
+		return -1;
+
+	return rer->surface_copy_content(surface, target, stride, size,
+					 src_x, src_y, width, height, format);
+}
+
 static void
 subsurface_set_position(struct wl_client *client,
 			struct wl_resource *resource, int32_t x, int32_t y)
diff --git a/src/compositor.h b/src/compositor.h
index 5c0ea74..16e85b6 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -571,6 +571,18 @@ struct weston_renderer {
 			       float red, float green,
 			       float blue, float alpha);
 	void (*destroy)(struct weston_compositor *ec);
+
+
+	/** See weston_surface_get_content_size() */
+	void (*surface_get_content_size)(struct weston_surface *surface,
+					 int *width, int *height);
+
+	/** See weston_surface_copy_content() */
+	int (*surface_copy_content)(struct weston_surface *surface,
+				    void *target, size_t stride, size_t size,
+				    int src_x, int src_y,
+				    int width, int height,
+				    pixman_format_code_t format);
 };
 
 enum weston_capability {
@@ -1262,6 +1274,17 @@ weston_surface_set_label_func(struct weston_surface *surface,
 			      int (*desc)(struct weston_surface *,
 					  char *, size_t));
 
+void
+weston_surface_get_content_size(struct weston_surface *surface,
+				int *width, int *height);
+
+int
+weston_surface_copy_content(struct weston_surface *surface,
+			    void *target, size_t stride, size_t size,
+			    int src_x, int src_y,
+			    int width, int height,
+			    pixman_format_code_t format);
+
 struct weston_buffer *
 weston_buffer_from_resource(struct wl_resource *resource);
 
-- 
2.0.5



More information about the wayland-devel mailing list