summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanc999@yahoo.com.tw>2018-05-22 18:05:35 +0800
committerChun-wei Fan <fanc999@yahoo.com.tw>2018-06-08 15:11:11 +0800
commitbc6576b8aa7a48ac0eddba302d56935b38e200fa (patch)
treea11fcded4bc7e6f3991b14102908059b90540146
parent82c700c5c3561bcd35b15acbfa07a93557c07b66 (diff)
downloadgtk+-wip/gtk322.win.egl.tar.gz
GDK-Win32: Fix glitches when using EGL/ANGLEwip/gtk322.win.egl
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.
-rw-r--r--gdk/win32/gdkevents-win32.c5
-rw-r--r--gdk/win32/gdkglcontext-win32.c63
-rw-r--r--gdk/win32/gdkglcontext-win32.h3
-rw-r--r--gdk/win32/gdkwindow-win32.c8
-rw-r--r--gdk/win32/gdkwindow-win32.h1
5 files changed, 78 insertions, 2 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index a2cd67cf03..f153dcba3d 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -93,6 +93,8 @@
* Private function declarations
*/
+extern void _gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
+
#define SYNAPSIS_ICON_WINDOW_CLASS "SynTrackCursorWindowClass"
static gboolean gdk_event_translate (MSG *msg,
@@ -3248,6 +3250,9 @@ gdk_event_translate (MSG *msg,
case SC_MINIMIZE:
case SC_RESTORE:
do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
+
+ if (msg->wParam == SC_RESTORE)
+ _gdk_win32_window_invalidate_egl_framebuffer (window);
break;
case SC_MAXIMIZE:
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 7a6ff8ee5a..26a8b02a6a 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -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
_gdk_win32_gl_context_end_frame (GdkGLContext *context,
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)
{
glDrawBuffer(GL_FRONT);
@@ -193,6 +221,21 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
else
{
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);
}
#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->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) &&
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;
}
+
+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
+}
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index f5535823f2..d58760ce63 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -86,6 +86,9 @@ gboolean
_gdk_win32_gl_context_realize (GdkGLContext *context,
GError **error);
+void
+_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
+
G_END_DECLS
#endif /* __GDK_WIN32_GL_CONTEXT__ */
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 2fd6ef2c5c..3535859194 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1701,6 +1701,8 @@ gdk_win32_window_move_resize (GdkWindow *window,
window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
window_impl->inhibit_configure = TRUE;
+ _gdk_win32_window_invalidate_egl_framebuffer (window);
+
/* We ignore changes to the window being moved or resized by the
user, as we don't want to fight the user */
if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
@@ -5275,6 +5277,8 @@ gdk_win32_window_maximize (GdkWindow *window)
GDK_WINDOW_HWND (window),
_gdk_win32_window_state_to_string (window->state)));
+ _gdk_win32_window_invalidate_egl_framebuffer (window);
+
if (GDK_WINDOW_IS_MAPPED (window))
GtkShowWindow (window, SW_MAXIMIZE);
else
@@ -5295,6 +5299,8 @@ gdk_win32_window_unmaximize (GdkWindow *window)
GDK_WINDOW_HWND (window),
_gdk_win32_window_state_to_string (window->state)));
+ _gdk_win32_window_invalidate_egl_framebuffer (window);
+
if (GDK_WINDOW_IS_MAPPED (window))
GtkShowWindow (window, SW_RESTORE);
else
@@ -6034,6 +6040,8 @@ GtkShowWindow (GdkWindow *window,
case SW_SHOWNA:
case SW_SHOWNOACTIVATE:
case SW_SHOWNORMAL:
+ _gdk_win32_window_invalidate_egl_framebuffer (window);
+
if (IsWindowVisible (hwnd))
break;
diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h
index a5e837ec8d..e1ef92096d 100644
--- a/gdk/win32/gdkwindow-win32.h
+++ b/gdk/win32/gdkwindow-win32.h
@@ -360,6 +360,7 @@ struct _GdkWindowImplWin32
#ifdef GDK_WIN32_ENABLE_EGL
EGLSurface egl_surface;
EGLSurface egl_dummy_surface;
+ guint egl_force_redraw_all : 1;
#endif
};