From 41e5902e7799808fc71504d4222ee6363fec1aef Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 1 Aug 2014 13:40:00 +0200 Subject: Add Desktop OpenGL backend for Windows Enabling rendering into a WGL backbuffer, in addition to the EGL/angle one. Change-Id: I8f2e3f5ecf52b6db22712b1129059f462725a256 Reviewed-by: Andras Becsi --- src/3rdparty | 2 +- src/core/config/windows.pri | 12 ++++- src/core/content_browser_client_qt.cpp | 2 +- src/core/delegated_frame_node.cpp | 25 +++++++-- src/core/gl_context_qt.cpp | 16 +++++- src/core/gl_surface_qt.cpp | 84 +++++++++++++++++++++++++++++- src/core/web_engine_context.cpp | 15 ++++-- src/core/yuv_video_node.cpp | 16 ++++-- tools/qmake/mkspecs/features/functions.prf | 1 - 9 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/3rdparty b/src/3rdparty index e7cb808b6..0f43b6230 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit e7cb808b6fcb765ad503068fa47c165c29a7570e +Subproject commit 0f43b623079ebd5a3d78978ed187f52bcba7e117 diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index 520500c63..f7644c83b 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -17,6 +17,14 @@ GYP_ARGS += "-D perl_exe=\"perl.exe\" -D bison_exe=\"bison.exe\" -D gperf_exe=\" # Gyp's parallel processing is broken on Windows GYP_ARGS += "--no-parallel" -CONFIG(release, debug|release): GYP_ARGS+= "-D qt_egl_library=\"libEGL.lib\" -D qt_glesv2_library=\"libGLESv2.lib\"" -else: GYP_ARGS+= "-D qt_egl_library=\"libEGLd.lib\" -D qt_glesv2_library=\"libGLESv2d.lib\"" +contains(QT_CONFIG, angle) { + CONFIG(release, debug|release) { + GYP_ARGS += "-D qt_egl_library=\"libEGL.lib\" -D qt_glesv2_library=\"libGLESv2.lib\"" + } else { + GYP_ARGS += "-D qt_egl_library=\"libEGLd.lib\" -D qt_glesv2_library=\"libGLESv2d.lib\"" + } + GYP_ARGS += "-D qt_gl=\"angle\"" +} else { + GYP_ARGS += "-D qt_gl=\"opengl\"" +} diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index ba4759ad4..11e068dca 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -250,7 +250,7 @@ public: if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglContext"), qtContext); else - qFatal("Only the EGLGLES2 implementation is supported on %s platform.", platform.toLatin1().constData()); + m_handle = pni->nativeResourceForContext(QByteArrayLiteral("renderingcontext"), qtContext); } else { qFatal("%s platform not yet supported", platform.toLatin1().constData()); // Add missing platforms once they work. diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 3d3e0dd8f..1a393a0c7 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -64,6 +64,7 @@ #include "cc/quads/yuv_video_draw_quad.h" #include #include +#include #include #include #include @@ -75,7 +76,7 @@ #include #endif -class RenderPassTexture : public QSGTexture +class RenderPassTexture : public QSGTexture, protected QOpenGLFunctions { public: RenderPassTexture(const cc::RenderPass::Id &id); @@ -105,7 +106,7 @@ private: QScopedPointer m_fbo; }; -class MailboxTexture : public QSGTexture { +class MailboxTexture : public QSGTexture, protected QOpenGLFunctions { public: MailboxTexture(const cc::TransferableResource &resource); virtual int textureId() const Q_DECL_OVERRIDE { return m_textureId; } @@ -232,7 +233,14 @@ static void waitChromiumSync(gfx::TransferableFence *sync) break; case gfx::TransferableFence::ArbSync: #ifdef GL_ARB_sync - glWaitSync(sync->arb.sync, 0, GL_TIMEOUT_IGNORED); + typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout); + static WaitSyncPtr glWaitSync_ = 0; + if (!glWaitSync_) { + QOpenGLContext *context = QOpenGLContext::currentContext(); + glWaitSync_ = (WaitSyncPtr)context->getProcAddress("glWaitSync"); + Q_ASSERT(glWaitSync_); + } + glWaitSync_(sync->arb.sync, 0, GL_TIMEOUT_IGNORED); #endif break; } @@ -270,7 +278,14 @@ static void deleteChromiumSync(gfx::TransferableFence *sync) break; case gfx::TransferableFence::ArbSync: #ifdef GL_ARB_sync - glDeleteSync(sync->arb.sync); + typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync); + static DeleteSyncPtr glDeleteSync_ = 0; + if (!glDeleteSync_) { + QOpenGLContext *context = QOpenGLContext::currentContext(); + glDeleteSync_ = (DeleteSyncPtr)context->getProcAddress("glDeleteSync"); + Q_ASSERT(glDeleteSync_); + } + glDeleteSync_(sync->arb.sync); sync->reset(); #endif break; @@ -286,6 +301,7 @@ RenderPassTexture::RenderPassTexture(const cc::RenderPass::Id &id) , m_sgEngine(new QSGEngine) , m_rootNode(new QSGRootNode) { + initializeOpenGLFunctions(); } void RenderPassTexture::bind() @@ -330,6 +346,7 @@ MailboxTexture::MailboxTexture(const cc::TransferableResource &resource) , m_target(GL_TEXTURE_2D) , m_importCount(1) { + initializeOpenGLFunctions(); } void MailboxTexture::bind() diff --git a/src/core/gl_context_qt.cpp b/src/core/gl_context_qt.cpp index 6aec2d3b3..e1255219d 100644 --- a/src/core/gl_context_qt.cpp +++ b/src/core/gl_context_qt.cpp @@ -41,11 +41,16 @@ #include #include #include "ui/gl/gl_context_egl.h" +#include "ui/gl/gl_implementation.h" #if defined(USE_X11) #include #endif +#if defined(OS_WIN) +#include "ui/gl/gl_context_wgl.h" +#endif + QT_BEGIN_NAMESPACE Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); @@ -135,7 +140,16 @@ namespace gfx { scoped_refptr GLContext::CreateGLContext(GLShareGroup* share_group, GLSurface* compatible_surface, GpuPreference gpu_preference) { - scoped_refptr context(new GLContextEGL(share_group)); +#if defined(OS_WIN) + scoped_refptr context; + if (GetGLImplementation() == kGLImplementationDesktopGL) + context = new GLContextWGL(share_group); + else + context = new GLContextEGL(share_group); +#else + scoped_refptr context = new GLContextEGL(share_group); +#endif + if (!GLContextHelper::initializeContext(context.get(), compatible_surface)) return NULL; diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index 72758cbff..cc2809af1 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -64,6 +64,11 @@ extern "C" { } #endif +#if defined(OS_WIN) +#include "ui/gl/gl_surface_wgl.h" +#include "ui/gl/gl_context_wgl.h" +#endif + using ui::GetLastEGLErrorString; namespace gfx { @@ -239,7 +244,75 @@ void* GLSurfaceQtGLX::GetHandle() return reinterpret_cast(m_surfaceBuffer); } -#endif // defined(USE_X11) +#elif defined(OS_WIN) + +class GLSurfaceQtWGL: public GLSurfaceQt { +public: + explicit GLSurfaceQtWGL(const gfx::Size& size); + + static bool InitializeOneOff(); + + virtual bool Initialize() Q_DECL_OVERRIDE; + virtual void Destroy() Q_DECL_OVERRIDE; + virtual void* GetHandle() Q_DECL_OVERRIDE; + virtual void* GetDisplay() Q_DECL_OVERRIDE; + virtual void* GetConfig() Q_DECL_OVERRIDE; + +protected: + ~GLSurfaceQtWGL(); + +private: + PbufferGLSurfaceWGL *m_surfaceBuffer; + DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtWGL); +}; + +GLSurfaceQtWGL::GLSurfaceQtWGL(const gfx::Size& size) + : GLSurfaceQt(size), + m_surfaceBuffer(0) +{ +} + +GLSurfaceQtWGL::~GLSurfaceQtWGL() +{ + Destroy(); +} + +bool GLSurfaceQtWGL::InitializeOneOff() +{ + return GLSurfaceWGL::InitializeOneOff(); +} + +bool GLSurfaceQtWGL::Initialize() +{ + m_surfaceBuffer = new PbufferGLSurfaceWGL(m_size); + + return m_surfaceBuffer->Initialize(); +} + +void GLSurfaceQtWGL::Destroy() +{ + if (m_surfaceBuffer) { + delete m_surfaceBuffer; + m_surfaceBuffer = 0; + } +} + +void *GLSurfaceQtWGL::GetHandle() +{ + return m_surfaceBuffer->GetHandle(); +} + +void *GLSurfaceQtWGL::GetDisplay() +{ + return m_surfaceBuffer->GetDisplay(); +} + +void *GLSurfaceQtWGL::GetConfig() +{ + return m_surfaceBuffer->GetConfig(); +} + +#endif // defined(OS_WIN) GLSurfaceQt::GLSurfaceQt() { @@ -287,9 +360,11 @@ bool GLSurface::InitializeOneOffInternal() if (GetGLImplementation() == kGLImplementationEGLGLES2) return GLSurfaceQtEGL::InitializeOneOff(); -#if defined(USE_X11) if (GetGLImplementation() == kGLImplementationDesktopGL) +#if defined(USE_X11) return GLSurfaceQtGLX::InitializeOneOff(); +#elif defined(OS_WIN) + return GLSurfaceQtWGL::InitializeOneOff(); #endif return false; @@ -456,6 +531,11 @@ GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) if (!surface->Initialize()) return NULL; return surface; +#elif defined(OS_WIN) + scoped_refptr surface = new GLSurfaceQtWGL(size); + if (!surface->Initialize()) + return NULL; + return surface; #else LOG(ERROR) << "Desktop GL is not supported on this platform."; Q_UNREACHABLE(); diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 7c0a45b68..13daef5f6 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -75,6 +75,7 @@ #include "web_engine_library_info.h" #include "web_engine_visited_links_manager.h" #include +#include #include #include #include @@ -170,10 +171,16 @@ WebEngineContext::WebEngineContext() GLContextHelper::initialize(); - // Tell Chromium to use EGL instead of GLX if the Qt xcb plugin also does. - if ((qApp->platformName() == QStringLiteral("xcb") || qApp->platformName() == QStringLiteral("eglfs")) - && qApp->platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("egldisplay"), 0)) - parsedCommandLine->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); + const char *glType; + switch (QOpenGLContext::currentContext()->openGLModuleType()) { + case QOpenGLContext::LibGL: + glType = gfx::kGLImplementationDesktopName; + break; + case QOpenGLContext::LibGLES: + glType = gfx::kGLImplementationEGLName; + break; + } + parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread); content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread); diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp index 256bf224e..0e3f17d85 100644 --- a/src/core/yuv_video_node.cpp +++ b/src/core/yuv_video_node.cpp @@ -36,6 +36,8 @@ #include "yuv_video_node.h" +#include +#include #include class YUVVideoMaterialShader : public QSGMaterialShader @@ -159,11 +161,13 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial * program()->setUniformValue(m_id_uTexture, 1); program()->setUniformValue(m_id_vTexture, 2); - glActiveTexture(GL_TEXTURE1); + QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); + + glFuncs.glActiveTexture(GL_TEXTURE1); mat->m_uTexture->bind(); - glActiveTexture(GL_TEXTURE2); + glFuncs.glActiveTexture(GL_TEXTURE2); mat->m_vTexture->bind(); - glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit + glFuncs.glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit mat->m_yTexture->bind(); program()->setUniformValue(m_id_texOffset, mat->m_texCoordRect.topLeft()); @@ -203,11 +207,13 @@ void YUVAVideoMaterialShader::updateState(const RenderState &state, QSGMaterial YUVAVideoMaterial *mat = static_cast(newMaterial); program()->setUniformValue(m_id_aTexture, 3); - glActiveTexture(GL_TEXTURE3); + QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); + + glFuncs.glActiveTexture(GL_TEXTURE3); mat->m_aTexture->bind(); // Reset the default texture unit. - glActiveTexture(GL_TEXTURE0); + glFuncs.glActiveTexture(GL_TEXTURE0); } diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf index 2c4b9e0c2..789af9a13 100644 --- a/tools/qmake/mkspecs/features/functions.prf +++ b/tools/qmake/mkspecs/features/functions.prf @@ -1,7 +1,6 @@ defineTest(isPlatformSupported) { static: return(false) osx:lessThan(QMAKE_XCODE_VERSION, 5.1): return(false) - win32: !contains(QT_CONFIG, angle): return(false) linux-g++|win32-msvc2013|macx-clang: return(true) android-g++-b2qt: return(true) -- cgit v1.2.3