swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 627e6427e56fa864a3228003e1b81dc2176c760e
parent fed8a9ccaf1302dff8b49c556c816ccc6738006f
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 17 Jan 2014 19:22:23 -0800

compositor: Add shm buffer support

Diffstat:
Mlibswc/compositor.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -9,6 +9,7 @@ #include "region.h" #include "screen.h" #include "seat.h" +#include "shm.h" #include "surface.h" #include "util.h" #include "view.h" @@ -35,6 +36,7 @@ struct view struct wl_listener event_listener; struct swc_compositor * compositor; struct swc_surface * surface; + struct wld_buffer * wld; /* The box that the surface covers (including it's border). */ pixman_box32_t extents; @@ -230,7 +232,7 @@ static void repaint_view(struct render_target * target, struct view * view, if (pixman_region32_not_empty(&view_damage)) { pixman_region32_translate(&view_damage, -geometry->x, -geometry->y); - wld_copy_region(swc.drm->renderer, view->base.buffer->wld, + wld_copy_region(swc.drm->renderer, view->wld, geometry->x - target->geometry->x, geometry->y - target->geometry->y, &view_damage); } @@ -282,11 +284,62 @@ static void renderer_repaint(struct render_target * target, static bool renderer_attach(struct view * view, struct swc_buffer * buffer) { + struct wld_buffer * wld; + bool was_proxy = view->base.buffer && view->wld != view->base.buffer->wld; + bool needs_proxy = buffer + && !(wld_capabilities(swc.drm->renderer, + buffer->wld) & WLD_CAPABILITY_READ); + bool resized = view->wld && buffer + && (view->wld->width != buffer->wld->width + || view->wld->height != buffer->wld->height); + + if (buffer) + { + /* Create a proxy buffer if necessary (for example a hardware buffer + * backing a SHM buffer). */ + if (needs_proxy) + { + if (!was_proxy || resized) + { + DEBUG("Creating a proxy buffer\n"); + wld = wld_create_buffer(swc.drm->context, + buffer->wld->width, buffer->wld->height, + buffer->wld->format); + + if (!wld) + return false; + } + else + { + /* Otherwise we can keep the original proxy buffer. */ + wld = view->wld; + } + } + else + wld = buffer->wld; + } + else + wld = NULL; + + /* If we no longer need a proxy buffer, or the original buffer is of a + * different size, destroy the old proxy image. */ + if (view->wld && ((!needs_proxy && was_proxy) || (needs_proxy && resized))) + wld_destroy_buffer(view->wld); + + view->wld = wld; + return true; } static void renderer_flush_view(struct view * view) { + if (view->wld == view->base.buffer->wld) + return; + + wld_set_target_buffer(swc.shm->renderer, view->wld); + wld_copy_region(swc.shm->renderer, view->base.buffer->wld, + 0, 0, &view->surface->state.damage); + wld_flush(swc.shm->renderer); } /* }}} */ @@ -447,6 +500,7 @@ bool swc_compositor_add_surface(struct swc_compositor * compositor, wl_signal_add(&view->base.event_signal, &view->event_listener); view->compositor = compositor; view->surface = surface; + view->wld = NULL; view->extents.x1 = 0; view->extents.y1 = 0; view->extents.x2 = 0;