[gtk/workaround-win32-intel-blit] gdkglcontext-win32.c: Workaround Intel glBlitFramebuffer() issues
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/workaround-win32-intel-blit] gdkglcontext-win32.c: Workaround Intel glBlitFramebuffer() issues
- Date: Wed, 23 Dec 2020 10:43:53 +0000 (UTC)
commit 6cd4eef1c8a3a03971f0a6713b7c2c858fe5d673
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Wed Dec 23 18:32:11 2020 +0800
gdkglcontext-win32.c: Workaround Intel glBlitFramebuffer() issues
Intel OpenGL drivers have an issue where the results of a series of
glBlitFramebuffer() can delay updating the display, when we use GDK_GL=always,
which is manifested when attempting to enter text in text boxes.
This attempts to work around this issue by requiring a glFlush() call and a
retry to the same glBlitFramebuffer() calls to avoid delays in keystrokes when
using GDK_GL=always and when not using libANGLE OpenGL/ES, when an Intel OpenGL
driver is being used.
Fixes issue 3487
emulation
gdk/win32/gdkdisplay-win32.h | 3 +++
gdk/win32/gdkglcontext-win32.c | 37 +++++++++++++++++++++++++++----------
2 files changed, 30 insertions(+), 10 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 3089f4dea0..f33b76bf34 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -102,6 +102,9 @@ struct _GdkWin32Display
guint hasWglARBPixelFormat : 1;
guint hasWglARBmultisample : 1;
+ /* compensate around Intel OpenGL driver issues on blitting, see issue #3487 */
+ guint needIntelGLWorkaround : 1;
+
#ifdef GDK_WIN32_ENABLE_EGL
guint hasEglKHRCreateContext : 1;
guint hasEglSurfacelessContext : 1;
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 0782c9a59a..7e7549af92 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -123,21 +123,34 @@ gdk_win32_gl_context_init (GdkWin32GLContext *self)
}
static void
-gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
+gdk_gl_blit_region (GdkWindow *window,
+ cairo_region_t *region,
+ gboolean use_intel_workaround)
{
- int n_rects, i;
+ int n_rects, i, j;
int scale = gdk_window_get_scale_factor (window);
int wh = gdk_window_get_height (window);
cairo_rectangle_int_t rect;
+ int retries = 0;
+
+ if (use_intel_workaround)
+ retries = 1;
n_rects = cairo_region_num_rectangles (region);
- for (i = 0; i < n_rects; i++)
+
+ for (i = 0; i <= retries; i ++)
{
- cairo_region_get_rectangle (region, i, &rect);
- glScissor (rect.x * scale, (wh - rect.y - rect.height) * scale, rect.width * scale, rect.height *
scale);
- glBlitFramebuffer (rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) * scale,
(wh - rect.y) * scale,
- rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) * scale,
(wh - rect.y) * scale,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ for (j = 0; j < n_rects; j++)
+ {
+ cairo_region_get_rectangle (region, j, &rect);
+ glScissor (rect.x * scale, (wh - rect.y - rect.height) * scale, rect.width * scale, rect.height *
scale);
+ glBlitFramebuffer (rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) *
scale, (wh - rect.y) * scale,
+ rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) *
scale, (wh - rect.y) * scale,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+
+ if (retries > 0)
+ glFlush ();
}
}
@@ -206,7 +219,7 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
{
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_BACK);
- gdk_gl_blit_region (window, painted);
+ gdk_gl_blit_region (window, painted, display->needIntelGLWorkaround);
glDrawBuffer(GL_BACK);
glFlush();
@@ -224,7 +237,7 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
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);
+ gdk_gl_blit_region (window, painted, FALSE);
else if (force_egl_redraw_all)
{
GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
@@ -616,10 +629,13 @@ _gdk_win32_display_init_gl (GdkDisplay *display,
epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_pixel_format");
display_win32->hasWglARBmultisample =
epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_multisample");
+ display_win32->needIntelGLWorkaround =
+ (g_ascii_strcasecmp (glGetString (GL_VENDOR), "intel") == 0);
GDK_NOTE (OPENGL,
g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
+ " - Intel OpenGL workaround: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
@@ -629,6 +645,7 @@ _gdk_win32_display_init_gl (GdkDisplay *display,
display_win32->gl_version / 10,
display_win32->gl_version % 10,
glGetString (GL_VENDOR),
+ display_win32->needIntelGLWorkaround ? "yes" : "no",
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]