diff options
author | Michal Klocek <michal.klocek@qt.io> | 2017-09-24 17:47:38 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2018-04-04 16:34:04 +0000 |
commit | 5c46e85c6683e08b8c2a839d4f08f6d8d8755281 (patch) | |
tree | 193def66c8f9cf6bc01fec4405888cec0fc0b6d6 /src/core/ozone | |
parent | a68f05b6d37b6f0d07fd3c001f6ee4a18da6eea2 (diff) |
Split GLSurfaceQt
Move GLSurfaceGLXQt and GLSurfaceEGLQt to own
implementation files,so they can be reused easly
by ozone backends.
Change-Id: Ie403a941424343e13775866772bed709d7cbff6a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core/ozone')
-rw-r--r-- | src/core/ozone/gl_surface_egl_qt.cpp | 318 | ||||
-rw-r--r-- | src/core/ozone/gl_surface_egl_qt.h | 97 | ||||
-rw-r--r-- | src/core/ozone/gl_surface_glx_qt.cpp | 213 | ||||
-rw-r--r-- | src/core/ozone/gl_surface_glx_qt.h | 72 |
4 files changed, 700 insertions, 0 deletions
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 000000000..0f21b8dfe --- /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 000000000..ecc2327b3 --- /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 000000000..51b0f58b0 --- /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 000000000..3a465f448 --- /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 |