From c0bc770eb1dfcc6689df44438cd396721d5129fc Mon Sep 17 00:00:00 2001
From: Andras Becsi <andras.becsi@digia.com>
Date: Wed, 14 May 2014 17:53:59 +0200
Subject: [PATCH] Enable GLContextHelper and register a SurfaceFactoryQt on
 eAndroid

This is needed to run on certain hardware that needs the shared EGL
contexts to be created on the same thread.
To prevent a deadlock on eAndroid only use a blocking connection
if we are not on the main thread where the singleton was created,
since there is a call to this from gpu_info_collector_android
before the GPU thread is launched.

Change-Id: I6887ad1218b8426097f454741dc5a79ee94f9d62
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
---
 src/core/gl_context_qt.cpp      | 13 +++++++++++--
 src/core/gl_context_qt.h        |  5 +++--
 src/core/surface_factory_qt.cpp | 10 ++++++++--
 src/core/surface_factory_qt.h   |  2 +-
 src/core/web_engine_context.cpp |  7 +++++++
 src/core/web_engine_context.h   |  4 ++++
 6 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/src/core/gl_context_qt.cpp b/src/core/gl_context_qt.cpp
index 1d51292dc..f440679cf 100644
--- a/src/core/gl_context_qt.cpp
+++ b/src/core/gl_context_qt.cpp
@@ -41,6 +41,8 @@
 
 #include "gl_context_qt.h"
 
+#include <QGuiApplication>
+#include <QThread>
 #include "ui/gl/gl_context_egl.h"
 
 QT_BEGIN_NAMESPACE
@@ -53,6 +55,12 @@ void GLContextHelper::initialize()
         contextHelper = new GLContextHelper;
 }
 
