summaryrefslogtreecommitdiffstats
path: root/src/core/browser_main_parts_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/browser_main_parts_qt.cpp')
-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 8f39386d4..056d6fda8 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(OS_MACOSX)
#include "ui/base/idle/idle.h"
@@ -156,8 +162,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;