diff options
Diffstat (limited to 'src/core/ozone')
24 files changed, 1289 insertions, 1280 deletions
diff --git a/src/core/ozone/BUILD.gn b/src/core/ozone/BUILD.gn index b96d8a47a..aa7b282ae 100644 --- a/src/core/ozone/BUILD.gn +++ b/src/core/ozone/BUILD.gn @@ -1,6 +1,14 @@ # Copyright 2016 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. +import("//ui/base/ui_features.gni") +import("//build/config/linux/pkg_config.gni") + +if (use_xkbcommon) { + pkg_config("xkb") { + packages = [ "xkbcommon", "xkbfile" ] + } +} source_set("qt") { sources = [ @@ -13,13 +21,18 @@ source_set("qt") { deps = [ "//base", + "//ui/base:buildflags", "//ui/ozone:ozone_base", "//ui/ozone/common", ] defines = [ "OZONE_IMPLEMENTATION" ] + libs = [] + if (use_xkbcommon) { + configs += [ ":xkb" ] + } - if (is_linux && !is_desktop_linux) { - deps += [ "//ui/events/ozone:events_ozone_evdev"] + if (ozone_platform_x11) { + libs += [ "X11" ] } } diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp index 9813a3256..2e358c0fb 100644 --- a/src/core/ozone/gl_context_qt.cpp +++ b/src/core/ozone/gl_context_qt.cpp @@ -1,68 +1,45 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "gl_context_qt.h" #include <QGuiApplication> #include <QOpenGLContext> #include <QThread> +#include <QtGui/private/qtgui-config_p.h> #include <qpa/qplatformnativeinterface.h> -#include "ui/gl/gl_context_egl.h" + #include "ui/gl/gl_implementation.h" +#include "ui/gl/gl_surface.h" + +#if defined(USE_OZONE) +#include "ui/gl/egl_util.h" + +#include <QOpenGLFunctions> +#include <QOffscreenSurface> + +#include <vector> +#endif -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) +#include "ui/gl/gl_context_egl.h" #include "ui/gl/gl_context_wgl.h" #endif QT_BEGIN_NAMESPACE Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); -GLContextHelper* GLContextHelper::contextHelper = 0; +GLContextHelper* GLContextHelper::contextHelper = nullptr; namespace { inline void *resourceForContext(const QByteArray &resource) { -#ifndef QT_NO_OPENGL +#if QT_CONFIG(opengl) QOpenGLContext *shareContext = qt_gl_global_share_context(); if (!shareContext) { - qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to call QtWebEngine::initialize() in your main() function."); + qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to " + "call QtWebEngineQuick::initialize() in your main() function."); } return qApp->platformNativeInterface()->nativeResourceForContext(resource, shareContext); #else @@ -81,12 +58,21 @@ void GLContextHelper::initialize() { if (!contextHelper) contextHelper = new GLContextHelper; +#if QT_CONFIG(opengl) + if (QGuiApplication::platformName() == QLatin1String("offscreen")){ + contextHelper->m_robustness = false; + return; + } + + if (QOpenGLContext *context = qt_gl_global_share_context()) + contextHelper->m_robustness = context->format().testOption(QSurfaceFormat::ResetNotification); +#endif } void GLContextHelper::destroy() { delete contextHelper; - contextHelper = 0; + contextHelper = nullptr; } bool GLContextHelper::initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs) @@ -114,12 +100,13 @@ void* GLContextHelper::getEGLConfig() void* GLContextHelper::getGlXConfig() { - return resourceForContext(QByteArrayLiteral("glxconfig")); + QByteArray resource = QByteArrayLiteral("glxconfig"); + return resourceForContext(resource); } void* GLContextHelper::getEGLDisplay() { -#ifdef Q_OS_WIN +#if BUILDFLAG(IS_WIN) // Windows QPA plugin does not implement resourceForIntegration for "egldisplay". // Use resourceForContext instead. return resourceForContext(QByteArrayLiteral("egldisplay")); @@ -130,10 +117,12 @@ void* GLContextHelper::getEGLDisplay() void* GLContextHelper::getXDisplay() { - QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface(); - if (pni) - return pni->nativeResourceForScreen(QByteArrayLiteral("display"), qApp->primaryScreen()); +#if QT_CONFIG(xcb) + auto *x11app = qGuiApp->nativeInterface<QNativeInterface::QX11Application>(); + return x11app ? x11app->display() : nullptr; +#else return nullptr; +#endif } void* GLContextHelper::getNativeDisplay() @@ -144,7 +133,7 @@ void* GLContextHelper::getNativeDisplay() QFunctionPointer GLContextHelper::getGlXGetProcAddress() { QFunctionPointer get_proc_address = nullptr; -#ifndef QT_NO_OPENGL +#if QT_CONFIG(xcb_glx) if (QOpenGLContext *context = qt_gl_global_share_context()) { get_proc_address = context->getProcAddress("glXGetProcAddress"); } @@ -155,7 +144,7 @@ QFunctionPointer GLContextHelper::getGlXGetProcAddress() QFunctionPointer GLContextHelper::getEglGetProcAddress() { QFunctionPointer get_proc_address = nullptr; -#ifndef QT_NO_OPENGL +#if QT_CONFIG(opengl) if (QOpenGLContext *context = qt_gl_global_share_context()) { get_proc_address = context->getProcAddress("eglGetProcAddress"); } @@ -163,44 +152,251 @@ QFunctionPointer GLContextHelper::getEglGetProcAddress() return get_proc_address; } -bool GLContextHelper::isCreateContextRobustnessSupported() +void *GLContextHelper::getGlxPlatformInterface() { -#if QT_CONFIG(opengl) - if (QGuiApplication::platformName() == QLatin1String("offscreen")) - return false; +#if QT_CONFIG(xcb_glx) + if (QOpenGLContext *context = qt_gl_global_share_context()) + return context->nativeInterface<QNativeInterface::QGLXContext>(); +#endif + return nullptr; +} +void *GLContextHelper::getEglPlatformInterface() +{ +#if QT_CONFIG(opengl) && QT_CONFIG(egl) if (QOpenGLContext *context = qt_gl_global_share_context()) - return context->format().testOption(QSurfaceFormat::ResetNotification); + return context->nativeInterface<QNativeInterface::QEGLContext>(); #endif - return false; + return nullptr; +} + +bool GLContextHelper::isCreateContextRobustnessSupported() +{ + return contextHelper->m_robustness; +} + +#if QT_CONFIG(opengl) && defined(USE_OZONE) +class ScopedGLContext +{ +public: + ScopedGLContext(QOffscreenSurface *surface) + : m_context(new QOpenGLContext()) + , m_previousContext(gl::GLContext::GetCurrent()) + , m_previousSurface(gl::GLSurface::GetCurrent()) + { + if (!m_context->create()) { + qWarning("Failed to create OpenGL context."); + return; + } + + Q_ASSERT(surface->isValid()); + if (!m_context->makeCurrent(surface)) { + qWarning("Failed to make OpenGL context current."); + return; + } + } + + ~ScopedGLContext() + { + if (!m_textures.empty()) { + auto glFun = m_context->functions(); + glFun->glDeleteTextures(m_textures.size(), m_textures.data()); + } + + if (m_previousContext) + m_previousContext->MakeCurrent(m_previousSurface); + } + + bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); } + + EGLDisplay eglDisplay() const + { + QNativeInterface::QEGLContext *nativeInterface = + m_context->nativeInterface<QNativeInterface::QEGLContext>(); + return nativeInterface->display(); + } + + EGLContext eglContext() const + { + QNativeInterface::QEGLContext *nativeInterface = + m_context->nativeInterface<QNativeInterface::QEGLContext>(); + return nativeInterface->nativeContext(); + } + + uint createTexture(int width, int height) + { + auto glFun = m_context->functions(); + + uint glTexture; + glFun->glGenTextures(1, &glTexture); + glFun->glBindTexture(GL_TEXTURE_2D, glTexture); + glFun->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + NULL); + glFun->glBindTexture(GL_TEXTURE_2D, 0); + + m_textures.push_back(glTexture); + return glTexture; + } + +private: + QScopedPointer<QOpenGLContext> m_context; + gl::GLContext *m_previousContext; + gl::GLSurface *m_previousSurface; + std::vector<uint> m_textures; +}; + +EGLHelper::EGLFunctions::EGLFunctions() +{ + const static auto getProcAddress = + reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress()); + + eglCreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(getProcAddress("eglCreateImage")); + eglDestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(getProcAddress("eglDestroyImage")); + eglGetError = reinterpret_cast<PFNEGLGETERRORPROC>(getProcAddress("eglGetError")); + eglExportDMABUFImageMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEMESAPROC>( + getProcAddress("eglExportDMABUFImageMESA")); + eglExportDMABUFImageQueryMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC>( + getProcAddress("eglExportDMABUFImageQueryMESA")); + eglQueryString = reinterpret_cast<PFNEGLQUERYSTRINGPROC>(getProcAddress("eglQueryString")); } + +EGLHelper *EGLHelper::instance() +{ + static EGLHelper eglHelper; + return &eglHelper; +} + +EGLHelper::EGLHelper() + : m_functions(new EGLHelper::EGLFunctions()), m_offscreenSurface(new QOffscreenSurface()) +{ + const char *extensions = m_functions->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (!extensions) { + qWarning("EGL: Failed to query EGL extensions."); + return; + } + + if (strstr(extensions, "EGL_KHR_base_image")) { + qWarning("EGL: EGL_KHR_base_image extension is not supported."); + return; + } + + auto eglDisplay = GLContextHelper::getEGLDisplay(); + if (!eglDisplay) { + qWarning("EGL: No EGL display."); + return; + } + + Q_ASSERT(QThread::currentThread() == qApp->thread()); + m_offscreenSurface->create(); + + const char *displayExtensions = m_functions->eglQueryString(eglDisplay, EGL_EXTENSIONS); + m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import") + && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers") + && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export"); + + if (m_isDmaBufSupported) { + // FIXME: This disables GBM for nvidia. Remove this when nvidia fixes its GBM support. + // + // "Buffer allocation and submission to DRM KMS using gbm is not currently supported." + // See: https://download.nvidia.com/XFree86/Linux-x86_64/550.40.07/README/kms.html + // + // Chromium uses GBM to allocate scanout buffers. Scanout requires DRM KMS. If KMS is + // enabled, gbm_device and gbm_buffer are created without any issues but rendering to the + // buffer will malfunction. It is not known how to detect this problem before rendering + // so we just disable GBM for nvidia. + const char *displayVendor = m_functions->eglQueryString(eglDisplay, EGL_VENDOR); + m_isDmaBufSupported = !strstr(displayVendor, "NVIDIA"); + } + + // Try to create dma-buf. + if (m_isDmaBufSupported) { + int fd = -1; + queryDmaBuf(2, 2, &fd, nullptr, nullptr, nullptr); + if (fd == -1) + m_isDmaBufSupported = false; + else + close(fd); + } +} + +void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset, + uint64_t *modifiers) +{ + if (!m_isDmaBufSupported) + return; + + ScopedGLContext context(m_offscreenSurface.get()); + if (!context.isValid()) + return; + + EGLDisplay eglDisplay = context.eglDisplay(); + EGLContext eglContext = context.eglContext(); + if (!eglContext) { + qWarning("EGL: No EGLContext."); + return; + } + + uint64_t textureId = context.createTexture(width, height); + EGLImage eglImage = m_functions->eglCreateImage(eglDisplay, eglContext, EGL_GL_TEXTURE_2D, + (EGLClientBuffer)textureId, NULL); + if (eglImage == EGL_NO_IMAGE) { + qWarning() << "EGL: Failed to create EGLImage:" + << ui::GetEGLErrorString(m_functions->eglGetError()); + return; + } + + int numPlanes = 0; + if (!m_functions->eglExportDMABUFImageQueryMESA(eglDisplay, eglImage, nullptr, &numPlanes, + modifiers)) + qWarning() << "EGL: Failed to retrieve the pixel format of the buffer:" + << ui::GetEGLErrorString(m_functions->eglGetError()); + Q_ASSERT(numPlanes == 1); + + if (!m_functions->eglExportDMABUFImageMESA(eglDisplay, eglImage, fd, stride, offset)) + qWarning() << "EGL: Failed to retrieve the dma_buf file descriptor:" + << ui::GetEGLErrorString(m_functions->eglGetError()); + + m_functions->eglDestroyImage(eglDisplay, eglImage); +} + +bool EGLHelper::isDmaBufSupported() +{ + return m_isDmaBufSupported; +} +#endif // QT_CONFIG(opengl) && defined(USE_OZONE) + QT_END_NAMESPACE -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) namespace gl { namespace init { -scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group, - GLSurface* compatible_surface, - const GLContextAttribs& attribs) +scoped_refptr<GLContext> CreateGLContext(GLShareGroup *share_group, + GLSurface *compatible_surface, + const GLContextAttribs &attribs) { - scoped_refptr<GLContext> context; - if (GetGLImplementation() == kGLImplementationDesktopGL) { - context = new GLContextWGL(share_group); + switch (GetGLImplementation()) { + case kGLImplementationDesktopGLCoreProfile: + case kGLImplementationDesktopGL: { + scoped_refptr<GLContext> context = new GLContextWGL(share_group); if (!context->Initialize(compatible_surface, attribs)) return nullptr; return context; - } else { - context = new GLContextEGL(share_group); } - - if (!GLContextHelper::initializeContext(context.get(), compatible_surface, attribs)) + case kGLImplementationEGLANGLE: + case kGLImplementationEGLGLES2: + return InitializeGLContext(new GLContextEGL(share_group), + compatible_surface, attribs); + case kGLImplementationDisabled: return nullptr; - - return context; + default: + break; + } + Q_UNREACHABLE(); + return nullptr; } } // namespace init } // namespace gl -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h index 8559af313..41c6a5f0c 100644 --- a/src/core/ozone/gl_context_qt.h +++ b/src/core/ozone/gl_context_qt.h @@ -1,55 +1,28 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef GL_GL_CONTEXT_QT_H_ #define GL_GL_CONTEXT_QT_H_ #include <QObject> +#include <QtCore/qscopedpointer.h> +#include <QtGui/qtgui-config.h> + #include "ui/gl/gl_context.h" +#if QT_CONFIG(opengl) && defined(USE_OZONE) +#include <EGL/egl.h> +#include <EGL/eglext.h> +#endif + namespace gl { -class GLContext; class GLSurface; } QT_BEGIN_NAMESPACE +class QOffscreenSurface; + class GLContextHelper : public QObject { Q_OBJECT public: @@ -65,12 +38,54 @@ public: static QFunctionPointer getGlXGetProcAddress(); static QFunctionPointer getEglGetProcAddress(); static bool isCreateContextRobustnessSupported(); + static void *getGlxPlatformInterface(); + static void *getEglPlatformInterface(); private: Q_INVOKABLE bool initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs); static GLContextHelper* contextHelper; + bool m_robustness = false; +}; + +#if QT_CONFIG(opengl) && defined(USE_OZONE) +#undef eglCreateImage +#undef eglDestroyImage +#undef eglExportDMABUFImageMESA +#undef eglExportDMABUFImageQueryMESA +#undef eglGetError +#undef eglQueryString + +class EGLHelper +{ +public: + struct EGLFunctions + { + EGLFunctions(); + + PFNEGLCREATEIMAGEPROC eglCreateImage; + PFNEGLDESTROYIMAGEPROC eglDestroyImage; + PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA; + PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA; + PFNEGLGETERRORPROC eglGetError; + PFNEGLQUERYSTRINGPROC eglQueryString; + }; + + static EGLHelper *instance(); + + EGLFunctions *functions() const { return m_functions.get(); } + void queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset, + uint64_t *modifiers); + bool isDmaBufSupported(); + +private: + EGLHelper(); + + QScopedPointer<EGLFunctions> m_functions; + QScopedPointer<QOffscreenSurface> m_offscreenSurface; + bool m_isDmaBufSupported = false; }; +#endif // QT_CONFIG(opengl) && defined(USE_OZONE) QT_END_NAMESPACE diff --git a/src/core/ozone/gl_ozone_egl_qt.cpp b/src/core/ozone/gl_ozone_egl_qt.cpp index 2fa86d79b..26d11df31 100644 --- a/src/core/ozone/gl_ozone_egl_qt.cpp +++ b/src/core/ozone/gl_ozone_egl_qt.cpp @@ -1,140 +1,70 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #if defined(USE_OZONE) -#include "gl_ozone_egl_qt.h" -#include "gl_context_qt.h" -#include "gl_surface_egl_qt.h" -#include "base/files/file_path.h" -#include "base/native_library.h" #include "gl_context_qt.h" #include "gl_ozone_egl_qt.h" -#include "ui/gl/gl_context_egl.h" -#include "ui/gl/gl_implementation.h" -#include "ui/gl/gl_surface.h" -#include "ui/gl/init/gl_factory.h" -#include "ui/gl/init/gl_initializer.h" - - -#include <EGL/egl.h> -#include <dlfcn.h> - -#include <QtGui/qtgui-config.h> // for QT_NO_OPENGL +#include "gl_surface_egl_qt.h" -#ifndef QT_NO_OPENGL -#include <QOpenGLContext> -QT_BEGIN_NAMESPACE -Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); -QT_END_NAMESPACE -#endif +#include "media/gpu/buildflags.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_display.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/gl_utils.h" +#include "ui/ozone/common/native_pixmap_egl_binding.h" namespace ui { -base::NativeLibrary LoadLibrary(const base::FilePath& filename) { - base::NativeLibraryLoadError error; - base::NativeLibrary library = base::LoadNativeLibrary(filename, &error); - if (!library) { - LOG(ERROR) << "Failed to load " << filename.MaybeAsASCII() << ": " << error.ToString(); - return NULL; - } - return library; -} - -bool GLOzoneEGLQt::LoadGLES2Bindings(gl::GLImplementation /*implementation*/) +bool LoadQtEGLBindings() { - base::NativeLibrary eglgles2Library = dlopen(NULL, RTLD_LAZY); - if (!eglgles2Library) { - LOG(ERROR) << "Failed to open EGL/GLES2 context " << dlerror(); - return false; - } - - gl::GLGetProcAddressProc get_proc_address = - reinterpret_cast<gl::GLGetProcAddressProc>( - base::GetFunctionPointerFromNativeLibrary(eglgles2Library, - "eglGetProcAddress")); -#ifndef QT_NO_OPENGL - if (!get_proc_address) { - // QTBUG-63341 most likely libgles2 not linked with libegl -> fallback to qpa - if (QOpenGLContext *context = qt_gl_global_share_context()) { - get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>( - context->getProcAddress("eglGetProcAddress")); - } - } -#endif - + gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress()); if (!get_proc_address) { LOG(ERROR) << "eglGetProcAddress not found."; - base::UnloadNativeLibrary(eglgles2Library); return false; } - gl::SetGLGetProcAddressProc(get_proc_address); - gl::AddGLNativeLibrary(eglgles2Library); return true; } -bool GLOzoneEGLQt::InitializeGLOneOffPlatform() +bool GLOzoneEGLQt::LoadGLES2Bindings(const gl::GLImplementationParts & /*implementation*/) { - if (!gl::GLSurfaceEGLQt::InitializeOneOff()) { - LOG(ERROR) << "GLOzoneEGLQt::InitializeOneOff failed."; - return false; + return LoadQtEGLBindings(); +} + +gl::GLDisplay *GLOzoneEGLQt::InitializeGLOneOffPlatform(bool supports_angle, + std::vector<gl::DisplayType> init_displays, + gl::GpuPreference gpu_preference) +{ + if (auto display = gl::GLSurfaceEGLQt::InitializeOneOff(gpu_preference)) { + if (!static_cast<gl::GLDisplayEGL*>(display)->Initialize(supports_angle, std::move(init_displays), GetNativeDisplay())) { + LOG(ERROR) << "GLDisplayEGL::Initialize failed."; + return nullptr; + } + return display; } - return true; + return nullptr; } -bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform() + +bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) { - return gl::GLSurfaceEGLQt::InitializeExtensionSettingsOneOff(); + return static_cast<gl::GLDisplayEGL*>(display)->InitializeExtensionSettings(); } -scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gfx::AcceleratedWidget window) +scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gl::GLDisplay* display, gfx::AcceleratedWidget window) { + Q_UNUSED(display); + Q_UNUSED(window); return nullptr; } -scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(const gfx::Size &size) +scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(gl::GLDisplay* display, const gfx::Size &size) { - scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(size); + scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(static_cast<gl::GLDisplayEGL*>(display), size); if (surface->Initialize(gl::GLSurfaceFormat())) return surface; - surface = new gl::GLSurfacelessQtEGL(size); + surface = new gl::GLSurfacelessQtEGL(static_cast<gl::GLDisplayEGL*>(display), size); if (surface->Initialize(gl::GLSurfaceFormat())) return surface; @@ -142,14 +72,29 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(const gfx::S return nullptr; } -intptr_t GLOzoneEGLQt::GetNativeDisplay() +gl::EGLDisplayPlatform GLOzoneEGLQt::GetNativeDisplay() { static void *display = GLContextHelper::getNativeDisplay(); + static gl::EGLDisplayPlatform platform(display ? reinterpret_cast<intptr_t>(display) : EGL_DEFAULT_DISPLAY); + return platform; +} - if (display) - return reinterpret_cast<intptr_t>(display); +bool GLOzoneEGLQt::CanImportNativePixmap() +{ + return gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_EXT_image_dma_buf_import; +} - return reinterpret_cast<intptr_t>(EGL_DEFAULT_DISPLAY); +std::unique_ptr<NativePixmapGLBinding> GLOzoneEGLQt::ImportNativePixmap( + scoped_refptr<gfx::NativePixmap> pixmap, + gfx::BufferFormat plane_format, + gfx::BufferPlane plane, + gfx::Size plane_size, + const gfx::ColorSpace &color_space, + GLenum target, + GLuint texture_id) +{ + return NativePixmapEGLBinding::Create(pixmap, plane_format, plane, plane_size, color_space, + target, texture_id); } } // namespace ui diff --git a/src/core/ozone/gl_ozone_egl_qt.h b/src/core/ozone/gl_ozone_egl_qt.h index c24d03a81..7ac55979a 100644 --- a/src/core/ozone/gl_ozone_egl_qt.h +++ b/src/core/ozone/gl_ozone_egl_qt.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef GL_OZONE_EGL_QT #define GL_OZONE_EGL_QT @@ -48,20 +12,33 @@ namespace ui { class GLOzoneEGLQt : public GLOzoneEGL { public: - bool InitializeGLOneOffPlatform() override; - bool InitializeExtensionSettingsOneOffPlatform() override; + gl::GLDisplay *InitializeGLOneOffPlatform(bool supports_angle, + std::vector<gl::DisplayType> init_displays, + gl::GpuPreference gpu_preference) override; + bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override; scoped_refptr<gl::GLSurface> CreateViewGLSurface( + gl::GLDisplay *display, gfx::AcceleratedWidget window) override; scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface( - const gfx::Size& size) override; + gl::GLDisplay *display, + const gfx::Size &size) override; + bool CanImportNativePixmap() override; + std::unique_ptr<NativePixmapGLBinding> ImportNativePixmap( + scoped_refptr<gfx::NativePixmap> pixmap, + gfx::BufferFormat plane_format, + gfx::BufferPlane plane, + gfx::Size plane_size, + const gfx::ColorSpace &color_space, + GLenum target, + GLuint texture_id) override; protected: // Returns native platform display handle. This is used to obtain the EGL // display connection for the native display. - intptr_t GetNativeDisplay() override; + gl::EGLDisplayPlatform GetNativeDisplay() override; // Sets up GL bindings for the native surface. - bool LoadGLES2Bindings(gl::GLImplementation implementation) override; + bool LoadGLES2Bindings(const gl::GLImplementationParts &implementation) override; }; } // namespace ui diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp index f934a5c80..23ba92ea4 100644 --- a/src/core/ozone/gl_ozone_glx_qt.cpp +++ b/src/core/ozone/gl_ozone_glx_qt.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -45,23 +9,25 @@ #include "gl_ozone_glx_qt.h" #include "gl_surface_glx_qt.h" #include "gl_context_qt.h" + +#include "media/gpu/buildflags.h" #include "ui/gl/gl_context_glx.h" #include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_glx_api_implementation.h" +#include "ui/gl/presenter.h" + #include <dlfcn.h> namespace ui { -bool GLOzoneGLXQt::InitializeGLOneOffPlatform() { - if (!gl::GLSurfaceGLXQt::InitializeOneOff()) { - LOG(ERROR) << "GLSurfaceGLXQt::InitializeOneOff failed."; - return false; - } - return true; +gl::GLDisplay *GLOzoneGLXQt::InitializeGLOneOffPlatform(bool, std::vector<gl::DisplayType>, gl::GpuPreference preference) +{ + return gl::GLSurfaceGLXQt::InitializeOneOff(preference); } bool GLOzoneGLXQt::InitializeStaticGLBindings( - gl::GLImplementation implementation) { + const gl::GLImplementationParts &implementation) { + Q_UNUSED(implementation); base::NativeLibrary library = dlopen(NULL, RTLD_LAZY); if (!library) { @@ -95,17 +61,12 @@ bool GLOzoneGLXQt::InitializeStaticGLBindings( return true; } -void GLOzoneGLXQt::InitializeDebugGLBindings() { - gl::InitializeDebugGLBindingsGL(); - gl::InitializeDebugGLBindingsGLX(); -} - void GLOzoneGLXQt::SetDisabledExtensionsPlatform( const std::string& disabled_extensions) { gl::SetDisabledExtensionsGLX(disabled_extensions); } -void GLOzoneGLXQt::ShutdownGL() { +void GLOzoneGLXQt::ShutdownGL(gl::GLDisplay *) { gl::ClearBindingsGL(); gl::ClearBindingsGLX(); } @@ -126,16 +87,19 @@ scoped_refptr<gl::GLContext> GLOzoneGLXQt::CreateGLContext( } scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateViewGLSurface( + gl::GLDisplay* display, gfx::AcceleratedWidget window) { return nullptr; } -scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateSurfacelessViewGLSurface( +scoped_refptr<gl::Presenter> GLOzoneGLXQt::CreateSurfacelessViewGLSurface( + gl::GLDisplay* display, gfx::AcceleratedWidget window) { return nullptr; } scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface( + gl::GLDisplay* display, const gfx::Size& size) { scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceGLXQt(size); if (surface->Initialize(gl::GLSurfaceFormat())) @@ -144,7 +108,19 @@ scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface( return nullptr; } -bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform() +bool GLOzoneGLXQt::CanImportNativePixmap() +{ + return false; +} + +std::unique_ptr<ui::NativePixmapGLBinding> GLOzoneGLXQt::ImportNativePixmap( + scoped_refptr<gfx::NativePixmap> pixmap, gfx::BufferFormat plane_format, gfx::BufferPlane plane, + gfx::Size plane_size, const gfx::ColorSpace &, GLenum target, GLuint texture_id) +{ + return nullptr; +} + +bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *) { return gl::GLSurfaceGLXQt::InitializeExtensionSettingsOneOff(); } diff --git a/src/core/ozone/gl_ozone_glx_qt.h b/src/core/ozone/gl_ozone_glx_qt.h index 1596ea12f..4df26ba71 100644 --- a/src/core/ozone/gl_ozone_glx_qt.h +++ b/src/core/ozone/gl_ozone_glx_qt.h @@ -1,46 +1,9 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef UI_OZONE_GLX_QT_H_ -#define UI_OZONE_GLX_QT_H +#define UI_OZONE_GLX_QT_H_ -#include "base/macros.h" #include "ui/gl/gl_implementation.h" #include "ui/ozone/public/gl_ozone.h" @@ -52,35 +15,39 @@ public: GLOzoneGLXQt() {} ~GLOzoneGLXQt() override {} - bool InitializeGLOneOffPlatform() override; - bool InitializeStaticGLBindings(gl::GLImplementation implementation) override; - void InitializeDebugGLBindings() override; - bool InitializeExtensionSettingsOneOffPlatform() override; - void ShutdownGL() override; + gl::GLDisplay *InitializeGLOneOffPlatform(bool, std::vector<gl::DisplayType>, gl::GpuPreference) override; + bool InitializeStaticGLBindings(const gl::GLImplementationParts &implementation) override; + bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override; + void ShutdownGL(gl::GLDisplay *display) override; void SetDisabledExtensionsPlatform( const std::string& disabled_extensions) override; bool GetGLWindowSystemBindingInfo( const gl::GLVersionInfo &gl_info, gl::GLWindowSystemBindingInfo *info) override; + bool CanImportNativePixmap() override; + std::unique_ptr<ui::NativePixmapGLBinding> ImportNativePixmap( + scoped_refptr<gfx::NativePixmap>, gfx::BufferFormat, gfx::BufferPlane, + gfx::Size, const gfx::ColorSpace &, GLenum, GLuint) override; + scoped_refptr<gl::GLContext> CreateGLContext( gl::GLShareGroup* share_group, gl::GLSurface* compatible_surface, const gl::GLContextAttribs& attribs) override; scoped_refptr<gl::GLSurface> CreateViewGLSurface( + gl::GLDisplay* display, gfx::AcceleratedWidget window) override; - scoped_refptr<gl::GLSurface> CreateSurfacelessViewGLSurface( + scoped_refptr<gl::Presenter> CreateSurfacelessViewGLSurface( + gl::GLDisplay* display, gfx::AcceleratedWidget window) override; scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface( + gl::GLDisplay* display, const gfx::Size& size) override; - -private: - DISALLOW_COPY_AND_ASSIGN(GLOzoneGLXQt); }; } // namespace ui -#endif // UI_OZONE_GLX_QT_H +#endif // UI_OZONE_GLX_QT_H_ diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp new file mode 100644 index 000000000..f2078b597 --- /dev/null +++ b/src/core/ozone/gl_share_context_qt.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "gl_share_context_qt.h" +#include <QtGui/qtgui-config.h> +#include <qpa/qplatformnativeinterface.h> + +#include "ui/gl/gl_context_egl.h" +#include "ui/gl/gl_implementation.h" + +#if QT_CONFIG(opengl) +#include <QtGui/qopenglcontext_platform.h> +#include <QOpenGLContext> +#include <QOpenGLExtraFunctions> +#endif // QT_CONFIG(opengl) + +namespace QtWebEngineCore { + +QtShareGLContext::QtShareGLContext(QOpenGLContext *context) + : gl::GLContext(nullptr), m_handle(nullptr) +{ +#if QT_CONFIG(opengl) +#if defined(Q_OS_MACOS) + qFatal("macOS only support using ANGLE."); +#endif +#if defined(Q_OS_WIN) + auto *win_ctx = context->nativeInterface<QNativeInterface::QWGLContext>(); + if (win_ctx && !m_handle) + m_handle = (void *)win_ctx->nativeContext(); +#endif +#if QT_CONFIG(xcb_glx_plugin) + auto *glx_ctx = context->nativeInterface<QNativeInterface::QGLXContext>(); + if (glx_ctx && !m_handle) + m_handle = (void *)glx_ctx->nativeContext(); +#endif +#if QT_CONFIG(egl) + auto *egl_ctx = context->nativeInterface<QNativeInterface::QEGLContext>(); + if (egl_ctx && !m_handle) + m_handle = (void *)egl_ctx->nativeContext(); +#endif + if (!m_handle) + qFatal("Could not get handle for shared context."); +#endif // QT_CONFIG(opengl) +} + +QtShareGLContext::~QtShareGLContext() +{ + OnContextWillDestroy(); +} + +unsigned int QtShareGLContext::CheckStickyGraphicsResetStatusImpl() +{ +#if QT_CONFIG(opengl) + if (QOpenGLContext *context = QOpenGLContext::globalShareContext()) { + if (context->format().testOption(QSurfaceFormat::ResetNotification)) + return context->extraFunctions()->glGetGraphicsResetStatus(); + } +#endif + return 0 /*GL_NO_ERROR*/; +} + +void ShareGroupQt::AboutToAddFirstContext() +{ + if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) { + m_shareContextQt = new gl::GLContextEGL(nullptr); + return; + } + +#if QT_CONFIG(opengl) + // This currently has to be setup by ::main in all applications using QQuickWebEngineView with + // delegated rendering. + QOpenGLContext *shareContext = QOpenGLContext::globalShareContext(); + if (!shareContext) { + qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to " + "call QtWebEngineQuick::initialize() in your main() function before " + "QCoreApplication is created."); + } + m_shareContextQt = new QtShareGLContext(shareContext); +#endif // QT_CONFIG(opengl) +} + +} // namespace diff --git a/src/core/ozone/gl_share_context_qt.h b/src/core/ozone/gl_share_context_qt.h new file mode 100644 index 000000000..6b0546a72 --- /dev/null +++ b/src/core/ozone/gl_share_context_qt.h @@ -0,0 +1,64 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef GL_SHARE_CONTEXT_QT +#define GL_SHARE_CONTEXT_QT + +#include "ui/gl/gpu_timing.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_share_group.h" +#include "qtwebenginecoreglobal.h" + +QT_FORWARD_DECLARE_CLASS(QOpenGLContext) + +namespace QtWebEngineCore { + +class QtShareGLContext : public gl::GLContext +{ + +public: + QtShareGLContext(QOpenGLContext *qtContext); + ~QtShareGLContext() override; + void *GetHandle() override { return m_handle; } + unsigned int CheckStickyGraphicsResetStatusImpl() override; + // We don't care about the rest, this context shouldn't be used except for its handle. + bool InitializeImpl(gl::GLSurface *, const gl::GLContextAttribs &) override + { + Q_UNREACHABLE(); + return false; + } + bool MakeCurrentImpl(gl::GLSurface *) override + { + Q_UNREACHABLE(); + return false; + } + void ReleaseCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); } + bool IsCurrent(gl::GLSurface *) override + { + Q_UNREACHABLE(); + return false; + } + scoped_refptr<gl::GPUTimingClient> CreateGPUTimingClient() override { return nullptr; } + const gfx::ExtensionSet &GetExtensions() override + { + static const gfx::ExtensionSet s_emptySet; + return s_emptySet; + } + void ResetExtensions() override {} + +private: + void *m_handle; +}; + +class ShareGroupQt : public gl::GLShareGroup +{ + +public: + gl::GLContext *GetContext() override { return m_shareContextQt.get(); } + void AboutToAddFirstContext() override; + +private: + scoped_refptr<gl::GLContext> m_shareContextQt; +}; +} // namespace +#endif diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp index 97c6cdee6..a0c120ac6 100644 --- a/src/core/ozone/gl_surface_egl_qt.cpp +++ b/src/core/ozone/gl_surface_egl_qt.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -44,55 +8,60 @@ #include "gl_context_qt.h" #include "ozone/gl_surface_egl_qt.h" -#if !defined(OS_MACOSX) #include "ui/gl/egl_util.h" -#include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_display.h" +#include "ui/gl/gl_display_manager.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 +#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN) using ui::GetLastEGLErrorString; -namespace gl{ +namespace gl { bool GLSurfaceEGLQt::g_egl_surfaceless_context_supported = false; bool GLSurfaceEGLQt::s_initialized = false; +GLSurfaceEGLQt::GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size) + : GLSurfaceQt(size), + m_surfaceBuffer(0) +{ +} + GLSurfaceEGLQt::~GLSurfaceEGLQt() { Destroy(); } -bool GLSurfaceEGLQt::InitializeOneOff() +gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(gl::GpuPreference preference) { if (s_initialized) - return true; + return g_display; - g_display = GLContextHelper::getEGLDisplay(); - if (!g_display) { + auto *egl_display = GLDisplayManagerEGL::GetInstance()->GetDisplay(preference); + g_display = egl_display; + egl_display->SetDisplay(GLContextHelper::getEGLDisplay()); + if (!egl_display->GetDisplay()) { LOG(ERROR) << "GLContextHelper::getEGLDisplay() failed."; - return false; + return nullptr; } g_config = GLContextHelper::getEGLConfig(); if (!g_config) { LOG(ERROR) << "GLContextHelper::getEGLConfig() failed."; - return false; + return nullptr; } - if (!eglInitialize(g_display, NULL, NULL)) { + if (!eglInitialize(egl_display->GetDisplay(), NULL, NULL)) { LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); - return false; + return nullptr; } - g_extensions = eglQueryString(g_display, EGL_EXTENSIONS); - g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context"); + g_extensions = eglQueryString(egl_display->GetDisplay(), EGL_EXTENSIONS); + g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions.c_str(), "EGL_KHR_surfaceless_context"); if (g_egl_surfaceless_context_supported) { - scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1)); + scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(egl_display, gfx::Size(1, 1)); gl::GLContextAttribs attribs; scoped_refptr<GLContext> context = init::CreateGLContext( NULL, surface.get(), attribs); @@ -107,8 +76,9 @@ bool GLSurfaceEGLQt::InitializeOneOff() context->ReleaseCurrent(surface.get()); } } + s_initialized = true; - return true; + return egl_display; } bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff() @@ -116,95 +86,12 @@ bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff() return s_initialized; } -bool GLSurfaceEGL::InitializeExtensionSettingsOneOff() -{ - return GLSurfaceEGLQt::InitializeExtensionSettingsOneOff(); -} - -EGLDisplay GLSurfaceEGL::GetHardwareDisplay() -{ - return static_cast<EGLDisplay>(GLSurfaceQt::g_display); -} - -bool GLSurfaceEGL::IsCreateContextRobustnessSupported() -{ - return GLContextHelper::isCreateContextRobustnessSupported() && HasEGLExtension("EGL_EXT_create_context_robustness"); -} - -bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() -{ - return false; -} -bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() -{ - return GLSurfaceEGLQt::g_egl_surfaceless_context_supported; -} -bool GLSurfaceEGL::IsEGLContextPrioritySupported() -{ - return false; -} - -bool GLSurfaceEGL::IsRobustResourceInitSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsCreateContextClientArraysSupported() -{ - return false; -} - -bool GLSurfaceEGL::IsPixelFormatFloatSupported() -{ - 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; + EGLDisplay display = GLContextHelper::getEGLDisplay(); if (!display) { LOG(ERROR) << "Trying to create surface with invalid display."; return false; @@ -232,7 +119,7 @@ bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format) void GLSurfaceEGLQt::Destroy() { if (m_surfaceBuffer) { - if (!eglDestroySurface(g_display, m_surfaceBuffer)) + if (!eglDestroySurface(GLContextHelper::getEGLDisplay(), m_surfaceBuffer)) LOG(ERROR) << "eglDestroySurface failed with error " << GetLastEGLErrorString(); m_surfaceBuffer = 0; @@ -240,7 +127,7 @@ void GLSurfaceEGLQt::Destroy() } bool GLSurfaceEGLQt::Resize(const gfx::Size& size, float scale_factor, - ColorSpace color_space, bool has_alpha) + const gfx::ColorSpace &color_space, bool has_alpha) { if (size == m_size) return true; @@ -270,7 +157,7 @@ void* GLSurfaceEGLQt::GetHandle() return reinterpret_cast<void*>(m_surfaceBuffer); } -GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) +GLSurfacelessQtEGL::GLSurfacelessQtEGL(GLDisplayEGL *display, const gfx::Size& size) : GLSurfaceQt(size) { } @@ -291,7 +178,7 @@ bool GLSurfacelessQtEGL::IsSurfaceless() const } bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, - ColorSpace color_space, bool has_alpha) + const gfx::ColorSpace &color_space, bool has_alpha) { m_size = size; return true; @@ -307,26 +194,5 @@ 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 -#else -namespace gl { -struct GL_EXPORT DriverEGL { - static std::string GetPlatformExtensions(); -}; - -std::string DriverEGL::GetPlatformExtensions() -{ - return ""; -} } // namespace gl -#endif // !defined(OS_MACOSX) +#endif // !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN) diff --git a/src/core/ozone/gl_surface_egl_qt.h b/src/core/ozone/gl_surface_egl_qt.h index ecc2327b3..d581f9079 100644 --- a/src/core/ozone/gl_surface_egl_qt.h +++ b/src/core/ozone/gl_surface_egl_qt.h @@ -1,63 +1,29 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #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 GLDisplayEGL; + class GLSurfaceEGLQt: public GLSurfaceQt { public: - explicit GLSurfaceEGLQt(const gfx::Size& size); + explicit GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size); - static bool InitializeOneOff(); + static gl::GLDisplay *InitializeOneOff(gl::GpuPreference preference); 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; + const gfx::ColorSpace &color_space, bool has_alpha) override; + protected: ~GLSurfaceEGLQt(); @@ -68,7 +34,6 @@ public: 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: @@ -78,19 +43,16 @@ private: class GLSurfacelessQtEGL : public GLSurfaceQt { public: - explicit GLSurfacelessQtEGL(const gfx::Size& size); + explicit GLSurfacelessQtEGL(gl::GLDisplayEGL *display, 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; + const gfx::ColorSpace &color_space, bool has_alpha) override; EGLSurface GetHandle() override; void* GetShareHandle() override; - -private: - DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL); }; } diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp index e150c940a..61c9ef9de 100644 --- a/src/core/ozone/gl_surface_glx_qt.cpp +++ b/src/core/ozone/gl_surface_glx_qt.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -43,27 +7,23 @@ #include "gl_context_qt.h" #include "ozone/gl_surface_glx_qt.h" + #include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_display.h" +#include "ui/gl/gl_display_manager.h" +#include "ui/gl/gl_surface.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() +static bool HasGLXExtension(const char *name) { + return GLSurface::ExtensionsContain(GLSurfaceQt::g_extensions.c_str(), name); } bool GLSurfaceGLX::IsCreateContextSupported() { - return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context"); + return HasGLXExtension("GLX_ARB_create_context"); } bool GLSurfaceGLX::IsCreateContextRobustnessSupported() @@ -71,16 +31,6 @@ bool GLSurfaceGLX::IsCreateContextRobustnessSupported() return GLContextHelper::isCreateContextRobustnessSupported() && HasGLXExtension("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"); @@ -88,92 +38,83 @@ bool GLSurfaceGLX::IsCreateContextProfileSupported() bool GLSurfaceGLX::IsCreateContextES2ProfileSupported() { - return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context_es2_profile"); + return HasGLXExtension("GLX_ARB_create_context_es2_profile"); } -bool GLSurfaceGLX::IsOMLSyncControlSupported() +bool GLSurfaceGLX::IsRobustnessVideoMemoryPurgeSupported() { - return false; // ExtensionsContain(g_extensions, "GLX_OML_sync_control"); + return false; } -bool GLSurfaceGLX::HasGLXExtension(const char *name) -{ - return ExtensionsContain(GLSurfaceQt::g_extensions, name); -} -bool GLSurfaceGLX::IsTextureFromPixmapSupported() +bool GLSurfaceGLXQt::s_initialized = false; + +GLSurfaceGLXQt::GLSurfaceGLXQt(const gfx::Size& size) + : GLSurfaceQt(size), + m_surfaceBuffer(0) { - return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_EXT_texture_from_pixmap"); } -const char* GLSurfaceGLX::GetGLXExtensions() +GLSurfaceGLXQt::~GLSurfaceGLXQt() { - return GLSurfaceQt::g_extensions; + Destroy(); } -bool GLSurfaceGLXQt::InitializeOneOff() +GLDisplay *GLSurfaceGLXQt::InitializeOneOff(gl::GpuPreference preference) { if (s_initialized) - return true; + return g_display; - XInitThreads(); - - g_display = GLContextHelper::getXDisplay(); - if (!g_display) { + g_display = GLDisplayManagerX11::GetInstance()->GetDisplay(preference); + if (!g_display->GetDisplay()) { LOG(ERROR) << "GLContextHelper::getXDisplay() failed."; - return false; + return nullptr; } g_config = GLContextHelper::getGlXConfig(); if (!g_config) { LOG(ERROR) << "GLContextHelper::getGlxConfig() failed."; - return false; + return nullptr; } - Display* display = static_cast<Display*>(g_display); + Display* display = static_cast<Display*>(g_display->GetDisplay()); int major, minor; if (!glXQueryVersion(display, &major, &minor)) { LOG(ERROR) << "glxQueryVersion failed."; - return false; + return nullptr; } if (major == 1 && minor < 3) { LOG(ERROR) << "GLX 1.3 or later is required."; - return false; + return nullptr; } s_initialized = true; - return true; + return g_display; } - bool GLSurfaceGLXQt::InitializeExtensionSettingsOneOff() { if (!s_initialized) return false; - Display* display = static_cast<Display*>(g_display); + Display* display = static_cast<Display*>(g_display->GetDisplay()); GLSurfaceQt::g_extensions = glXQueryExtensionsString(display, 0); - g_driver_glx.InitializeExtensionBindings(g_extensions); + g_driver_glx.InitializeExtensionBindings(g_extensions.c_str()); return true; } -bool GLSurfaceGLX::InitializeExtensionSettingsOneOff() -{ - return GLSurfaceGLXQt::InitializeExtensionSettingsOneOff(); -} - bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format) { Q_ASSERT(!m_surfaceBuffer); - Display* display = static_cast<Display*>(g_display); + Display* display = static_cast<Display*>(g_display->GetDisplay()); 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, - x11::None // MEMO doc: ...must be terminated with None or NULL + GLX_LARGEST_PBUFFER, GL_FALSE, + GLX_PRESERVED_CONTENTS, GL_FALSE, + GL_NONE // MEMO doc: ...must be terminated with None or NULL }; m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes); @@ -190,17 +131,11 @@ bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format) void GLSurfaceGLXQt::Destroy() { if (m_surfaceBuffer) { - glXDestroyPbuffer(static_cast<Display*>(g_display), m_surfaceBuffer); + glXDestroyPbuffer(static_cast<Display*>(g_display->GetDisplay()), 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); diff --git a/src/core/ozone/gl_surface_glx_qt.h b/src/core/ozone/gl_surface_glx_qt.h index 3a465f448..8cbf1fcf2 100644 --- a/src/core/ozone/gl_surface_glx_qt.h +++ b/src/core/ozone/gl_surface_glx_qt.h @@ -1,58 +1,18 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #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 gl::GLDisplay *InitializeOneOff(gl::GpuPreference preference); static bool InitializeExtensionSettingsOneOff(); bool Initialize(GLSurfaceFormat format) override; @@ -64,8 +24,7 @@ protected: private: static bool s_initialized; - XID m_surfaceBuffer; - DISALLOW_COPY_AND_ASSIGN(GLSurfaceGLXQt); + int m_surfaceBuffer; }; } diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp index 82f8cd0e5..cebeb8b67 100644 --- a/src/core/ozone/gl_surface_qt.cpp +++ b/src/core/ozone/gl_surface_qt.cpp @@ -1,84 +1,39 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // 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.Chromium file. +#include "qtwebenginecoreglobal_p.h" + +#if !defined(Q_OS_MACOS) + #include "gl_surface_qt.h" -#if !defined(OS_MACOSX) +#include "base/logging.h" -#include <QGuiApplication> -#include "gl_context_qt.h" -#include "qtwebenginecoreglobal_p.h" +#if BUILDFLAG(IS_WIN) #include "web_engine_context.h" -#include "ozone/gl_surface_egl_qt.h" +#include "ozone/gl_surface_wgl_qt.h" -#include "base/logging.h" -#include "base/threading/thread_restrictions.h" #include "gpu/ipc/service/image_transport_surface.h" -#include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" +#include "ui/gl/init/gl_display_initializer.h" +#include "ui/gl/direct_composition_support.h" +#include "ui/gl/gl_angle_util_win.h" +#include "ui/gl/gl_display.h" #include "ui/gl/gl_implementation.h" -#include "ui/gl/init/gl_initializer.h" -#include "ui/gl/init/gl_factory.h" -#include "ui/gl/gl_gl_api_implementation.h" -#if defined(OS_WIN) -#include "ozone/gl_surface_wgl_qt.h" - -#include "gpu/ipc/service/direct_composition_surface_win.h" +#include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_utils.h" #include "ui/gl/vsync_provider_win.h" #endif -#include "ozone/gl_surface_egl_qt.h" -#include "ui/gl/gl_egl_api_implementation.h" namespace gl { -namespace { -bool g_initializedEGL = false; -} - -void* GLSurfaceQt::g_display = NULL; -void* GLSurfaceQt::g_config = NULL; -const char* GLSurfaceQt::g_extensions = NULL; +GLDisplay *GLSurfaceQt::g_display = nullptr; +void *GLSurfaceQt::g_config = nullptr; +std::string GLSurfaceQt::g_extensions; GLSurfaceQt::~GLSurfaceQt() { @@ -99,7 +54,7 @@ GLSurfaceQt::GLSurfaceQt(const gfx::Size& size) bool GLSurfaceQt::HasEGLExtension(const char* name) { - return ExtensionsContain(g_extensions, name); + return ExtensionsContain(g_extensions.c_str(), name); } bool GLSurfaceQt::IsOffscreen() @@ -107,7 +62,7 @@ bool GLSurfaceQt::IsOffscreen() return true; } -gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback) +gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback, gfx::FrameData data) { LOG(ERROR) << "Attempted to call SwapBuffers on a pbuffer."; Q_UNREACHABLE(); @@ -124,7 +79,7 @@ GLSurfaceFormat GLSurfaceQt::GetFormat() return m_format; } -void* GLSurfaceQt::GetDisplay() +GLDisplay *GLSurfaceQt::GetGLDisplay() { return g_display; } @@ -134,96 +89,79 @@ void* GLSurfaceQt::GetConfig() return g_config; } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) namespace init { -bool InitializeGLOneOffPlatform() + +gl::GLDisplay *InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference) { VSyncProviderWin::InitializeOneOff(); - if (GetGLImplementation() == kGLImplementationEGLGLES2) - return GLSurfaceEGLQt::InitializeOneOff(); + if (GetGLImplementation() == kGLImplementationDesktopGL || GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) + return GLSurfaceWGLQt::InitializeOneOff(gpu_preference); - if (GetGLImplementation() == kGLImplementationDesktopGL) { - return GLSurfaceWGLQt::InitializeOneOff(); - - // Fallback to trying EGL with desktop GL. - if (GLSurfaceEGLQt::InitializeOneOff()) { - g_initializedEGL = true; - return true; + GLDisplayEGL *display = GetDisplayEGL(gpu_preference); + switch (GetGLImplementation()) { + case kGLImplementationEGLANGLE: + case kGLImplementationEGLGLES2: + if (!InitializeDisplay(display, EGLDisplayPlatform(GetDC(nullptr)))) { + LOG(ERROR) << "GLDisplayEGL::Initialize failed."; + return nullptr; } + if (auto d3d11_device = QueryD3D11DeviceObjectFromANGLE()) + InitializeDirectComposition(std::move(d3d11_device)); + break; + case kGLImplementationMockGL: + case kGLImplementationStubGL: + break; + default: + NOTREACHED(); } - - return false; + return display; } bool usingSoftwareDynamicGL() { +#if QT_CONFIG(opengl) return QtWebEngineCore::usingSoftwareDynamicGL(); +#else + return false; +#endif // QT_CONFIG(opengl) } -scoped_refptr<GLSurface> -CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format) +scoped_refptr<GLSurface> CreateOffscreenGLSurface(GLDisplay *display, const gfx::Size &size) { scoped_refptr<GLSurface> surface; switch (GetGLImplementation()) { case kGLImplementationDesktopGLCoreProfile: case kGLImplementationDesktopGL: { surface = new GLSurfaceWGLQt(size); - if (surface->Initialize(format)) + if (surface->Initialize(GLSurfaceFormat())) return surface; break; } + case kGLImplementationEGLANGLE: case kGLImplementationEGLGLES2: { - 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 (GLSurfaceEGLQt::g_egl_surfaceless_context_supported) { - surface = new GLSurfacelessQtEGL(size); - if (surface->Initialize(format)) - return surface; - } - LOG(ERROR) << "eglCreatePbufferSurface failed and surfaceless context not available"; - LOG(WARNING) << "Failed to create offscreen GL surface"; - break; + GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>(); + if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0) + return InitializeGLSurface(new SurfacelessEGL(display_egl, size)); + return InitializeGLSurface(new PbufferGLSurfaceEGL(display_egl, size)); } default: break; } LOG(ERROR) << "Requested OpenGL implementation is not supported. Implementation: " << GetGLImplementation(); Q_UNREACHABLE(); - return NULL; + return nullptr; } scoped_refptr<GLSurface> -CreateViewGLSurface(gfx::AcceleratedWidget window) +CreateViewGLSurface(GLDisplay *display, gfx::AcceleratedWidget window) { - QT_NOT_USED - return NULL; + return nullptr; } } // namespace init -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) } // namespace gl -#if defined(OS_WIN) -namespace gpu { -class GpuCommandBufferStub; -class GpuChannelManager; -scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface(base::WeakPtr<ImageTransportSurfaceDelegate>, - SurfaceHandle, gl::GLSurfaceFormat) -{ - QT_NOT_USED - return scoped_refptr<gl::GLSurface>(); -} - -bool DirectCompositionSurfaceWin::IsHDRSupported() -{ - return false; -} -} // namespace gpu -#endif -#endif // !defined(OS_MACOSX) +#endif // !defined(Q_OS_MACOS) diff --git a/src/core/ozone/gl_surface_qt.h b/src/core/ozone/gl_surface_qt.h index cbdc8876a..1ae41a078 100644 --- a/src/core/ozone/gl_surface_qt.h +++ b/src/core/ozone/gl_surface_qt.h @@ -1,47 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef GL_SURFACE_QT_H_ #define GL_SURFACE_QT_H_ +#include <string> + #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_surface.h" @@ -54,10 +18,10 @@ public: static bool HasEGLExtension(const char* name); // Implement GLSurface. - void *GetDisplay() override; + GLDisplay *GetGLDisplay() override; void *GetConfig() override; bool IsOffscreen() override; - gfx::SwapResult SwapBuffers(PresentationCallback callback) override; + gfx::SwapResult SwapBuffers(PresentationCallback callback, gfx::FrameData data) override; gfx::Size GetSize() override; GLSurfaceFormat GetFormat() override; @@ -70,13 +34,10 @@ protected: public: static void* g_config; - static void* g_display; - static const char* g_extensions; - -private: - DISALLOW_COPY_AND_ASSIGN(GLSurfaceQt); + static GLDisplay *g_display; + static std::string g_extensions; }; -} +} // namespace gl -#endif +#endif // GL_SURFACE_QT_H_ diff --git a/src/core/ozone/gl_surface_wgl_qt.cpp b/src/core/ozone/gl_surface_wgl_qt.cpp index ac27a9c20..db4aed884 100644 --- a/src/core/ozone/gl_surface_wgl_qt.cpp +++ b/src/core/ozone/gl_surface_wgl_qt.cpp @@ -1,45 +1,10 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "gl_surface_wgl_qt.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) +#include "ui/gl/gl_display_manager.h" #include "ui/gl/gl_surface_wgl.h" namespace gl { @@ -55,9 +20,12 @@ GLSurfaceWGLQt::~GLSurfaceWGLQt() Destroy(); } -bool GLSurfaceWGLQt::InitializeOneOff() +gl::GLDisplay *GLSurfaceWGLQt::InitializeOneOff(gl::GpuPreference gpu_preference) { - return GLSurfaceWGL::InitializeOneOff(); + if (GLSurfaceWGL::InitializeOneOff()) + return GLDisplayManagerWGL::GetInstance()->GetDisplay(gpu_preference); + + return nullptr; } bool GLSurfaceWGLQt::Initialize(GLSurfaceFormat format) @@ -77,9 +45,9 @@ void *GLSurfaceWGLQt::GetHandle() return m_surfaceBuffer->GetHandle(); } -void *GLSurfaceWGLQt::GetDisplay() +GLDisplay *GLSurfaceWGLQt::GetGLDisplay() { - return m_surfaceBuffer->GetDisplay(); + return m_surfaceBuffer->GetGLDisplay(); } void *GLSurfaceWGLQt::GetConfig() @@ -89,4 +57,4 @@ void *GLSurfaceWGLQt::GetConfig() } //namespace gl -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) diff --git a/src/core/ozone/gl_surface_wgl_qt.h b/src/core/ozone/gl_surface_wgl_qt.h index 2b562b61b..6c590e46c 100644 --- a/src/core/ozone/gl_surface_wgl_qt.h +++ b/src/core/ozone/gl_surface_wgl_qt.h @@ -1,48 +1,12 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef GL_SURFACE_WGL_QT_H #define GL_SURFACE_WGL_QT_H #include "gl_surface_qt.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) namespace gl { @@ -52,12 +16,12 @@ class GLSurfaceWGLQt: public GLSurfaceQt { public: explicit GLSurfaceWGLQt(const gfx::Size& size); - static bool InitializeOneOff(); + static gl::GLDisplay *InitializeOneOff(gl::GpuPreference gpu_preference); bool Initialize(GLSurfaceFormat format) override; void Destroy() override; void *GetHandle() override; - void *GetDisplay() override; + GLDisplay *GetGLDisplay() override; void *GetConfig() override; protected: @@ -65,10 +29,9 @@ protected: private: scoped_refptr<PbufferGLSurfaceWGL> m_surfaceBuffer; - DISALLOW_COPY_AND_ASSIGN(GLSurfaceWGLQt); }; } -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) #endif // GL_SURFACE_WGL_QT_H diff --git a/src/core/ozone/ozone_extra.gni b/src/core/ozone/ozone_extra.gni index a832f741a..191bb3787 100644 --- a/src/core/ozone/ozone_extra.gni +++ b/src/core/ozone/ozone_extra.gni @@ -17,3 +17,17 @@ ozone_external_platform_deps = [] # so that they get included into ozone_unittests. # ozone_external_platform_test_deps = [ "platform/foo1:foo1_unitests", ... ] ozone_external_platform_test_deps = [] + +# If a platform has integration tests, the corresponding source_set can be +# listed here so that they get included into ozone_integration_tests. +ozone_external_platform_integration_test_deps = [] + +# If a platform has test support files for ui, the corresponding source_set can +# be listed here so that they get included into ui_test_support. +# ozone_external_platform_ui_test_support_deps = [ "platform/foo1:ui_test_support", ... ] +ozone_external_platform_ui_test_support_deps = [] + +# If a platform has a test support for interactive_ui_tests, the corresponding +# source_set can be listed here so that they can included into +# interactive_ui_tests. +ozone_external_interactive_ui_tests_deps = [] diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp index eb7610c0f..6384ea2db 100644 --- a/src/core/ozone/ozone_platform_qt.cpp +++ b/src/core/ozone/ozone_platform_qt.cpp @@ -1,60 +1,50 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "ozone_platform_qt.h" #if defined(USE_OZONE) +#include "base/no_destructor.h" +#include "base/task/thread_pool.h" +#include "media/gpu/buildflags.h" +#include "ui/base/buildflags.h" +#include "ui/base/ime/input_method.h" #include "ui/display/types/native_display_delegate.h" -#include "ui/events/system_input_injector.h" -#include "ui/ozone/common/stub_client_native_pixmap_factory.h" +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" +#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" +#include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h" +#include "ui/ozone/common/bitmap_cursor_factory.h" #include "ui/ozone/common/stub_overlay_manager.h" -#include "ui/ozone/public/cursor_factory_ozone.h" #include "ui/ozone/public/gpu_platform_support_host.h" #include "ui/ozone/public/input_controller.h" #include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/platform_screen.h" +#include "ui/ozone/public/system_input_injector.h" +#include "ui/ozone/platform/wayland/gpu/wayland_gl_egl_utility.h" #include "ui/platform_window/platform_window_delegate.h" #include "ui/platform_window/platform_window_init_properties.h" -#include "ui/platform_window/platform_window.h" #include "surface_factory_qt.h" #include "platform_window_qt.h" +#if BUILDFLAG(USE_XKBCOMMON) +#include "base/logging.h" +#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h" +#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" + +#include <X11/XKBlib.h> +#include <X11/extensions/XKBrules.h> +#include <filesystem> +#endif // BUILDFLAG(USE_XKBCOMMON) + +#if BUILDFLAG(IS_OZONE_X11) +#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h" +#include "ui/ozone/platform/x11/gl_egl_utility_x11.h" + +extern void *GetQtXDisplay(); +#endif + namespace ui { namespace { @@ -65,26 +55,50 @@ public: ~OzonePlatformQt() override; ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override; - ui::CursorFactoryOzone* GetCursorFactoryOzone() override; + ui::CursorFactory* GetCursorFactory() override; GpuPlatformSupportHost* GetGpuPlatformSupportHost() override; std::unique_ptr<PlatformWindow> CreatePlatformWindow(PlatformWindowDelegate* delegate, PlatformWindowInitProperties properties) override; std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate() override; ui::InputController* GetInputController() override; std::unique_ptr<ui::SystemInputInjector> CreateSystemInputInjector() override; ui::OverlayManagerOzone* GetOverlayManager() override; + std::unique_ptr<InputMethod> CreateInputMethod(ImeKeyEventDispatcher *ime_key_event_dispatcher, gfx::AcceleratedWidget widget) override; + std::unique_ptr<ui::PlatformScreen> CreateScreen() override { return nullptr; } + const PlatformProperties &GetPlatformProperties() override; + PlatformGLEGLUtility *GetPlatformGLEGLUtility() override; + + const PlatformRuntimeProperties &GetPlatformRuntimeProperties() override + { + static OzonePlatform::PlatformRuntimeProperties properties; + if (has_initialized_gpu()) { + // This property is set when the GetPlatformRuntimeProperties is + // called on the gpu process side. + DCHECK(m_supportsNativePixmaps); + properties.supports_native_pixmaps = m_supportsNativePixmaps.value(); + } + return properties; + } + bool IsNativePixmapConfigSupported(gfx::BufferFormat format, gfx::BufferUsage usage) const override; private: - void InitializeUI(const ui::OzonePlatform::InitParams &) override; + bool InitializeUI(const ui::OzonePlatform::InitParams &) override; void InitializeGPU(const ui::OzonePlatform::InitParams &) override; + void InitScreen(ui::PlatformScreen *) override {} + + absl::optional<bool> m_supportsNativePixmaps; std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_; - std::unique_ptr<CursorFactoryOzone> cursor_factory_ozone_; + std::unique_ptr<CursorFactory> cursor_factory_; std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_; std::unique_ptr<InputController> input_controller_; std::unique_ptr<OverlayManagerOzone> overlay_manager_; - DISALLOW_COPY_AND_ASSIGN(OzonePlatformQt); +#if BUILDFLAG(USE_XKBCOMMON) + XkbEvdevCodes m_xkbEvdevCodeConverter; +#endif + std::unique_ptr<KeyboardLayoutEngine> m_keyboardLayoutEngine; + std::unique_ptr<PlatformGLEGLUtility> gl_egl_utility_; }; @@ -92,14 +106,27 @@ OzonePlatformQt::OzonePlatformQt() {} OzonePlatformQt::~OzonePlatformQt() {} +const ui::OzonePlatform::PlatformProperties &OzonePlatformQt::GetPlatformProperties() +{ + static base::NoDestructor<ui::OzonePlatform::PlatformProperties> properties; + static bool initialized = false; + if (!initialized) { + DCHECK(m_supportsNativePixmaps); + properties->fetch_buffer_formats_for_gmb_on_gpu = m_supportsNativePixmaps.value(); + initialized = true; + } + + return *properties; +} + ui::SurfaceFactoryOzone* OzonePlatformQt::GetSurfaceFactoryOzone() { return surface_factory_ozone_.get(); } -ui::CursorFactoryOzone* OzonePlatformQt::GetCursorFactoryOzone() +ui::CursorFactory* OzonePlatformQt::GetCursorFactory() { - return cursor_factory_ozone_.get(); + return cursor_factory_.get(); } GpuPlatformSupportHost* OzonePlatformQt::GetGpuPlatformSupportHost() @@ -133,26 +160,123 @@ std::unique_ptr<display::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDis return nullptr; } -void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &) +#if BUILDFLAG(USE_XKBCOMMON) +static std::string getCurrentKeyboardLayout() +{ + Display *dpy = static_cast<Display *>(GetQtXDisplay()); + if (dpy == nullptr) + return std::string(); + + int d; + if (!XkbQueryExtension(dpy, &d, &d, &d, &d, &d)) { + // no Xkb extension + return std::string(); + } + + XkbStateRec state; + if (XkbGetState(dpy, XkbUseCoreKbd, &state) != 0) + return std::string(); + + XkbRF_VarDefsRec vdr {}; // zero initialize it + struct Cleanup { + XkbRF_VarDefsRec &vdr; + Cleanup(XkbRF_VarDefsRec &vdr) : vdr(vdr) { } + ~Cleanup() { + free (vdr.model); + free (vdr.layout); + free (vdr.variant); + free (vdr.options); + } + } cleanup(vdr); + if (XkbRF_GetNamesProp(dpy, nullptr, &vdr) == 0) + return std::string(); + + if (!vdr.layout) + return std::string(); + + if (!vdr.variant) + return std::string(vdr.layout); + + std::string layoutWithVariant = vdr.layout; + layoutWithVariant = layoutWithVariant.append("-"); + layoutWithVariant = layoutWithVariant.append(vdr.variant); + + return layoutWithVariant; +} +#endif // BUILDFLAG(USE_XKBCOMMON) + +bool OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &) { +#if BUILDFLAG(USE_XKBCOMMON) + std::string xkb_path("/usr/share/X11/xkb"); + std::string layout = getCurrentKeyboardLayout(); + if (layout.empty() || !std::filesystem::exists(xkb_path) || std::filesystem::is_empty(xkb_path)) { + LOG(WARNING) << "Failed to load keymap file, falling back to StubKeyboardLayoutEngine"; + m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>(); + } else { + m_keyboardLayoutEngine = std::make_unique<XkbKeyboardLayoutEngine>(m_xkbEvdevCodeConverter); + m_keyboardLayoutEngine->SetCurrentLayoutByName(layout); + } +#else + m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>(); +#endif // BUILDFLAG(USE_XKBCOMMON) + + KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(m_keyboardLayoutEngine.get()); + overlay_manager_.reset(new StubOverlayManager()); - cursor_factory_ozone_.reset(new CursorFactoryOzone()); - gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost()); input_controller_ = CreateStubInputController(); + cursor_factory_.reset(new BitmapCursorFactory()); + gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost()); + m_supportsNativePixmaps = QtWebEngineCore::SurfaceFactoryQt::SupportsNativePixmaps(); + return true; } -void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &) +void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams ¶ms) { surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt()); + +#if BUILDFLAG(IS_OZONE_X11) + if (params.enable_native_gpu_memory_buffers) { + base::ThreadPool::PostTask(FROM_HERE, + base::BindOnce([]() + { + ui::GpuMemoryBufferSupportX11::GetInstance(); + })); + } +#endif +} + +std::unique_ptr<InputMethod> OzonePlatformQt::CreateInputMethod(ImeKeyEventDispatcher *, gfx::AcceleratedWidget) +{ + NOTREACHED(); + return nullptr; +} + +bool OzonePlatformQt::IsNativePixmapConfigSupported(gfx::BufferFormat format, gfx::BufferUsage usage) const +{ + return gfx::ClientNativePixmapDmaBuf::IsConfigurationSupported(format, usage); +} + +PlatformGLEGLUtility *OzonePlatformQt::GetPlatformGLEGLUtility() +{ + if (!gl_egl_utility_) { +#if BUILDFLAG(IS_OZONE_X11) + if (GetQtXDisplay()) + gl_egl_utility_ = std::make_unique<GLEGLUtilityX11>(); + else +#endif + gl_egl_utility_ = std::make_unique<WaylandGLEGLUtility>(); + } + return gl_egl_utility_.get(); } } // namespace OzonePlatform* CreateOzonePlatformQt() { return new OzonePlatformQt; } -gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt() +gfx::ClientNativePixmapFactory *CreateClientNativePixmapFactoryQt() { - return CreateStubClientNativePixmapFactory(); + return gfx::CreateClientNativePixmapFactoryDmabuf(); } } // namespace ui diff --git a/src/core/ozone/ozone_platform_qt.h b/src/core/ozone/ozone_platform_qt.h index dee66beb3..23629b2eb 100644 --- a/src/core/ozone/ozone_platform_qt.h +++ b/src/core/ozone/ozone_platform_qt.h @@ -1,55 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef OZONE_PLATFORM_QT_H #define OZONE_PLATFORM_QT_H -#if defined(USE_OZONE) - -#include "ui/ozone/public/ozone_platform.h" - namespace ui { +class OzonePlatform; // Constructor hook for use in ozone_platform_list.cc -OzonePlatform* CreateOzonePlatformQt(); +OzonePlatform *CreateOzonePlatformQt(); } // namespace ui -#endif // defined(USE_OZONE) #endif // OZONE_PLATFORM_QT_H diff --git a/src/core/ozone/platform_window_qt.cpp b/src/core/ozone/platform_window_qt.cpp index 757c042f0..4923f0f88 100644 --- a/src/core/ozone/platform_window_qt.cpp +++ b/src/core/ozone/platform_window_qt.cpp @@ -1,46 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #if defined(USE_OZONE) -#include "base/bind.h" +#include "base/functional/bind.h" #include "ozone/platform_window_qt.h" +#include "ui/base/cursor/platform_cursor.h" #include "ui/events/ozone/events_ozone.h" #include "ui/events/platform/platform_event_source.h" #include "ui/platform_window/platform_window_delegate.h" @@ -59,17 +24,24 @@ PlatformWindowQt::~PlatformWindowQt() ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); } -gfx::Rect PlatformWindowQt::GetBounds() +gfx::Rect PlatformWindowQt::GetBoundsInPixels() const { return bounds_; } -void PlatformWindowQt::SetBounds(const gfx::Rect& bounds) +void PlatformWindowQt::Close() +{ + delegate_->OnClosed(); +} + +void PlatformWindowQt::SetBoundsInPixels(const gfx::Rect& bounds) { if (bounds == bounds_) return; + const bool origin_changed = (bounds_.origin() != bounds.origin()); + bounds_ = bounds; - delegate_->OnBoundsChanged(bounds); + delegate_->OnBoundsChanged({origin_changed}); } bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/) @@ -77,11 +49,21 @@ bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/) return true; } +gfx::Rect PlatformWindowQt::GetBoundsInDIP() const +{ + return delegate_->ConvertRectToDIP(bounds_); +} + +void PlatformWindowQt::SetBoundsInDIP(const gfx::Rect &bounds_in_dip) +{ + SetBoundsInPixels(delegate_->ConvertRectToPixels(bounds_in_dip)); +} + uint32_t PlatformWindowQt::DispatchEvent(const ui::PlatformEvent& native_event) { DispatchEventFromNativeUiEvent( - native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent, - base::Unretained(delegate_))); + native_event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(delegate_))); return ui::POST_DISPATCH_STOP_PROPAGATION; } diff --git a/src/core/ozone/platform_window_qt.h b/src/core/ozone/platform_window_qt.h index bb2fc714b..c025102bb 100644 --- a/src/core/ozone/platform_window_qt.h +++ b/src/core/ozone/platform_window_qt.h @@ -1,82 +1,55 @@ -/**************************************************************************** -** -** 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) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PLATFORM_WINDOW_QT_H #define PLATFORM_WINDOW_QT_H #if defined(USE_OZONE) +#include "ui/base/cursor/platform_cursor.h" #include "ui/events/platform/platform_event_dispatcher.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_delegate.h" namespace ui { -class PlatformWindowDelegate; - class PlatformWindowQt : public PlatformWindow, public PlatformEventDispatcher { public: PlatformWindowQt(PlatformWindowDelegate* delegate, const gfx::Rect& bounds); ~PlatformWindowQt() override; // PlatformWindow: - gfx::Rect GetBounds() override; - void SetBounds(const gfx::Rect& bounds) override; - void Show() override { } + gfx::Rect GetBoundsInPixels() const override; + void SetBoundsInPixels(const gfx::Rect& bounds) override; + gfx::Rect GetBoundsInDIP() const override; + void SetBoundsInDIP(const gfx::Rect& bounds) override; + void Show(bool inactive = false) override { } void Hide() override { } - void Close() override { } - void SetTitle(const base::string16&) override { } + void Close() override; + bool IsVisible() const override { return true; } + void SetTitle(const std::u16string&) override { } void SetCapture() override { } void ReleaseCapture() override { } bool HasCapture() const override { return false; } - void ToggleFullscreen() override { } + void SetFullscreen(bool, int64_t) override { } void Maximize() override { } void Minimize() override { } void Restore() override { } - PlatformWindowState GetPlatformWindowState() const override { return PLATFORM_WINDOW_STATE_UNKNOWN; } - void SetCursor(PlatformCursor) override { } + PlatformWindowState GetPlatformWindowState() const override { return PlatformWindowState::kUnknown; } + void SetCursor(scoped_refptr<PlatformCursor>) override { } void MoveCursorTo(const gfx::Point&) override { } void ConfineCursorToBounds(const gfx::Rect&) override { } - PlatformImeController* GetPlatformImeController() override { return nullptr; } - void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override { } - gfx::Rect GetRestoredBoundsInPixels() const override { return gfx::Rect(); } + void SetRestoredBoundsInDIP(const gfx::Rect& bounds) override { } + gfx::Rect GetRestoredBoundsInDIP() const override { return gfx::Rect(); } + void Activate() override { } + void Deactivate() override { } + void SetUseNativeFrame(bool use_native_frame) override { } + bool ShouldUseNativeFrame() const override { return false; } + void SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) override { } + void SizeConstraintsChanged() override { } // PlatformEventDispatcher: bool CanDispatchEvent(const PlatformEvent& event) override; @@ -86,8 +59,6 @@ public: private: PlatformWindowDelegate* delegate_; gfx::Rect bounds_; - - DISALLOW_COPY_AND_ASSIGN(PlatformWindowQt); }; } diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp index 5420b4809..1bfa49c60 100644 --- a/src/core/ozone/surface_factory_qt.cpp +++ b/src/core/ozone/surface_factory_qt.cpp @@ -1,85 +1,266 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#if defined(USE_OZONE) #include "surface_factory_qt.h" -#include "gl_context_qt.h" -#include "gl_ozone_egl_qt.h" -#if defined(USE_GLX) -#include "gl_ozone_glx_qt.h" -#endif -#include "ui/gl/gl_surface.h" -#include <QGuiApplication> +#include "qtwebenginecoreglobal_p.h" +#include "ozone/gl_context_qt.h" +#include "ozone/gl_ozone_egl_qt.h" -#if defined(USE_OZONE) +#include "media/gpu/buildflags.h" +#include "ui/base/ozone_buildflags.h" +#include "ui/gfx/linux/drm_util_linux.h" +#include "ui/gfx/linux/gbm_buffer.h" +#include "ui/gfx/linux/native_pixmap_dmabuf.h" +#include "ui/gl/egl_util.h" + +#include <QDebug> +#include <QtGui/qtgui-config.h> + +#if BUILDFLAG(IS_OZONE_X11) +#include "ozone/gl_ozone_glx_qt.h" + +#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h" +#endif + +#if QT_CONFIG(webengine_vulkan) +#include "compositor/vulkan_implementation_qt.h" +#endif -#include "ozone/gl_ozone_egl_qt.h" -#include "ozone/surface_factory_qt.h" -#include "ui/gl/gl_surface.h" namespace QtWebEngineCore { SurfaceFactoryQt::SurfaceFactoryQt() { - Q_ASSERT(qApp); -#if defined(USE_GLX) - if (GLContextHelper::getGlXConfig()) { - m_impl = gl::kGLImplementationDesktopGL; +#if BUILDFLAG(IS_OZONE_X11) + if (GLContextHelper::getGlxPlatformInterface()) { + m_impl = { gl::GLImplementationParts(gl::kGLImplementationDesktopGL), + gl::GLImplementationParts(gl::kGLImplementationDisabled) }; m_ozone.reset(new ui::GLOzoneGLXQt()); } else #endif - if (GLContextHelper::getEGLConfig()) { - m_impl = gl::kGLImplementationEGLGLES2; + if (GLContextHelper::getEglPlatformInterface()) { + m_impl = { gl::GLImplementationParts(gl::kGLImplementationEGLGLES2), + gl::GLImplementationParts(gl::kGLImplementationDesktopGL), + gl::GLImplementationParts(gl::kGLImplementationDisabled) }; m_ozone.reset(new ui::GLOzoneEGLQt()); } else { - qFatal("No suitable graphics backend found\n"); + m_impl = { gl::GLImplementationParts(gl::kGLImplementationDisabled) }; } } -std::vector<gl::GLImplementation> SurfaceFactoryQt::GetAllowedGLImplementations() +std::vector<gl::GLImplementationParts> SurfaceFactoryQt::GetAllowedGLImplementations() { - return { m_impl }; + return m_impl; } -ui::GLOzone* SurfaceFactoryQt::GetGLOzone(gl::GLImplementation implementation) +ui::GLOzone *SurfaceFactoryQt::GetGLOzone(const gl::GLImplementationParts &implementation) { return m_ozone.get(); } +#if BUILDFLAG(ENABLE_VULKAN) +std::unique_ptr<gpu::VulkanImplementation> +SurfaceFactoryQt::CreateVulkanImplementation(bool /*allow_protected_memory*/, + bool /*enforce_protected_memory*/) +{ +#if QT_CONFIG(webengine_vulkan) + return std::make_unique<gpu::VulkanImplementationQt>(); +#else + return nullptr; +#endif +} +#endif + +bool SurfaceFactoryQt::CanCreateNativePixmapForFormat(gfx::BufferFormat format) +{ +#if BUILDFLAG(IS_OZONE_X11) + if (GLContextHelper::getGlxPlatformInterface()) + return ui::GpuMemoryBufferSupportX11::GetInstance()->CanCreateNativePixmapForFormat(format); +#endif + + if (GLContextHelper::getEglPlatformInterface()) + return ui::SurfaceFactoryOzone::CanCreateNativePixmapForFormat(format); + + return false; +} + +scoped_refptr<gfx::NativePixmap> SurfaceFactoryQt::CreateNativePixmap( + gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue *device_queue, + gfx::Size size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + absl::optional<gfx::Size> framebuffer_size) +{ + if (!SupportsNativePixmaps()) + return nullptr; + +#if QT_CONFIG(opengl) + if (framebuffer_size && !gfx::Rect(size).Contains(gfx::Rect(*framebuffer_size))) + return nullptr; + + gfx::NativePixmapHandle handle; + +#if BUILDFLAG(IS_OZONE_X11) + if (GLContextHelper::getGlxPlatformInterface()) { + auto gbmBuffer = + ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBuffer(format, size, usage); + if (!gbmBuffer) + qFatal("Failed to create GBM buffer for GLX."); + handle = gbmBuffer->ExportHandle(); + } +#endif + + if (GLContextHelper::getEglPlatformInterface()) { + int fd = -1; + int stride; + int offset; + uint64_t modifiers; + EGLHelper::instance()->queryDmaBuf(size.width(), size.height(), &fd, &stride, &offset, + &modifiers); + if (fd == -1) + qFatal("Failed to query DRM FD for EGL."); + + const uint64_t planeSize = uint64_t(size.width()) * size.height() * 4; + gfx::NativePixmapPlane plane(stride, offset, planeSize, base::ScopedFD(::dup(fd))); + + handle.planes.push_back(std::move(plane)); + handle.modifier = modifiers; + } + + return base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format, std::move(handle)); +#else + return nullptr; +#endif // QT_CONFIG(opengl) +} + +void SurfaceFactoryQt::CreateNativePixmapAsync( + gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue *device_queue, + gfx::Size size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + NativePixmapCallback callback) +{ + if (!SupportsNativePixmaps()) { + std::move(callback).Run(nullptr); + return; + } + + // CreateNativePixmap is non-blocking operation. Thus, it is safe to call it + // and return the result with the provided callback. + std::move(callback).Run(CreateNativePixmap(widget, device_queue, size, format, usage)); +} + +scoped_refptr<gfx::NativePixmap> +SurfaceFactoryQt::CreateNativePixmapFromHandle( + gfx::AcceleratedWidget /*widget*/, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) +{ + if (!SupportsNativePixmaps()) + return nullptr; + +#if QT_CONFIG(opengl) + gfx::NativePixmapHandle bufferHandle; + +#if BUILDFLAG(IS_OZONE_X11) + if (GLContextHelper::getGlxPlatformInterface()) { + auto gbmBuffer = ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBufferFromHandle( + size, format, std::move(handle)); + if (!gbmBuffer) + qFatal("Failed to create GBM buffer for GLX."); + bufferHandle = gbmBuffer->ExportHandle(); + } +#endif + + if (GLContextHelper::getEglPlatformInterface()) { + const size_t numPlanes = handle.planes.size(); + const uint32_t fourccFormat = ui::GetFourCCFormatFromBufferFormat(format); + + std::vector<EGLAttrib> attrs; + attrs.push_back(EGL_WIDTH); + attrs.push_back(size.width()); + attrs.push_back(EGL_HEIGHT); + attrs.push_back(size.height()); + attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT); + attrs.push_back(fourccFormat); + for (size_t planeIndex = 0; planeIndex < numPlanes; ++planeIndex) { + attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + planeIndex * 3); + attrs.push_back(handle.planes[planeIndex].fd.get()); + attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + planeIndex * 3); + attrs.push_back(handle.planes[planeIndex].offset); + attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + planeIndex * 3); + attrs.push_back(handle.planes[planeIndex].stride); + attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + planeIndex * 2); + attrs.push_back(handle.modifier & 0xffffffff); + attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + planeIndex * 2); + attrs.push_back(handle.modifier >> 32); + } + attrs.push_back(EGL_NONE); + + EGLDisplay eglDisplay = GLContextHelper::getEGLDisplay(); + EGLHelper *eglHelper = EGLHelper::instance(); + auto *eglFun = eglHelper->functions(); + + EGLImage eglImage = + eglFun->eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer)NULL, attrs.data()); + if (eglImage == EGL_NO_IMAGE_KHR) { + qFatal() << "Failed to import EGLImage:" + << ui::GetEGLErrorString(eglFun->eglGetError()); + } + + Q_ASSERT(numPlanes <= 3); + int fds[3]; + int strides[3]; + int offsets[3]; + if (!eglFun->eglExportDMABUFImageMESA(eglDisplay, eglImage, fds, strides, offsets)) { + qFatal() << "Failed to export EGLImage:" + << ui::GetEGLErrorString(eglFun->eglGetError()); + } + + bufferHandle.modifier = handle.modifier; + for (size_t i = 0; i < numPlanes; ++i) { + int fd = fds[i]; + int stride = strides[i]; + int offset = offsets[i]; + int planeSize = handle.planes[i].size; + + if (fd == -1) { + fd = fds[0]; + stride = handle.planes[i].stride; + offset = handle.planes[i].offset; + } + + gfx::NativePixmapPlane plane(stride, offset, planeSize, base::ScopedFD(::dup(fd))); + bufferHandle.planes.push_back(std::move(plane)); + } + + eglFun->eglDestroyImage(eglDisplay, eglImage); + } + + return base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format, std::move(bufferHandle)); +#else + return nullptr; +#endif // QT_CONFIG(opengl) +} + +bool SurfaceFactoryQt::SupportsNativePixmaps() +{ +#if QT_CONFIG(opengl) +#if BUILDFLAG(IS_OZONE_X11) + if (GLContextHelper::getGlxPlatformInterface()) + return ui::GpuMemoryBufferSupportX11::GetInstance()->has_gbm_device(); +#endif // BUILDFLAG(IS_OZONE_X11) + + if (GLContextHelper::getEglPlatformInterface()) + return EGLHelper::instance()->isDmaBufSupported(); +#endif // QT_CONFIG(opengl) + + return false; +} } // namespace QtWebEngineCore #endif // defined(USE_OZONE) diff --git a/src/core/ozone/surface_factory_qt.h b/src/core/ozone/surface_factory_qt.h index dee41d948..d69467a26 100644 --- a/src/core/ozone/surface_factory_qt.h +++ b/src/core/ozone/surface_factory_qt.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef SURFACE_FACTORY_QT #define SURFACE_FACTORY_QT @@ -50,10 +14,36 @@ class SurfaceFactoryQt : public ui::SurfaceFactoryOzone { public: SurfaceFactoryQt(); - std::vector<gl::GLImplementation> GetAllowedGLImplementations() override; - ui::GLOzone* GetGLOzone(gl::GLImplementation implementation) override; + std::vector<gl::GLImplementationParts> GetAllowedGLImplementations() override; + ui::GLOzone *GetGLOzone(const gl::GLImplementationParts &implementation) override; +#if BUILDFLAG(ENABLE_VULKAN) + std::unique_ptr<gpu::VulkanImplementation> + CreateVulkanImplementation(bool allow_protected_memory, bool enforce_protected_memory) override; +#endif + bool CanCreateNativePixmapForFormat(gfx::BufferFormat format) override; + scoped_refptr<gfx::NativePixmap> CreateNativePixmap( + gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue* device_queue, + gfx::Size size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + absl::optional<gfx::Size> framebuffer_size = absl::nullopt) override; + void CreateNativePixmapAsync(gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue* device_queue, + gfx::Size size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + NativePixmapCallback callback) override; + scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) override; + + static bool SupportsNativePixmaps(); + private: - gl::GLImplementation m_impl; + std::vector<gl::GLImplementationParts> m_impl; std::unique_ptr<ui::GLOzone> m_ozone; }; |