Commit 4abb728f authored by Daniel van Vugt's avatar Daniel van Vugt

renderer-native: Count pending CRTCs per flip attempt

Instead of using a global counter. This is necessary to support the
future possibility of having multiple flips pending concurrently, so as
to support multiple monitors each at full speed (#3).
parent c3326eee
......@@ -153,6 +153,12 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
int pending_flips;
} MetaOnscreenNativeSecondaryGpuState;
typedef struct _ConcurrentFlip
{
MetaRendererView *view;
int pending_crtcs_count;
} ConcurrentFlip;
typedef struct _MetaOnscreenNative
{
MetaRendererNative *renderer_native;
......@@ -184,7 +190,7 @@ typedef struct _MetaOnscreenNative
int64_t pending_swap_notify_frame_count;
MetaRendererView *view;
int total_pending_flips;
ConcurrentFlip *last_flip;
} MetaOnscreenNative;
struct _MetaRendererNative
......@@ -1124,12 +1130,13 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
}
static void
on_crtc_flipped (GClosure *closure,
MetaGpuKms *gpu_kms,
MetaCrtc *crtc,
int64_t page_flip_time_ns,
MetaRendererView *view)
on_crtc_flipped (GClosure *closure,
MetaGpuKms *gpu_kms,
MetaCrtc *crtc,
int64_t page_flip_time_ns,
ConcurrentFlip *flip)
{
MetaRendererView *view = flip->view;
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
CoglFramebuffer *framebuffer =
clutter_stage_view_get_onscreen (stage_view);
......@@ -1165,8 +1172,8 @@ on_crtc_flipped (GClosure *closure,
secondary_gpu_state->pending_flips--;
}
onscreen_native->total_pending_flips--;
if (onscreen_native->total_pending_flips == 0)
flip->pending_crtcs_count--;
if (flip->pending_crtcs_count == 0)
{
MetaRendererNativeGpuData *renderer_gpu_data;
......@@ -1208,8 +1215,9 @@ free_next_secondary_bo (MetaGpuKms *gpu_kms,
}
static void
flip_closure_destroyed (MetaRendererView *view)
flip_closure_destroyed (ConcurrentFlip *flip)
{
MetaRendererView *view = flip->view;
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
CoglFramebuffer *framebuffer =
clutter_stage_view_get_onscreen (stage_view);
......@@ -1244,7 +1252,11 @@ flip_closure_destroyed (MetaRendererView *view)
onscreen_native->pending_queue_swap_notify = FALSE;
}
g_object_unref (view);
if (onscreen_native->last_flip == flip)
onscreen_native->last_flip = NULL;
g_object_unref (flip->view);
g_free (flip);
}
#ifdef HAVE_EGL_DEVICE
......@@ -1348,7 +1360,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
fb_in_use))
return;
onscreen_native->total_pending_flips++;
onscreen_native->last_flip->pending_crtcs_count++;
if (secondary_gpu_state)
secondary_gpu_state->pending_flips++;
......@@ -1357,7 +1369,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
if (flip_egl_stream (onscreen_native,
flip_closure))
onscreen_native->total_pending_flips++;
onscreen_native->last_flip->pending_crtcs_count++;
*fb_in_use = TRUE;
break;
#endif
......@@ -1497,6 +1509,11 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
GClosure *flip_closure;
MetaLogicalMonitor *logical_monitor;
gboolean fb_in_use = FALSE;
ConcurrentFlip *flip;
flip = g_new0 (ConcurrentFlip, 1);
flip->view = g_object_ref (view);
onscreen_native->last_flip = flip;
/*
* Create a closure that either will be invoked or destructed.
......@@ -1509,7 +1526,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
* closure will be destructed before this function goes out of scope.
*/
flip_closure = g_cclosure_new (G_CALLBACK (on_crtc_flipped),
g_object_ref (view),
flip,
(GClosureNotify) flip_closure_destroyed);
g_closure_set_marshal (flip_closure, meta_marshal_VOID__OBJECT_OBJECT_INT64);
......@@ -1549,7 +1566,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
* Since we won't receive a flip callback, lets just notify listeners
* directly.
*/
if (fb_in_use && onscreen_native->total_pending_flips == 0)
if (fb_in_use && flip->pending_crtcs_count == 0)
{
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaRendererNativeGpuData *renderer_gpu_data;
......@@ -1590,7 +1607,8 @@ wait_for_pending_flips (CoglOnscreen *onscreen)
meta_gpu_kms_wait_for_flip (secondary_gpu_state->gpu_kms, NULL);
}
while (onscreen_native->total_pending_flips)
while (onscreen_native->last_flip &&
onscreen_native->last_flip->pending_crtcs_count > 0)
meta_gpu_kms_wait_for_flip (onscreen_native->render_gpu, NULL);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment