compositor: add surface-shooting API
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@collabora.co.uk> v1 Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
+102
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2010-2011 Intel Corporation
|
* Copyright © 2010-2011 Intel Corporation
|
||||||
* Copyright © 2008-2011 Kristian Høgsberg
|
* 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
|
* Permission to use, copy, modify, distribute, and sell this software and
|
||||||
* its documentation for any purpose is hereby granted without fee, provided
|
* 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;
|
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
|
static void
|
||||||
subsurface_set_position(struct wl_client *client,
|
subsurface_set_position(struct wl_client *client,
|
||||||
struct wl_resource *resource, int32_t x, int32_t y)
|
struct wl_resource *resource, int32_t x, int32_t y)
|
||||||
|
|||||||
@@ -571,6 +571,17 @@ struct weston_renderer {
|
|||||||
float red, float green,
|
float red, float green,
|
||||||
float blue, float alpha);
|
float blue, float alpha);
|
||||||
void (*destroy)(struct weston_compositor *ec);
|
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 {
|
enum weston_capability {
|
||||||
@@ -1262,6 +1273,16 @@ weston_surface_set_label_func(struct weston_surface *surface,
|
|||||||
int (*desc)(struct weston_surface *,
|
int (*desc)(struct weston_surface *,
|
||||||
char *, size_t));
|
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 *
|
struct weston_buffer *
|
||||||
weston_buffer_from_resource(struct wl_resource *resource);
|
weston_buffer_from_resource(struct wl_resource *resource);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user