+void GLContextHelper::destroy()
+{
+    delete contextHelper;
+    contextHelper = 0;
+}
+
 bool GLContextHelper::initializeContextOnBrowserThread(gfx::GLContext* context, gfx::GLSurface* surface)
 {
     return context->Initialize(surface, gfx::PreferDiscreteGpu);
@@ -61,7 +69,8 @@ bool GLContextHelper::initializeContextOnBrowserThread(gfx::GLContext* context,
 bool GLContextHelper::initializeContext(gfx::GLContext* context, gfx::GLSurface* surface)
 {
     bool ret = false;
-    QMetaObject::invokeMethod(contextHelper, "initializeContextOnBrowserThread", Qt::BlockingQueuedConnection,
+    Qt::ConnectionType connType = (QThread::currentThread() == qApp->thread()) ? Qt::DirectConnection : Qt::BlockingQueuedConnection;
+    QMetaObject::invokeMethod(contextHelper, "initializeContextOnBrowserThread", connType,
             Q_RETURN_ARG(bool, ret),
             Q_ARG(gfx::GLContext*, context),
             Q_ARG(gfx::GLSurface*, surface));
@@ -70,7 +79,7 @@ bool GLContextHelper::initializeContext(gfx::GLContext* context, gfx::GLSurface*
 
 QT_END_NAMESPACE
 
-#if defined(USE_OZONE)
+#if defined(USE_OZONE) || defined(OS_ANDROID)
 
 namespace gfx {
 
diff --git a/src/core/gl_context_qt.h b/src/core/gl_context_qt.h
index efe8958be..1ad6d2944 100644
--- a/src/core/gl_context_qt.h
+++ b/src/core/gl_context_qt.h
@@ -44,17 +44,18 @@
 
 #include <QObject>
 
-QT_BEGIN_NAMESPACE
-
 namespace gfx {
 class GLContext;
 class GLSurface;
 }
 
+QT_BEGIN_NAMESPACE
+
 class GLContextHelper : public QObject {
     Q_OBJECT
 public:
     static void initialize();
+    static void destroy();
     static bool initializeContext(gfx::GLContext* context, gfx::GLSurface* surface);
 
 private:
diff --git a/src/core/surface_factory_qt.cpp b/src/core/surface_factory_qt.cpp
index 3b4dcfc8b..9db9a9d2c 100644
--- a/src/core/surface_factory_qt.cpp
+++ b/src/core/surface_factory_qt.cpp
@@ -50,7 +50,7 @@
 #include <QGuiApplication>
 #include <qpa/qplatformnativeinterface.h>
 
-#if defined(USE_OZONE)
+#if defined(USE_OZONE) || defined(OS_ANDROID)
 #include <EGL/egl.h>
 
 #ifndef QT_LIBDIR_EGL
@@ -62,7 +62,12 @@
 
 bool SurfaceFactoryQt::LoadEGLGLES2Bindings(AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address)
 {
-
+#if defined(OS_ANDROID)
+    // This is done in gl_implementation_android.cc for now. We might need to switch if we
+    // start supporting the emulator platform but that would be a more intrusive change.
+    Q_UNREACHABLE();
+    return false;
+#else
     base::FilePath libEGLPath = toFilePath(QT_LIBDIR_EGL);
     libEGLPath = libEGLPath.Append("libEGL.so");
     base::NativeLibrary eglLibrary = gfx::LoadLibrary(libEGLPath);
@@ -91,6 +96,7 @@ bool SurfaceFactoryQt::LoadEGLGLES2Bindings(AddGLLibraryCallback add_gl_library,
     gfx::AddGLNativeLibrary(eglLibrary);
     gfx::AddGLNativeLibrary(gles2Library);
     return true;
+#endif
 }
 
 intptr_t SurfaceFactoryQt::GetNativeDisplay()
diff --git a/src/core/surface_factory_qt.h b/src/core/surface_factory_qt.h
index 28a377e2c..78ccbf2e2 100644
--- a/src/core/surface_factory_qt.h
+++ b/src/core/surface_factory_qt.h
@@ -42,7 +42,7 @@
 #ifndef SURFACE_FACTORY_QT
 #define SURFACE_FACTORY_QT
 
-#if defined(USE_OZONE)
+#if defined(USE_OZONE) || defined(OS_ANDROID)
 
 #include "ui/gfx/ozone/surface_factory_ozone.h"
 
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index d2550e48d..feec45e90 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -75,6 +75,7 @@
 #include "gl_context_qt.h"
 #include "media_capture_devices_dispatcher.h"
 #include "type_conversion.h"
+#include "surface_factory_qt.h"
 #include "web_engine_library_info.h"
 #include <QGuiApplication>
 #include <QStringList>
@@ -94,6 +95,7 @@ void destroyContext()
 
 WebEngineContext::~WebEngineContext()
 {
+    GLContextHelper::destroy();
     m_runLoop->AfterRun();
 }
 
@@ -159,6 +161,11 @@ WebEngineContext::WebEngineContext()
     parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
 
     parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
+
+    // On eAndroid we use this to get the native display
+    // from Qt in GLSurfaceEGL::InitializeOneOff.
+    m_surfaceFactory.reset(new SurfaceFactoryQt());
+    gfx::SurfaceFactoryOzone::SetInstance(m_surfaceFactory.get());
 #endif
 
     GLContextHelper::initialize();
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index e0624afa1..13554066b 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -55,6 +55,7 @@ class ContentMainRunner;
 }
 
 class ContentMainDelegateQt;
+class SurfaceFactoryQt;
 
 class WebEngineContext : public base::RefCounted<WebEngineContext> {
 public:
@@ -69,6 +70,9 @@ private:
     scoped_ptr<ContentMainDelegateQt> m_mainDelegate;
     scoped_ptr<content::ContentMainRunner> m_contentRunner;
     scoped_ptr<content::BrowserMainRunner> m_browserRunner;
+#if defined(OS_ANDROID)
+    scoped_ptr<SurfaceFactoryQt> m_surfaceFactory;
+#endif
 };
 
 #endif // WEB_ENGINE_CONTEXT_H
-- 
GitLab