From: Pekka Paalanen <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
