diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2021-05-27 07:21:22 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-06-22 22:49:14 +0000 |
commit | 85665d8e34ff16e68bf12186c432886f46f64954 (patch) | |
tree | b8137237fc796777f5b24c16a0314b52cb0148bf | |
parent | 8a964f4b87095f32db612618d17a3185c692f689 (diff) |
Add DisplaySkiaOutputDevice for skia-on-gl rendering
Change-Id: Ia855e60e74f79a5750e68f2b97ccba1e747a3ef6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit b11790982532b04d63c45f1e985cb45f75370e9a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/compositor/display_overrides.cpp | 11 | ||||
-rw-r--r-- | src/core/compositor/display_skia_output_device.cpp | 260 | ||||
-rw-r--r-- | src/core/compositor/display_skia_output_device.h | 119 | ||||
-rw-r--r-- | src/core/web_engine_context.cpp | 3 |
5 files changed, 391 insertions, 3 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b881a316e..591f1b333 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -83,6 +83,7 @@ foreach(config ${configs}) compositor/content_gpu_client_qt.cpp compositor/content_gpu_client_qt.h compositor/display_overrides.cpp compositor/display_software_output_surface.cpp compositor/display_software_output_surface.h + compositor/display_skia_output_device.cpp compositor/display_skia_output_device.h content_browser_client_qt.cpp content_browser_client_qt.h content_client_qt.cpp content_client_qt.h content_main_delegate_qt.cpp content_main_delegate_qt.h diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp index 89bf8ad2f..4636d7a3a 100644 --- a/src/core/compositor/display_overrides.cpp +++ b/src/core/compositor/display_overrides.cpp @@ -38,9 +38,11 @@ ****************************************************************************/ #include "display_gl_output_surface.h" +#include "display_skia_output_device.h" #include "display_software_output_surface.h" #include "components/viz/service/display_embedder/output_surface_provider_impl.h" +#include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h" #include "gpu/ipc/in_process_command_buffer.h" #include <qtgui-config.h> @@ -61,6 +63,15 @@ viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface() return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(); } +std::unique_ptr<viz::SkiaOutputDevice> +viz::SkiaOutputSurfaceImplOnGpu::CreateOutputDevice() +{ + return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>( + context_state_, + shared_gpu_deps_->memory_tracker(), + GetDidSwapBuffersCompleteCallback()); +} + void gpu::InProcessCommandBuffer::GetTextureQt( unsigned int client_id, GetTextureCallback callback, diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp new file mode 100644 index 000000000..7107f00d4 --- /dev/null +++ b/src/core/compositor/display_skia_output_device.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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$ +** +****************************************************************************/ + +#include "display_skia_output_device.h" + +#include "type_conversion.h" + +#include "gpu/command_buffer/service/skia_utils.h" +#include "skia/ext/legacy_display_globals.h" + +namespace QtWebEngineCore { + +class DisplaySkiaOutputDevice::Buffer +{ +public: + Buffer(DisplaySkiaOutputDevice *parent) + : m_parent(parent) + , m_shape(m_parent->m_shape) + { + auto formatIndex = static_cast<int>(m_shape.format); + const auto &colorType = m_parent->capabilities_.sk_color_types[formatIndex]; + DCHECK(colorType != kUnknown_SkColorType) + << "SkColorType is invalid for format: " << formatIndex; + + m_texture = m_parent->m_contextState->gr_context()->createBackendTexture( + m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height(), colorType, + GrMipMapped::kNo, GrRenderable::kYes); + DCHECK(m_texture.isValid()); + + if (m_texture.backend() == GrBackendApi::kVulkan) { + GrVkImageInfo info; + bool result = m_texture.getVkImageInfo(&info); + DCHECK(result); + m_estimatedSize = info.fAlloc.fSize; + } else { + auto info = SkImageInfo::Make(m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height(), + colorType, kUnpremul_SkAlphaType); + m_estimatedSize = info.computeMinByteSize(); + } + m_parent->memory_type_tracker_->TrackMemAlloc(m_estimatedSize); + + SkSurfaceProps surfaceProps = skia::LegacyDisplayGlobals::GetSkSurfaceProps(); + m_surface = SkSurface::MakeFromBackendTexture( + m_parent->m_contextState->gr_context(), m_texture, + m_parent->capabilities_.output_surface_origin == gfx::SurfaceOrigin::kTopLeft + ? kTopLeft_GrSurfaceOrigin + : kBottomLeft_GrSurfaceOrigin, + 0 /* sampleCount */, colorType, m_shape.colorSpace.ToSkColorSpace(), + &surfaceProps); + } + + ~Buffer() + { + DeleteGrBackendTexture(m_parent->m_contextState.get(), &m_texture); + m_parent->memory_type_tracker_->TrackMemFree(m_estimatedSize); + } + + void createFence() + { + m_fence = CompositorResourceFence::create(); + } + + void consumeFence() + { + if (m_fence) { + m_fence->wait(); + m_fence.reset(); + } + } + + const Shape &shape() const { return m_shape; } + const GrBackendTexture &texture() const { return m_texture; } + SkSurface *surface() const { return m_surface.get(); } + +private: + DisplaySkiaOutputDevice *m_parent; + Shape m_shape; + GrBackendTexture m_texture; + sk_sp<SkSurface> m_surface; + uint64_t m_estimatedSize = 0; + scoped_refptr<CompositorResourceFence> m_fence; +}; + +DisplaySkiaOutputDevice::DisplaySkiaOutputDevice( + scoped_refptr<gpu::SharedContextState> contextState, + gpu::MemoryTracker *memoryTracker, + DidSwapBufferCompleteCallback didSwapBufferCompleteCallback) + : SkiaOutputDevice( + contextState->gr_context(), + memoryTracker, + didSwapBufferCompleteCallback) + , Compositor(Compositor::Type::OpenGL) + , m_contextState(contextState) +{ + capabilities_.uses_default_gl_framebuffer = false; + + capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = + kRGBA_8888_SkColorType; + capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = + kRGBA_8888_SkColorType; + capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = + kRGBA_8888_SkColorType; + capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = + kRGBA_8888_SkColorType; +} + +DisplaySkiaOutputDevice::~DisplaySkiaOutputDevice() +{ +} + +void DisplaySkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id) +{ + bind(id); +} + +bool DisplaySkiaOutputDevice::Reshape(const gfx::Size& sizeInPixels, + float devicePixelRatio, + const gfx::ColorSpace& colorSpace, + gfx::BufferFormat format, + gfx::OverlayTransform transform) +{ + m_shape = Shape{sizeInPixels, devicePixelRatio, colorSpace, format}; + DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); + return true; +} + +void DisplaySkiaOutputDevice::SwapBuffers(BufferPresentedCallback feedback, + std::vector<ui::LatencyInfo> latencyInfo) +{ + DCHECK(m_backBuffer); + + StartSwapBuffers(std::move(feedback)); + m_latencyInfo = std::move(latencyInfo); + m_backBuffer->createFence(); + + { + QMutexLocker locker(&m_mutex); + m_taskRunner = base::ThreadTaskRunnerHandle::Get(); + m_middleBuffer = std::move(m_backBuffer); + m_readyToUpdate = true; + } + + if (auto obs = observer()) + obs->readyToSwap(); +} + +void DisplaySkiaOutputDevice::EnsureBackbuffer() +{ +} + +void DisplaySkiaOutputDevice::DiscardBackbuffer() +{ +} + +SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *) +{ + if (!m_backBuffer || m_backBuffer->shape() != m_shape) + m_backBuffer = std::make_unique<Buffer>(this); + return m_backBuffer->surface(); +} + +void DisplaySkiaOutputDevice::EndPaint() +{ +} + +void DisplaySkiaOutputDevice::swapFrame() +{ + QMutexLocker locker(&m_mutex); + if (m_readyToUpdate) { + std::swap(m_middleBuffer, m_frontBuffer); + m_taskRunner->PostTask(FROM_HERE, + base::BindOnce(&DisplaySkiaOutputDevice::SwapBuffersFinished, + base::Unretained(this))); + m_taskRunner.reset(); + m_readyToUpdate = false; + } +} + +void DisplaySkiaOutputDevice::waitForTexture() +{ + if (m_frontBuffer) + m_frontBuffer->consumeFence(); +} + +int DisplaySkiaOutputDevice::textureId() +{ + if (!m_frontBuffer) + return 0; + + GrGLTextureInfo info; + if (!m_frontBuffer->texture().getGLTextureInfo(&info)) + return 0; + + return info.fID; +} + +QSize DisplaySkiaOutputDevice::size() +{ + return m_frontBuffer ? toQt(m_frontBuffer->shape().sizeInPixels) : QSize(); +} + +bool DisplaySkiaOutputDevice::hasAlphaChannel() +{ + return true; +} + +float DisplaySkiaOutputDevice::devicePixelRatio() +{ + return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1; +} + +void DisplaySkiaOutputDevice::SwapBuffersFinished() +{ + { + QMutexLocker locker(&m_mutex); + m_backBuffer = std::move(m_middleBuffer); + } + + FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK), + gfx::Size(m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height()), + std::move(m_latencyInfo)); +} + +} // namespace QtWebEngineCore diff --git a/src/core/compositor/display_skia_output_device.h b/src/core/compositor/display_skia_output_device.h new file mode 100644 index 000000000..a4225b047 --- /dev/null +++ b/src/core/compositor/display_skia_output_device.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_SKIA_OUTPUT_DEVICE_H +#define DISPLAY_SKIA_OUTPUT_DEVICE_H + +#include "compositor_resource_fence.h" +#include "compositor.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "components/viz/service/display_embedder/skia_output_device.h" +#include "gpu/command_buffer/service/shared_context_state.h" + +#include <QMutex> + +namespace QtWebEngineCore { + +class DisplaySkiaOutputDevice final : public viz::SkiaOutputDevice, public Compositor +{ +public: + DisplaySkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState, + gpu::MemoryTracker *memoryTracker, + DidSwapBufferCompleteCallback didSwapBufferCompleteCallback); + ~DisplaySkiaOutputDevice() override; + + // Overridden from SkiaOutputDevice. + void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override; + bool Reshape(const gfx::Size& size, + float devicePixelRatio, + const gfx::ColorSpace& colorSpace, + gfx::BufferFormat format, + gfx::OverlayTransform transform) override; + void SwapBuffers(BufferPresentedCallback feedback, + std::vector<ui::LatencyInfo> latencyInfo) override; + void EnsureBackbuffer() override; + void DiscardBackbuffer() override; + SkSurface *BeginPaint(std::vector<GrBackendSemaphore> *semaphores) override; + void EndPaint() override; + + // Overridden from Compositor. + void swapFrame() override; + void waitForTexture() override; + int textureId() override; + QSize size() override; + bool hasAlphaChannel() override; + float devicePixelRatio() override; + +private: + struct Shape + { + gfx::Size sizeInPixels; + float devicePixelRatio; + gfx::ColorSpace colorSpace; + gfx::BufferFormat format; + + bool operator==(const Shape &that) const + { + return (sizeInPixels == that.sizeInPixels && + devicePixelRatio == that.devicePixelRatio && + colorSpace == that.colorSpace && + format == that.format); + } + bool operator!=(const Shape &that) const { return !(*this == that); } + }; + + class Buffer; + + void SwapBuffersFinished(); + + mutable QMutex m_mutex; + scoped_refptr<gpu::SharedContextState> m_contextState; + Shape m_shape; + std::unique_ptr<Buffer> m_frontBuffer; + std::unique_ptr<Buffer> m_middleBuffer; + std::unique_ptr<Buffer> m_backBuffer; + std::vector<ui::LatencyInfo> m_latencyInfo; + bool m_readyToUpdate = false; + scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner; +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_SKIA_OUTPUT_DEVICE_H diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 4479264cc..1c9dfbf54 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -719,9 +719,6 @@ WebEngineContext::WebEngineContext() disableFeatures.push_back(features::kFontSrcLocalMatching.name); #endif - // We don't support the skia renderer (enabled by default on Linux since 80) - disableFeatures.push_back(features::kUseSkiaRenderer.name); - disableFeatures.push_back(network::features::kDnsOverHttpsUpgrade.name); // When enabled, event.movement is calculated in blink instead of in browser. |