wayland: perform buffer resizes lazily at swap buffers

Resizing a wayland client framebuffer should not affect the viewport
of additional primitives drawn to that framebuffer before the next swap
buffers request nor should querying the framebuffer's width and height
be affected until the next swap buffers request completes.

This patch changes cogl_wayland_onscreen_resize() so it only saves the
new geometry as "pending" state internal to the given CoglOnscreen. Only
when cogl_framebuffer_swap_buffers() is next called will the pending
size be flushed to the wayland egl api.
This commit is contained in:
Robert Bragg 2012-01-16 12:30:06 +00:00
parent e1bd0b2090
commit 87ce1b21f9
2 changed files with 70 additions and 8 deletions

View File

@ -185,6 +185,35 @@ cogl_wayland_onscreen_get_surface (CoglOnscreen *onscreen);
struct wl_shell_surface *
cogl_wayland_onscreen_get_shell_surface (CoglOnscreen *onscreen);
/**
* cogl_wayland_onscreen_resize:
* @onscreen: A #CoglOnscreen framebuffer
* @width: The desired width of the framebuffer
* @height: The desired height of the framebuffer
* @offset_x: A relative x offset for the new framebuffer
* @offset_y: A relative x offset for the new framebuffer
*
* Queues a resize of the given @onscreen framebuffer which will be applied
* during the next swap buffers request. Since a buffer is usually conceptually
* scaled with a center point the @offset_x and @offset_y arguments allow the
* newly allocated buffer to be positioned relative to the old buffer size.
*
* For example a buffer that is being resized by moving the bottom right
* corner, and the top left corner is remaining static would use x and y
* offsets of (0, 0) since the top-left of the new buffer should have the same
* position as the old buffer. If the center of the old buffer is being zoomed
* into then all the corners of the new buffer move out from the center and the x
* and y offsets would be (-half_x_size_increase, -half_y_size_increase) where
* x/y_size_increase is how many pixels bigger the buffer is on the x and y
* axis.
*
* If cogl_wayland_onscreen_resize() is called multiple times before the next
* swap buffers request then the relative x and y offsets accumulate instead of
* being replaced. The @width and @height values superseed the old values.
*
* Since: 1.10
* Stability: unstable
*/
void
cogl_wayland_onscreen_resize (CoglOnscreen *onscreen,
int width,

View File

@ -60,6 +60,15 @@ typedef struct _CoglOnscreenWayland
struct wl_egl_window *wayland_egl_native_window;
struct wl_surface *wayland_surface;
struct wl_shell_surface *wayland_shell_surface;
/* Resizing a wayland framebuffer doesn't take affect
* until the next swap buffers request, so we have to
* track the resize geometry until then... */
int pending_width;
int pending_height;
int pending_dx;
int pending_dy;
gboolean has_pending;
} CoglOnscreenWayland;
static void
@ -363,12 +372,29 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
static void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = fb->context;
CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglOnscreenWayland *wayland_onscreen = egl_onscreen->platform;
/* First chain-up */
if (wayland_onscreen->has_pending)
{
wl_egl_window_resize (wayland_onscreen->wayland_egl_native_window,
wayland_onscreen->pending_width,
wayland_onscreen->pending_height,
wayland_onscreen->pending_dx,
wayland_onscreen->pending_dy);
_cogl_framebuffer_winsys_update_size (fb,
wayland_onscreen->pending_width,
wayland_onscreen->pending_height);
wayland_onscreen->has_pending = FALSE;
}
/* chain-up */
parent_vtable->onscreen_swap_buffers (onscreen);
/*
@ -514,13 +540,20 @@ cogl_wayland_onscreen_resize (CoglOnscreen *onscreen,
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglOnscreenWayland *wayland_onscreen = egl_onscreen->platform;
wl_egl_window_resize (wayland_onscreen->wayland_egl_native_window,
width,
height,
offset_x,
offset_y);
_cogl_framebuffer_winsys_update_size (fb, width, height);
if (cogl_framebuffer_get_width (fb) != width ||
cogl_framebuffer_get_height (fb) != height ||
offset_x ||
offset_y)
{
wayland_onscreen->pending_width = width;
wayland_onscreen->pending_height = height;
wayland_onscreen->pending_dx += offset_x;
wayland_onscreen->pending_dy += offset_y;
wayland_onscreen->has_pending = TRUE;
}
}
else
_cogl_framebuffer_winsys_update_size (fb, width, height);
}
static const CoglWinsysEGLVtable