diff options
author | Chun-wei Fan <fanc999@yahoo.com.tw> | 2018-05-22 18:05:35 +0800 |
---|---|---|
committer | Chun-wei Fan <fanc999@yahoo.com.tw> | 2018-06-08 15:11:11 +0800 |
commit | bc6576b8aa7a48ac0eddba302d56935b38e200fa (patch) | |
tree | a11fcded4bc7e6f3991b14102908059b90540146 | |
parent | 82c700c5c3561bcd35b15acbfa07a93557c07b66 (diff) | |
download | gtk+-bc6576b8aa7a48ac0eddba302d56935b38e200fa.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.c | 5 | ||||
-rw-r--r-- | gdk/win32/gdkglcontext-win32.c | 63 | ||||
-rw-r--r-- | gdk/win32/gdkglcontext-win32.h | 3 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 8 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.h | 1 |
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 }; |