summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2018-11-27 09:20:46 +0100
committerLiang Qi <liang.qi@qt.io>2018-11-27 15:06:33 +0000
commitbbee17d60ae390a8c2c53d429cfa552f726a6d45 (patch)
tree0ac2d18d1d41a9b1a2fb829e5a2c05076b2a8184
parentcfef46154053b1c53a879e19f0e8c76db2182976 (diff)
Fix GL context tracking when running in GPU-on-UI mode
Both Qt and Chromium keep track of the current GL context by using thread-local variables, and naturally they are completely unaware of each other. As a result, when a QOpenGLContext is made current, the previous gl::GLContext is not released, and vice-versa. This is fine as long as each thread uses exclusively either Qt or Chromium GL bindings, which is usually the case. The only exception is when the GL driver is considered thread-unsafe (QOpenGLContext::supportsThreadedOpenGL() is false), in which case we have to run all GL operations, including Chromium's GPU service, on the UI thread. Now the bindings are being mixed and both Qt and Chromium get quite confused regarding the current state of the surface. To get this to work we have to release the current QOpenGLContext before executing any tasks from Chromium's GPU service and the gl::GLContext afterwards. Since GPU service just posts tasks to the UI thread task runner, we'll have to instrument the entire UI thread message pump. Fixes: QTBUG-72017 Change-Id: Ibd72e3041d213217fd097dfb4272e49243e31e67 Reviewed-by: Michael Brüning <michael.bruning@qt.io> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Michal Klocek <michal.klocek@qt.io> Reviewed-by: Liang Qi <liang.qi@qt.io>
-rw-r--r--src/core/browser_main_parts_qt.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index 38e048470..1cb1ae5a2 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -59,6 +59,12 @@
#include <QEventLoop>
#include <QObject>
#include <QTimerEvent>
+#include <QtGui/qtgui-config.h>
+
+#if QT_CONFIG(opengl)
+#include "ui/gl/gl_context.h"
+#include <QOpenGLContext>
+#endif
#if defined(Q_OS_WIN)
#include "ui/display/win/screen_win.h"
@@ -152,8 +158,55 @@ protected:
}
private:
+ // Both Qt and Chromium keep track of the current GL context by using
+ // thread-local variables, and naturally they are completely unaware of each
+ // other. As a result, when a QOpenGLContext is made current, the previous
+ // gl::GLContext is not released, and vice-versa. This is fine as long as
+ // each thread uses exclusively either Qt or Chromium GL bindings, which is
+ // usually the case.
+ //
+ // The only exception is when the GL driver is considered thread-unsafe
+ // (QOpenGLContext::supportsThreadedOpenGL() is false), in which case we
+ // have to run all GL operations, including Chromium's GPU service, on the
+ // UI thread. Now the bindings are being mixed and both Qt and Chromium get
+ // quite confused regarding the current state of the surface.
+ //
+ // To get this to work we have to release the current QOpenGLContext before
+ // executing any tasks from Chromium's GPU service and the gl::GLContext
+ // afterwards. Since GPU service just posts tasks to the UI thread task
+ // runner, we'll have to instrument the entire UI thread message pump.
+ class ScopedGLContextChecker
+ {
+#if QT_CONFIG(opengl)
+ public:
+ ScopedGLContextChecker()
+ {
+ if (!m_enabled)
+ return;
+
+ if (QOpenGLContext *context = QOpenGLContext::currentContext())
+ context->doneCurrent();
+ }
+
+ ~ScopedGLContextChecker()
+ {
+ if (!m_enabled)
+ return;
+
+ if (gl::GLContext *context = gl::GLContext::GetCurrent())
+ context->ReleaseCurrent(nullptr);
+ }
+
+ private:
+ bool m_enabled = !QOpenGLContext::supportsThreadedOpenGL();
+#endif // QT_CONFIG(opengl)
+ };
+
+
void handleScheduledWork()
{
+ ScopedGLContextChecker glContextChecker;
+
bool more_work_is_plausible = m_delegate->DoWork();
base::TimeTicks delayed_work_time;