mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
compositor: Sync X drawing only once per frame
We only need to call XSync() once per frame to synchronize X with GL drawing. https://bugzilla.gnome.org/show_bug.cgi?id=728464
This commit is contained in:
parent
048f035d30
commit
1e6b042778
@ -38,6 +38,8 @@ struct _MetaCompositor
|
|||||||
gint switch_workspace_in_progress;
|
gint switch_workspace_in_progress;
|
||||||
|
|
||||||
MetaPluginManager *plugin_mgr;
|
MetaPluginManager *plugin_mgr;
|
||||||
|
|
||||||
|
gboolean frame_has_updated_xsurfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Wait 2ms after vblank before starting to draw next frame */
|
/* Wait 2ms after vblank before starting to draw next frame */
|
||||||
|
@ -146,6 +146,8 @@ process_damage (MetaCompositor *compositor,
|
|||||||
{
|
{
|
||||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||||
meta_window_actor_process_x11_damage (window_actor, event);
|
meta_window_actor_process_x11_damage (window_actor, event);
|
||||||
|
|
||||||
|
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Window
|
static Window
|
||||||
@ -1125,11 +1127,12 @@ frame_callback (CoglOnscreen *onscreen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
pre_paint_windows (MetaCompositor *compositor)
|
meta_repaint_func (gpointer data)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
MetaWindowActor *top_window;
|
MetaWindowActor *top_window;
|
||||||
|
MetaCompositor *compositor = data;
|
||||||
|
|
||||||
if (compositor->onscreen == NULL)
|
if (compositor->onscreen == NULL)
|
||||||
{
|
{
|
||||||
@ -1141,7 +1144,7 @@ pre_paint_windows (MetaCompositor *compositor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (compositor->windows == NULL)
|
if (compositor->windows == NULL)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
top_window = g_list_last (compositor->windows)->data;
|
top_window = g_list_last (compositor->windows)->data;
|
||||||
|
|
||||||
@ -1153,13 +1156,34 @@ pre_paint_windows (MetaCompositor *compositor)
|
|||||||
|
|
||||||
for (l = compositor->windows; l; l = l->next)
|
for (l = compositor->windows; l; l = l->next)
|
||||||
meta_window_actor_pre_paint (l->data);
|
meta_window_actor_pre_paint (l->data);
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
if (compositor->frame_has_updated_xsurfaces)
|
||||||
meta_repaint_func (gpointer data)
|
{
|
||||||
{
|
/* We need to make sure that any X drawing that happens before
|
||||||
MetaCompositor *compositor = data;
|
* the XDamageSubtract() for each window above is visible to
|
||||||
pre_paint_windows (compositor);
|
* subsequent GL rendering; the only standardized way to do this
|
||||||
|
* is EXT_x11_sync_object, which isn't yet widely available. For
|
||||||
|
* now, we count on details of Xorg and the open source drivers,
|
||||||
|
* and hope for the best otherwise.
|
||||||
|
*
|
||||||
|
* Xorg and open source driver specifics:
|
||||||
|
*
|
||||||
|
* The X server makes sure to flush drawing to the kernel before
|
||||||
|
* sending out damage events, but since we use
|
||||||
|
* DamageReportBoundingBox there may be drawing between the last
|
||||||
|
* damage event and the XDamageSubtract() that needs to be
|
||||||
|
* flushed as well.
|
||||||
|
*
|
||||||
|
* Xorg always makes sure that drawing is flushed to the kernel
|
||||||
|
* before writing events or responses to the client, so any
|
||||||
|
* round trip request at this point is sufficient to flush the
|
||||||
|
* GLX buffers.
|
||||||
|
*/
|
||||||
|
XSync (compositor->display->xdisplay, False);
|
||||||
|
|
||||||
|
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,26 +238,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
|||||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||||
meta_error_trap_pop (display);
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
/* We need to make sure that any X drawing that happens before the
|
|
||||||
* XDamageSubtract() above is visible to subsequent GL rendering;
|
|
||||||
* the only standardized way to do this is EXT_x11_sync_object,
|
|
||||||
* which isn't yet widely available. For now, we count on details
|
|
||||||
* of Xorg and the open source drivers, and hope for the best
|
|
||||||
* otherwise.
|
|
||||||
*
|
|
||||||
* Xorg and open source driver specifics:
|
|
||||||
*
|
|
||||||
* The X server makes sure to flush drawing to the kernel before
|
|
||||||
* sending out damage events, but since we use DamageReportBoundingBox
|
|
||||||
* there may be drawing between the last damage event and the
|
|
||||||
* XDamageSubtract() that needs to be flushed as well.
|
|
||||||
*
|
|
||||||
* Xorg always makes sure that drawing is flushed to the kernel
|
|
||||||
* before writing events or responses to the client, so any round trip
|
|
||||||
* request at this point is sufficient to flush the GLX buffers.
|
|
||||||
*/
|
|
||||||
XSync (xdisplay, False);
|
|
||||||
|
|
||||||
priv->received_damage = FALSE;
|
priv->received_damage = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user