diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index d33aa9677e91a646711c66e9e1c8a6c9b3987709..bec272c79078192519e0abca46f4b36e6031095f 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -81,6 +81,8 @@ SOURCES = \ net/url_request_qrc_job_qt.cpp \ net/webui_controller_factory_qt.cpp \ ozone/gl_ozone_qt.cpp \ + ozone/gl_surface_egl_qt.cpp \ + ozone/gl_surface_glx_qt.cpp \ ozone/ozone_platform_qt.cpp \ ozone/platform_window_qt.cpp \ ozone/surface_factory_qt.cpp \ @@ -164,6 +166,8 @@ HEADERS = \ net/url_request_qrc_job_qt.h \ net/webui_controller_factory_qt.h \ ozone/gl_ozone_qt.h \ + ozone/gl_surface_egl_qt.h \ + ozone/gl_surface_glx_qt.h \ ozone/ozone_platform_qt.h \ ozone/platform_window_qt.h \ ozone/surface_factory_qt.h \ diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index 31d5e030f6b352ded5fe2d3e5aee3178d7705bf7..54f220f8d3992b0240439df2618a800a9dd47df0 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -49,285 +49,43 @@ #include "gl_context_qt.h" #include "qtwebenginecoreglobal_p.h" #include "web_engine_context.h" +#include "ozone/gl_surface_egl_qt.h" #include "base/logging.h" #include "gpu/ipc/service/image_transport_surface.h" -#include "ui/gl/egl_util.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" -#include "ui/gl/gl_surface_egl.h" #include "ui/gl/init/gl_initializer.h" #include "ui/gl/init/gl_factory.h" -#if defined(USE_X11) -#include "ui/gl/gl_surface_glx.h" - -extern "C" { -#include <X11/Xlib.h> -} -#endif - #if defined(OS_WIN) #include "ui/gl/gl_surface_wgl.h" #include "ui/gl/gl_context_wgl.h" #include "ui/gl/vsync_provider_win.h" #endif -// From ANGLE's egl/eglext.h. -#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle -#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 -#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#if defined(USE_X11) +#include "ozone/gl_surface_glx_qt.h" #endif -using ui::GetLastEGLErrorString; +#include "ozone/gl_surface_egl_qt.h" namespace gl { namespace { - -void* g_config; -void* g_display; - -const char* g_extensions = NULL; - -bool g_egl_surfaceless_context_supported = false; - bool g_initializedEGL = false; - -} // namespace - - -class GLSurfaceQtEGL: public GLSurfaceQt { -public: - explicit GLSurfaceQtEGL(const gfx::Size& size); - - static bool InitializeOneOff(); - static bool InitializeExtensionSettingsOneOff(); - - bool Initialize(GLSurfaceFormat format) override; - void Destroy() override; - void* GetHandle() override; - bool Resize(const gfx::Size& size, float scale_factor, ColorSpace color_space, bool has_alpha) override; - -protected: - ~GLSurfaceQtEGL(); - -private: - EGLSurface m_surfaceBuffer; - static bool s_initialized; - DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtEGL); -}; - -bool GLSurfaceQtEGL::s_initialized = false; - -// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc: -// SurfacelessEGL is used as Offscreen surface when platform supports -// KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the -// need to create a dummy EGLsurface in case we render to client API targets. -class GLSurfacelessQtEGL : public GLSurfaceQt { -public: - explicit GLSurfacelessQtEGL(const gfx::Size& size); - - public: - bool Initialize(GLSurfaceFormat format) override; - void Destroy() override; - bool IsSurfaceless() const override; - bool Resize(const gfx::Size& size, float scale_factor, ColorSpace color_space, bool has_alpha) override; - EGLSurface GetHandle() override; - void* GetShareHandle() override; - -private: - DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL); -}; - -GLSurfaceQt::~GLSurfaceQt() -{ -} - -GLSurfaceQtEGL::~GLSurfaceQtEGL() -{ - Destroy(); -} - -#if defined(USE_X11) -class GLSurfaceQtGLX: public GLSurfaceQt { -public: - explicit GLSurfaceQtGLX(const gfx::Size& size); - - static bool InitializeOneOff(); - static bool InitializeExtensionSettingsOneOff(); - - bool Initialize(GLSurfaceFormat format) override; - void Destroy() override; - void* GetHandle() override; - -protected: - ~GLSurfaceQtGLX(); - -private: - static bool s_initialized; - XID m_surfaceBuffer; - DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtGLX); -}; - -GLSurfaceQtGLX::~GLSurfaceQtGLX() -{ - Destroy(); -} - - -bool GLSurfaceQtGLX::s_initialized = false; - -void GLSurfaceGLX::ShutdownOneOff() -{ -} - -bool GLSurfaceGLX::IsCreateContextSupported() -{ - return ExtensionsContain(g_extensions, "GLX_ARB_create_context"); -} - -bool GLSurfaceGLX::IsCreateContextRobustnessSupported() -{ - return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness"); -} - -bool GLSurfaceGLX::IsEXTSwapControlSupported() -{ - return HasGLXExtension("GLX_EXT_swap_control"); } -bool GLSurfaceGLX::IsMESASwapControlSupported() -{ - return HasGLXExtension("GLX_MESA_swap_control"); -} - -bool GLSurfaceGLX::IsCreateContextProfileSupported() -{ - return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile"); -} - -bool GLSurfaceGLX::IsCreateContextES2ProfileSupported() -{ - return ExtensionsContain(g_extensions, "GLX_ARB_create_context_es2_profile"); -} - -bool GLSurfaceGLX::IsOMLSyncControlSupported() -{ - return false; // ExtensionsContain(g_extensions, "GLX_OML_sync_control"); -} - -bool GLSurfaceQtGLX::InitializeExtensionSettingsOneOff() -{ - if (!s_initialized) - return false; - - Display* display = static_cast<Display*>(g_display); - g_extensions = glXQueryExtensionsString(display, 0); - g_driver_glx.InitializeExtensionBindings(); - - return true; -} +void* GLSurfaceQt::g_display = NULL; +void* GLSurfaceQt::g_config = NULL; +const char* GLSurfaceQt::g_extensions = NULL; -bool GLSurfaceGLX::InitializeExtensionSettingsOneOff() -{ - return GLSurfaceQtGLX::InitializeExtensionSettingsOneOff(); -} - -bool GLSurfaceGLX::HasGLXExtension(const char *name) -{ - return ExtensionsContain(g_extensions, name); -} - -bool GLSurfaceGLX::IsTextureFromPixmapSupported() -{ - return ExtensionsContain(g_extensions, "GLX_EXT_texture_from_pixmap"); -} - -const char* GLSurfaceGLX::GetGLXExtensions() -{ - return g_extensions; -} - -bool GLSurfaceQtGLX::InitializeOneOff() -{ - if (s_initialized) - return true; - - XInitThreads(); - - g_display = GLContextHelper::getXDisplay(); - if (!g_display) { - LOG(ERROR) << "GLContextHelper::getXDisplay() failed."; - return false; - } - - g_config = GLContextHelper::getXConfig(); - if (!g_config) { - LOG(ERROR) << "GLContextHelper::getXConfig() failed."; - return false; - } - - Display* display = static_cast<Display*>(g_display); - int major, minor; - if (!glXQueryVersion(display, &major, &minor)) { - LOG(ERROR) << "glxQueryVersion failed."; - return false; - } - - if (major == 1 && minor < 3) { - LOG(ERROR) << "GLX 1.3 or later is required."; - return false; - } - - s_initialized = true; - return true; -} - -bool GLSurfaceQtGLX::Initialize(GLSurfaceFormat format) -{ - Q_ASSERT(!m_surfaceBuffer); - - Display* display = static_cast<Display*>(g_display); - const int pbuffer_attributes[] = { - GLX_PBUFFER_WIDTH, m_size.width(), - GLX_PBUFFER_HEIGHT, m_size.height(), - GLX_LARGEST_PBUFFER, x11::False, - GLX_PRESERVED_CONTENTS, x11::False, - GLX_NONE - }; - - m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes); - m_format = format; - - if (!m_surfaceBuffer) { - Destroy(); - LOG(ERROR) << "glXCreatePbuffer failed."; - return false; - } - return true; -} - -void GLSurfaceQtGLX::Destroy() -{ - if (m_surfaceBuffer) { - glXDestroyPbuffer(static_cast<Display*>(g_display), m_surfaceBuffer); - m_surfaceBuffer = 0; - } -} - -GLSurfaceQtGLX::GLSurfaceQtGLX(const gfx::Size& size) - : GLSurfaceQt(size), - m_surfaceBuffer(0) -{ -} - -void* GLSurfaceQtGLX::GetHandle() +GLSurfaceQt::~GLSurfaceQt() { - return reinterpret_cast<void*>(m_surfaceBuffer); } -#elif defined(OS_WIN) +#if defined(OS_WIN) class GLSurfaceQtWGL: public GLSurfaceQt { public: @@ -399,128 +157,6 @@ GLSurfaceQt::GLSurfaceQt() { } -bool GLSurfaceQtEGL::InitializeOneOff() -{ - if (s_initialized) - return true; - - g_display = GLContextHelper::getEGLDisplay(); - if (!g_display) { - LOG(ERROR) << "GLContextHelper::getEGLDisplay() failed."; - return false; - } - - g_config = GLContextHelper::getEGLConfig(); - if (!g_config) { - LOG(ERROR) << "GLContextHelper::getEGLConfig() failed."; - return false; - } - - if (!eglInitialize(g_display, NULL, NULL)) { - LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); - return false; - } - - s_initialized = true; - return true; -} - -EGLDisplay GLSurfaceEGL::GetHardwareDisplay() -{ - return static_cast<EGLDisplay>(g_display); -} - -bool GLSurfaceEGL::IsCreateContextRobustnessSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() -{ - return false; -} - -bool GLSurfaceEGL::IsEGLContextPrioritySupported() -{ - return false; -} - -bool GLSurfaceEGL::IsRobustResourceInitSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsCreateContextClientArraysSupported() -{ - return false; -} - -void GLSurfaceEGL::ShutdownOneOff() -{ -} - -bool GLSurfaceQtEGL::InitializeExtensionSettingsOneOff() -{ - if (!s_initialized) - return false; - - g_extensions = eglQueryString(g_display, EGL_EXTENSIONS); - g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context"); - if (g_egl_surfaceless_context_supported) { - scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1)); - gl::GLContextAttribs attribs; - scoped_refptr<GLContext> context = init::CreateGLContext( - NULL, surface.get(), attribs); - - if (!context->MakeCurrent(surface.get())) - g_egl_surfaceless_context_supported = false; - - // Ensure context supports GL_OES_surfaceless_context. - if (g_egl_surfaceless_context_supported) { - g_egl_surfaceless_context_supported = context->HasExtension( - "GL_OES_surfaceless_context"); - context->ReleaseCurrent(surface.get()); - } - } - - return true; -} - -bool GLSurfaceEGL::InitializeExtensionSettingsOneOff() -{ - return GLSurfaceQtEGL::InitializeExtensionSettingsOneOff(); -} - -const char* GLSurfaceEGL::GetEGLExtensions() -{ - return g_extensions; -} - -bool GLSurfaceEGL::HasEGLExtension(const char* name) -{ - return ExtensionsContain(GetEGLExtensions(), name); -} - -bool GLSurfaceEGL::InitializeOneOff(EGLNativeDisplayType /*native_display*/) -{ - return GLSurfaceQtEGL::InitializeOneOff(); -} - -bool GLSurfaceEGL::IsAndroidNativeFenceSyncSupported() -{ - return false; -} - GLSurfaceQt::GLSurfaceQt(const gfx::Size& size) : m_size(size) { @@ -535,52 +171,6 @@ bool GLSurfaceQt::HasEGLExtension(const char* name) return ExtensionsContain(g_extensions, name); } -GLSurfaceQtEGL::GLSurfaceQtEGL(const gfx::Size& size) - : GLSurfaceQt(size), - m_surfaceBuffer(0) -{ -} - -bool GLSurfaceQtEGL::Initialize(GLSurfaceFormat format) -{ - Q_ASSERT(!m_surfaceBuffer); - m_format = format; - - EGLDisplay display = g_display; - if (!display) { - LOG(ERROR) << "Trying to create surface with invalid display."; - return false; - } - - const EGLint pbuffer_attributes[] = { - EGL_WIDTH, m_size.width(), - EGL_HEIGHT, m_size.height(), - EGL_LARGEST_PBUFFER, EGL_FALSE, - EGL_NONE - }; - - m_surfaceBuffer = eglCreatePbufferSurface(display, - g_config, - pbuffer_attributes); - if (!m_surfaceBuffer) { - LOG(ERROR) << "eglCreatePbufferSurface failed with error " << GetLastEGLErrorString(); - Destroy(); - return false; - } - - return true; -} - -void GLSurfaceQtEGL::Destroy() -{ - if (m_surfaceBuffer) { - if (!eglDestroySurface(g_display, m_surfaceBuffer)) - LOG(ERROR) << "eglDestroySurface failed with error " << GetLastEGLErrorString(); - - m_surfaceBuffer = 0; - } -} - bool GLSurfaceQt::IsOffscreen() { return true; @@ -598,43 +188,11 @@ gfx::Size GLSurfaceQt::GetSize() return m_size; } - GLSurfaceFormat GLSurfaceQt::GetFormat() { return m_format; } - -bool GLSurfaceQtEGL::Resize(const gfx::Size& size, float scale_factor, ColorSpace /*color_space*/, bool has_alpha) -{ - if (size == m_size) - return true; - - GLContext *currentContext = GLContext::GetCurrent(); - bool wasCurrent = currentContext && currentContext->IsCurrent(this); - if (wasCurrent) - currentContext->ReleaseCurrent(this); - - Destroy(); - - m_size = size; - - if (!Initialize(GetFormat())) { - LOG(ERROR) << "Failed to resize pbuffer."; - return false; - } - - if (wasCurrent) - return currentContext->MakeCurrent(this); - - return true; -} - -void* GLSurfaceQtEGL::GetHandle() -{ - return reinterpret_cast<void*>(m_surfaceBuffer); -} - void* GLSurfaceQt::GetDisplay() { return g_display; @@ -645,42 +203,6 @@ void* GLSurfaceQt::GetConfig() return g_config; } -GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) - : GLSurfaceQt(size) -{ -} - -bool GLSurfacelessQtEGL::Initialize(GLSurfaceFormat format) -{ - m_format = format; - return true; -} - -void GLSurfacelessQtEGL::Destroy() -{ -} - -bool GLSurfacelessQtEGL::IsSurfaceless() const -{ - return true; -} - -bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, ColorSpace color_space, bool has_alpha) -{ - m_size = size; - return true; -} - -EGLSurface GLSurfacelessQtEGL::GetHandle() -{ - return EGL_NO_SURFACE; -} - -void* GLSurfacelessQtEGL::GetShareHandle() -{ - return NULL; -} - namespace init { bool InitializeGLOneOffPlatform() @@ -693,17 +215,17 @@ bool InitializeGLOneOffPlatform() return false; if (GetGLImplementation() == kGLImplementationEGLGLES2) - return GLSurfaceQtEGL::InitializeOneOff(); + return GLSurfaceEGLQt::InitializeOneOff(); if (GetGLImplementation() == kGLImplementationDesktopGL) { #if defined(OS_WIN) return GLSurfaceQtWGL::InitializeOneOff(); #elif defined(USE_X11) - if (GLSurfaceQtGLX::InitializeOneOff()) + if (GLSurfaceGLXQt::InitializeOneOff()) return true; #endif // Fallback to trying EGL with desktop GL. - if (GLSurfaceQtEGL::InitializeOneOff()) { + if (GLSurfaceEGLQt::InitializeOneOff()) { g_initializedEGL = true; return true; } @@ -731,7 +253,7 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format break; #elif defined(USE_X11) if (!g_initializedEGL) { - surface = new GLSurfaceQtGLX(size); + surface = new GLSurfaceGLXQt(size); if (surface->Initialize(format)) return surface; } @@ -739,14 +261,14 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format #endif } case kGLImplementationEGLGLES2: { - surface = new GLSurfaceQtEGL(size); + surface = new GLSurfaceEGLQt(size); if (surface->Initialize(format)) return surface; // Surfaceless context will be used ONLY if pseudo surfaceless context // is not available since some implementations of surfaceless context // have problems. (e.g. QTBUG-57290) - if (g_egl_surfaceless_context_supported) { + if (GLSurfaceEGLQt::g_egl_surfaceless_context_supported) { surface = new GLSurfacelessQtEGL(size); if (surface->Initialize(format)) return surface; @@ -770,18 +292,6 @@ CreateViewGLSurface(gfx::AcceleratedWidget window) } } // namespace init - -std::string DriverEGL::GetPlatformExtensions() -{ - EGLDisplay display = GLContextHelper::getEGLDisplay(); - if (display == EGL_NO_DISPLAY) - return ""; - - DCHECK(g_driver_egl.fn.eglQueryStringFn); - const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS); - return str ? std::string(str) : ""; -} - } // namespace gl namespace gpu { diff --git a/src/core/gl_surface_qt.h b/src/core/gl_surface_qt.h index ceb8cbba3b394e84c2ea8c762c5b53115fce3098..514527df93e4a4735f83b5be330cab0738adcff7 100644 --- a/src/core/gl_surface_qt.h +++ b/src/core/gl_surface_qt.h @@ -68,6 +68,11 @@ protected: gfx::Size m_size; GLSurfaceFormat m_format; +public: + static void* g_config; + static void* g_display; + static const char* g_extensions; + private: DISALLOW_COPY_AND_ASSIGN(GLSurfaceQt); }; diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f21b8dfe50f29c81d2b35c6a4d39ae689af5531 --- /dev/null +++ b/src/core/ozone/gl_surface_egl_qt.cpp @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gl_context_qt.h" +#include "ozone/gl_surface_egl_qt.h" + +#if !defined(OS_MACOSX) +#include "ui/gl/gl_surface_egl.h" +#include "ui/gl/egl_util.h" +#include "ui/gl/init/gl_factory.h" + +// From ANGLE's egl/eglext.h. +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif + +using ui::GetLastEGLErrorString; + +namespace gl{ + +bool GLSurfaceEGLQt::g_egl_surfaceless_context_supported = false; +bool GLSurfaceEGLQt::s_initialized = false; + +GLSurfaceEGLQt::~GLSurfaceEGLQt() +{ + Destroy(); +} + +bool GLSurfaceEGLQt::InitializeOneOff() +{ + if (s_initialized) + return true; + + g_display = GLContextHelper::getEGLDisplay(); + if (!g_display) { + LOG(ERROR) << "GLContextHelper::getEGLDisplay() failed."; + return false; + } + + g_config = GLContextHelper::getEGLConfig(); + if (!g_config) { + LOG(ERROR) << "GLContextHelper::getEGLConfig() failed."; + return false; + } + + if (!eglInitialize(g_display, NULL, NULL)) { + LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); + return false; + } + + s_initialized = true; + return true; +} + +bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff() +{ + if (!s_initialized) + return false; + + g_extensions = eglQueryString(g_display, EGL_EXTENSIONS); + g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context"); + if (g_egl_surfaceless_context_supported) { + scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1)); + gl::GLContextAttribs attribs; + scoped_refptr<GLContext> context = init::CreateGLContext( + NULL, surface.get(), attribs); + + if (!context->MakeCurrent(surface.get())) + g_egl_surfaceless_context_supported = false; + + // Ensure context supports GL_OES_surfaceless_context. + if (g_egl_surfaceless_context_supported) { + g_egl_surfaceless_context_supported = context->HasExtension( + "GL_OES_surfaceless_context"); + context->ReleaseCurrent(surface.get()); + } + } + + return true; +} + +bool GLSurfaceEGL::InitializeExtensionSettingsOneOff() +{ + return GLSurfaceEGLQt::InitializeExtensionSettingsOneOff(); +} + +EGLDisplay GLSurfaceEGL::GetHardwareDisplay() +{ + return static_cast<EGLDisplay>(GLSurfaceQt::g_display); +} + +bool GLSurfaceEGL::IsCreateContextRobustnessSupported() +{ + return false; +} + +bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported() +{ + return false; +} + +bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() +{ + return false; +} + +bool GLSurfaceEGL::IsEGLContextPrioritySupported() +{ + return false; +} + +bool GLSurfaceEGL::IsRobustResourceInitSupported() +{ + return false; +} + +bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported() +{ + return false; +} + +bool GLSurfaceEGL::IsCreateContextClientArraysSupported() +{ + return false; +} + +void GLSurfaceEGL::ShutdownOneOff() +{ +} + +const char* GLSurfaceEGL::GetEGLExtensions() +{ + return GLSurfaceQt::g_extensions; +} + +bool GLSurfaceEGL::HasEGLExtension(const char* name) +{ + return ExtensionsContain(GetEGLExtensions(), name); +} + +bool GLSurfaceEGL::InitializeOneOff(EGLNativeDisplayType /*native_display*/) +{ + return GLSurfaceEGLQt::InitializeOneOff(); +} + +bool GLSurfaceEGL::IsAndroidNativeFenceSyncSupported() +{ + return false; +} + +GLSurfaceEGLQt::GLSurfaceEGLQt(const gfx::Size& size) + : GLSurfaceQt(size), + m_surfaceBuffer(0) +{ +} + +bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format) +{ + Q_ASSERT(!m_surfaceBuffer); + m_format = format; + + EGLDisplay display = g_display; + if (!display) { + LOG(ERROR) << "Trying to create surface with invalid display."; + return false; + } + + const EGLint pbuffer_attributes[] = { + EGL_WIDTH, m_size.width(), + EGL_HEIGHT, m_size.height(), + EGL_LARGEST_PBUFFER, EGL_FALSE, + EGL_NONE + }; + + m_surfaceBuffer = eglCreatePbufferSurface(display, + g_config, + pbuffer_attributes); + if (!m_surfaceBuffer) { + LOG(ERROR) << "eglCreatePbufferSurface failed with error " << GetLastEGLErrorString(); + Destroy(); + return false; + } + + return true; +} + +void GLSurfaceEGLQt::Destroy() +{ + if (m_surfaceBuffer) { + if (!eglDestroySurface(g_display, m_surfaceBuffer)) + LOG(ERROR) << "eglDestroySurface failed with error " << GetLastEGLErrorString(); + + m_surfaceBuffer = 0; + } +} + +bool GLSurfaceEGLQt::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) +{ + if (size == m_size) + return true; + + GLContext *currentContext = GLContext::GetCurrent(); + bool wasCurrent = currentContext && currentContext->IsCurrent(this); + if (wasCurrent) + currentContext->ReleaseCurrent(this); + + Destroy(); + + m_size = size; + + if (!Initialize(GetFormat())) { + LOG(ERROR) << "Failed to resize pbuffer."; + return false; + } + + if (wasCurrent) + return currentContext->MakeCurrent(this); + + return true; +} + +void* GLSurfaceEGLQt::GetHandle() +{ + return reinterpret_cast<void*>(m_surfaceBuffer); +} + +GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) + : GLSurfaceQt(size) +{ +} + +bool GLSurfacelessQtEGL::Initialize(GLSurfaceFormat format) +{ + m_format = format; + return true; +} + +void GLSurfacelessQtEGL::Destroy() +{ +} + +bool GLSurfacelessQtEGL::IsSurfaceless() const +{ + return true; +} + +bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) +{ + m_size = size; + return true; +} + +EGLSurface GLSurfacelessQtEGL::GetHandle() +{ + return EGL_NO_SURFACE; +} + +void* GLSurfacelessQtEGL::GetShareHandle() +{ + return NULL; +} + +std::string DriverEGL::GetPlatformExtensions() +{ + EGLDisplay display = GLContextHelper::getEGLDisplay(); + if (display == EGL_NO_DISPLAY) + return ""; + + DCHECK(g_driver_egl.fn.eglQueryStringFn); + const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS); + return str ? std::string(str) : ""; +} + +} // namespace gl +#endif // !defined(OS_MACOSX) diff --git a/src/core/ozone/gl_surface_egl_qt.h b/src/core/ozone/gl_surface_egl_qt.h new file mode 100644 index 0000000000000000000000000000000000000000..ecc2327b3c875ba385e8b80387590253ad2eb3a2 --- /dev/null +++ b/src/core/ozone/gl_surface_egl_qt.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GL_SURFACE_EGL_QT_H_ +#define GL_SURFACE_EGL_QT_H_ + +#include "gl_surface_qt.h" +#include <EGL/egl.h> +#include <EGL/eglext.h> + +namespace gl { + +class GLSurfaceEGLQt: public GLSurfaceQt { +public: + explicit GLSurfaceEGLQt(const gfx::Size& size); + + static bool InitializeOneOff(); + static bool InitializeExtensionSettingsOneOff(); + + bool Initialize(GLSurfaceFormat format) override; + void Destroy() override; + void* GetHandle() override; + bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; + +protected: + ~GLSurfaceEGLQt(); + +public: + static bool g_egl_surfaceless_context_supported; + +private: + EGLSurface m_surfaceBuffer; + static bool s_initialized; + DISALLOW_COPY_AND_ASSIGN(GLSurfaceEGLQt); +}; + +// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc: +// SurfacelessEGL is used as Offscreen surface when platform supports +// KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the +// need to create a dummy EGLsurface in case we render to client API targets. + +class GLSurfacelessQtEGL : public GLSurfaceQt { +public: + explicit GLSurfacelessQtEGL(const gfx::Size& size); + +public: + bool Initialize(GLSurfaceFormat format) override; + void Destroy() override; + bool IsSurfaceless() const override; + bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; + EGLSurface GetHandle() override; + void* GetShareHandle() override; + +private: + DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL); +}; +} + +#endif diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..51b0f58b03af010e72bddb15dc2563fd9f5f02ca --- /dev/null +++ b/src/core/ozone/gl_surface_glx_qt.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(USE_X11) + +#include "gl_context_qt.h" +#include "ozone/gl_surface_glx_qt.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_surface_glx.h" +#include <GL/glx.h> +#include <GL/glxext.h> + +namespace gl { + +bool GLSurfaceGLXQt::s_initialized = false; + +GLSurfaceGLXQt::~GLSurfaceGLXQt() +{ + Destroy(); +} + +void GLSurfaceGLX::ShutdownOneOff() +{ +} + +bool GLSurfaceGLX::IsCreateContextSupported() +{ + return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context"); +} + +bool GLSurfaceGLX::IsCreateContextRobustnessSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness"); +} + +bool GLSurfaceGLX::IsEXTSwapControlSupported() +{ + return HasGLXExtension("GLX_EXT_swap_control"); +} + +bool GLSurfaceGLX::IsMESASwapControlSupported() +{ + return HasGLXExtension("GLX_MESA_swap_control"); +} + +bool GLSurfaceGLX::IsCreateContextProfileSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile"); +} + +bool GLSurfaceGLX::IsCreateContextES2ProfileSupported() +{ + return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context_es2_profile"); +} + +bool GLSurfaceGLX::IsOMLSyncControlSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_OML_sync_control"); +} + +bool GLSurfaceGLX::HasGLXExtension(const char *name) +{ + return ExtensionsContain(GLSurfaceQt::g_extensions, name); +} + +bool GLSurfaceGLX::IsTextureFromPixmapSupported() +{ + return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_EXT_texture_from_pixmap"); +} + +const char* GLSurfaceGLX::GetGLXExtensions() +{ + return GLSurfaceQt::g_extensions; +} + +bool GLSurfaceGLXQt::InitializeOneOff() +{ + if (s_initialized) + return true; + + XInitThreads(); + + g_display = GLContextHelper::getXDisplay(); + if (!g_display) { + LOG(ERROR) << "GLContextHelper::getXDisplay() failed."; + return false; + } + + g_config = GLContextHelper::getXConfig(); + if (!g_config) { + LOG(ERROR) << "GLContextHelper::getXConfig() failed."; + return false; + } + + Display* display = static_cast<Display*>(g_display); + int major, minor; + if (!glXQueryVersion(display, &major, &minor)) { + LOG(ERROR) << "glxQueryVersion failed."; + return false; + } + + if (major == 1 && minor < 3) { + LOG(ERROR) << "GLX 1.3 or later is required."; + return false; + } + + s_initialized = true; + return true; +} + + +bool GLSurfaceGLXQt::InitializeExtensionSettingsOneOff() +{ + if (!s_initialized) + return false; + + Display* display = static_cast<Display*>(g_display); + GLSurfaceQt::g_extensions = glXQueryExtensionsString(display, 0); + g_driver_glx.InitializeExtensionBindings(); + return true; +} + +bool GLSurfaceGLX::InitializeExtensionSettingsOneOff() +{ + return GLSurfaceGLXQt::InitializeExtensionSettingsOneOff(); +} + +bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format) +{ + Q_ASSERT(!m_surfaceBuffer); + + Display* display = static_cast<Display*>(g_display); + const int pbuffer_attributes[] = { + GLX_PBUFFER_WIDTH, m_size.width(), + GLX_PBUFFER_HEIGHT, m_size.height(), + GLX_LARGEST_PBUFFER, x11::False, + GLX_PRESERVED_CONTENTS, x11::False, + GLX_NONE + }; + + m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes); + m_format = format; + + if (!m_surfaceBuffer) { + Destroy(); + LOG(ERROR) << "glXCreatePbuffer failed."; + return false; + } + return true; +} + +void GLSurfaceGLXQt::Destroy() +{ + if (m_surfaceBuffer) { + glXDestroyPbuffer(static_cast<Display*>(g_display), m_surfaceBuffer); + m_surfaceBuffer = 0; + } +} + +GLSurfaceGLXQt::GLSurfaceGLXQt(const gfx::Size& size) + : GLSurfaceQt(size), + m_surfaceBuffer(0) +{ +} + +void* GLSurfaceGLXQt::GetHandle() +{ + return reinterpret_cast<void*>(m_surfaceBuffer); +} + +} //namespace gl + +#endif // defined(USE_X11) diff --git a/src/core/ozone/gl_surface_glx_qt.h b/src/core/ozone/gl_surface_glx_qt.h new file mode 100644 index 0000000000000000000000000000000000000000..3a465f448dc8d6edf0c57a0eda63af1d208e0f06 --- /dev/null +++ b/src/core/ozone/gl_surface_glx_qt.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GL_SURFACE_GLX_QT_H_ +#define GL_SURFACE_GLX_QT_H_ + +#include "gl_surface_qt.h" + +extern "C" { +#include <X11/Xlib.h> +} + +namespace gl { + +class GLSurfaceGLXQt: public GLSurfaceQt { +public: + explicit GLSurfaceGLXQt(const gfx::Size& size); + + static bool InitializeOneOff(); + static bool InitializeExtensionSettingsOneOff(); + + bool Initialize(GLSurfaceFormat format) override; + void Destroy() override; + void* GetHandle() override; + +protected: + ~GLSurfaceGLXQt(); + +private: + static bool s_initialized; + XID m_surfaceBuffer; + DISALLOW_COPY_AND_ASSIGN(GLSurfaceGLXQt); +}; + +} +#endif