summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2021-05-27 07:21:22 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-06-22 22:49:14 +0000
commit85665d8e34ff16e68bf12186c432886f46f64954 (patch)
treeb8137237fc796777f5b24c16a0314b52cb0148bf
parent8a964f4b87095f32db612618d17a3185c692f689 (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.txt1
-rw-r--r--src/core/compositor/display_overrides.cpp11
-rw-r--r--src/core/compositor/display_skia_output_device.cpp260
-rw-r--r--src/core/compositor/display_skia_output_device.h119
-rw-r--r--src/core/web_engine_context.cpp3
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.