mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 05:50:10 +00:00
Merge branch 'wip/on-the-surface-good-fences-can-make-bad-neighbors' into 'master'
x11: Handle window getting unmap while frame still pending Closes #2902 See merge request GNOME/gtk!2168
This commit is contained in:
commit
e25c25fcb5
@ -1184,7 +1184,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
|
|||||||
if (timings)
|
if (timings)
|
||||||
timings->drawn_time = frame_drawn_time;
|
timings->drawn_time = frame_drawn_time;
|
||||||
|
|
||||||
if (surface_impl->toplevel->frame_pending)
|
if (!surface_impl->toplevel->frame_still_painting && surface_impl->toplevel->frame_pending)
|
||||||
{
|
{
|
||||||
surface_impl->toplevel->frame_pending = FALSE;
|
surface_impl->toplevel->frame_pending = FALSE;
|
||||||
gdk_surface_thaw_updates (win);
|
gdk_surface_thaw_updates (win);
|
||||||
|
@ -582,6 +582,23 @@ create_legacy_context (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
|
static void
|
||||||
|
finish_frame (GdkGLContext *context)
|
||||||
|
{
|
||||||
|
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||||
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
|
|
||||||
|
if (context_x11->xdamage == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (context_x11->frame_fence == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glDeleteSync (context_x11->frame_fence);
|
||||||
|
context_x11->frame_fence = 0;
|
||||||
|
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bind_context_for_frame_fence (GdkGLContext *context)
|
bind_context_for_frame_fence (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
@ -628,7 +645,6 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
GdkX11Display *display_x11)
|
GdkX11Display *display_x11)
|
||||||
{
|
{
|
||||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
|
||||||
XDamageNotifyEvent *damage_xevent;
|
XDamageNotifyEvent *damage_xevent;
|
||||||
|
|
||||||
if (!context_x11->is_attached)
|
if (!context_x11->is_attached)
|
||||||
@ -675,9 +691,7 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
case GL_WAIT_FAILED:
|
case GL_WAIT_FAILED:
|
||||||
if (wait_result == GL_WAIT_FAILED)
|
if (wait_result == GL_WAIT_FAILED)
|
||||||
g_warning ("failed to wait on GL fence associated with last swap buffers call");
|
g_warning ("failed to wait on GL fence associated with last swap buffers call");
|
||||||
glDeleteSync (context_x11->frame_fence);
|
finish_frame (context);
|
||||||
context_x11->frame_fence = 0;
|
|
||||||
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* We assume that if the fence hasn't been signaled, that this
|
/* We assume that if the fence hasn't been signaled, that this
|
||||||
@ -696,6 +710,21 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_surface_state_changed (GdkGLContext *context)
|
||||||
|
{
|
||||||
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
|
|
||||||
|
if ((surface->state & GDK_SURFACE_STATE_WITHDRAWN) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If we're about to withdraw the surface, then we don't care if the frame is
|
||||||
|
* still getting rendered by the GPU. The compositor is going to remove the surface
|
||||||
|
* from the scene anyway, so wrap up the frame.
|
||||||
|
*/
|
||||||
|
finish_frame (context);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -878,13 +907,23 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
|
|||||||
gdk_x11_surface_get_xid (surface),
|
gdk_x11_surface_get_xid (surface),
|
||||||
XDamageReportRawRectangles);
|
XDamageReportRawRectangles);
|
||||||
if (gdk_x11_display_error_trap_pop (display))
|
if (gdk_x11_display_error_trap_pop (display))
|
||||||
context_x11->xdamage = 0;
|
{
|
||||||
|
context_x11->xdamage = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_signal_connect_object (G_OBJECT (display),
|
{
|
||||||
"xevent",
|
g_signal_connect_object (G_OBJECT (display),
|
||||||
G_CALLBACK (on_gl_surface_xevent),
|
"xevent",
|
||||||
context,
|
G_CALLBACK (on_gl_surface_xevent),
|
||||||
G_CONNECT_SWAPPED);
|
context,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
g_signal_connect_object (G_OBJECT (surface),
|
||||||
|
"notify::state",
|
||||||
|
G_CALLBACK (on_surface_state_changed),
|
||||||
|
context,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user