diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h index 21f0d241a..94310c545 100644 --- a/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl-framebuffer-private.h @@ -170,6 +170,10 @@ struct _CoglFramebuffer int clear_clip_y1; CoglBool clear_clip_dirty; + /* Whether something has been drawn to the buffer since the last + * swap buffers or swap region. */ + CoglBool mid_scene; + /* driver specific */ CoglBool dirty_bitmasks; CoglFramebufferBits bits; diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index 740154a89..d65823503 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -236,6 +236,7 @@ void _cogl_framebuffer_mark_mid_scene (CoglFramebuffer *framebuffer) { framebuffer->clear_clip_dirty = TRUE; + framebuffer->mid_scene = TRUE; } void @@ -398,6 +399,8 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, cleared: + _cogl_framebuffer_mark_mid_scene (framebuffer); + if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH) { /* For our fast-path for reading back a single pixel of simple @@ -425,8 +428,6 @@ cleared: /* FIXME: set degenerate clip */ } } - else - _cogl_framebuffer_mark_mid_scene (framebuffer); } /* Note: the 'buffers' and 'color' arguments were switched around on diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c index 5adba2fd8..763b619e6 100644 --- a/cogl/cogl-journal.c +++ b/cogl/cogl-journal.c @@ -1455,6 +1455,12 @@ _cogl_journal_log_quad (CoglJournal *journal, COGL_TIMER_START (_cogl_uprof_context, log_timer); + /* Adding something to the journal should mean that we are in the + * middle of the scene. Although this will also end up being set + * when the journal is actually flushed, we set it here explicitly + * so that we will know sooner */ + _cogl_framebuffer_mark_mid_scene (framebuffer); + /* If the framebuffer was previously empty then we'll take a reference to the current framebuffer. This reference will be removed when the journal is flushed */ diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c index ab898fbed..e0546b128 100644 --- a/cogl/cogl-onscreen.c +++ b/cogl/cogl-onscreen.c @@ -205,6 +205,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, } onscreen->frame_counter++; + framebuffer->mid_scene = FALSE; } void @@ -261,6 +262,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, } onscreen->frame_counter++; + framebuffer->mid_scene = FALSE; } int diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h index 23a69e36b..6ce1f5140 100644 --- a/cogl/cogl-onscreen.h +++ b/cogl/cogl-onscreen.h @@ -212,12 +212,12 @@ cogl_wayland_onscreen_set_foreign_surface (CoglOnscreen *onscreen, * @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 + * @offset_y: A relative y 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. + * Resizes the backbuffer of the given @onscreen framebuffer to the + * given size. 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 @@ -228,9 +228,14 @@ cogl_wayland_onscreen_set_foreign_surface (CoglOnscreen *onscreen, * 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. + * Note that if some drawing commands have been applied to the + * framebuffer since the last swap buffers then the resize will be + * queued and will only take effect in the next swap buffers. + * + * If multiple calls to cogl_wayland_onscreen_resize() get queued + * 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 diff --git a/cogl/winsys/cogl-winsys-egl-wayland.c b/cogl/winsys/cogl-winsys-egl-wayland.c index 62d449c52..50075500e 100644 --- a/cogl/winsys/cogl-winsys-egl-wayland.c +++ b/cogl/winsys/cogl-winsys-egl-wayland.c @@ -420,15 +420,8 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen) } static void -_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles) +flush_pending_resize (CoglOnscreen *onscreen) { - 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; @@ -440,11 +433,28 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, wayland_onscreen->pending_dx, wayland_onscreen->pending_dy); - _cogl_framebuffer_winsys_update_size (fb, + _cogl_framebuffer_winsys_update_size (COGL_FRAMEBUFFER (onscreen), wayland_onscreen->pending_width, wayland_onscreen->pending_height); + + wayland_onscreen->pending_dx = 0; + wayland_onscreen->pending_dy = 0; wayland_onscreen->has_pending = FALSE; } +} + +static void +_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles) +{ + 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; + + flush_pending_resize (onscreen); parent_vtable->onscreen_swap_buffers_with_damage (onscreen, rectangles, @@ -641,6 +651,15 @@ cogl_wayland_onscreen_resize (CoglOnscreen *onscreen, wayland_onscreen->pending_dx += offset_x; wayland_onscreen->pending_dy += offset_y; wayland_onscreen->has_pending = TRUE; + + /* If nothing has been drawn to the framebuffer since the + * last swap then wl_egl_window_resize will take effect + * immediately. Otherwise it might not take effect until the + * next swap, depending on the version of Mesa. To keep + * consistent behaviour we'll delay the resize until the + * next swap unless we're sure nothing has been drawn */ + if (!fb->mid_scene) + flush_pending_resize (onscreen); } } else