GDK-Win32: Fix glitches when using EGL/ANGLE
We need to force redraws of the whole window when we are using EGL/ANGLE during maximize, restore and Aerosnap ops so that we do not get glitches in the resulting window.
This commit is contained in:

committed by
Chun-wei Fan

parent
af66faf604
commit
b2ea707614
@ -93,6 +93,8 @@
|
|||||||
* Private function declarations
|
* Private function declarations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern void _gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
|
||||||
|
|
||||||
#define SYNAPSIS_ICON_WINDOW_CLASS "SynTrackCursorWindowClass"
|
#define SYNAPSIS_ICON_WINDOW_CLASS "SynTrackCursorWindowClass"
|
||||||
|
|
||||||
static gboolean gdk_event_translate (MSG *msg,
|
static gboolean gdk_event_translate (MSG *msg,
|
||||||
@ -3248,6 +3250,9 @@ gdk_event_translate (MSG *msg,
|
|||||||
case SC_MINIMIZE:
|
case SC_MINIMIZE:
|
||||||
case SC_RESTORE:
|
case SC_RESTORE:
|
||||||
do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
|
do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
|
||||||
|
|
||||||
|
if (msg->wParam == SC_RESTORE)
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||||
break;
|
break;
|
||||||
case SC_MAXIMIZE:
|
case SC_MAXIMIZE:
|
||||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
|
@ -141,6 +141,35 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_get_is_egl_force_redraw (GdkWindow *window)
|
||||||
|
{
|
||||||
|
/* We only need to call gdk_window_invalidate_rect () if necessary */
|
||||||
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
|
if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
|
||||||
|
{
|
||||||
|
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
|
|
||||||
|
return impl->egl_force_redraw_all;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_reset_egl_force_redraw (GdkWindow *window)
|
||||||
|
{
|
||||||
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
|
if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
|
||||||
|
{
|
||||||
|
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
|
|
||||||
|
if (impl->egl_force_redraw_all)
|
||||||
|
impl->egl_force_redraw_all = FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gdk_win32_gl_context_end_frame (GdkGLContext *context,
|
_gdk_win32_gl_context_end_frame (GdkGLContext *context,
|
||||||
cairo_region_t *painted,
|
cairo_region_t *painted,
|
||||||
@ -173,7 +202,6 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EGL does not have do_blit_swap */
|
|
||||||
if (context_win32->do_blit_swap)
|
if (context_win32->do_blit_swap)
|
||||||
{
|
{
|
||||||
glDrawBuffer(GL_FRONT);
|
glDrawBuffer(GL_FRONT);
|
||||||
@ -193,6 +221,21 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
|
EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
|
||||||
|
gboolean force_egl_redraw_all = _get_is_egl_force_redraw (window);
|
||||||
|
|
||||||
|
if (context_win32->do_blit_swap && !force_egl_redraw_all)
|
||||||
|
gdk_gl_blit_region (window, painted);
|
||||||
|
else if (force_egl_redraw_all)
|
||||||
|
{
|
||||||
|
GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
|
||||||
|
|
||||||
|
/* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
|
||||||
|
* restoring or using aerosnap
|
||||||
|
*/
|
||||||
|
gdk_window_invalidate_rect (window, &rect, TRUE);
|
||||||
|
_reset_egl_force_redraw (window);
|
||||||
|
}
|
||||||
|
|
||||||
eglSwapBuffers (display->egl_disp, egl_surface);
|
eglSwapBuffers (display->egl_disp, egl_surface);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -214,7 +257,6 @@ _gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
|
|||||||
context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
|
context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
|
||||||
context_win32->do_blit_swap = FALSE;
|
context_win32->do_blit_swap = FALSE;
|
||||||
|
|
||||||
/* gdk_gl_context_has_framebuffer_blit() is for Desktop GL only ! */
|
|
||||||
if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
|
if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
|
||||||
cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
|
cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
|
||||||
{
|
{
|
||||||
@ -1309,3 +1351,20 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
|
||||||
|
{
|
||||||
|
/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
|
||||||
|
* as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
|
||||||
|
* using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
|
||||||
|
*/
|
||||||
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
|
if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
|
||||||
|
{
|
||||||
|
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
|
|
||||||
|
impl->egl_force_redraw_all = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -86,6 +86,9 @@ gboolean
|
|||||||
_gdk_win32_gl_context_realize (GdkGLContext *context,
|
_gdk_win32_gl_context_realize (GdkGLContext *context,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_WIN32_GL_CONTEXT__ */
|
#endif /* __GDK_WIN32_GL_CONTEXT__ */
|
||||||
|
@ -1701,6 +1701,8 @@ gdk_win32_window_move_resize (GdkWindow *window,
|
|||||||
window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
window_impl->inhibit_configure = TRUE;
|
window_impl->inhibit_configure = TRUE;
|
||||||
|
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||||
|
|
||||||
/* We ignore changes to the window being moved or resized by the
|
/* We ignore changes to the window being moved or resized by the
|
||||||
user, as we don't want to fight the user */
|
user, as we don't want to fight the user */
|
||||||
if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
|
if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
|
||||||
@ -5275,6 +5277,8 @@ gdk_win32_window_maximize (GdkWindow *window)
|
|||||||
GDK_WINDOW_HWND (window),
|
GDK_WINDOW_HWND (window),
|
||||||
_gdk_win32_window_state_to_string (window->state)));
|
_gdk_win32_window_state_to_string (window->state)));
|
||||||
|
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||||
|
|
||||||
if (GDK_WINDOW_IS_MAPPED (window))
|
if (GDK_WINDOW_IS_MAPPED (window))
|
||||||
GtkShowWindow (window, SW_MAXIMIZE);
|
GtkShowWindow (window, SW_MAXIMIZE);
|
||||||
else
|
else
|
||||||
@ -5295,6 +5299,8 @@ gdk_win32_window_unmaximize (GdkWindow *window)
|
|||||||
GDK_WINDOW_HWND (window),
|
GDK_WINDOW_HWND (window),
|
||||||
_gdk_win32_window_state_to_string (window->state)));
|
_gdk_win32_window_state_to_string (window->state)));
|
||||||
|
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||||
|
|
||||||
if (GDK_WINDOW_IS_MAPPED (window))
|
if (GDK_WINDOW_IS_MAPPED (window))
|
||||||
GtkShowWindow (window, SW_RESTORE);
|
GtkShowWindow (window, SW_RESTORE);
|
||||||
else
|
else
|
||||||
@ -6034,6 +6040,8 @@ GtkShowWindow (GdkWindow *window,
|
|||||||
case SW_SHOWNA:
|
case SW_SHOWNA:
|
||||||
case SW_SHOWNOACTIVATE:
|
case SW_SHOWNOACTIVATE:
|
||||||
case SW_SHOWNORMAL:
|
case SW_SHOWNORMAL:
|
||||||
|
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||||
|
|
||||||
if (IsWindowVisible (hwnd))
|
if (IsWindowVisible (hwnd))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -360,6 +360,7 @@ struct _GdkWindowImplWin32
|
|||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
EGLSurface egl_dummy_surface;
|
EGLSurface egl_dummy_surface;
|
||||||
|
guint egl_force_redraw_all : 1;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user