[RFC] Weston sprite support
Jesse Barnes
jbarnes at virtuousgeek.org
Mon Jan 9 12:32:14 PST 2012
On Fri, 6 Jan 2012 16:22:33 -0500
Kristian Høgsberg <krh at bitplanet.net> wrote:
> I'm concerned about make all of weston_output_repaint an output hook.
> There's a lot of non-trivial (at least it took me a while to get it
> right) region code in there to analyze the overlap of the surfaces to
> minimize the overdraw and to enable the incremental repaint. I think
> we can just do a different type of hook though. Maybe after
> calculating the per-surface damage, we can call into the backend,
> which can then look through the stack, decide whether and which
> surfaces should use sprites, set that up and then clear their damage.
> When the hook returns to weston_output_repaint, the repaint will then
> skip those surfaces.
>
> For that to work I think we need two changes: the wl_list_for_each
> that applies the per-surface damage (line 820) needs to move up above
> setup_scanout_surface(). In fact, I think we can roll
> setup_scanout_surface() into that hook and handle pageflipping to
> client buffers in the same hook. It's not all that different.
> Attached a patch/sketch.
So something like this is more like what you had in mind?
--
Jesse Barnes, Intel Open Source Technology Center
From 43134f5c35052e77369d13ee9a1179da26d3ca5f Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbarnes at virtuousgeek.org>
Date: Fri, 6 Jan 2012 11:24:20 -0800
Subject: [PATCH] compositor: make surface setup a special case of sprite assignment
Remove the surface prepare hook and add a new assign overlays hook.
This lets back ends do more sophisticated surface management.
---
src/compositor-drm.c | 46 ++++++++++++++++++++++++++++++++++++++--
src/compositor-wayland.c | 9 --------
src/compositor-x11.c | 9 --------
src/compositor.c | 52 ++++++++++++++++++++-------------------------
src/compositor.h | 6 ++--
5 files changed, 69 insertions(+), 53 deletions(-)
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 433c644..61108fe 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -78,6 +78,19 @@ struct drm_output {
uint32_t pending_fs_surf_fb_id;
};
+/*
+ * An output has a primary display plane plus zero or more sprites for
+ * blending display contents.
+ */
+struct drm_output_sprite {
+ uint32_t fb_id;
+
+ int32_t src_x, src_y;
+ uint32_t src_w, src_h;
+ uint32_t dest_x, dest_y;
+ uint32_t dest_w, dest_h;
+};
+
static int
drm_output_prepare_render(struct weston_output *output_base)
{
@@ -188,6 +201,35 @@ drm_output_prepare_scanout_surface(struct weston_output *output_base,
}
static int
+drm_assign_overlays(struct weston_output *output)
+{
+ struct weston_compositor *ec = output->compositor;
+ struct weston_surface *es;
+
+ es = container_of(ec->surface_list.next, struct weston_surface, link);
+
+ if (es->visual == WESTON_RGB_VISUAL) {
+ if (!drm_output_prepare_scanout_surface(output, es))
+ weston_queue_scanout_surface(output, es);
+ }
+
+ /*
+ * Find a surface for each sprite in the output using some heuristics:
+ * 1) size
+ * 2) frequency of update
+ * 3) opacity (though some hw might support alpha blending)
+ * 4) clipping (this can be fixed with color keys)
+ *
+ * The idea is to save on blitting since this should save power.
+ * If we can get a large video surface on the sprite for example,
+ * the main display surface may not need to update at all, and
+ * the client buffer can be used directly for the sprite surface
+ * as we do for flipping full screen surfaces.
+ */
+ return 0;
+}
+
+static int
drm_output_set_cursor(struct weston_output *output_base,
struct weston_input_device *eid)
{
@@ -548,11 +590,9 @@ create_output_for_connector(struct drm_compositor *ec,
wl_list_insert(ec->base.output_list.prev, &output->base.link);
output->pending_fs_surf_fb_id = 0;
- output->base.repaint = weston_output_repaint;
+ output->base.assign_overlays = drm_assign_overlays;
output->base.prepare_render = drm_output_prepare_render;
output->base.present = drm_output_present;
- output->base.prepare_scanout_surface =
- drm_output_prepare_scanout_surface;
output->base.set_hardware_cursor = drm_output_set_cursor;
output->base.destroy = drm_output_destroy;
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 4966017..a80670d 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -207,13 +207,6 @@ wayland_output_present(struct weston_output *output_base)
}
static int
-wayland_output_prepare_scanout_surface(struct weston_output *output_base,
- struct weston_surface *es)
-{
- return -1;
-}
-
-static int
wayland_output_set_cursor(struct weston_output *output_base,
struct weston_input_device *input)
{
@@ -293,8 +286,6 @@ wayland_compositor_create_output(struct wayland_compositor *c,
output->base.repaint = weston_output_repaint;
output->base.prepare_render = wayland_output_prepare_render;
output->base.present = wayland_output_present;
- output->base.prepare_scanout_surface =
- wayland_output_prepare_scanout_surface;
output->base.set_hardware_cursor = wayland_output_set_cursor;
output->base.destroy = wayland_output_destroy;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 1b23e83..d4850c8 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -231,13 +231,6 @@ x11_output_present(struct weston_output *output_base)
}
static int
-x11_output_prepare_scanout_surface(struct weston_output *output_base,
- struct weston_surface *es)
-{
- return -1;
-}
-
-static int
x11_output_set_cursor(struct weston_output *output_base,
struct weston_input_device *input)
{
@@ -464,8 +457,6 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
output->base.repaint = weston_output_repaint;
output->base.prepare_render = x11_output_prepare_render;
output->base.present = x11_output_present;
- output->base.prepare_scanout_surface =
- x11_output_prepare_scanout_surface;
output->base.set_hardware_cursor = x11_output_set_cursor;
output->base.destroy = x11_output_destroy;
diff --git a/src/compositor.c b/src/compositor.c
index 7c41123..8a12748 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -733,13 +733,10 @@ out:
pixman_region32_fini(&cursor_region);
}
-static int
-setup_scanout_surface(struct weston_output *output, struct weston_surface *es)
+WL_EXPORT int
+weston_queue_scanout_surface(struct weston_output *output,
+ struct weston_surface *es)
{
- if (es->visual != WESTON_RGB_VISUAL ||
- output->prepare_scanout_surface(output, es) != 0)
- return -1;
-
/* assert output->pending_scanout_buffer == NULL */
output->pending_scanout_buffer = es->buffer;
output->pending_scanout_buffer->busy_count++;
@@ -789,30 +786,27 @@ weston_output_repaint(struct weston_output *output)
es = container_of(ec->surface_list.next, struct weston_surface, link);
- if (setup_scanout_surface(output, es) == 0)
- /* We're drawing nothing, just let the damage accumulate */
- return;
-
- if (es->fullscreen_output == output) {
- if (es->width < output->current->width ||
- es->height < output->current->height)
- glClear(GL_COLOR_BUFFER_BIT);
- weston_surface_draw(es, output, &total_damage);
- } else {
- wl_list_for_each(es, &ec->surface_list, link) {
- pixman_region32_copy(&es->damage, &total_damage);
- pixman_region32_subtract(&total_damage, &total_damage, &es->opaque);
- }
+ wl_list_for_each(es, &ec->surface_list, link) {
+ pixman_region32_copy(&es->damage, &total_damage);
+ pixman_region32_subtract(&total_damage, &total_damage,
+ &es->opaque);
+ }
- wl_list_for_each_reverse(es, &ec->surface_list, link) {
- pixman_region32_init(&repaint);
- pixman_region32_intersect(&repaint, &output->region,
- &es->damage);
- weston_surface_draw(es, output, &repaint);
- pixman_region32_subtract(&es->damage,
- &es->damage, &output->region);
- pixman_region32_fini(&repaint);
- }
+ if (output->assign_overlays)
+ /* This will queue flips for the fbs and sprites where
+ * applicable and clear the damage for those surfaces.
+ * The repaint loop below will repaint everything
+ * else. */
+ output->assign_overlays(output);
+
+ wl_list_for_each_reverse(es, &ec->surface_list, link) {
+ pixman_region32_init(&repaint);
+ pixman_region32_intersect(&repaint, &output->region,
+ &es->damage);
+ weston_surface_draw(es, output, &repaint);
+ pixman_region32_subtract(&es->damage,
+ &es->damage, &output->region);
+ pixman_region32_fini(&repaint);
}
if (ec->fade.spring.current > 0.001)
diff --git a/src/compositor.h b/src/compositor.h
index 5608899..d8cd375 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -90,8 +90,7 @@ struct weston_output {
void (*repaint)(struct weston_output *output);
int (*prepare_render)(struct weston_output *output);
int (*present)(struct weston_output *output);
- int (*prepare_scanout_surface)(struct weston_output *output,
- struct weston_surface *es);
+ int (*assign_overlays)(struct weston_output *output);
int (*set_hardware_cursor)(struct weston_output *output,
struct weston_input_device *input);
void (*destroy)(struct weston_output *output);
@@ -492,5 +491,6 @@ typedef void (*weston_zoom_done_func_t)(struct weston_zoom *zoom, void *data);
struct weston_zoom *
weston_zoom_run(struct weston_surface *surface, GLfloat start, GLfloat stop,
weston_zoom_done_func_t done, void *data);
-
+int weston_queue_scanout_surface(struct weston_output *output,
+ struct weston_surface *es);
#endif
--
1.7.4.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20120109/bbc1121f/attachment.pgp>
More information about the wayland-devel
mailing list