From 479d9d965acaff3fc08412d56ce205e8c8822dbf Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 29 Mar 2023 16:21:37 +0200 Subject: Support painting to Direct3D11 using ANGLE Pick-to: 6.5 Task-number: QTBUG-112280 Fixes: QTBUG-109401 Change-Id: Iaebb79921030ce42bcfe8be1ba46d309c93dca6d Reviewed-by: Peter Varga --- src/core/CMakeLists.txt | 2 + src/core/api/qtwebenginecoreglobal.cpp | 6 +-- src/core/compositor/native_skia_output_device.cpp | 56 ++++++++++++++++++++++- src/core/ozone/gl_share_context_qt.cpp | 2 +- src/core/web_engine_context.cpp | 9 +++- src/webenginequick/api/qtwebenginequickglobal.cpp | 5 +- 6 files changed, 71 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6f6b82221..735088dd2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -323,6 +323,7 @@ foreach(arch ${archs}) angle_enable_swiftshader=false dawn_use_swiftshader=false use_dawn=false + build_dawn_tests=false enable_vr=false enable_web_speech=false enable_widevine=true @@ -530,6 +531,7 @@ foreach(arch ${archs}) com_init_check_hook_disabled=true heterogeneous_executables=true enable_vr=false + use_static_angle=true ) endif() diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp index 3301695b3..d8d3d3b26 100644 --- a/src/core/api/qtwebenginecoreglobal.cpp +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -212,9 +212,9 @@ static void initialize() // QCoreApplication is not yet instantiated, ensuring the call will be deferred qAddPreRoutine(QtWebEngineCore::initialize); auto api = QQuickWindow::graphicsApi(); - if (api != QSGRendererInterface::OpenGLRhi && api != QSGRendererInterface::VulkanRhi - && api != QSGRendererInterface::MetalRhi) - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan + && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11) + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); #endif // QT_CONFIG(opengl) } diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp index 47cbd1981..aa0be8c26 100644 --- a/src/core/compositor/native_skia_output_device.cpp +++ b/src/core/compositor/native_skia_output_device.cpp @@ -16,8 +16,12 @@ #include "third_party/skia/include/core/SkSurfaceProps.h" #include "ui/gl/gl_fence.h" -#ifdef Q_OS_MACOS +#if defined(Q_OS_MACOS) #include "ui/gl/gl_image_io_surface.h" +#elif defined(Q_OS_WIN) +#include "ui/gl/gl_image_d3d.h" +#include +#include #endif #include @@ -155,6 +159,10 @@ public: return; m_scopedOverlayReadAccess.reset(); + if (m_textureCleanup) { + m_textureCleanup(); + m_textureCleanup = nullptr; + } } gl::GLImage *glImage() { @@ -178,6 +186,7 @@ public: const Shape &shape() const { return m_shape; } + std::function m_textureCleanup; private: NativeSkiaOutputDevice *m_parent; Shape m_shape; @@ -347,10 +356,53 @@ QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureO return texture; } +#elif defined(Q_OS_WIN) +QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions) +{ + if (!m_frontBuffer || !m_readyWithTexture) + return nullptr; + Q_ASSERT(QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11); + + QSGTexture *texture = nullptr; + gl::GLImageD3D *gl_image_d3d = gl::GLImageD3D::FromGLImage(m_frontBuffer->glImage()); + if (gl_image_d3d) { + // Pass texture between two D3D devices: + HRESULT status = S_OK; + HANDLE sharedHandle; + sharedHandle = gl_image_d3d->shared_handle(); + if (!sharedHandle) { + qWarning() << "No shared handle"; + return nullptr; + } + Q_ASSERT(sharedHandle); + + HANDLE sharedHandleDup; + DuplicateHandle(GetCurrentProcess(), sharedHandle, GetCurrentProcess(), &sharedHandleDup, 0, FALSE, DUPLICATE_SAME_ACCESS); + + QSGRendererInterface *ri = win->rendererInterface(); + ID3D11Device1 *device = static_cast(ri->getResource(win, QSGRendererInterface::DeviceResource)); + + ID3D11Texture2D *qtTexture; + status = device->OpenSharedResource1(sharedHandleDup, __uuidof(ID3D11Texture2D), (void**)&qtTexture); + Q_ASSERT(status == S_OK); + + QQuickWindow::CreateTextureOptions texOpts(textureOptions); + texture = QNativeInterface::QSGD3D11Texture::fromNative(qtTexture, win, size(), texOpts); + + m_frontBuffer->m_textureCleanup = [qtTexture,sharedHandleDup]() { + qtTexture->Release(); + ::CloseHandle(sharedHandleDup); + }; + } else { + qWarning() << "GLImage is not D3D"; + } + + return texture; +} #else QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *, uint32_t) { - // Add Windows and Linux versions. + // Add Linux versions. NOTIMPLEMENTED(); return nullptr; } diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp index 0290d7123..35bd18f22 100644 --- a/src/core/ozone/gl_share_context_qt.cpp +++ b/src/core/ozone/gl_share_context_qt.cpp @@ -77,7 +77,7 @@ void ShareGroupQt::AboutToAddFirstContext() "QCoreApplication is created."); } m_shareContextQt = new QtShareGLContext(shareContext); -#endif +#endif // QT_CONFIG(opengl) } } // namespace diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 769807ca2..cc4c89609 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -131,7 +131,8 @@ static bool usingSupportedSGBackend() { if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL && QQuickWindow::graphicsApi() != QSGRendererInterface::Vulkan - && QQuickWindow::graphicsApi() != QSGRendererInterface::Metal) + && QQuickWindow::graphicsApi() != QSGRendererInterface::Metal + && QQuickWindow::graphicsApi() != QSGRendererInterface::Direct3D11) return false; const QStringList args = QGuiApplication::arguments(); @@ -194,6 +195,9 @@ static const char *getGLType(bool enableGLSoftwareRendering, bool disableGpu) #if defined(Q_OS_MACOS) if (QQuickWindow::graphicsApi() == QSGRendererInterface::Metal) return gl::kGLImplementationANGLEName; +#elif defined(Q_OS_WIN) + if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11) + return gl::kGLImplementationANGLEName; #endif if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) { @@ -240,6 +244,9 @@ static const char *getGLType(bool /*enableGLSoftwareRendering*/, bool disableGpu #if defined(Q_OS_MACOS) if (QQuickWindow::graphicsApi() == QSGRendererInterface::Metal) return gl::kGLImplementationANGLEName; +#elif defined(Q_OS_WIN) + if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11) + return gl::kGLImplementationANGLEName; #endif return gl::kGLImplementationDisabledName; } diff --git a/src/webenginequick/api/qtwebenginequickglobal.cpp b/src/webenginequick/api/qtwebenginequickglobal.cpp index 60f7991c8..f8f520a05 100644 --- a/src/webenginequick/api/qtwebenginequickglobal.cpp +++ b/src/webenginequick/api/qtwebenginequickglobal.cpp @@ -47,8 +47,9 @@ void initialize() // call initialize the same way as widgets do qAddPreRoutine(QtWebEngineCore::initialize); auto api = QQuickWindow::graphicsApi(); - if (api != QSGRendererInterface::OpenGLRhi && api != QSGRendererInterface::VulkanRhi && api != QSGRendererInterface::MetalRhi) - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan + && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11) + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); } } // namespace QtWebEngineQuick -- cgit v1.2.1