mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 00:50:42 -05:00
MetaRendererNative: Flush all pending swap notifies on idle
We need to do swap notifications asynchronously from flip events since these might be processed during swap buffers if we are waiting for the previous frame's flip to continue with the current. This means that we might have more than one swap notification queued to be delivered when the idle handler runs. In that case we must deliver all notifications for which we've already seen a flip event. Failing to do so means that if a new frame, that only swaps buffers on such a swap notification backlogged Onscreen, is started, when later we get its flip event, we'd notify only an old frame which would hit this MetaStageNative's frame_cb() early exit: if (global_frame_counter <= presented_frame_counter) return; and we'd never finish the new frame and thus clutter's master clock would be waiting forever stuck. https://bugzilla.gnome.org/show_bug.cgi?id=774557
This commit is contained in:
parent
a943c0fc12
commit
497a94fac7
@ -73,6 +73,9 @@ typedef struct _MetaOnscreenNative
|
|||||||
|
|
||||||
gboolean pending_set_crtc;
|
gboolean pending_set_crtc;
|
||||||
|
|
||||||
|
int64_t pending_queue_swap_notify_frame_count;
|
||||||
|
int64_t pending_swap_notify_frame_count;
|
||||||
|
|
||||||
MetaRendererView *view;
|
MetaRendererView *view;
|
||||||
int pending_flips;
|
int pending_flips;
|
||||||
} MetaOnscreenNative;
|
} MetaOnscreenNative;
|
||||||
@ -124,16 +127,19 @@ flush_pending_swap_notify (CoglFramebuffer *framebuffer)
|
|||||||
|
|
||||||
if (onscreen_native->pending_swap_notify)
|
if (onscreen_native->pending_swap_notify)
|
||||||
{
|
{
|
||||||
CoglFrameInfo *info =
|
CoglFrameInfo *info;
|
||||||
g_queue_pop_head (&onscreen->pending_frame_infos);
|
|
||||||
|
|
||||||
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
while ((info = g_queue_peek_head (&onscreen->pending_frame_infos)) &&
|
||||||
_cogl_onscreen_notify_complete (onscreen, info);
|
info->global_frame_counter <= onscreen_native->pending_swap_notify_frame_count)
|
||||||
|
{
|
||||||
|
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
||||||
|
_cogl_onscreen_notify_complete (onscreen, info);
|
||||||
|
cogl_object_unref (info);
|
||||||
|
g_queue_pop_head (&onscreen->pending_frame_infos);
|
||||||
|
}
|
||||||
|
|
||||||
onscreen_native->pending_swap_notify = FALSE;
|
onscreen_native->pending_swap_notify = FALSE;
|
||||||
cogl_object_unref (onscreen);
|
cogl_object_unref (onscreen);
|
||||||
|
|
||||||
cogl_object_unref (info);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,6 +206,9 @@ meta_onscreen_native_queue_swap_notify (CoglOnscreen *onscreen)
|
|||||||
CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
|
CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
|
||||||
MetaRendererNative *renderer_native = egl_renderer->platform;
|
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||||
|
|
||||||
|
onscreen_native->pending_swap_notify_frame_count =
|
||||||
|
onscreen_native->pending_queue_swap_notify_frame_count;
|
||||||
|
|
||||||
/* We only want to notify that the swap is complete when the
|
/* We only want to notify that the swap is complete when the
|
||||||
* application calls cogl_context_dispatch so instead of
|
* application calls cogl_context_dispatch so instead of
|
||||||
* immediately notifying we queue an idle callback */
|
* immediately notifying we queue an idle callback */
|
||||||
@ -640,6 +649,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
onscreen_native->pending_set_crtc = FALSE;
|
onscreen_native->pending_set_crtc = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter;
|
||||||
meta_onscreen_native_flip_crtcs (onscreen);
|
meta_onscreen_native_flip_crtcs (onscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user