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

Pekka Paalanen ppaalanen at gmail.com
Wed Feb 25 03:05:57 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.

Changes in v2:
- remove stride and format arguments from the API

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
v1 Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp>
---
 src/compositor.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/compositor.h |  21 ++++++++++++
 2 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index 0cb140e..b22c5d0 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
@@ -2903,6 +2903,107 @@ 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 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.
+ * \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,
+ * which has size bytes of space available. The target memory
+ * may be larger than needed, but being smaller returns an error.
+ * The extra bytes in target may or may not be written; their content is
+ * unspecified. Size must be large enough to hold the image.
+ *
+ * The image in the target memory will be arranged in rows from
+ * top to bottom, and pixels on a row from left to right. The pixel
+ * format is PIXMAN_a8b8g8r8, 4 bytes per pixel, and stride is exactly
+ * width * 4.
+ *
+ * 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.
+ *
+ * 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:
+ * - 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 size,
+			    int src_x, int src_y,
+			    int width, int height)
+{
+	struct weston_renderer *rer = surface->compositor->renderer;
+	int cw, ch;
+	const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
+
+	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;
+
+	if (width * bytespp * height > size)
+		return -1;
+
+	return rer->surface_copy_content(surface, target, size,
+					 src_x, src_y, width, height);
+}
+
 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 e356e33..2d70ad1 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -571,6 +571,17 @@ 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 size,
+				    int src_x, int src_y,
+				    int width, int height);
 };
 
 enum weston_capability {
@@ -1262,6 +1273,16 @@ 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 size,
+			    int src_x, int src_y,
+			    int width, int height);
+
 struct weston_buffer *
 weston_buffer_from_resource(struct wl_resource *resource);
 
-- 
2.0.5



More information about the wayland-devel mailing list