compositor: Handle GL video memory purged errors
Emit a signal so that interested parties can recreate their FBOs and queue a full scene graph redraw to ensure we don't end up showing graphical artifacts. This relies on the GL driver supporting the NV_robustness_video_memory_purge extension and cogl creating a suitable GL context. For now we only make use of it with the X backend since the only driver with which this is useful is NVIDIA. https://bugzilla.gnome.org/show_bug.cgi?id=739178
This commit is contained in:
parent
7ed14e0ee8
commit
7f6bcea331
@ -884,6 +884,8 @@ meta_backend_x11_init (MetaBackendX11 *x11)
|
|||||||
{
|
{
|
||||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
clutter_x11_request_reset_on_video_memory_purge ();
|
||||||
|
|
||||||
/* We do X11 event retrieval ourselves */
|
/* We do X11 event retrieval ourselves */
|
||||||
clutter_x11_disable_event_retrieval ();
|
clutter_x11_disable_event_retrieval ();
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ struct _MetaCompositor
|
|||||||
|
|
||||||
CoglOnscreen *onscreen;
|
CoglOnscreen *onscreen;
|
||||||
CoglFrameClosure *frame_closure;
|
CoglFrameClosure *frame_closure;
|
||||||
|
CoglContext *context;
|
||||||
|
|
||||||
/* Used for unredirecting fullscreen windows */
|
/* Used for unredirecting fullscreen windows */
|
||||||
guint disable_unredirect_count;
|
guint disable_unredirect_count;
|
||||||
|
@ -1021,8 +1021,7 @@ frame_callback (CoglOnscreen *onscreen,
|
|||||||
* is fairly fast, so calling it twice and subtracting to get a
|
* is fairly fast, so calling it twice and subtracting to get a
|
||||||
* nearly-zero number is acceptable, if a litle ugly.
|
* nearly-zero number is acceptable, if a litle ugly.
|
||||||
*/
|
*/
|
||||||
CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
|
gint64 current_cogl_time = cogl_get_clock_time (compositor->context);
|
||||||
gint64 current_cogl_time = cogl_get_clock_time (context);
|
|
||||||
gint64 current_monotonic_time = g_get_monotonic_time ();
|
gint64 current_monotonic_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
presentation_time =
|
presentation_time =
|
||||||
@ -1052,6 +1051,7 @@ meta_pre_paint_func (gpointer data)
|
|||||||
frame_callback,
|
frame_callback,
|
||||||
compositor,
|
compositor,
|
||||||
NULL);
|
NULL);
|
||||||
|
compositor->context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (compositor->onscreen));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compositor->windows == NULL)
|
if (compositor->windows == NULL)
|
||||||
@ -1105,6 +1105,7 @@ static gboolean
|
|||||||
meta_post_paint_func (gpointer data)
|
meta_post_paint_func (gpointer data)
|
||||||
{
|
{
|
||||||
MetaCompositor *compositor = data;
|
MetaCompositor *compositor = data;
|
||||||
|
CoglGraphicsResetStatus status;
|
||||||
|
|
||||||
if (compositor->frame_has_updated_xsurfaces)
|
if (compositor->frame_has_updated_xsurfaces)
|
||||||
{
|
{
|
||||||
@ -1114,6 +1115,29 @@ meta_post_paint_func (gpointer data)
|
|||||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = cogl_get_graphics_reset_status (compositor->context);
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case COGL_GRAPHICS_RESET_STATUS_NO_ERROR:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET:
|
||||||
|
g_signal_emit_by_name (compositor->display, "gl-video-memory-purged");
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (compositor->stage));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* The ARB_robustness spec says that, on error, the application
|
||||||
|
should destroy the old context and create a new one. Since we
|
||||||
|
don't have the necessary plumbing to do this we'll simply
|
||||||
|
restart the process. Obviously we can't do this when we are
|
||||||
|
a wayland compositor but in that case we shouldn't get here
|
||||||
|
since we don't enable robustness in that case. */
|
||||||
|
g_assert (!meta_is_wayland_compositor ());
|
||||||
|
meta_restart (NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ enum
|
|||||||
SHOW_RESTART_MESSAGE,
|
SHOW_RESTART_MESSAGE,
|
||||||
RESTART,
|
RESTART,
|
||||||
SHOW_RESIZE_POPUP,
|
SHOW_RESIZE_POPUP,
|
||||||
|
GL_VIDEO_MEMORY_PURGED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -342,6 +343,14 @@ meta_display_class_init (MetaDisplayClass *klass)
|
|||||||
G_TYPE_BOOLEAN, 4,
|
G_TYPE_BOOLEAN, 4,
|
||||||
G_TYPE_BOOLEAN, META_TYPE_RECTANGLE, G_TYPE_INT, G_TYPE_INT);
|
G_TYPE_BOOLEAN, META_TYPE_RECTANGLE, G_TYPE_INT, G_TYPE_INT);
|
||||||
|
|
||||||
|
display_signals[GL_VIDEO_MEMORY_PURGED] =
|
||||||
|
g_signal_new ("gl-video-memory-purged",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_FOCUS_WINDOW,
|
PROP_FOCUS_WINDOW,
|
||||||
g_param_spec_object ("focus-window",
|
g_param_spec_object ("focus-window",
|
||||||
|
Loading…
Reference in New Issue
Block a user