summaryrefslogtreecommitdiffstats
path: root/src/core/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/compositor')
-rw-r--r--src/core/compositor/chromium_gpu_helper.cpp101
-rw-r--r--src/core/compositor/chromium_gpu_helper.h89
-rw-r--r--src/core/compositor/compositor.cpp252
-rw-r--r--src/core/compositor/compositor.h238
-rw-r--r--src/core/compositor/compositor_resource.h123
-rw-r--r--src/core/compositor/compositor_resource_fence.cpp51
-rw-r--r--src/core/compositor/compositor_resource_fence.h42
-rw-r--r--src/core/compositor/compositor_resource_tracker.cpp266
-rw-r--r--src/core/compositor/compositor_resource_tracker.h127
-rw-r--r--src/core/compositor/content_gpu_client_qt.cpp49
-rw-r--r--src/core/compositor/content_gpu_client_qt.h50
-rw-r--r--src/core/compositor/delegated_frame_node.cpp1123
-rw-r--r--src/core/compositor/delegated_frame_node.h133
-rw-r--r--src/core/compositor/display_consumer.h62
-rw-r--r--src/core/compositor/display_frame_sink.cpp140
-rw-r--r--src/core/compositor/display_frame_sink.h77
-rw-r--r--src/core/compositor/display_gl_output_surface.cpp292
-rw-r--r--src/core/compositor/display_gl_output_surface.h148
-rw-r--r--src/core/compositor/display_gl_output_surface_qsg.cpp121
-rw-r--r--src/core/compositor/display_overrides.cpp156
-rw-r--r--src/core/compositor/display_producer.h69
-rw-r--r--src/core/compositor/display_skia_output_device.cpp240
-rw-r--r--src/core/compositor/display_skia_output_device.h89
-rw-r--r--src/core/compositor/display_software_output_surface.cpp180
-rw-r--r--src/core/compositor/display_software_output_surface.h46
-rw-r--r--src/core/compositor/native_skia_output_device.cpp422
-rw-r--r--src/core/compositor/native_skia_output_device.h183
-rw-r--r--src/core/compositor/native_skia_output_device_direct3d11.cpp89
-rw-r--r--src/core/compositor/native_skia_output_device_direct3d11.h28
-rw-r--r--src/core/compositor/native_skia_output_device_mac.mm97
-rw-r--r--src/core/compositor/native_skia_output_device_metal.cpp66
-rw-r--r--src/core/compositor/native_skia_output_device_metal.h31
-rw-r--r--src/core/compositor/native_skia_output_device_opengl.cpp86
-rw-r--r--src/core/compositor/native_skia_output_device_opengl.h28
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.cpp309
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.h28
-rw-r--r--src/core/compositor/stream_video_node.cpp169
-rw-r--r--src/core/compositor/stream_video_node.h88
-rw-r--r--src/core/compositor/vulkan_implementation_qt.cpp162
-rw-r--r--src/core/compositor/vulkan_implementation_qt.h46
-rw-r--r--src/core/compositor/yuv_video_node.cpp352
-rw-r--r--src/core/compositor/yuv_video_node.h117
42 files changed, 2352 insertions, 4213 deletions
diff --git a/src/core/compositor/chromium_gpu_helper.cpp b/src/core/compositor/chromium_gpu_helper.cpp
deleted file mode 100644
index 71d0f3687..000000000
--- a/src/core/compositor/chromium_gpu_helper.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** 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) 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 "chromium_gpu_helper.h"
-
-// Some headers include the namespace ws, and can not coexist with
-// Qt headers that include QTextStream, which includes most QSG headers
-// via QMatrix4x4.
-#include "content/browser/renderer_host/render_widget_host_impl.h"
-
-// Including gpu/command_buffer headers before content/gpu headers makes sure that
-// guards are defined to prevent duplicate definition errors with forward declared
-// GL typedefs cascading through content header includes.
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/texture_base.h"
-
-#include "content/gpu/gpu_child_thread.h"
-#include "gpu/ipc/service/gpu_channel_manager.h"
-
-#ifdef Q_OS_QNX
-#include "content/common/gpu/stream_texture_qnx.h"
-#endif
-
-scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner()
-{
- return content::GpuChildThread::instance()->main_thread_runner();
-}
-
-gpu::MailboxManager *mailbox_manager()
-{
- gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->gpu_channel_manager();
- return gpuChannelManager->mailbox_manager();
-}
-
-gpu::TextureBase* ConsumeTexture(gpu::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox)
-{
- Q_UNUSED(target);
- return mailboxManager->ConsumeTexture(mailbox);
-}
-
-unsigned int service_id(gpu::TextureBase *tex)
-{
- return tex->service_id();
-}
-
-void ProgressFlingIfNeeded(content::RenderWidgetHost *host, const base::TimeTicks &current_time)
-{
- content::RenderWidgetHostImpl::From(host)->ProgressFlingIfNeeded(current_time);
-}
-
-#ifdef Q_OS_QNX
-EGLStreamData eglstream_connect_consumer(gpu::Texture *tex)
-{
- EGLStreamData egl_stream;
- content::StreamTexture* image = static_cast<content::StreamTexture *>(tex->GetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0));
- if (image) {
- image->ConnectConsumerIfNeeded(&egl_stream.egl_display, &egl_stream.egl_str_handle);
- }
- return egl_stream;
-}
-#endif
diff --git a/src/core/compositor/chromium_gpu_helper.h b/src/core/compositor/chromium_gpu_helper.h
deleted file mode 100644
index 4086d12ab..000000000
--- a/src/core/compositor/chromium_gpu_helper.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef CHROMIUM_GPU_HELPER_H
-#define CHROMIUM_GPU_HELPER_H
-
-#include <QtGlobal> // We need this for the Q_OS_QNX define.
-
-#include "base/memory/scoped_refptr.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-class TimeTicks;
-}
-
-namespace content {
-class RenderWidgetHost;
-}
-
-namespace gpu {
-struct Mailbox;
-class MailboxManager;
-class TextureBase;
-}
-
-// These functions wrap code that needs to include headers that are
-// incompatible with Qt GL headers.
-// From the outside, types from incompatible headers referenced in these
-// functions should only be forward-declared and considered as opaque types.
-
-scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner();
-gpu::MailboxManager *mailbox_manager();
-
-gpu::TextureBase* ConsumeTexture(gpu::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox);
-unsigned int service_id(gpu::TextureBase *tex);
-
-void ProgressFlingIfNeeded(content::RenderWidgetHost *host, const base::TimeTicks &current_time);
-
-#ifdef Q_OS_QNX
-typedef void* EGLDisplay;
-typedef void* EGLStreamKHR;
-
-struct EGLStreamData {
- EGLDisplay egl_display;
- EGLStreamKHR egl_str_handle;
-
- EGLStreamData(): egl_display(NULL), egl_str_handle(NULL) {}
-};
-
-EGLStreamData eglstream_connect_consumer(gpu::Texture *tex);
-#endif
-
-#endif // CHROMIUM_GPU_HELPER_H
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 56693961c..4c0bd4c0d 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -1,188 +1,162 @@
-/****************************************************************************
-**
-** 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) 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 "compositor.h"
-#include "compositor_resource_tracker.h"
-#include "delegated_frame_node.h"
+#include "base/memory/ref_counted.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
-#include "base/task/post_task.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
+#include <QHash>
+#include <QMutex>
+#include <QQuickWindow>
namespace QtWebEngineCore {
-Compositor::Compositor(content::RenderWidgetHost *host)
- : m_resourceTracker(new CompositorResourceTracker)
- , m_host(host)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+// Compositor::Id
- m_taskRunner = base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI, base::TaskPriority::USER_VISIBLE});
- m_beginFrameSource =
- std::make_unique<viz::DelayBasedBeginFrameSource>(
- std::make_unique<viz::DelayBasedTimeSource>(m_taskRunner.get()),
- viz::BeginFrameSource::kNotRestartableId);
-}
+Compositor::Id::Id(viz::FrameSinkId fid) : client_id(fid.client_id()), sink_id(fid.sink_id()) { }
-Compositor::~Compositor()
+static size_t qHash(Compositor::Id id, size_t seed = 0)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ QtPrivate::QHashCombine hasher;
+ seed = hasher(seed, id.client_id);
+ seed = hasher(seed, id.sink_id);
+ return seed;
}
-void Compositor::setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient)
+static bool operator==(Compositor::Id id1, Compositor::Id id2)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- if (m_frameSinkClient == frameSinkClient)
- return;
-
- // Accumulated resources belong to the old RendererCompositorFrameSink and
- // should not be returned.
- //
- // TODO(juvaldma): Can there be a pending frame from the old client?
- m_resourceTracker->returnResources();
- m_frameSinkClient = frameSinkClient;
+ return id1.client_id == id2.client_id && id1.sink_id == id2.sink_id;
}
-void Compositor::setNeedsBeginFrames(bool needsBeginFrames)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- if (m_needsBeginFrames == needsBeginFrames)
- return;
-
- if (needsBeginFrames)
- m_beginFrameSource->AddObserver(this);
- else
- m_beginFrameSource->RemoveObserver(this);
+// Compositor::Binding and Compositor::Bindings
- m_needsBeginFrames = needsBeginFrames;
-}
-
-void Compositor::submitFrame(viz::CompositorFrame frame, base::OnceClosure callback)
+struct Compositor::Binding
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- DCHECK(!m_submitCallback);
+ const Id id;
+ Compositor *compositor = nullptr;
+ Observer *observer = nullptr;
- m_pendingFrame = std::move(frame);
- m_submitCallback = std::move(callback);
- m_resourceTracker->submitResources(
- m_pendingFrame,
- base::BindOnce(&Compositor::runSubmitCallback, base::Unretained(this)));
-}
+ Binding(Id id) : id(id) { }
+ ~Binding();
+};
-QSGNode *Compositor::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate)
+class Compositor::BindingMap
{
- // DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- //
- // This might be called from a Qt Quick render thread, but the UI thread
- // will still be blocked for the duration of this call.
+public:
+ void lock() { m_mutex.lock(); }
- DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
- if (!frameNode)
- frameNode = new DelegatedFrameNode;
+ void unlock() { m_mutex.unlock(); }
- if (!m_updatePaintNodeShouldCommit) {
- frameNode->commit(m_committedFrame, viz::CompositorFrame(), m_resourceTracker.get(), viewDelegate);
- return frameNode;
+ Binding *findOrCreate(Id id)
+ {
+ auto it = m_map.find(id);
+ if (it == m_map.end())
+ it = m_map.insert(id, new Binding(id));
+ return *it;
}
- m_updatePaintNodeShouldCommit = false;
- gfx::PresentationFeedback dummyFeedback(base::TimeTicks::Now(), base::TimeDelta(), gfx::PresentationFeedback::Flags::kVSync);
- m_presentations.insert({m_committedFrame.metadata.frame_token, dummyFeedback});
+ void remove(Id id) { m_map.remove(id); }
- m_resourceTracker->commitResources();
- frameNode->commit(m_pendingFrame, m_committedFrame, m_resourceTracker.get(), viewDelegate);
- m_committedFrame = std::move(m_pendingFrame);
- m_pendingFrame = viz::CompositorFrame();
+private:
+ QMutex m_mutex;
+ QHash<Id, Binding *> m_map;
+} static g_bindings;
- m_taskRunner->PostTask(FROM_HERE,
- base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
+Compositor::Binding::~Binding()
+{
+ g_bindings.remove(id);
+}
+
+// Compositor::Observer
- return frameNode;
+void Compositor::Observer::bind(Id id)
+{
+ DCHECK(!m_binding);
+ g_bindings.lock();
+ m_binding = g_bindings.findOrCreate(id);
+ DCHECK(!m_binding->observer);
+ m_binding->observer = this;
+ g_bindings.unlock();
}
-void Compositor::runSubmitCallback()
+void Compositor::Observer::unbind()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(m_binding);
+ g_bindings.lock();
+ m_binding->observer = nullptr;
+ if (m_binding->compositor == nullptr)
+ delete m_binding;
+ m_binding = nullptr;
+ g_bindings.unlock();
+}
- m_updatePaintNodeShouldCommit = true;
- std::move(m_submitCallback).Run();
+Compositor::Handle<Compositor> Compositor::Observer::compositor()
+{
+ g_bindings.lock();
+ if (m_binding && m_binding->compositor)
+ return m_binding->compositor; // delay unlock
+ g_bindings.unlock();
+ return nullptr;
}
-void Compositor::notifyFrameCommitted()
+// Compositor
+
+void Compositor::bind(Id id)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!m_binding);
+ g_bindings.lock();
+ m_binding = g_bindings.findOrCreate(id);
+ DCHECK(!m_binding->compositor);
+ m_binding->compositor = this;
+ g_bindings.unlock();
+}
- m_beginFrameSource->DidFinishFrame(this);
- if (m_frameSinkClient)
- m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourceTracker->returnResources());
+void Compositor::unbind()
+{
+ DCHECK(m_binding);
+ g_bindings.lock();
+ m_binding->compositor = nullptr;
+ if (m_binding->observer == nullptr)
+ delete m_binding;
+ m_binding = nullptr;
+ g_bindings.unlock();
}
-void Compositor::sendPresentationFeedback(uint frame_token)
+Compositor::Handle<Compositor::Observer> Compositor::observer()
{
- gfx::PresentationFeedback dummyFeedback(base::TimeTicks::Now(), base::TimeDelta(), gfx::PresentationFeedback::Flags::kVSync);
- m_presentations.insert({frame_token, dummyFeedback});
+ g_bindings.lock();
+ if (m_binding && m_binding->observer)
+ return m_binding->observer; // delay unlock
+ g_bindings.unlock();
+ return nullptr;
}
-bool Compositor::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args)
+void Compositor::waitForTexture()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
- ProgressFlingIfNeeded(m_host, args.frame_time);
- m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
- if (m_frameSinkClient) {
- m_frameSinkClient->OnBeginFrame(args, m_presentations);
- m_presentations.clear();
- }
+void Compositor::releaseTexture()
+{
+}
- return true;
+QSGTexture *Compositor::texture(QQuickWindow *, uint32_t textureOptions)
+{
+ Q_UNREACHABLE();
+ return nullptr;
}
-void Compositor::OnBeginFrameSourcePausedChanged(bool)
+bool Compositor::textureIsFlipped()
{
- // Ignored for now. If the begin frame source is paused, the renderer
- // doesn't need to be informed about it and will just not receive more
- // begin frames.
+ Q_UNREACHABLE();
+ return false;
}
+void Compositor::releaseResources() { }
+
+// static
+void Compositor::unlockBindings()
+{
+ g_bindings.unlock();
+}
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 6d88dc054..501559060 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -1,129 +1,153 @@
-/****************************************************************************
-**
-** 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) 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 COMPOSITOR_H
#define COMPOSITOR_H
-#include "base/memory/weak_ptr.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "ui/gfx/presentation_feedback.h"
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qshareddata.h>
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qshareddata.h>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
QT_BEGIN_NAMESPACE
-class QSGNode;
+class QQuickWindow;
+class QSize;
+class QSGTexture;
QT_END_NAMESPACE
-namespace content {
-class RenderWidgetHost;
-}
namespace viz {
-struct ReturnedResource;
-namespace mojom {
-class CompositorFrameSinkClient;
-} // namespace mojom
+class FrameSinkId;
} // namespace viz
namespace QtWebEngineCore {
-class CompositorResourceTracker;
-class RenderWidgetHostViewQtDelegate;
-
-// Receives viz::CompositorFrames from child compositors and provides QSGNodes
-// to the Qt Quick renderer.
-//
-// The life cycle of a frame:
-//
-// Step 1. A new CompositorFrame is received from child compositors and handed
-// off to submitFrame(). The new frame will start off in a pending state.
+// Produces composited frames for display.
//
-// Step 2. Once the new frame is ready to be rendered, Compositor will notify
-// the client by running the callback given to submitFrame().
-//
-// Step 3. Once the client is ready to render, updatePaintNode() should be
-// called to receive the scene graph for the new frame. This call will commit
-// the pending frame. Until the next frame is ready, all subsequent calls to
-// updatePaintNode() will keep using this same committed frame.
-//
-// Step 4. The Compositor will return unneeded resources back to the child
-// compositors. Go to step 1.
-class Compositor final : private viz::BeginFrameObserverBase
+// Used by quick/widgets libraries for accessing the frames and
+// controlling frame swapping.
+class Q_WEBENGINECORE_EXPORT Compositor
{
+ struct Binding;
+
public:
- explicit Compositor(content::RenderWidgetHost *host);
- ~Compositor() override;
+ // Identifies the implementation type.
+ enum class Type {
+ Software,
+ OpenGL, // TODO: Legacy, remove it with DisplaySkiaOutputDevice!
+ Native
+ };
+
+ // Identifies a compositor.
+ //
+ // The purpose of assigning ids to compositors is to allow the
+ // corresponding observer to be registered before the compositor
+ // itself is created, which is necessary since the creation
+ // happens on a different thread in the depths of viz.
+ //
+ // (Maps to viz::FrameSinkId internally).
+ struct Id
+ {
+ quint32 client_id;
+ quint32 sink_id;
+
+ Id(viz::FrameSinkId);
+ };
+
+ // Pointer to Compositor or Observer that holds a lock to prevent
+ // either from being unbound and destroyed.
+ template<typename T>
+ class Handle
+ {
+ public:
+ Handle(std::nullptr_t) : m_data(nullptr) { }
+ Handle(T *data) : m_data(data) { }
+ Handle(Handle &&that) : m_data(that.m_data) { that.m_data = nullptr; }
+ ~Handle()
+ {
+ if (m_data)
+ Compositor::unlockBindings();
+ }
+ T *operator->() const { return m_data; }
+ T &operator*() const { return *m_data; }
+ explicit operator bool() const { return m_data; }
+
+ private:
+ T *m_data;
+ };
+
+ // Observes the compositor corresponding to the given id.
+ //
+ // Only one observer can exist per compositor.
+ class Q_WEBENGINECORE_EXPORT Observer
+ {
+ public:
+ // Binding to compositor
+ void bind(Id id);
+ void unbind();
+
+ // Compositor if bound
+ Handle<Compositor> compositor();
+
+ // There's a new frame ready, time to swapFrame().
+ virtual void readyToSwap() = 0;
+
+ protected:
+ Observer() = default;
+ ~Observer() { if (m_binding) unbind(); }
+
+ private:
+ Binding *m_binding = nullptr;
+ };
+
+ // Type determines which methods can be called.
+ Type type() const { return m_type; }
+
+ // Binding to observer.
+ void bind(Id id);
+ void unbind();
+
+ // Observer if bound.
+ Handle<Observer> observer();
+
+ // Update to next frame if possible.
+ virtual void swapFrame() = 0;
+
+ // Ratio of pixels to DIPs.
+ //
+ // Don't use the devicePixelRatio of QImage, it's always 1.
+ virtual float devicePixelRatio() = 0;
+
+ // Size of frame in pixels.
+ virtual QSize size() = 0;
+
+ // Whether frame needs an alpha channel.
+ virtual bool requiresAlphaChannel() = 0;
+
+ // Wait on texture to be ready aka. sync.
+ virtual void waitForTexture();
+
+ // Release any held texture resources
+ virtual void releaseTexture();
+
+ // QSGTexture of the frame.
+ virtual QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions);
+
+ // Is the texture produced upside down?
+ virtual bool textureIsFlipped();
+
+ // Release resources created in texture()
+ virtual void releaseResources();
+
+protected:
+ Compositor(Type type) : m_type(type) { }
+ virtual ~Compositor() { if (m_binding) unbind(); }
- void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient);
- void setNeedsBeginFrames(bool needsBeginFrames);
+private:
+ template<typename T>
+ friend class Handle;
- void submitFrame(viz::CompositorFrame frame, base::OnceClosure callback);
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate);
+ class BindingMap;
+ static void unlockBindings();
-private:
- void runSubmitCallback();
- void notifyFrameCommitted();
- void sendPresentationFeedback(uint frame_token);
-
- // viz::BeginFrameObserverBase
- bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) override;
- void OnBeginFrameSourcePausedChanged(bool paused) override;
-
- viz::CompositorFrame m_committedFrame;
- viz::CompositorFrame m_pendingFrame;
- base::OnceClosure m_submitCallback;
- std::unique_ptr<CompositorResourceTracker> m_resourceTracker;
- content::RenderWidgetHost *m_host;
- std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
- base::flat_map<uint32_t, gfx::PresentationFeedback> m_presentations;
- viz::mojom::CompositorFrameSinkClient *m_frameSinkClient = nullptr;
- bool m_updatePaintNodeShouldCommit = false;
- bool m_needsBeginFrames = false;
-
- scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
- base::WeakPtrFactory<Compositor> m_weakPtrFactory{this};
-
- DISALLOW_COPY_AND_ASSIGN(Compositor);
+ const Type m_type;
+ Binding *m_binding = nullptr;
};
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor_resource.h b/src/core/compositor/compositor_resource.h
deleted file mode 100644
index f7df2ab59..000000000
--- a/src/core/compositor/compositor_resource.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef COMPOSITOR_RESOURCE_H
-#define COMPOSITOR_RESOURCE_H
-
-#include <base/memory/ref_counted.h>
-#include <components/viz/common/resources/transferable_resource.h>
-
-#include <QtCore/qglobal.h>
-#include <QtGui/qtgui-config.h>
-
-#if QT_CONFIG(opengl)
-# include "compositor_resource_fence.h"
-#endif
-
-namespace viz {
-class SharedBitmap;
-} // namespace viz
-
-namespace QtWebEngineCore {
-
-using CompositorResourceId = quint32;
-
-// A resource (OpenGL texture or software shared bitmap).
-//
-// - Created by the CompositorResourceTracker from a newly submitted
-// CompositorFrame's resource_list.
-//
-// - Until the frame is committed, its resources are in a 'pending' state and
-// are inaccessible from outside the CompositorResourceTracker.
-//
-// - Once the frame is committed, its resources can be found via
-// CompositorResourceTracker::findResource.
-//
-// - A committed resource's fields may not be updated and are safe to use from
-// other threads without synchronization (unless noted otherwise).
-class CompositorResource : public viz::TransferableResource
-{
-public:
- CompositorResource(const viz::TransferableResource &tr) : viz::TransferableResource(tr) {}
-
- // Counts the number of times this resource has been encountered in
- // CompositorFrames' resource lists.
- //
- // Corresponds to viz::ReturnedResource::count.
- //
- // Updated by CompositorResourceTracker on UI thread.
- int import_count = 1;
-
- // Identifies the last frame that needed this resource. Used by
- // CompositorResourceTracker to return unused resources back to child
- // compositors.
- //
- // Updated by CompositorResourceTracker on UI thread.
- quint32 last_used_for_frame = 0;
-
- // Bitmap (if is_software).
- std::unique_ptr<viz::SharedBitmap> bitmap;
-
-#if QT_CONFIG(opengl)
- // OpenGL texture id (if !is_software).
- quint32 texture_id = 0;
-
- // Should be waited on before using the texture (non-null if !is_software).
- scoped_refptr<CompositorResourceFence> texture_fence;
-#endif // QT_CONFIG(opengl)
-};
-
-inline bool operator<(const CompositorResource &r1, const CompositorResource &r2)
-{
- return r1.id < r2.id;
-}
-
-inline bool operator<(const CompositorResource &r, CompositorResourceId id)
-{
- return r.id < id;
-}
-
-inline bool operator<(CompositorResourceId id, const CompositorResource &r)
-{
- return id < r.id;
-}
-
-} // namespace QtWebEngineCore
-
-#endif // !COMPOSITOR_RESOURCE_H
diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp
index 4179395d6..bd1c95cd9 100644
--- a/src/core/compositor/compositor_resource_fence.cpp
+++ b/src/core/compositor/compositor_resource_fence.cpp
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** 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 "compositor_resource_fence.h"
-
+#include "ozone/gl_surface_qt.h"
#include "ui/gl/gl_context.h"
#include <QtGui/qopenglcontext.h>
@@ -47,6 +11,12 @@
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#endif
+
+#if QT_CONFIG(egl)
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
namespace QtWebEngineCore {
void CompositorResourceFence::wait()
@@ -55,7 +25,8 @@ void CompositorResourceFence::wait()
return;
QOpenGLContext *context = QOpenGLContext::currentContext();
- Q_ASSERT(context);
+ if (!context)
+ return;
// Chromium uses its own GL bindings and stores in in thread local storage.
// For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
diff --git a/src/core/compositor/compositor_resource_fence.h b/src/core/compositor/compositor_resource_fence.h
index 196297f78..ab92ca5c7 100644
--- a/src/core/compositor/compositor_resource_fence.h
+++ b/src/core/compositor/compositor_resource_fence.h
@@ -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
#ifndef COMPOSITOR_RESOURCE_FENCE_H
#define COMPOSITOR_RESOURCE_FENCE_H
@@ -52,7 +16,7 @@ public:
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
CompositorResourceFence() {}
- CompositorResourceFence(const gl::TransferableFence &sync) : m_sync(sync) {};
+ CompositorResourceFence(const gl::TransferableFence &sync) : m_sync(sync) {}
~CompositorResourceFence() { release(); }
// May be used only by Qt Quick render thread.
diff --git a/src/core/compositor/compositor_resource_tracker.cpp b/src/core/compositor/compositor_resource_tracker.cpp
deleted file mode 100644
index 741c2717c..000000000
--- a/src/core/compositor/compositor_resource_tracker.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "compositor_resource_tracker.h"
-
-#include "chromium_gpu_helper.h"
-#include "render_widget_host_view_qt_delegate.h"
-#include "web_engine_context.h"
-
-#include "base/message_loop/message_loop.h"
-#include "base/task/post_task.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
-#include "content/browser/browser_main_loop.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/gpu/content_gpu_client.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-
-namespace QtWebEngineCore {
-
-CompositorResourceTracker::CompositorResourceTracker()
-{}
-
-CompositorResourceTracker::~CompositorResourceTracker()
-{}
-
-void CompositorResourceTracker::submitResources(const viz::CompositorFrame &frame, base::OnceClosure callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- DCHECK(!m_submitCallback);
- DCHECK(m_pendingResources.empty());
- DCHECK(m_pendingImports.empty());
- DCHECK(m_pendingResourceUpdates == 0);
-
- m_submitCallback = std::move(callback);
-
- m_pendingResources.reserve(frame.resource_list.size());
- m_pendingImports.reserve(frame.resource_list.size());
-
- for (const viz::TransferableResource &transferableResource : frame.resource_list) {
- auto it = m_committedResources.find(transferableResource.id);
- if (it != m_committedResources.end())
- m_pendingImports.push_back(&*it);
- else
- m_pendingResources.emplace_back(transferableResource);
- }
-
- if (m_pendingResources.empty()) {
- scheduleRunSubmitCallback();
- return;
- }
-
- m_pendingResourceUpdates = m_pendingResources.size();
-
- std::vector<CompositorResource *> batch;
- batch.reserve(m_pendingResources.size());
-
- for (CompositorResource &resource : m_pendingResources) {
- if (resource.is_software)
- updateBitmap(&resource);
- else if (!scheduleUpdateMailbox(&resource))
- batch.push_back(&resource);
- }
-
- if (!batch.empty())
- scheduleUpdateMailboxes(std::move(batch));
-}
-
-void CompositorResourceTracker::commitResources()
-{
- // DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- //
- // This might be called from a Qt Quick render thread, but the UI thread
- // will still be blocked for the duration of this call.
-
- DCHECK(m_pendingResourceUpdates == 0);
-
- for (CompositorResource *resource : m_pendingImports)
- resource->import_count++;
- m_pendingImports.clear();
-
- m_committedResources.insert(std::make_move_iterator(m_pendingResources.begin()),
- std::make_move_iterator(m_pendingResources.end()));
- m_pendingResources.clear();
-
- ++m_committedFrameId;
-}
-
-std::vector<viz::ReturnedResource> CompositorResourceTracker::returnResources()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- std::vector<viz::ReturnedResource> returnedResources;
- base::EraseIf(m_committedResources, [&](const CompositorResource &resource) {
- if (resource.last_used_for_frame != m_committedFrameId) {
- viz::ReturnedResource returnedResource;
- returnedResource.id = resource.id;
- returnedResource.count = resource.import_count;
- returnedResources.push_back(std::move(returnedResource));
- return true;
- }
- return false;
- });
- return returnedResources;
-}
-
-const CompositorResource *CompositorResourceTracker::findResource(CompositorResourceId id) const
-{
- auto it = m_committedResources.find(id);
- DCHECK(it != m_committedResources.end());
-
- const_cast<CompositorResource &>(*it).last_used_for_frame = m_committedFrameId;
-
- return &*it;
-}
-
-void CompositorResourceTracker::updateBitmap(CompositorResource *resource)
-{
- content::BrowserMainLoop *browserMainLoop = content::BrowserMainLoop::GetInstance();
- viz::ServerSharedBitmapManager *bitmapManager = browserMainLoop->GetServerSharedBitmapManager();
-
- resource->bitmap = bitmapManager->GetSharedBitmapFromId(
- resource->size,
- viz::BGRA_8888,
- resource->mailbox_holder.mailbox);
-
- if (--m_pendingResourceUpdates == 0)
- scheduleRunSubmitCallback();
-}
-
-quint32 CompositorResourceTracker::consumeMailbox(const gpu::MailboxHolder &mailboxHolder)
-{
-#if QT_CONFIG(opengl)
- gpu::MailboxManager *mailboxManager = mailbox_manager();
- DCHECK(mailboxManager);
- if (mailboxHolder.sync_token.HasData())
- mailboxManager->PullTextureUpdates(mailboxHolder.sync_token);
- gpu::TextureBase *tex = mailboxManager->ConsumeTexture(mailboxHolder.mailbox);
- return tex ? service_id(tex) : 0;
-#else
- NOTREACHED();
-#endif // QT_CONFIG(OPENGL)
-}
-
-bool CompositorResourceTracker::scheduleUpdateMailbox(CompositorResource *resource)
-{
-#if QT_CONFIG(opengl)
- gpu::SyncPointManager *syncPointManager = WebEngineContext::syncPointManager();
- DCHECK(syncPointManager);
- return syncPointManager->WaitOutOfOrder(
- resource->mailbox_holder.sync_token,
- base::BindOnce(&CompositorResourceTracker::updateMailbox,
- m_weakPtrFactory.GetWeakPtr(),
- resource));
-#else
- NOTREACHED();
-#endif // QT_CONFIG(OPENGL)
-}
-
-void CompositorResourceTracker::updateMailbox(CompositorResource *resource)
-{
-#if QT_CONFIG(opengl)
- resource->texture_id = consumeMailbox(resource->mailbox_holder);
- resource->texture_fence = CompositorResourceFence::create();
-
- if (--m_pendingResourceUpdates == 0)
- scheduleRunSubmitCallback();
-#else
- NOTREACHED();
-#endif // QT_CONFIG(OPENGL)
-}
-
-void CompositorResourceTracker::scheduleUpdateMailboxes(std::vector<CompositorResource *> resources)
-{
-#if QT_CONFIG(opengl)
- scoped_refptr<base::SingleThreadTaskRunner> gpuTaskRunner = gpu_task_runner();
- DCHECK(gpuTaskRunner);
- thread_local bool currentThreadIsGpu = gpuTaskRunner->BelongsToCurrentThread();
- if (currentThreadIsGpu)
- return updateMailboxes(std::move(resources));
- gpuTaskRunner->PostTask(
- FROM_HERE,
- base::BindOnce(&CompositorResourceTracker::updateMailboxes,
- m_weakPtrFactory.GetWeakPtr(),
- std::move(resources)));
-#else
- NOTREACHED();
-#endif // QT_CONFIG(OPENGL)
-}
-
-void CompositorResourceTracker::updateMailboxes(std::vector<CompositorResource *> resources)
-{
-#if QT_CONFIG(opengl)
- for (CompositorResource *resource : resources)
- resource->texture_id = consumeMailbox(resource->mailbox_holder);
-
- scoped_refptr<CompositorResourceFence> fence = CompositorResourceFence::create();
-
- for (CompositorResource *resource : resources)
- resource->texture_fence = fence;
-
- if ((m_pendingResourceUpdates -= resources.size()) == 0)
- scheduleRunSubmitCallback();
-#else
- NOTREACHED();
-#endif // QT_CONFIG(OPENGL)
-}
-
-void CompositorResourceTracker::scheduleRunSubmitCallback()
-{
- thread_local bool currentThreadIsUi = content::BrowserThread::CurrentlyOn(content::BrowserThread::UI);
- if (currentThreadIsUi)
- return runSubmitCallback();
- base::PostTaskWithTraits(
- FROM_HERE, { content::BrowserThread::UI, base::TaskPriority::USER_VISIBLE },
- base::BindOnce(&CompositorResourceTracker::runSubmitCallback,
- m_weakPtrFactory.GetWeakPtr()));
-}
-
-void CompositorResourceTracker::runSubmitCallback()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- std::move(m_submitCallback).Run();
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor_resource_tracker.h b/src/core/compositor/compositor_resource_tracker.h
deleted file mode 100644
index 080891e5f..000000000
--- a/src/core/compositor/compositor_resource_tracker.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef COMPOSITOR_RESOURCE_TRACKER_H
-#define COMPOSITOR_RESOURCE_TRACKER_H
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/containers/flat_set.h"
-
-#include "compositor_resource.h"
-#include "locked_ptr.h"
-
-#include <atomic>
-#include <vector>
-
-namespace viz {
-class CompositorFrame;
-struct ReturnedResource;
-} // namespace viz
-
-namespace gpu {
-struct MailboxHolder;
-} // namespace gpu
-
-namespace QtWebEngineCore {
-
-// Ensures resources are not used before they are ready.
-//
-// The life cycle of a frame's resources:
-//
-// Step 1. A new CompositorFrame is received and given to submitResources().
-// The frame's resources will extracted and initialized to a pending state.
-//
-// Step 2. Once the new resources are ready to be committed,
-// CompositorResourceTracker will notify the client by running the callback
-// given to submitResources().
-//
-// Step 3. Once the client is ready to render, commitResources() should be
-// called. This will commit all the pending resources, making them available
-// via findResource().
-//
-// Step 4. Once all the resources have been used (via findResource()),
-// returnResources() may be called to return a list of all the resources which
-// were *not* used since the last commitResources(). Go to step 1.
-class CompositorResourceTracker final
-{
-public:
- CompositorResourceTracker();
- ~CompositorResourceTracker();
-
- void submitResources(const viz::CompositorFrame &frame, base::OnceClosure callback);
- void commitResources();
- std::vector<viz::ReturnedResource> returnResources();
-
- // The returned pointer is invalidated by the next call to commitFrame() or
- // returnResources(). It should therefore not be stored in data structures
- // but used immediately.
- //
- // Do not ask for resources which do not exist.
- const CompositorResource *findResource(CompositorResourceId id) const;
-
-private:
- void updateBitmap(CompositorResource *resource);
-
- quint32 consumeMailbox(const gpu::MailboxHolder &mailboxHolder);
-
- bool scheduleUpdateMailbox(CompositorResource *resource);
- void updateMailbox(CompositorResource *resource);
-
- void scheduleUpdateMailboxes(std::vector<CompositorResource *> resources);
- void updateMailboxes(std::vector<CompositorResource *> resources);
-
- void scheduleRunSubmitCallback();
- void runSubmitCallback();
-
- base::flat_set<CompositorResource> m_committedResources;
- std::vector<CompositorResource> m_pendingResources;
- std::vector<CompositorResource *> m_pendingImports;
- base::OnceClosure m_submitCallback;
- std::atomic<size_t> m_pendingResourceUpdates{0};
- quint32 m_committedFrameId = 0;
-
- base::LockedPtrFactory<CompositorResourceTracker> m_weakPtrFactory{this};
-
- DISALLOW_COPY_AND_ASSIGN(CompositorResourceTracker);
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !COMPOSITOR_RESOURCE_TRACKER_H
diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp
index f934979a0..6ef8048f2 100644
--- a/src/core/compositor/content_gpu_client_qt.cpp
+++ b/src/core/compositor/content_gpu_client_qt.cpp
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** 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 "content_gpu_client_qt.h"
-
-#include "web_engine_context.h"
+#include "ozone/gl_share_context_qt.h"
namespace QtWebEngineCore {
@@ -51,9 +14,11 @@ ContentGpuClientQt::~ContentGpuClientQt()
{
}
-gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager()
+gl::GLShareGroup *ContentGpuClientQt::GetInProcessGpuShareGroup()
{
- return WebEngineContext::syncPointManager();
+ if (!m_shareGroupQt.get())
+ m_shareGroupQt = new ShareGroupQt;
+ return m_shareGroupQt.get();
}
} // namespace
diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h
index d7ad43881..33314e0bb 100644
--- a/src/core/compositor/content_gpu_client_qt.h
+++ b/src/core/compositor/content_gpu_client_qt.h
@@ -1,47 +1,16 @@
-/****************************************************************************
-**
-** 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 CONTENT_GPU_CLIENT_QT_H
#define CONTENT_GPU_CLIENT_QT_H
#include "content/public/gpu/content_gpu_client.h"
+namespace gl {
+class GLShareGroup;
+}
+
namespace QtWebEngineCore {
+class ShareGroupQt;
class ContentGpuClientQt : public content::ContentGpuClient {
public:
@@ -49,7 +18,10 @@ public:
~ContentGpuClientQt() override;
// content::ContentGpuClient implementation.
- gpu::SyncPointManager *GetSyncPointManager() override;
+ gl::GLShareGroup *GetInProcessGpuShareGroup() override;
+
+private:
+ scoped_refptr<ShareGroupQt> m_shareGroupQt;
};
}
diff --git a/src/core/compositor/delegated_frame_node.cpp b/src/core/compositor/delegated_frame_node.cpp
deleted file mode 100644
index 19e8d1b82..000000000
--- a/src/core/compositor/delegated_frame_node.cpp
+++ /dev/null
@@ -1,1123 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-// On Mac we need to reset this define in order to prevent definition
-// of "check" macros etc. The "check" macro collides with a member function name in QtQuick.
-// See AssertMacros.h in the Mac SDK.
-#include <QtGlobal> // We need this for the Q_OS_MAC define.
-#if defined(Q_OS_MAC)
-#undef __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES
-#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
-#endif
-
-#include "delegated_frame_node.h"
-
-#include "chromium_gpu_helper.h"
-#include "stream_video_node.h"
-#include "type_conversion.h"
-#include "yuv_video_node.h"
-#include "compositor_resource_tracker.h"
-
-#include "base/bind.h"
-#include "cc/base/math_util.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/debug_border_draw_quad.h"
-#include "components/viz/common/quads/draw_quad.h"
-#include "components/viz/common/quads/render_pass_draw_quad.h"
-#include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/common/quads/stream_video_draw_quad.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/quads/tile_draw_quad.h"
-#include "components/viz/common/quads/yuv_video_draw_quad.h"
-#include "components/viz/service/display/bsp_tree.h"
-#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
-
-#ifndef QT_NO_OPENGL
-# include <QOpenGLContext>
-# include <QOpenGLFunctions>
-# include <QSGFlatColorMaterial>
-#endif
-#include <QSGTexture>
-#include <private/qsgadaptationlayer_p.h>
-
-#include <QSGImageNode>
-#include <QSGRectangleNode>
-
-#if !defined(QT_NO_EGL)
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#endif
-
-#ifndef GL_TEXTURE_RECTANGLE
-#define GL_TEXTURE_RECTANGLE 0x84F5
-#endif
-
-#ifndef GL_NEAREST
-#define GL_NEAREST 0x2600
-#endif
-
-#ifndef GL_LINEAR
-#define GL_LINEAR 0x2601
-#endif
-
-#ifndef GL_RGBA
-#define GL_RGBA 0x1908
-#endif
-
-#ifndef GL_RGB
-#define GL_RGB 0x1907
-#endif
-
-#ifndef GL_LINE_LOOP
-#define GL_LINE_LOOP 0x0002
-#endif
-
-#ifndef QT_NO_OPENGL
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-QT_END_NAMESPACE
-#endif
-
-namespace QtWebEngineCore {
-#ifndef QT_NO_OPENGL
-class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
-public:
- MailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target = -1);
- ~MailboxTexture();
- // QSGTexture:
- int textureId() const override { return m_textureId; }
- QSize textureSize() const override { return m_textureSize; }
- bool hasAlphaChannel() const override { return m_hasAlpha; }
- bool hasMipmaps() const override { return false; }
- void bind() override;
-
-private:
- int m_textureId;
- scoped_refptr<CompositorResourceFence> m_fence;
- QSize m_textureSize;
- bool m_hasAlpha;
- GLenum m_target;
-#if defined(USE_OZONE)
- bool m_ownsTexture;
-#endif
-#ifdef Q_OS_QNX
- EGLStreamData m_eglStreamData;
-#endif
- friend class DelegatedFrameNode;
-};
-#endif // QT_NO_OPENGL
-
-class RectClipNode : public QSGClipNode
-{
-public:
- RectClipNode(const QRectF &);
-private:
- QSGGeometry m_geometry;
-};
-
-class DelegatedNodeTreeHandler
-{
-public:
- DelegatedNodeTreeHandler(QVector<QSGNode*> *sceneGraphNodes)
- : m_sceneGraphNodes(sceneGraphNodes)
- {
- }
-
- virtual ~DelegatedNodeTreeHandler(){}
-
- virtual void setupRenderPassNode(QSGTexture *, const QRect &, const QRectF &, QSGNode *) = 0;
- virtual void setupTextureContentNode(QSGTexture *, const QRect &, const QRectF &,
- QSGImageNode::TextureCoordinatesTransformMode,
- QSGNode *) = 0;
- virtual void setupSolidColorNode(const QRect &, const QColor &, QSGNode *) = 0;
-
-#ifndef QT_NO_OPENGL
- virtual void setupDebugBorderNode(QSGGeometry *, QSGFlatColorMaterial *, QSGNode *) = 0;
- virtual void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *,
- const QRectF &, const QRectF &, const QSizeF &, const QSizeF &,
- gfx::ColorSpace, float, float, const QRectF &,
- QSGNode *) = 0;
-#ifdef GL_OES_EGL_image_external
- virtual void setupStreamVideoNode(MailboxTexture *, const QRectF &,
- const QMatrix4x4 &, QSGNode *) = 0;
-#endif // GL_OES_EGL_image_external
-#endif // QT_NO_OPENGL
-protected:
- QVector<QSGNode*> *m_sceneGraphNodes;
-};
-
-class DelegatedNodeTreeUpdater : public DelegatedNodeTreeHandler
-{
-public:
- DelegatedNodeTreeUpdater(QVector<QSGNode*> *sceneGraphNodes)
- : DelegatedNodeTreeHandler(sceneGraphNodes)
- , m_nodeIterator(sceneGraphNodes->begin())
- {
- }
-
- void setupRenderPassNode(QSGTexture *layer, const QRect &rect, const QRectF &sourceRect, QSGNode *) override
- {
- Q_ASSERT(layer);
- Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
- QSGImageNode *imageNode = static_cast<QSGImageNode*>(*m_nodeIterator++);
- imageNode->setRect(rect);
- imageNode->setSourceRect(sourceRect);
- imageNode->setTexture(layer);
- }
-
- void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGImageNode::TextureCoordinatesTransformMode texCoordTransForm,
- QSGNode *) override
- {
- Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
- QSGImageNode *textureNode = static_cast<QSGImageNode*>(*m_nodeIterator++);
- if (textureNode->texture() != texture) {
- // Chromium sometimes uses textures that doesn't completely fit
- // in which case the geometry needs to be recalculated even if
- // rect and src-rect matches.
- if (textureNode->texture()->textureSize() != texture->textureSize())
- textureNode->markDirty(QSGImageNode::DirtyGeometry);
- textureNode->setTexture(texture);
- }
- if (textureNode->textureCoordinatesTransform() != texCoordTransForm)
- textureNode->setTextureCoordinatesTransform(texCoordTransForm);
- if (textureNode->rect() != rect)
- textureNode->setRect(rect);
- if (textureNode->sourceRect() != sourceRect)
- textureNode->setSourceRect(sourceRect);
- if (textureNode->filtering() != texture->filtering())
- textureNode->setFiltering(texture->filtering());
- }
- void setupSolidColorNode(const QRect &rect, const QColor &color, QSGNode *) override
- {
- Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
- QSGRectangleNode *rectangleNode = static_cast<QSGRectangleNode*>(*m_nodeIterator++);
-
- if (rectangleNode->rect() != rect)
- rectangleNode->setRect(rect);
- if (rectangleNode->color() != color)
- rectangleNode->setColor(color);
- }
-#ifndef QT_NO_OPENGL
- void setupDebugBorderNode(QSGGeometry *geometry, QSGFlatColorMaterial *material,
- QSGNode *) override
- {
- Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
- QSGGeometryNode *geometryNode = static_cast<QSGGeometryNode*>(*m_nodeIterator++);
-
- geometryNode->setGeometry(geometry);
- geometryNode->setMaterial(material);
- }
-
- void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *,
- const QRectF &, const QRectF &, const QSizeF &, const QSizeF &,
- gfx::ColorSpace, float, float, const QRectF &,
- QSGNode *) override
- {
- Q_UNREACHABLE();
- }
-#ifdef GL_OES_EGL_image_external
- void setupStreamVideoNode(MailboxTexture *, const QRectF &,
- const QMatrix4x4 &, QSGNode *) override
- {
- Q_UNREACHABLE();
- }
-#endif // GL_OES_EGL_image_external
-#endif // QT_NO_OPENGL
-
-private:
- QVector<QSGNode*>::iterator m_nodeIterator;
-};
-
-class DelegatedNodeTreeCreator : public DelegatedNodeTreeHandler
-{
-public:
- DelegatedNodeTreeCreator(QVector<QSGNode*> *sceneGraphNodes,
- RenderWidgetHostViewQtDelegate *apiDelegate)
- : DelegatedNodeTreeHandler(sceneGraphNodes)
- , m_apiDelegate(apiDelegate)
- {
- }
-
- void setupRenderPassNode(QSGTexture *layer, const QRect &rect, const QRectF &sourceRect,
- QSGNode *layerChain) override
- {
- Q_ASSERT(layer);
- QSGImageNode *imageNode = m_apiDelegate->createImageNode();
- imageNode->setRect(rect);
- imageNode->setSourceRect(sourceRect);
- imageNode->setTexture(layer);
-
- layerChain->appendChildNode(imageNode);
- m_sceneGraphNodes->append(imageNode);
- }
-
- void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGImageNode::TextureCoordinatesTransformMode texCoordTransForm,
- QSGNode *layerChain) override
- {
- QSGImageNode *textureNode = m_apiDelegate->createImageNode();
- textureNode->setTextureCoordinatesTransform(texCoordTransForm);
- textureNode->setRect(rect);
- textureNode->setSourceRect(sourceRect);
- textureNode->setTexture(texture);
- textureNode->setFiltering(texture->filtering());
-
- layerChain->appendChildNode(textureNode);
- m_sceneGraphNodes->append(textureNode);
- }
-
- void setupSolidColorNode(const QRect &rect, const QColor &color,
- QSGNode *layerChain) override
- {
- QSGRectangleNode *rectangleNode = m_apiDelegate->createRectangleNode();
- rectangleNode->setRect(rect);
- rectangleNode->setColor(color);
-
- layerChain->appendChildNode(rectangleNode);
- m_sceneGraphNodes->append(rectangleNode);
- }
-
-#ifndef QT_NO_OPENGL
- void setupDebugBorderNode(QSGGeometry *geometry, QSGFlatColorMaterial *material,
- QSGNode *layerChain) override
- {
- QSGGeometryNode *geometryNode = new QSGGeometryNode;
- geometryNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial);
-
- geometryNode->setGeometry(geometry);
- geometryNode->setMaterial(material);
-
- layerChain->appendChildNode(geometryNode);
- m_sceneGraphNodes->append(geometryNode);
- }
-
- void setupYUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
- QSGTexture *aTexture, const QRectF &yaTexCoordRect,
- const QRectF &uvTexCoordRect, const QSizeF &yaTexSize,
- const QSizeF &uvTexSize, gfx::ColorSpace colorspace,
- float rMul, float rOff, const QRectF &rect,
- QSGNode *layerChain) override
- {
- YUVVideoNode *videoNode = new YUVVideoNode(
- yTexture,
- uTexture,
- vTexture,
- aTexture,
- yaTexCoordRect,
- uvTexCoordRect,
- yaTexSize,
- uvTexSize,
- colorspace,
- rMul,
- rOff);
- videoNode->setRect(rect);
-
- layerChain->appendChildNode(videoNode);
- m_sceneGraphNodes->append(videoNode);
- }
-#ifdef GL_OES_EGL_image_external
- void setupStreamVideoNode(MailboxTexture *texture, const QRectF &rect,
- const QMatrix4x4 &textureMatrix, QSGNode *layerChain) override
- {
- StreamVideoNode *svideoNode = new StreamVideoNode(texture, false, ExternalTarget);
- svideoNode->setRect(rect);
- svideoNode->setTextureMatrix(textureMatrix);
- layerChain->appendChildNode(svideoNode);
- m_sceneGraphNodes->append(svideoNode);
- }
-#endif // GL_OES_EGL_image_external
-#endif // QT_NO_OPENGL
-
-private:
- RenderWidgetHostViewQtDelegate *m_apiDelegate;
-};
-
-
-static inline QSharedPointer<QSGLayer> findRenderPassLayer(const int &id, const QVector<QPair<int, QSharedPointer<QSGLayer> > > &list)
-{
- typedef QPair<int, QSharedPointer<QSGLayer> > Pair;
- for (const Pair &pair : list)
- if (pair.first == id)
- return pair.second;
- return QSharedPointer<QSGLayer>();
-}
-
-static QSGNode *buildRenderPassChain(QSGNode *chainParent)
-{
- // Chromium already ordered the quads from back to front for us, however the
- // Qt scene graph layers individual geometries in their own z-range and uses
- // the depth buffer to visually stack nodes according to their item tree order.
-
- // This gets rid of the z component of all quads, once any x and y perspective
- // transformation has been applied to vertices not on the z=0 plane. Qt will
- // use an orthographic projection to render them.
- QSGTransformNode *zCompressNode = new QSGTransformNode;
- QMatrix4x4 zCompressMatrix;
- zCompressMatrix.scale(1, 1, 0);
- zCompressNode->setMatrix(zCompressMatrix);
- chainParent->appendChildNode(zCompressNode);
- return zCompressNode;
-}
-
-static QSGNode *buildLayerChain(QSGNode *chainParent, const viz::SharedQuadState *layerState)
-{
- QSGNode *layerChain = chainParent;
- if (layerState->is_clipped) {
- RectClipNode *clipNode = new RectClipNode(toQt(layerState->clip_rect));
- layerChain->appendChildNode(clipNode);
- layerChain = clipNode;
- }
- if (!layerState->quad_to_target_transform.IsIdentity()) {
- QSGTransformNode *transformNode = new QSGTransformNode;
- QMatrix4x4 qMatrix;
- convertToQt(layerState->quad_to_target_transform.matrix(), qMatrix);
- transformNode->setMatrix(qMatrix);
- layerChain->appendChildNode(transformNode);
- layerChain = transformNode;
- }
- if (layerState->opacity < 1.0) {
- QSGOpacityNode *opacityNode = new QSGOpacityNode;
- opacityNode->setOpacity(layerState->opacity);
- layerChain->appendChildNode(opacityNode);
- layerChain = opacityNode;
- }
- return layerChain;
-}
-
-#ifndef QT_NO_OPENGL
-MailboxTexture::MailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target)
- : m_textureId(resource->texture_id)
- , m_fence(resource->texture_fence)
- , m_textureSize(toQt(resource->size))
- , m_hasAlpha(hasAlphaChannel)
- , m_target(target >= 0 ? target : GL_TEXTURE_2D)
-#if defined(USE_OZONE)
- , m_ownsTexture(false)
-#endif
-{
- initializeOpenGLFunctions();
-
- // Assume that resources without a size will be used with a full source rect.
- // Setting a size of 1x1 will let any texture node compute a normalized source
- // rect of (0, 0) to (1, 1) while an empty texture size would set (0, 0) on all corners.
- if (m_textureSize.isEmpty())
- m_textureSize = QSize(1, 1);
-}
-
-MailboxTexture::~MailboxTexture()
-{
-#if defined(USE_OZONE)
- // This is rare case, where context is not shared
- // we created extra texture in current context, so
- // delete it now
- if (m_ownsTexture) {
- QOpenGLContext *currentContext = QOpenGLContext::currentContext() ;
- QOpenGLFunctions *funcs = currentContext->functions();
- GLuint id(m_textureId);
- funcs->glDeleteTextures(1, &id);
- }
-#endif
-}
-
-void MailboxTexture::bind()
-{
- if (m_fence)
- m_fence->wait();
- glBindTexture(m_target, m_textureId);
-#ifdef Q_OS_QNX
- if (m_target == GL_TEXTURE_EXTERNAL_OES) {
- static bool resolved = false;
- static PFNEGLSTREAMCONSUMERACQUIREKHRPROC eglStreamConsumerAcquire = 0;
-
- if (!resolved) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- eglStreamConsumerAcquire = (PFNEGLSTREAMCONSUMERACQUIREKHRPROC)context->getProcAddress("eglStreamConsumerAcquireKHR");
- resolved = true;
- }
- if (eglStreamConsumerAcquire)
- eglStreamConsumerAcquire(m_eglStreamData.egl_display, m_eglStreamData.egl_str_handle);
- }
-#endif
-}
-#endif // !QT_NO_OPENGL
-
-RectClipNode::RectClipNode(const QRectF &rect)
- : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
-{
- QSGGeometry::updateRectGeometry(&m_geometry, rect);
- setGeometry(&m_geometry);
- setClipRect(rect);
- setIsRectangular(true);
-}
-
-DelegatedFrameNode::DelegatedFrameNode()
-#if defined(USE_OZONE) && !defined(QT_NO_OPENGL)
- : m_contextShared(true)
-#endif
-{
- setFlag(UsePreprocess);
-#if defined(USE_OZONE) && !defined(QT_NO_OPENGL)
- QOpenGLContext *currentContext = QOpenGLContext::currentContext() ;
- QOpenGLContext *sharedContext = qt_gl_global_share_context();
- if (currentContext && sharedContext && !QOpenGLContext::areSharing(currentContext, sharedContext)) {
- static bool allowNotSharedContextWarningShown = true;
- if (allowNotSharedContextWarningShown) {
- allowNotSharedContextWarningShown = false;
- qWarning("Context is not shared, textures will be copied between contexts.");
- }
- m_offsurface.reset(new QOffscreenSurface);
- m_offsurface->create();
- m_contextShared = false;
- }
-#endif
-}
-
-DelegatedFrameNode::~DelegatedFrameNode()
-{
-}
-
-void DelegatedFrameNode::preprocess()
-{
- // Then render any intermediate RenderPass in order.
- typedef QPair<int, QSharedPointer<QSGLayer> > Pair;
- for (const Pair &pair : qAsConst(m_sgObjects.renderPassLayers)) {
- // The layer is non-live, request a one-time update here.
- pair.second->scheduleUpdate();
- // Proceed with the actual update.
- pair.second->updateTexture();
- }
-}
-
-static bool areSharedQuadStatesEqual(const viz::SharedQuadState *layerState,
- const viz::SharedQuadState *prevLayerState)
-{
- if (layerState->sorting_context_id != 0 || prevLayerState->sorting_context_id != 0)
- return false;
- if (layerState->is_clipped != prevLayerState->is_clipped
- || layerState->clip_rect != prevLayerState->clip_rect)
- return false;
- if (layerState->quad_to_target_transform != prevLayerState->quad_to_target_transform)
- return false;
- return qFuzzyCompare(layerState->opacity, prevLayerState->opacity);
-}
-
-// Compares if the frame data that we got from the Chromium Compositor is
-// *structurally* equivalent to the one of the previous frame.
-// If it is, we will just reuse and update the old nodes where necessary.
-static bool areRenderPassStructuresEqual(const viz::CompositorFrame *frameData,
- const viz::CompositorFrame *previousFrameData)
-{
- if (!previousFrameData)
- return false;
-
- if (previousFrameData->render_pass_list.size() != frameData->render_pass_list.size())
- return false;
-
- for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) {
- viz::RenderPass *newPass = frameData->render_pass_list.at(i).get();
- viz::RenderPass *prevPass = previousFrameData->render_pass_list.at(i).get();
-
- if (newPass->id != prevPass->id)
- return false;
-
- if (newPass->quad_list.size() != prevPass->quad_list.size())
- return false;
-
- viz::QuadList::ConstBackToFrontIterator it = newPass->quad_list.BackToFrontBegin();
- viz::QuadList::ConstBackToFrontIterator end = newPass->quad_list.BackToFrontEnd();
- viz::QuadList::ConstBackToFrontIterator prevIt = prevPass->quad_list.BackToFrontBegin();
- viz::QuadList::ConstBackToFrontIterator prevEnd = prevPass->quad_list.BackToFrontEnd();
- for (; it != end && prevIt != prevEnd; ++it, ++prevIt) {
- const viz::DrawQuad *quad = *it;
- const viz::DrawQuad *prevQuad = *prevIt;
- if (quad->material != prevQuad->material)
- return false;
-#ifndef QT_NO_OPENGL
- if (quad->material == viz::DrawQuad::YUV_VIDEO_CONTENT)
- return false;
-#ifdef GL_OES_EGL_image_external
- if (quad->material == viz::DrawQuad::STREAM_VIDEO_CONTENT)
- return false;
-#endif // GL_OES_EGL_image_external
-#endif // QT_NO_OPENGL
- if (!areSharedQuadStatesEqual(quad->shared_quad_state, prevQuad->shared_quad_state))
- return false;
- if (quad->shared_quad_state->is_clipped && quad->visible_rect != prevQuad->visible_rect) {
- gfx::Rect targetRect1 =
- cc::MathUtil::MapEnclosingClippedRect(quad->shared_quad_state->quad_to_target_transform, quad->visible_rect);
- gfx::Rect targetRect2 =
- cc::MathUtil::MapEnclosingClippedRect(quad->shared_quad_state->quad_to_target_transform, prevQuad->visible_rect);
- targetRect1.Intersect(quad->shared_quad_state->clip_rect);
- targetRect2.Intersect(quad->shared_quad_state->clip_rect);
- if (targetRect1.IsEmpty() != targetRect2.IsEmpty())
- return false;
- }
- }
- }
- return true;
-}
-
-void DelegatedFrameNode::commit(const viz::CompositorFrame &pendingFrame,
- const viz::CompositorFrame &committedFrame,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- const viz::CompositorFrame* frameData = &pendingFrame;
- if (frameData->render_pass_list.empty())
- return;
-
- // DelegatedFrameNode is a transform node only for the purpose of
- // countering the scale of devicePixel-scaled tiles when rendering them
- // to the final surface.
- QMatrix4x4 matrix;
- const float devicePixelRatio = frameData->metadata.device_scale_factor;
- matrix.scale(1 / devicePixelRatio, 1 / devicePixelRatio);
- if (QSGTransformNode::matrix() != matrix)
- setMatrix(matrix);
-
- QScopedPointer<DelegatedNodeTreeHandler> nodeHandler;
-
- const QSizeF viewportSizeInPt = apiDelegate->viewGeometry().size();
- const QSizeF viewportSizeF = viewportSizeInPt * devicePixelRatio;
- const QSize viewportSize(std::ceil(viewportSizeF.width()), std::ceil(viewportSizeF.height()));
-
- // We first compare if the render passes from the previous frame data are structurally
- // equivalent to the render passes in the current frame data. If they are, we are going
- // to reuse the old nodes. Otherwise, we will delete the old nodes and build a new tree.
- //
- // Additionally, because we clip (i.e. don't build scene graph nodes for) quads outside
- // of the visible area, we also have to rebuild the tree whenever the window is resized.
- const bool buildNewTree =
- !areRenderPassStructuresEqual(frameData, &committedFrame) ||
- m_sceneGraphNodes.empty() ||
- viewportSize != m_previousViewportSize;
-
- if (buildNewTree) {
- // Keep the old objects in scope to hold a ref on layers, resources and textures
- // that we can re-use. Destroy the remaining objects before returning.
- qSwap(m_sgObjects, m_previousSGObjects);
- // Discard the scene graph nodes from the previous frame.
- while (QSGNode *oldChain = firstChild())
- delete oldChain;
- m_sceneGraphNodes.clear();
- nodeHandler.reset(new DelegatedNodeTreeCreator(&m_sceneGraphNodes, apiDelegate));
- } else {
- qSwap(m_sgObjects.bitmapTextures, m_previousSGObjects.bitmapTextures);
- qSwap(m_sgObjects.mailboxTextures, m_previousSGObjects.mailboxTextures);
- nodeHandler.reset(new DelegatedNodeTreeUpdater(&m_sceneGraphNodes));
- }
- // The RenderPasses list is actually a tree where a parent RenderPass is connected
- // to its dependencies through a RenderPassId reference in one or more RenderPassQuads.
- // The list is already ordered with intermediate RenderPasses placed before their
- // parent, with the last one in the list being the root RenderPass, the one
- // that we displayed to the user.
- // All RenderPasses except the last one are rendered to an FBO.
- viz::RenderPass *rootRenderPass = frameData->render_pass_list.back().get();
-
- gfx::Rect viewportRect(toGfx(viewportSize));
- for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) {
- viz::RenderPass *pass = frameData->render_pass_list.at(i).get();
-
- QSGNode *renderPassParent = 0;
- gfx::Rect scissorRect;
- if (pass != rootRenderPass) {
- QSharedPointer<QSGLayer> rpLayer;
- if (buildNewTree) {
- rpLayer = findRenderPassLayer(pass->id, m_previousSGObjects.renderPassLayers);
- if (!rpLayer) {
- rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer());
- // Avoid any premature texture update since we need to wait
- // for the GPU thread to produce the dependent resources first.
- rpLayer->setLive(false);
- }
- QSharedPointer<QSGRootNode> rootNode(new QSGRootNode);
- rpLayer->setItem(rootNode.data());
- m_sgObjects.renderPassLayers.append(QPair<int,
- QSharedPointer<QSGLayer> >(pass->id, rpLayer));
- m_sgObjects.renderPassRootNodes.append(rootNode);
- renderPassParent = rootNode.data();
- } else
- rpLayer = findRenderPassLayer(pass->id, m_sgObjects.renderPassLayers);
-
- rpLayer->setRect(toQt(pass->output_rect));
- rpLayer->setSize(toQt(pass->output_rect.size()));
- rpLayer->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
- rpLayer->setHasMipmaps(pass->generate_mipmap);
- rpLayer->setMirrorVertical(true);
- scissorRect = pass->output_rect;
- } else {
- renderPassParent = this;
- scissorRect = viewportRect;
- scissorRect += rootRenderPass->output_rect.OffsetFromOrigin();
- }
-
- if (scissorRect.IsEmpty()) {
- holdResources(pass, resourceTracker);
- continue;
- }
-
- QSGNode *renderPassChain = nullptr;
- if (buildNewTree)
- renderPassChain = buildRenderPassChain(renderPassParent);
-
- base::circular_deque<std::unique_ptr<viz::DrawPolygon>> polygonQueue;
- int nextPolygonId = 0;
- int currentSortingContextId = 0;
- const viz::SharedQuadState *currentLayerState = nullptr;
- QSGNode *currentLayerChain = nullptr;
- const auto quadListBegin = pass->quad_list.BackToFrontBegin();
- const auto quadListEnd = pass->quad_list.BackToFrontEnd();
- for (auto it = quadListBegin; it != quadListEnd; ++it) {
- const viz::DrawQuad *quad = *it;
- const viz::SharedQuadState *quadState = quad->shared_quad_state;
-
- gfx::Rect targetRect =
- cc::MathUtil::MapEnclosingClippedRect(quadState->quad_to_target_transform,
- quad->visible_rect);
- if (quadState->is_clipped)
- targetRect.Intersect(quadState->clip_rect);
- targetRect.Intersect(scissorRect);
- if (targetRect.IsEmpty()) {
- holdResources(quad, resourceTracker);
- continue;
- }
-
- if (quadState->sorting_context_id != currentSortingContextId) {
- flushPolygons(&polygonQueue, renderPassChain,
- nodeHandler.data(), resourceTracker, apiDelegate);
- currentSortingContextId = quadState->sorting_context_id;
- }
-
- if (currentSortingContextId != 0) {
- std::unique_ptr<viz::DrawPolygon> polygon(
- new viz::DrawPolygon(
- quad,
- gfx::RectF(quad->visible_rect),
- quadState->quad_to_target_transform,
- nextPolygonId++));
- if (polygon->points().size() > 2u)
- polygonQueue.push_back(std::move(polygon));
- continue;
- }
-
- if (renderPassChain && currentLayerState != quadState) {
- currentLayerState = quadState;
- currentLayerChain = buildLayerChain(renderPassChain, quadState);
- }
-
- handleQuad(quad, currentLayerChain,
- nodeHandler.data(), resourceTracker, apiDelegate);
- }
- flushPolygons(&polygonQueue, renderPassChain,
- nodeHandler.data(), resourceTracker, apiDelegate);
- }
-
- copyMailboxTextures();
-
- m_previousViewportSize = viewportSize;
- m_previousSGObjects = SGObjects();
-}
-
-void DelegatedFrameNode::flushPolygons(
- base::circular_deque<std::unique_ptr<viz::DrawPolygon>> *polygonQueue,
- QSGNode *renderPassChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- if (polygonQueue->empty())
- return;
-
- const auto actionHandler = [&](viz::DrawPolygon *polygon) {
- const viz::DrawQuad *quad = polygon->original_ref();
- const viz::SharedQuadState *quadState = quad->shared_quad_state;
-
- QSGNode *currentLayerChain = nullptr;
- if (renderPassChain)
- currentLayerChain = buildLayerChain(renderPassChain, quad->shared_quad_state);
-
- gfx::Transform inverseTransform;
- bool invertible = quadState->quad_to_target_transform.GetInverse(&inverseTransform);
- DCHECK(invertible);
- polygon->TransformToLayerSpace(inverseTransform);
-
- handlePolygon(polygon, currentLayerChain,
- nodeHandler, resourceTracker, apiDelegate);
- };
-
- viz::BspTree(polygonQueue).TraverseWithActionHandler(&actionHandler);
-}
-
-void DelegatedFrameNode::handlePolygon(
- const viz::DrawPolygon *polygon,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- const viz::DrawQuad *quad = polygon->original_ref();
-
- if (!polygon->is_split()) {
- handleQuad(quad, currentLayerChain,
- nodeHandler, resourceTracker, apiDelegate);
- } else {
- std::vector<gfx::QuadF> clipRegionList;
- polygon->ToQuads2D(&clipRegionList);
- for (const auto & clipRegion : clipRegionList)
- handleClippedQuad(quad, clipRegion, currentLayerChain,
- nodeHandler, resourceTracker, apiDelegate);
- }
-}
-
-void DelegatedFrameNode::handleClippedQuad(
- const viz::DrawQuad *quad,
- const gfx::QuadF &clipRegion,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- if (currentLayerChain) {
- auto clipGeometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
- auto clipGeometryVertices = clipGeometry->vertexDataAsPoint2D();
- clipGeometryVertices[0].set(clipRegion.p1().x(), clipRegion.p1().y());
- clipGeometryVertices[1].set(clipRegion.p2().x(), clipRegion.p2().y());
- clipGeometryVertices[2].set(clipRegion.p4().x(), clipRegion.p4().y());
- clipGeometryVertices[3].set(clipRegion.p3().x(), clipRegion.p3().y());
- auto clipNode = new QSGClipNode;
- clipNode->setGeometry(clipGeometry);
- clipNode->setIsRectangular(false);
- clipNode->setFlag(QSGNode::OwnsGeometry);
- currentLayerChain->appendChildNode(clipNode);
- currentLayerChain = clipNode;
- }
- handleQuad(quad, currentLayerChain,
- nodeHandler, resourceTracker, apiDelegate);
-}
-
-void DelegatedFrameNode::handleQuad(
- const viz::DrawQuad *quad,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- switch (quad->material) {
- case viz::DrawQuad::RENDER_PASS: {
- const viz::RenderPassDrawQuad *renderPassQuad = viz::RenderPassDrawQuad::MaterialCast(quad);
- if (!renderPassQuad->mask_texture_size.IsEmpty()) {
- const CompositorResource *resource = findAndHoldResource(renderPassQuad->mask_resource_id(), resourceTracker);
- Q_UNUSED(resource); // FIXME: QTBUG-67652
- }
- QSGLayer *layer =
- findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data();
-
- if (layer)
- nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), toQt(renderPassQuad->tex_coord_rect), currentLayerChain);
-
- break;
- }
- case viz::DrawQuad::TEXTURE_CONTENT: {
- const viz::TextureDrawQuad *tquad = viz::TextureDrawQuad::MaterialCast(quad);
- const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
- QSGTexture *texture =
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate);
- QSizeF textureSize;
- if (texture)
- textureSize = texture->textureSize();
- gfx::RectF uv_rect =
- gfx::ScaleRect(gfx::BoundingRect(tquad->uv_top_left, tquad->uv_bottom_right),
- textureSize.width(), textureSize.height());
-
- nodeHandler->setupTextureContentNode(
- texture, toQt(quad->rect), toQt(uv_rect),
- tquad->y_flipped ? QSGImageNode::MirrorVertically : QSGImageNode::NoTransform,
- currentLayerChain);
- break;
- }
- case viz::DrawQuad::SOLID_COLOR: {
- const viz::SolidColorDrawQuad *scquad = viz::SolidColorDrawQuad::MaterialCast(quad);
- // Qt only supports MSAA and this flag shouldn't be needed.
- // If we ever want to use QSGRectangleNode::setAntialiasing for this we should
- // try to see if we can do something similar for tile quads first.
- Q_UNUSED(scquad->force_anti_aliasing_off);
- nodeHandler->setupSolidColorNode(toQt(quad->rect), toQt(scquad->color), currentLayerChain);
- break;
-#ifndef QT_NO_OPENGL
- }
- case viz::DrawQuad::DEBUG_BORDER: {
- const viz::DebugBorderDrawQuad *dbquad = viz::DebugBorderDrawQuad::MaterialCast(quad);
-
- QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
- geometry->setDrawingMode(GL_LINE_LOOP);
- geometry->setLineWidth(dbquad->width);
- // QSGGeometry::updateRectGeometry would actually set the
- // corners in the following order:
- // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross,
- // instead of having a closed loop.
- const gfx::Rect &r(dbquad->rect);
- geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
- geometry->vertexDataAsPoint2D()[1].set(r.x() + r.width(), r.y());
- geometry->vertexDataAsPoint2D()[2].set(r.x() + r.width(), r.y() + r.height());
- geometry->vertexDataAsPoint2D()[3].set(r.x(), r.y() + r.height());
-
- QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
- material->setColor(toQt(dbquad->color));
-
- nodeHandler->setupDebugBorderNode(geometry, material, currentLayerChain);
- break;
-#endif
- }
- case viz::DrawQuad::TILED_CONTENT: {
- const viz::TileDrawQuad *tquad = viz::TileDrawQuad::MaterialCast(quad);
- const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
- nodeHandler->setupTextureContentNode(
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate),
- toQt(quad->rect), toQt(tquad->tex_coord_rect),
- QSGImageNode::NoTransform, currentLayerChain);
- break;
-#ifndef QT_NO_OPENGL
- }
- case viz::DrawQuad::YUV_VIDEO_CONTENT: {
- const viz::YUVVideoDrawQuad *vquad = viz::YUVVideoDrawQuad::MaterialCast(quad);
- const CompositorResource *yResource =
- findAndHoldResource(vquad->y_plane_resource_id(), resourceTracker);
- const CompositorResource *uResource =
- findAndHoldResource(vquad->u_plane_resource_id(), resourceTracker);
- const CompositorResource *vResource =
- findAndHoldResource(vquad->v_plane_resource_id(), resourceTracker);
- const CompositorResource *aResource = nullptr;
- // This currently requires --enable-vp8-alpha-playback and
- // needs a video with alpha data to be triggered.
- if (vquad->a_plane_resource_id())
- aResource = findAndHoldResource(vquad->a_plane_resource_id(), resourceTracker);
-
- nodeHandler->setupYUVVideoNode(
- initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()),
- initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()),
- initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()),
- aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0,
- toQt(vquad->ya_tex_coord_rect), toQt(vquad->uv_tex_coord_rect),
- toQt(vquad->ya_tex_size), toQt(vquad->uv_tex_size), vquad->video_color_space,
- vquad->resource_multiplier, vquad->resource_offset, toQt(quad->rect),
- currentLayerChain);
- break;
-#ifdef GL_OES_EGL_image_external
- }
- case viz::DrawQuad::STREAM_VIDEO_CONTENT: {
- const viz::StreamVideoDrawQuad *squad = viz::StreamVideoDrawQuad::MaterialCast(quad);
- const CompositorResource *resource = findAndHoldResource(squad->resource_id(), resourceTracker);
- MailboxTexture *texture = static_cast<MailboxTexture *>(
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate, GL_TEXTURE_EXTERNAL_OES));
-
- QMatrix4x4 qMatrix;
-// convertToQt(squad->matrix.matrix(), qMatrix);
- nodeHandler->setupStreamVideoNode(texture, toQt(squad->rect), qMatrix, currentLayerChain);
- break;
-#endif // GL_OES_EGL_image_external
-#endif // QT_NO_OPENGL
- }
- case viz::DrawQuad::SURFACE_CONTENT:
- Q_UNREACHABLE();
- default:
- qWarning("Unimplemented quad material: %d", quad->material);
- }
-}
-
-const CompositorResource *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, const CompositorResourceTracker *resourceTracker)
-{
- return resourceTracker->findResource(resourceId);
-}
-
-void DelegatedFrameNode::holdResources(const viz::DrawQuad *quad, const CompositorResourceTracker *resourceTracker)
-{
- for (auto resource : quad->resources)
- findAndHoldResource(resource, resourceTracker);
-}
-
-void DelegatedFrameNode::holdResources(const viz::RenderPass *pass, const CompositorResourceTracker *resourceTracker)
-{
- for (const auto &quad : pass->quad_list)
- holdResources(quad, resourceTracker);
-}
-
-template<class Container, class Key>
-inline auto &findTexture(Container &map, Container &previousMap, const Key &key)
-{
- auto &value = map[key];
- if (value)
- return value;
- value = previousMap[key];
- return value;
-}
-
-QSGTexture *DelegatedFrameNode::initAndHoldTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate, int target)
-{
- QSGTexture::Filtering filtering;
-
- if (resource->filter == GL_NEAREST)
- filtering = QSGTexture::Nearest;
- else if (resource->filter == GL_LINEAR)
- filtering = QSGTexture::Linear;
- else {
- // Depends on qtdeclarative fix, see QTBUG-71322
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1)
- filtering = QSGTexture::Linear;
-#else
- filtering = QSGTexture::Nearest;
-#endif
- }
-
- if (resource->is_software) {
- QSharedPointer<QSGTexture> &texture =
- findTexture(m_sgObjects.bitmapTextures, m_previousSGObjects.bitmapTextures, resource->id);
- if (texture)
- return texture.data();
- texture = createBitmapTexture(resource, hasAlphaChannel, apiDelegate);
- texture->setFiltering(filtering);
- return texture.data();
- } else {
-#if QT_CONFIG(opengl)
- QSharedPointer<MailboxTexture> &texture =
- findTexture(m_sgObjects.mailboxTextures, m_previousSGObjects.mailboxTextures, resource->id);
- if (texture)
- return texture.data();
- texture = createMailboxTexture(resource, hasAlphaChannel, target);
- texture->setFiltering(filtering);
- return texture.data();
-#else
- Q_UNREACHABLE();
- return nullptr;
-#endif
- }
-}
-
-QSharedPointer<QSGTexture> DelegatedFrameNode::createBitmapTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- Q_ASSERT(apiDelegate);
- viz::SharedBitmap *sharedBitmap = resource->bitmap.get();
- gfx::Size size = resource->size;
-
- // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending
- // to draw it but Chromium keeps this information in the quads.
- // The input format is currently always Format_ARGB32_Premultiplied, so assume that all
- // alpha bytes are 0xff if quads aren't requesting blending and avoid the conversion
- // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to
- // return false.
- QImage::Format format = hasAlphaChannel ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- QImage image = sharedBitmap
- ? QImage(sharedBitmap->pixels(), size.width(), size.height(), format)
- : QImage(size.width(), size.height(), format);
- return QSharedPointer<QSGTexture>(apiDelegate->createTextureFromImage(image.copy()));
-}
-
-QSharedPointer<MailboxTexture> DelegatedFrameNode::createMailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target)
-{
-#ifndef QT_NO_OPENGL
- return QSharedPointer<MailboxTexture>::create(resource, hasAlphaChannel, target);
-#else
- Q_UNREACHABLE();
-#endif
-}
-
-void DelegatedFrameNode::copyMailboxTextures()
-{
-#if !defined(QT_NO_OPENGL) && defined(USE_OZONE)
- // Workaround when context is not shared QTBUG-48969
- // Make slow copy between two contexts.
- if (!m_contextShared) {
- QOpenGLContext *currentContext = QOpenGLContext::currentContext() ;
- QOpenGLContext *sharedContext = qt_gl_global_share_context();
-
- QSurface *surface = currentContext->surface();
- Q_ASSERT(m_offsurface);
- sharedContext->makeCurrent(m_offsurface.data());
- QOpenGLFunctions *funcs = sharedContext->functions();
-
- GLuint fbo = 0;
- funcs->glGenFramebuffers(1, &fbo);
-
- for (const QSharedPointer<MailboxTexture> &mailboxTexture : qAsConst(m_sgObjects.mailboxTextures)) {
- if (mailboxTexture->m_ownsTexture)
- continue;
-
- // Read texture into QImage from shared context.
- // Switch to shared context.
- sharedContext->makeCurrent(m_offsurface.data());
- funcs = sharedContext->functions();
- QImage img(mailboxTexture->textureSize(), QImage::Format_RGBA8888_Premultiplied);
- funcs->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- mailboxTexture->m_fence->wait();
- funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mailboxTexture->m_textureId, 0);
- GLenum status = funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- qWarning("fbo error, skipping slow copy...");
- continue;
- }
- funcs->glReadPixels(0, 0, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(),
- GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
-
- // Restore current context.
- // Create texture from QImage in current context.
- currentContext->makeCurrent(surface);
- GLuint texture = 0;
- funcs = currentContext->functions();
- funcs->glGenTextures(1, &texture);
- funcs->glBindTexture(GL_TEXTURE_2D, texture);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
- mailboxTexture->m_textureId = texture;
- mailboxTexture->m_ownsTexture = true;
- }
- // Cleanup allocated resources
- sharedContext->makeCurrent(m_offsurface.data());
- funcs = sharedContext->functions();
- funcs->glBindFramebuffer(GL_FRAMEBUFFER, 0);
- funcs->glDeleteFramebuffers(1, &fbo);
- currentContext->makeCurrent(surface);
- }
-#endif
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/delegated_frame_node.h b/src/core/compositor/delegated_frame_node.h
deleted file mode 100644
index 34e4ba029..000000000
--- a/src/core/compositor/delegated_frame_node.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef DELEGATED_FRAME_NODE_H
-#define DELEGATED_FRAME_NODE_H
-
-#include "base/containers/circular_deque.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/render_pass.h"
-
-#include <QtCore/QSharedPointer>
-#include <QtGui/QOffscreenSurface>
-#include <QtQuick/QSGTransformNode>
-
-#include "chromium_gpu_helper.h"
-#include "render_widget_host_view_qt_delegate.h"
-
-QT_BEGIN_NAMESPACE
-class QSGLayer;
-QT_END_NAMESPACE
-
-namespace gfx {
-class QuadF;
-}
-
-namespace viz {
-class DelegatedFrameData;
-class DrawQuad;
-class DrawPolygon;
-}
-
-namespace QtWebEngineCore {
-
-class CompositorResource;
-class CompositorResourceTracker;
-class DelegatedNodeTreeHandler;
-class MailboxTexture;
-
-class DelegatedFrameNode : public QSGTransformNode {
-public:
- DelegatedFrameNode();
- ~DelegatedFrameNode();
- void preprocess() override;
- void commit(const viz::CompositorFrame &pendingFrame, const viz::CompositorFrame &committedFrame, const CompositorResourceTracker *resourceTracker, RenderWidgetHostViewQtDelegate *apiDelegate);
-
-private:
- void flushPolygons(base::circular_deque<std::unique_ptr<viz::DrawPolygon> > *polygonQueue,
- QSGNode *renderPassChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate);
- void handlePolygon(
- const viz::DrawPolygon *polygon,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate);
- void handleClippedQuad(
- const viz::DrawQuad *quad,
- const gfx::QuadF &clipRegion,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate);
- void handleQuad(
- const viz::DrawQuad *quad,
- QSGNode *currentLayerChain,
- DelegatedNodeTreeHandler *nodeHandler,
- const CompositorResourceTracker *resourceTracker,
- RenderWidgetHostViewQtDelegate *apiDelegate);
-
- const CompositorResource *findAndHoldResource(unsigned resourceId, const CompositorResourceTracker *resourceTracker);
- void holdResources(const viz::DrawQuad *quad, const CompositorResourceTracker *resourceTracker);
- void holdResources(const viz::RenderPass *pass, const CompositorResourceTracker *resourceTracker);
- QSGTexture *initAndHoldTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate = 0, int target = -1);
- QSharedPointer<QSGTexture> createBitmapTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate);
- QSharedPointer<MailboxTexture> createMailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target);
-
- void copyMailboxTextures();
-
- struct SGObjects {
- QVector<QPair<int, QSharedPointer<QSGLayer> > > renderPassLayers;
- QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes;
- QHash<unsigned, QSharedPointer<QSGTexture> > bitmapTextures;
- QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextures;
- } m_sgObjects, m_previousSGObjects;
- QVector<QSGNode*> m_sceneGraphNodes;
-#if defined(USE_OZONE)
- bool m_contextShared;
- QScopedPointer<QOffscreenSurface> m_offsurface;
-#endif
- QSize m_previousViewportSize;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // DELEGATED_FRAME_NODE_H
diff --git a/src/core/compositor/display_consumer.h b/src/core/compositor/display_consumer.h
deleted file mode 100644
index d220088ad..000000000
--- a/src/core/compositor/display_consumer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_CONSUMER_H
-#define DISPLAY_CONSUMER_H
-
-#include "qtwebenginecoreglobal_p.h"
-
-namespace QtWebEngineCore {
-
-// Receives composited frames for display.
-class DisplayConsumer
-{
-public:
- // Schedule a call to updatePaintNode soon.
- //
- // Called on the consumer thread.
- virtual void scheduleUpdate() = 0;
-
-protected:
- ~DisplayConsumer() {}
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_CONSUMER_H
diff --git a/src/core/compositor/display_frame_sink.cpp b/src/core/compositor/display_frame_sink.cpp
deleted file mode 100644
index 945600299..000000000
--- a/src/core/compositor/display_frame_sink.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_frame_sink.h"
-
-#include <QMap>
-
-namespace QtWebEngineCore {
-
-namespace {
-
-class DisplayFrameSinkMap
-{
-public:
- static DisplayFrameSinkMap *instance()
- {
- static DisplayFrameSinkMap map;
- return &map;
- }
-
- scoped_refptr<DisplayFrameSink> findOrCreate(viz::FrameSinkId frameSinkId)
- {
- QMutexLocker locker(&m_mutex);
- auto it = m_map.find(frameSinkId);
- if (it == m_map.end())
- it = m_map.insert(frameSinkId, new DisplayFrameSink(frameSinkId));
- return *it;
- }
-
- void remove(viz::FrameSinkId frameSinkId)
- {
- QMutexLocker locker(&m_mutex);
- m_map.remove(frameSinkId);
- }
-
-private:
- mutable QMutex m_mutex;
- QMap<viz::FrameSinkId, DisplayFrameSink *> m_map;
-};
-
-} // namespace
-
-// static
-scoped_refptr<DisplayFrameSink> DisplayFrameSink::findOrCreate(viz::FrameSinkId frameSinkId)
-{
- return DisplayFrameSinkMap::instance()->findOrCreate(frameSinkId);
-}
-
-DisplayFrameSink::DisplayFrameSink(viz::FrameSinkId frameSinkId)
- : m_frameSinkId(frameSinkId)
-{
- DCHECK(m_frameSinkId.is_valid());
-}
-
-DisplayFrameSink::~DisplayFrameSink()
-{
- DisplayFrameSinkMap::instance()->remove(m_frameSinkId);
-}
-
-void DisplayFrameSink::connect(DisplayConsumer *consumer)
-{
- QMutexLocker locker(&m_mutex);
- DCHECK(m_consumer == nullptr);
- m_consumer = consumer;
-}
-
-void DisplayFrameSink::connect(DisplayProducer *producer)
-{
- QMutexLocker locker(&m_mutex);
- DCHECK(m_producer == nullptr);
- m_producer = producer;
-}
-
-void DisplayFrameSink::disconnect(DisplayConsumer *consumer)
-{
- QMutexLocker locker(&m_mutex);
- DCHECK(m_consumer == consumer);
- m_consumer = nullptr;
-}
-
-void DisplayFrameSink::disconnect(DisplayProducer *producer)
-{
- QMutexLocker locker(&m_mutex);
- DCHECK(m_producer == producer);
- m_producer = nullptr;
-}
-
-void DisplayFrameSink::scheduleUpdate()
-{
- QMutexLocker locker(&m_mutex);
- if (m_consumer)
- m_consumer->scheduleUpdate();
-}
-
-QSGNode *DisplayFrameSink::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
-{
- QMutexLocker locker(&m_mutex);
- QSGNode *newNode = oldNode;
- if (m_producer)
- newNode = m_producer->updatePaintNode(oldNode, delegate);
- return newNode;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_frame_sink.h b/src/core/compositor/display_frame_sink.h
deleted file mode 100644
index f620dc4f2..000000000
--- a/src/core/compositor/display_frame_sink.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_FRAME_SINK_H
-#define DISPLAY_FRAME_SINK_H
-
-#include "display_consumer.h"
-#include "display_producer.h"
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "components/viz/common/surfaces/frame_sink_id.h"
-
-#include <QMutex>
-
-namespace QtWebEngineCore {
-
-// Connects a DisplayConsumer with a DisplayProducer.
-class DisplayFrameSink final : public base::RefCountedThreadSafe<DisplayFrameSink>
-{
-public:
- static scoped_refptr<DisplayFrameSink> findOrCreate(viz::FrameSinkId frameSinkId);
- DisplayFrameSink(viz::FrameSinkId frameSinkId);
- ~DisplayFrameSink();
- void connect(DisplayConsumer *consumer);
- void connect(DisplayProducer *producer);
- void disconnect(DisplayConsumer *consumer);
- void disconnect(DisplayProducer *producer);
- void scheduleUpdate();
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate);
-
-private:
- const viz::FrameSinkId m_frameSinkId;
- mutable QMutex m_mutex;
- DisplayProducer *m_producer = nullptr;
- DisplayConsumer *m_consumer = nullptr;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_FRAME_SINK_H
diff --git a/src/core/compositor/display_gl_output_surface.cpp b/src/core/compositor/display_gl_output_surface.cpp
deleted file mode 100644
index 5a78b8322..000000000
--- a/src/core/compositor/display_gl_output_surface.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_gl_output_surface.h"
-
-#include "chromium_gpu_helper.h"
-
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/viz/service/display/display.h"
-#include "components/viz/service/display/output_surface_frame.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/texture_base.h"
-#include "gpu/ipc/in_process_command_buffer.h"
-#include "ui/gl/color_space_utils.h"
-
-namespace QtWebEngineCore {
-
-DisplayGLOutputSurface::DisplayGLOutputSurface(
- scoped_refptr<viz::VizProcessContextProvider> contextProvider,
- viz::UpdateVSyncParametersCallback callback)
- : OutputSurface(contextProvider)
- , m_commandBuffer(contextProvider->command_buffer())
- , m_gl(contextProvider->ContextGL())
-{
- capabilities_.uses_default_gl_framebuffer = false;
- m_gl->GenFramebuffers(1, &m_fboId);
- contextProvider->SetUpdateVSyncParametersCallback(std::move(callback));
-}
-
-DisplayGLOutputSurface::~DisplayGLOutputSurface()
-{
- m_gl->DeleteFramebuffers(1, &m_fboId);
- if (m_sink)
- m_sink->disconnect(this);
-}
-
-// Called from viz::Display::Initialize.
-void DisplayGLOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
-{
- m_display = static_cast<viz::Display *>(client);
- m_sink = DisplayFrameSink::findOrCreate(m_display->frame_sink_id());
- m_sink->connect(this);
-}
-
-// Triggered by ui::Compositor::SetVisible(true).
-void DisplayGLOutputSurface::EnsureBackbuffer()
-{
-}
-
-// Triggered by ui::Compositor::SetVisible(false). Framebuffer must be cleared.
-void DisplayGLOutputSurface::DiscardBackbuffer()
-{
- NOTIMPLEMENTED();
- // m_gl->DiscardBackbufferCHROMIUM();
-}
-
-// Called from viz::DirectRenderer::DrawFrame before rendering starts, but only
-// if the parameters differ from the previous Reshape call.
-//
-// Parameters:
-//
-// - sizeInPixels comes from ui::Compositor::SetScaleAndSize via
-// viz::HostContextFactoryPrivate::ResizeDisplay.
-//
-// - devicePixelRatio comes from viz::CompositorFrame::device_scale_factor()
-// via viz::RootCompositorFrameSinkImpl::SubmitCompositorFrame and
-// viz::Display::SetLocalSurfaceId.
-//
-// - colorSpace and hasAlpha correspond to the color_space and
-// has_transparent_background properties of the root viz::RenderPass.
-//
-// - useStencil should create a stencil buffer, but this is only needed for
-// overdraw feedback (--show-overdraw-feedback), so it's safe to ignore.
-// Accordingly, capabilities_.supports_stencil should be set to false.
-//
-void DisplayGLOutputSurface::Reshape(const gfx::Size &sizeInPixels,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- bool hasAlpha,
- bool /*useStencil*/)
-{
- m_currentShape = Shape{sizeInPixels, devicePixelRatio, colorSpace, hasAlpha};
- m_gl->ResizeCHROMIUM(sizeInPixels.width(), sizeInPixels.height(), devicePixelRatio,
- gl::ColorSpaceUtils::GetGLColorSpace(colorSpace), hasAlpha);
-}
-
-std::unique_ptr<DisplayGLOutputSurface::Buffer> DisplayGLOutputSurface::makeBuffer(const Shape &shape)
-{
- std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this);
- buffer->shape = shape;
- m_gl->GenTextures(1, &buffer->clientId);
- m_gl->BindTexture(GL_TEXTURE_2D, buffer->clientId);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- uint32_t width = shape.sizeInPixels.width();
- uint32_t height = shape.sizeInPixels.height();
- uint32_t format = shape.hasAlpha ? GL_RGBA : GL_RGB;
- m_gl->TexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
- return buffer;
-}
-
-void DisplayGLOutputSurface::deleteBufferResources(Buffer *buffer)
-{
- m_gl->DeleteTextures(1, &buffer->clientId);
-}
-
-// Called by viz::GLRenderer during rendering whenever it switches to the root
-// render pass.
-void DisplayGLOutputSurface::BindFramebuffer()
-{
- if (!m_backBuffer || m_backBuffer->shape != m_currentShape)
- m_backBuffer = makeBuffer(m_currentShape);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer->clientId, 0);
-}
-
-// Called from viz::Display::DrawAndSwap after rendering.
-//
-// Parameters:
-//
-// - frame.size is the same as the size given to Reshape.
-//
-// - frame.sub_buffer_rect and frame.content_bounds are never used since these
-// are only enabled if gl::GLSurface::SupportsPostSubBuffer() or
-// gl::GLSurface::SupportsSwapBuffersWithBounds() are true, respectively,
-// but this not the case for any offscreen gl::GLSurface.
-//
-// - frame.latency_info is viz::CompositorFrame::metadata.latency_info.
-void DisplayGLOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame)
-{
- DCHECK(frame.size == m_currentShape.sizeInPixels);
- DCHECK(!frame.sub_buffer_rect.has_value());
- DCHECK(frame.content_bounds.empty());
- DCHECK(m_backBuffer);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- gpu::SyncToken syncToken;
- m_gl->GenSyncTokenCHROMIUM(syncToken.GetData());
-
- unsigned int clientId = m_backBuffer->clientId;
-
- // Now some thread-hopping:
- //
- // - We start here on the viz thread (client side of command buffer).
- //
- // - Then we'll jump to the gpu thread (service side of command buffer) to
- // get the real OpenGL texture id.
- //
- // - Then we'll get a call from the Qt Quick Scene Graph thread (could be
- // a separate thread or the main thread).
- //
- // - Finally we'll return to the viz thread to acknowledge the swap.
-
- {
- QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_middleBuffer = std::move(m_backBuffer);
- m_middleBuffer->serviceId = 0;
- }
-
- m_commandBuffer->GetTextureQt(
- clientId,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnGpuThread, base::Unretained(this)),
- std::vector<gpu::SyncToken>{syncToken});
-}
-
-void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence)
-{
- {
- QMutexLocker locker(&m_mutex);
- m_middleBuffer->serviceId = id;
- m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence));
- }
-
- m_sink->scheduleUpdate();
-}
-
-void DisplayGLOutputSurface::swapBuffersOnVizThread()
-{
- {
- QMutexLocker locker(&m_mutex);
- m_backBuffer = std::move(m_middleBuffer);
- }
-
- m_display->DidReceiveSwapBuffersAck();
- m_display->DidReceivePresentationFeedback(
- gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(),
- gfx::PresentationFeedback::Flags::kVSync));
-}
-
-void DisplayGLOutputSurface::SetDrawRectangle(const gfx::Rect &)
-{
-}
-
-// Returning nullptr here effectively disables viz::OverlayProcessor.
-viz::OverlayCandidateValidator *DisplayGLOutputSurface::GetOverlayCandidateValidator() const
-{
- return nullptr;
-}
-
-// Returning true here will cause viz::GLRenderer to try to render the output
-// surface as an overlay plane (see viz::DirectRenderer::DrawFrame and
-// viz::GLRenderer::ScheduleOverlays).
-bool DisplayGLOutputSurface::IsDisplayedAsOverlayPlane() const
-{
- return false;
-}
-
-// Only used if IsDisplayedAsOverlayPlane was true (called from
-// viz::GLRenderer::ScheduleOverlays).
-unsigned DisplayGLOutputSurface::GetOverlayTextureId() const
-{
- return 0;
-}
-
-// Only used if IsDisplayedAsOverlayPlane was true (called from
-// viz::DirectRender::DrawFrame).
-gfx::BufferFormat DisplayGLOutputSurface::GetOverlayBufferFormat() const
-{
- return gfx::BufferFormat();
-}
-
-// Called by viz::GLRenderer but always false in all implementations except for
-// android_webview::ParentOutputSurface.
-bool DisplayGLOutputSurface::HasExternalStencilTest() const
-{
- return false;
-}
-
-// Only called if HasExternalStencilTest was true. Dead code?
-void DisplayGLOutputSurface::ApplyExternalStencil()
-{
- NOTREACHED();
-}
-
-// Called from GLRenderer::GetFramebufferCopyTextureFormat when using
-// glCopyTexSubImage2D on our framebuffer.
-uint32_t DisplayGLOutputSurface::GetFramebufferCopyTextureFormat()
-{
- return GL_RGBA;
-}
-
-// Called from viz::DirectRenderer::DrawFrame, only used for overlays.
-unsigned DisplayGLOutputSurface::UpdateGpuFence()
-{
- NOTREACHED();
- return 0;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h
deleted file mode 100644
index c42a6630a..000000000
--- a/src/core/compositor/display_gl_output_surface.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_GL_OUTPUT_SURFACE_H
-#define DISPLAY_GL_OUTPUT_SURFACE_H
-
-#include "compositor_resource_fence.h"
-#include "display_frame_sink.h"
-
-#include "components/viz/common/display/update_vsync_parameters_callback.h"
-#include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display_embedder/viz_process_context_provider.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-
-namespace viz {
-class Display;
-class SyntheticBeginFrameSource;
-} // namespace viz
-
-namespace QtWebEngineCore {
-
-// NOTE: Some methods are defined in display_gl_output_surface_qsg.cpp due
-// to conflicts between Qt & Chromium OpenGL APIs.
-class DisplayGLOutputSurface final : public viz::OutputSurface, public DisplayProducer
-{
-public:
- DisplayGLOutputSurface(
- scoped_refptr<viz::VizProcessContextProvider> contextProvider,
- viz::UpdateVSyncParametersCallback callback);
- ~DisplayGLOutputSurface() override;
-
- // Overridden from viz::OutputSurface.
- void BindToClient(viz::OutputSurfaceClient *client) override;
- void EnsureBackbuffer() override;
- void DiscardBackbuffer() override;
- void BindFramebuffer() override;
- void SetDrawRectangle(const gfx::Rect &drawRect) override;
- viz::OverlayCandidateValidator *GetOverlayCandidateValidator() const override;
- bool IsDisplayedAsOverlayPlane() const override;
- unsigned GetOverlayTextureId() const override;
- gfx::BufferFormat GetOverlayBufferFormat() const override;
- void Reshape(const gfx::Size &size,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- bool hasAlpha,
- bool useStencil) override;
- bool HasExternalStencilTest() const override;
- void ApplyExternalStencil() override;
- uint32_t GetFramebufferCopyTextureFormat() override;
- void SwapBuffers(viz::OutputSurfaceFrame frame) override;
- unsigned UpdateGpuFence() override;
-
- // Overridden from DisplayProducer.
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
-
-private:
- struct Shape
- {
- gfx::Size sizeInPixels;
- float devicePixelRatio;
- gfx::ColorSpace colorSpace;
- bool hasAlpha;
-
- bool operator==(const Shape &that) const
- {
- return (sizeInPixels == that.sizeInPixels &&
- devicePixelRatio == that.devicePixelRatio &&
- colorSpace == that.colorSpace &&
- hasAlpha == that.hasAlpha);
- }
- bool operator!=(const Shape &that) const { return !(*this == that); }
- };
-
- struct Buffer
- {
- DisplayGLOutputSurface *parent;
- Shape shape;
- uint32_t clientId = 0;
- uint32_t serviceId = 0;
- scoped_refptr<CompositorResourceFence> fence;
-
- Buffer(DisplayGLOutputSurface *parent) : parent(parent) {}
- ~Buffer() { parent->deleteBufferResources(this); }
- };
-
- class Texture;
-
- void swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence);
- void swapBuffersOnVizThread();
-
- std::unique_ptr<Buffer> makeBuffer(const Shape &shape);
- void deleteBufferResources(Buffer *buffer);
- void attachBuffer();
- void detachBuffer();
-
- gpu::InProcessCommandBuffer *const m_commandBuffer;
- gpu::gles2::GLES2Interface *const m_gl;
- mutable QMutex m_mutex;
- uint32_t m_fboId = 0;
- viz::Display *m_display = nullptr;
- scoped_refptr<DisplayFrameSink> m_sink;
- Shape m_currentShape;
- std::unique_ptr<Buffer> m_backBuffer;
- std::unique_ptr<Buffer> m_middleBuffer;
- std::unique_ptr<Buffer> m_frontBuffer;
- scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_GL_OUTPUT_SURFACE_H
diff --git a/src/core/compositor/display_gl_output_surface_qsg.cpp b/src/core/compositor/display_gl_output_surface_qsg.cpp
deleted file mode 100644
index 2f7b3de84..000000000
--- a/src/core/compositor/display_gl_output_surface_qsg.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_gl_output_surface.h"
-
-#include "compositor_resource_fence.h"
-#include "render_widget_host_view_qt_delegate.h"
-#include "type_conversion.h"
-
-#include <QOpenGLFunctions>
-#include <QSGImageNode>
-#include <QSGTexture>
-
-namespace QtWebEngineCore {
-
-class DisplayGLOutputSurface::Texture final : public QSGTexture
-{
-public:
- Texture(uint32_t id, QSize sizeInPixels, bool hasAlphaChannel, scoped_refptr<CompositorResourceFence> fence)
- : m_id(id)
- , m_sizeInPixels(sizeInPixels)
- , m_hasAlphaChannel(hasAlphaChannel)
- , m_fence(std::move(fence))
- {
- }
-
- // QSGTexture:
- int textureId() const override { return m_id; }
- QSize textureSize() const override { return m_sizeInPixels; }
- bool hasAlphaChannel() const override { return m_hasAlphaChannel; }
- bool hasMipmaps() const override { return false; }
- void bind() override
- {
- if (m_fence) {
- m_fence->wait();
- m_fence.reset();
- }
-
- QOpenGLContext *context = QOpenGLContext::currentContext();
- QOpenGLFunctions *funcs = context->functions();
- funcs->glBindTexture(GL_TEXTURE_2D, m_id);
- }
-
-private:
- uint32_t m_id;
- QSize m_sizeInPixels;
- bool m_hasAlphaChannel;
- scoped_refptr<CompositorResourceFence> m_fence;
-};
-
-QSGNode *DisplayGLOutputSurface::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
-{
- {
- QMutexLocker locker(&m_mutex);
- if (m_middleBuffer && m_middleBuffer->serviceId) {
- std::swap(m_middleBuffer, m_frontBuffer);
- m_taskRunner->PostTask(
- FROM_HERE,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnVizThread, base::Unretained(this)));
- m_taskRunner.reset();
- }
- }
-
- if (!m_frontBuffer)
- return oldNode;
-
- auto node = static_cast<QSGImageNode *>(oldNode);
- if (!node)
- node = delegate->createImageNode();
-
- QSize sizeInPixels = toQt(m_frontBuffer->shape.sizeInPixels);
- QSizeF sizeInDips = QSizeF(sizeInPixels) / m_frontBuffer->shape.devicePixelRatio;
- QRectF rectInDips(QPointF(0, 0), sizeInDips);
- node->setRect(rectInDips);
- node->setOwnsTexture(true);
- node->setTexture(new Texture(m_frontBuffer->serviceId,
- sizeInPixels,
- m_frontBuffer->shape.hasAlpha,
- m_frontBuffer->fence));
- node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-
- return node;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp
index 4547bb04b..ebaa96dbb 100644
--- a/src/core/compositor/display_overrides.cpp
+++ b/src/core/compositor/display_overrides.cpp
@@ -1,80 +1,100 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_gl_output_surface.h"
+// Copyright (C) 2019 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 "display_skia_output_device.h"
#include "display_software_output_surface.h"
+#include "native_skia_output_device.h"
-#include "components/viz/service/display_embedder/gpu_display_provider.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"
-std::unique_ptr<viz::OutputSurface>
-viz::GpuDisplayProvider::CreateGLOutputSurface(
- scoped_refptr<VizProcessContextProvider> context_provider,
- UpdateVSyncParametersCallback update_vsync_callback)
-{
- return std::make_unique<QtWebEngineCore::DisplayGLOutputSurface>(
- std::move(context_provider), std::move(update_vsync_callback));
-}
+#include <qtgui-config.h>
+#include <QtQuick/qquickwindow.h>
+
+#if QT_CONFIG(opengl)
+#include "native_skia_output_device_opengl.h"
+#endif
+
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "native_skia_output_device_vulkan.h"
+#endif
+
+#if defined(Q_OS_WIN)
+#include "native_skia_output_device_direct3d11.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "native_skia_output_device_metal.h"
+#endif
std::unique_ptr<viz::OutputSurface>
-viz::GpuDisplayProvider::CreateSoftwareOutputSurface(
- UpdateVSyncParametersCallback update_vsync_callback)
+viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface(const RendererSettings &renderer_settings)
{
- return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(std::move(update_vsync_callback));
+ return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(renderer_settings.requires_alpha_channel);
}
-void gpu::InProcessCommandBuffer::GetTextureQt(
- unsigned int client_id,
- GetTextureCallback callback,
- const std::vector<SyncToken>& sync_token_fences)
+std::unique_ptr<viz::SkiaOutputDevice>
+viz::SkiaOutputSurfaceImplOnGpu::CreateOutputDevice()
{
- ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::GetTextureQtOnGpuThread,
- gpu_thread_weak_ptr_factory_.GetWeakPtr(),
- client_id,
- std::move(callback)),
- sync_token_fences);
-}
+ static const auto graphicsApi = QQuickWindow::graphicsApi();
-void gpu::InProcessCommandBuffer::GetTextureQtOnGpuThread(
- unsigned int client_id, GetTextureCallback callback)
-{
- MakeCurrent();
- gpu::TextureBase *texture = decoder_->GetTextureBase(client_id);
- std::move(callback).Run(texture ? texture->service_id() : 0, gl::GLFence::Create());
+#if QT_CONFIG(opengl)
+ if (graphicsApi == QSGRendererInterface::OpenGL) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE) {
+#if !defined(Q_OS_MACOS)
+ return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback());
+#else
+ qFatal("macOS only supports ANGLE.");
+#endif // !defined(Q_OS_MACOS)
+ }
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceOpenGL>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+ }
+#endif // QT_CONFIG(opengl)
+
+#if BUILDFLAG(ENABLE_VULKAN)
+ if (graphicsApi == QSGRendererInterface::Vulkan) {
+#if !defined(Q_OS_MACOS)
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceVulkan>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+#else
+ qFatal("Vulkan is not supported on macOS.");
+#endif // !defined(Q_OS_MACOS)
+ }
+#endif // BUILDFLAG(ENABLE_VULKAN)
+
+#if defined(Q_OS_WIN)
+ if (graphicsApi == QSGRendererInterface::Direct3D11) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE)
+ qFatal("Direct3D11 is only supported over ANGLE.");
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceDirect3D11>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+ }
+#endif
+
+#if defined(Q_OS_MACOS)
+ if (graphicsApi == QSGRendererInterface::Metal) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE)
+ qFatal("Metal is only supported over ANGLE.");
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceMetal>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+ }
+#endif
+
+ qFatal() << "Unsupported Graphics API:" << graphicsApi;
+ return nullptr;
}
diff --git a/src/core/compositor/display_producer.h b/src/core/compositor/display_producer.h
deleted file mode 100644
index 5de09d2d2..000000000
--- a/src/core/compositor/display_producer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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_PRODUCER_H
-#define DISPLAY_PRODUCER_H
-
-#include "qtwebenginecoreglobal_p.h"
-
-QT_BEGIN_NAMESPACE
-class QSGNode;
-QT_END_NAMESPACE
-
-namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegate;
-
-// Produces composited frames for display.
-class DisplayProducer
-{
-public:
- // Generate scene graph nodes for the current frame.
- //
- // If this is a scheduled update (that is, scheduleUpdate was called
- // earlier), then updatePaintNode will generate nodes for a new frame.
- // Otherwise, it will just regenerate nodes for the old frame.
- virtual QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) = 0;
-
-protected:
- ~DisplayProducer() {}
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_PRODUCER_H
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..ab891f814
--- /dev/null
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -0,0 +1,240 @@
+// Copyright (C) 2021 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 "display_skia_output_device.h"
+
+#include "compositor_resource_fence.h"
+#include "type_conversion.h"
+
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkSurfaceProps.h"
+#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
+#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
+
+#include <QSGTexture>
+
+namespace QtWebEngineCore {
+
+class DisplaySkiaOutputDevice::Buffer
+{
+public:
+ Buffer(DisplaySkiaOutputDevice *parent)
+ : m_parent(parent)
+ , m_shape(m_parent->m_shape)
+ {
+ }
+ void initialize()
+ {
+ const auto &colorType = m_shape.imageInfo.colorType();
+ DCHECK(colorType != kUnknown_SkColorType);
+
+ m_texture = m_parent->m_contextState->gr_context()->createBackendTexture(
+ m_shape.imageInfo.width(), m_shape.imageInfo.height(), colorType,
+ skgpu::Mipmapped::kNo, GrRenderable::kYes);
+ DCHECK(m_texture.isValid());
+
+ DCHECK(m_texture.backend() == GrBackendApi::kOpenGL);
+ auto info = SkImageInfo::Make(m_shape.imageInfo.width(), m_shape.imageInfo.height(),
+ colorType, kUnpremul_SkAlphaType);
+ m_estimatedSize = info.computeMinByteSize();
+ m_parent->memory_type_tracker_->TrackMemAlloc(m_estimatedSize);
+
+ SkSurfaceProps surfaceProps = SkSurfaceProps{0, kUnknown_SkPixelGeometry};
+ m_surface = SkSurfaces::WrapBackendTexture(
+ 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()
+ {
+ if (m_texture.isValid()) {
+ 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,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : SkiaOutputDevice(contextState->gr_context(), contextState->graphite_context(),
+ memoryTracker, didSwapBufferCompleteCallback)
+ , Compositor(Compositor::Type::OpenGL)
+ , m_contextState(contextState)
+ , m_requiresAlpha(requiresAlpha)
+{
+ capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.supports_surfaceless = true;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+ capabilities_.number_of_buffers = 3;
+
+ 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 SkImageInfo &image_info,
+ const gfx::ColorSpace &colorSpace,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform)
+{
+ m_shape = Shape{image_info, device_scale_factor, colorSpace};
+ DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
+ return true;
+}
+
+void DisplaySkiaOutputDevice::Present(const absl::optional<gfx::Rect> &update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame)
+{
+ DCHECK(m_backBuffer);
+
+ StartSwapBuffers(std::move(feedback));
+ m_frame = std::move(frame);
+ m_backBuffer->createFence();
+
+ {
+ QMutexLocker locker(&m_mutex);
+ m_taskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ std::swap(m_middleBuffer, m_backBuffer);
+ m_readyToUpdate = true;
+ }
+
+ if (auto obs = observer())
+ obs->readyToSwap();
+}
+
+void DisplaySkiaOutputDevice::EnsureBackbuffer()
+{
+}
+
+void DisplaySkiaOutputDevice::DiscardBackbuffer()
+{
+}
+
+SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
+{
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
+ m_backBuffer = std::make_unique<Buffer>(this);
+ m_backBuffer->initialize();
+ }
+ 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();
+}
+
+QSGTexture *DisplaySkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer)
+ return nullptr;
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+
+ QSGTexture *texture = nullptr;
+ GrGLTextureInfo info;
+ if (GrBackendTextures::GetGLTextureInfo(m_frontBuffer->texture(), &info))
+ texture = QNativeInterface::QSGOpenGLTexture::fromNative(info.fID, win, size(), texOpts);
+ return texture;
+}
+
+bool DisplaySkiaOutputDevice::textureIsFlipped()
+{
+ return true;
+}
+
+QSize DisplaySkiaOutputDevice::size()
+{
+ return m_frontBuffer ? toQt(m_frontBuffer->shape().imageInfo.dimensions()) : QSize();
+}
+
+bool DisplaySkiaOutputDevice::requiresAlphaChannel()
+{
+ return m_requiresAlpha;
+}
+
+float DisplaySkiaOutputDevice::devicePixelRatio()
+{
+ return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1;
+}
+
+void DisplaySkiaOutputDevice::SwapBuffersFinished()
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ std::swap(m_backBuffer, m_middleBuffer);
+ }
+
+ FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
+ gfx::Size(m_shape.imageInfo.width(), m_shape.imageInfo.height()),
+ std::move(m_frame));
+}
+
+} // 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..e6a97b810
--- /dev/null
+++ b/src/core/compositor/display_skia_output_device.h
@@ -0,0 +1,89 @@
+// Copyright (C) 2021 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 DISPLAY_SKIA_OUTPUT_DEVICE_H
+#define DISPLAY_SKIA_OUTPUT_DEVICE_H
+
+#include <QtCore/QMutex>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+
+#include "compositor.h"
+
+#include "base/task/single_thread_task_runner.h"
+#include "components/viz/service/display_embedder/skia_output_device.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class DisplaySkiaOutputDevice final : public viz::SkiaOutputDevice, public Compositor
+{
+public:
+ DisplaySkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~DisplaySkiaOutputDevice() override;
+
+ // Overridden from SkiaOutputDevice.
+ void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override;
+ bool Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &color_space,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform) override;
+ void Present(const absl::optional<gfx::Rect>& update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame) 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;
+ QSGTexture *texture(QQuickWindow *win, uint32_t texOpts) override;
+ bool textureIsFlipped() override;
+ QSize size() override;
+ bool requiresAlphaChannel() override;
+ float devicePixelRatio() override;
+
+private:
+ struct Shape
+ {
+ SkImageInfo imageInfo;
+ float devicePixelRatio;
+ gfx::ColorSpace colorSpace;
+
+ bool operator==(const Shape &that) const
+ {
+ return (imageInfo == that.imageInfo &&
+ devicePixelRatio == that.devicePixelRatio &&
+ colorSpace == that.colorSpace);
+ }
+ 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;
+ viz::OutputSurfaceFrame m_frame;
+ bool m_readyToUpdate = false;
+ bool m_requiresAlpha;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_SKIA_OUTPUT_DEVICE_H
diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
index 13f8e8f38..2c208ca57 100644
--- a/src/core/compositor/display_software_output_surface.cpp
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -1,93 +1,53 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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) 2019 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 "display_software_output_surface.h"
-#include "display_frame_sink.h"
-#include "render_widget_host_view_qt_delegate.h"
+#include "compositor.h"
#include "type_conversion.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/task/single_thread_task_runner.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/output_surface_frame.h"
#include <QMutex>
#include <QPainter>
-#include <QSGImageNode>
+#include <QQuickWindow>
namespace QtWebEngineCore {
-class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice, public DisplayProducer
+class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice,
+ public Compositor
{
public:
- ~Device();
-
- // Called from DisplaySoftwareOutputSurface.
- void bind(viz::FrameSinkId frameSinkId);
+ Device(bool requiresAlpha);
// Overridden from viz::SoftwareOutputDevice.
void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
- void OnSwapBuffers(base::OnceClosure swapCompletionCallback) override;
+ void OnSwapBuffers(SwapBuffersCallback swap_ack_callback, gfx::FrameData data) override;
- // Overridden from DisplayProducer.
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
+ // Overridden from Compositor.
+ void swapFrame() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t) override;
+ bool textureIsFlipped() override;
+ float devicePixelRatio() override;
+ QSize size() override;
+ bool requiresAlphaChannel() override;
private:
mutable QMutex m_mutex;
- scoped_refptr<DisplayFrameSink> m_sink;
float m_devicePixelRatio = 1.0;
+ bool m_requiresAlpha;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
- base::OnceClosure m_swapCompletionCallback;
+ SwapBuffersCallback m_swapCompletionCallback;
QImage m_image;
float m_imageDevicePixelRatio = 1.0;
};
-DisplaySoftwareOutputSurface::Device::~Device()
-{
- if (m_sink)
- m_sink->disconnect(this);
-}
-
-void DisplaySoftwareOutputSurface::Device::bind(viz::FrameSinkId frameSinkId)
+DisplaySoftwareOutputSurface::Device::Device(bool requiresAlpha)
+ : Compositor(Type::Software)
+ , m_requiresAlpha(requiresAlpha)
{
- m_sink = DisplayFrameSink::findOrCreate(frameSinkId);
- m_sink->connect(this);
}
void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
@@ -96,15 +56,19 @@ void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels,
return;
m_devicePixelRatio = devicePixelRatio;
viewport_pixel_size_ = sizeInPixels;
- surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height()));
+ surface_ = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height()));
}
-void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(base::OnceClosure swapCompletionCallback)
+void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(SwapBuffersCallback swap_ack_callback, gfx::FrameData data)
{
- QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_swapCompletionCallback = std::move(swapCompletionCallback);
- m_sink->scheduleUpdate();
+ { // MEMO don't hold a lock together with an 'observer', as the call from Qt's scene graph may come at the same time
+ QMutexLocker locker(&m_mutex);
+ m_taskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ m_swapCompletionCallback = std::move(swap_ack_callback);
+ }
+
+ if (auto obs = observer())
+ obs->readyToSwap();
}
inline QImage::Format imageFormat(SkColorType colorType)
@@ -120,54 +84,68 @@ inline QImage::Format imageFormat(SkColorType colorType)
}
}
-QSGNode *DisplaySoftwareOutputSurface::Device::updatePaintNode(
- QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
+void DisplaySoftwareOutputSurface::Device::swapFrame()
{
QMutexLocker locker(&m_mutex);
- // Delete old node to make sure refcount of m_image is at most 1.
- delete oldNode;
- QSGImageNode *node = delegate->createImageNode();
-
- if (m_swapCompletionCallback) {
- SkPixmap skPixmap;
- surface_->peekPixels(&skPixmap);
- QImage image(reinterpret_cast<const uchar *>(skPixmap.addr()),
- viewport_pixel_size_.width(), viewport_pixel_size_.height(),
- skPixmap.rowBytes(), imageFormat(skPixmap.colorType()));
- if (m_image.size() == image.size()) {
- QRect damageRect = toQt(damage_rect_);
- QPainter(&m_image).drawImage(damageRect, image, damageRect);
- } else {
- m_image = image;
- m_image.detach();
- }
- m_imageDevicePixelRatio = m_devicePixelRatio;
- m_taskRunner->PostTask(FROM_HERE, std::move(m_swapCompletionCallback));
- m_taskRunner.reset();
+ if (!m_swapCompletionCallback)
+ return;
+
+ SkPixmap skPixmap;
+ surface_->peekPixels(&skPixmap);
+ QImage image(reinterpret_cast<const uchar *>(skPixmap.addr()), viewport_pixel_size_.width(),
+ viewport_pixel_size_.height(), skPixmap.rowBytes(),
+ imageFormat(skPixmap.colorType()));
+ if (m_image.size() == image.size()) {
+ QRect damageRect = toQt(damage_rect_);
+ QPainter painter(&m_image);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.drawImage(damageRect, image, damageRect);
+ } else {
+ m_image = image;
+ m_image.detach();
}
+ m_imageDevicePixelRatio = m_devicePixelRatio;
+ m_taskRunner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(m_swapCompletionCallback), toGfx(m_image.size())));
+ m_taskRunner.reset();
+}
+
+QSGTexture *DisplaySoftwareOutputSurface::Device::texture(QQuickWindow *win, uint32_t)
+{
+ return win->createTextureFromImage(m_image);
+}
- QSizeF sizeInDips = QSizeF(m_image.size()) / m_imageDevicePixelRatio;
- node->setRect(QRectF(QPointF(0, 0), sizeInDips));
- node->setOwnsTexture(true);
- node->setTexture(delegate->createTextureFromImage(m_image));
+bool DisplaySoftwareOutputSurface::Device::textureIsFlipped()
+{
+ return false;
+}
- return node;
+float DisplaySoftwareOutputSurface::Device::devicePixelRatio()
+{
+ return m_imageDevicePixelRatio;
+}
+
+QSize DisplaySoftwareOutputSurface::Device::size()
+{
+ return m_image.size();
+}
+
+bool DisplaySoftwareOutputSurface::Device::requiresAlphaChannel()
+{
+ return m_requiresAlpha;
}
-DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback)
- : SoftwareOutputSurface(std::make_unique<Device>(), std::move(callback))
+DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(bool requiresAlpha)
+ : SoftwareOutputSurface(std::make_unique<Device>(requiresAlpha))
{}
DisplaySoftwareOutputSurface::~DisplaySoftwareOutputSurface() {}
// Called from viz::Display::Initialize.
-void DisplaySoftwareOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
+void DisplaySoftwareOutputSurface::SetFrameSinkId(const viz::FrameSinkId &id)
{
- auto display = static_cast<viz::Display *>(client);
- auto device = static_cast<Device *>(software_device());
- device->bind(display->frame_sink_id());
- SoftwareOutputSurface::BindToClient(client);
+ static_cast<Device *>(software_device())->bind(id);
}
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_software_output_surface.h b/src/core/compositor/display_software_output_surface.h
index 6707c74dc..d23664d56 100644
--- a/src/core/compositor/display_software_output_surface.h
+++ b/src/core/compositor/display_software_output_surface.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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) 2019 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 DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
#define DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
@@ -47,11 +11,11 @@ namespace QtWebEngineCore {
class DisplaySoftwareOutputSurface final : public viz::SoftwareOutputSurface
{
public:
- DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback);
+ DisplaySoftwareOutputSurface(bool requiresAlpha);
~DisplaySoftwareOutputSurface() override;
- // Overridden from viz::SoftwareOutputSurface.
- void BindToClient(viz::OutputSurfaceClient *client) override;
+ // Overridden from viz::OutputSurface.
+ void SetFrameSinkId(const viz::FrameSinkId &id) override;
private:
class Device;
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
new file mode 100644
index 000000000..708692df7
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -0,0 +1,422 @@
+// 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
+
+#include "native_skia_output_device.h"
+
+#include "type_conversion.h"
+
+#include "components/viz/common/resources/shared_image_format.h"
+#include "components/viz/common/resources/shared_image_format_utils.h"
+#include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "third_party/skia/include/gpu/GrDirectContext.h"
+#include "third_party/skia/include/core/SkSurfaceProps.h"
+#include "ui/gfx/native_pixmap.h"
+#include "ui/gfx/gpu_fence.h"
+#include "ui/gl/gl_fence.h"
+
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#endif
+
+namespace QtWebEngineCore {
+
+namespace {
+
+// Helper function for moving a GpuFence from a fence handle to a unique_ptr.
+std::unique_ptr<gfx::GpuFence> TakeGpuFence(gfx::GpuFenceHandle fence)
+{
+ return fence.is_null() ? nullptr : std::make_unique<gfx::GpuFence>(std::move(fence));
+}
+
+} // namespace
+
+NativeSkiaOutputDevice::NativeSkiaOutputDevice(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : SkiaOutputDevice(contextState->gr_context(), contextState->graphite_context(), memoryTracker,
+ didSwapBufferCompleteCallback)
+ , Compositor(Type::Native)
+ , m_contextState(contextState)
+ , m_requiresAlpha(requiresAlpha)
+ , m_factory(shared_image_factory)
+ , m_representationFactory(shared_image_representation_factory)
+ , m_deps(dependency)
+{
+ capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.supports_surfaceless = true;
+ capabilities_.output_surface_origin = gfx::SurfaceOrigin::kTopLeft;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+
+#if defined(USE_OZONE)
+ m_isNativeBufferSupported = ui::OzonePlatform::GetInstance()
+ ->GetPlatformRuntimeProperties()
+ .supports_native_pixmaps;
+#endif
+}
+
+NativeSkiaOutputDevice::~NativeSkiaOutputDevice()
+{
+}
+
+void NativeSkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
+{
+ bind(id);
+}
+
+bool NativeSkiaOutputDevice::Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &colorSpace,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform)
+{
+ m_shape = Shape{image_info, device_scale_factor, colorSpace, sample_count};
+ DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
+ return true;
+}
+
+void NativeSkiaOutputDevice::Present(const absl::optional<gfx::Rect> &update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame)
+{
+ DCHECK(m_backBuffer);
+
+ StartSwapBuffers(std::move(feedback));
+ m_frame = std::move(frame);
+ {
+ QMutexLocker locker(&m_mutex);
+ m_backBuffer->createFence();
+ m_gpuTaskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ std::swap(m_middleBuffer, m_backBuffer);
+ m_readyToUpdate = true;
+ }
+
+ if (auto obs = observer())
+ obs->readyToSwap();
+}
+
+void NativeSkiaOutputDevice::EnsureBackbuffer()
+{
+}
+
+void NativeSkiaOutputDevice::DiscardBackbuffer()
+{
+}
+
+SkSurface *NativeSkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
+ m_backBuffer = std::make_unique<Buffer>(this);
+ if (!m_backBuffer->initialize())
+ return nullptr;
+ }
+ }
+ auto surface = m_backBuffer->beginWriteSkia();
+ *end_semaphores = m_backBuffer->takeEndWriteSkiaSemaphores();
+ return surface;
+}
+
+void NativeSkiaOutputDevice::EndPaint()
+{
+ m_backBuffer->endWriteSkia(true);
+}
+
+void NativeSkiaOutputDevice::swapFrame()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_readyToUpdate) {
+ std::swap(m_frontBuffer, m_middleBuffer);
+ m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::SwapBuffersFinished,
+ base::Unretained(this)));
+ m_readyToUpdate = false;
+ if (m_frontBuffer) {
+ m_readyWithTexture = true;
+ m_frontBuffer->beginPresent();
+ }
+ if (m_middleBuffer)
+ m_middleBuffer->freeTexture();
+ m_gpuTaskRunner.reset();
+ }
+}
+
+void NativeSkiaOutputDevice::waitForTexture()
+{
+ if (m_readyWithTexture)
+ m_frontBuffer->consumeFence();
+}
+
+void NativeSkiaOutputDevice::releaseTexture()
+{
+ if (m_readyWithTexture) {
+ m_frontBuffer->endPresent();
+ m_readyWithTexture = false;
+ }
+}
+
+void NativeSkiaOutputDevice::releaseResources()
+{
+ if (m_frontBuffer)
+ m_frontBuffer->freeTexture();
+}
+
+bool NativeSkiaOutputDevice::textureIsFlipped()
+{
+ return false;
+}
+
+QSize NativeSkiaOutputDevice::size()
+{
+ return m_frontBuffer ? toQt(m_frontBuffer->shape().imageInfo.dimensions()) : QSize();
+}
+
+bool NativeSkiaOutputDevice::requiresAlphaChannel()
+{
+ return m_requiresAlpha;
+}
+
+float NativeSkiaOutputDevice::devicePixelRatio()
+{
+ return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1;
+}
+
+void NativeSkiaOutputDevice::SwapBuffersFinished()
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ std::swap(m_backBuffer, m_middleBuffer);
+ }
+
+ FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
+ gfx::Size(m_shape.imageInfo.width(), m_shape.imageInfo.height()),
+ std::move(m_frame));
+}
+
+NativeSkiaOutputDevice::Buffer::Buffer(NativeSkiaOutputDevice *parent)
+ : m_parent(parent), m_shape(m_parent->m_shape)
+{
+}
+
+NativeSkiaOutputDevice::Buffer::~Buffer()
+{
+ if (m_scopedSkiaWriteAccess)
+ endWriteSkia(false);
+
+ if (!m_mailbox.IsZero())
+ m_parent->m_factory->DestroySharedImage(m_mailbox);
+}
+
+// The following Buffer methods are based on
+// components/viz/service/display_embedder/output_presenter.cc: Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+bool NativeSkiaOutputDevice::Buffer::initialize()
+{
+ static const uint32_t kDefaultSharedImageUsage = gpu::SHARED_IMAGE_USAGE_SCANOUT
+ | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE
+ | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+ auto mailbox = gpu::Mailbox::GenerateForSharedImage();
+
+ SkColorType skColorType = m_shape.imageInfo.colorType();
+ if (!m_parent->m_factory->CreateSharedImage(
+ mailbox, viz::SkColorTypeToSinglePlaneSharedImageFormat(skColorType),
+ { m_shape.imageInfo.width(), m_shape.imageInfo.height() }, m_shape.colorSpace,
+ kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, m_parent->m_deps->GetSurfaceHandle(),
+ kDefaultSharedImageUsage, "QWE_SharedImageBuffer")) {
+ LOG(ERROR) << "CreateSharedImage failed.";
+ return false;
+ }
+ m_mailbox = mailbox;
+
+ m_skiaRepresentation =
+ m_parent->m_representationFactory->ProduceSkia(m_mailbox, m_parent->m_contextState);
+ if (!m_skiaRepresentation) {
+ LOG(ERROR) << "ProduceSkia() failed.";
+ return false;
+ }
+
+ if (m_parent->m_isNativeBufferSupported) {
+ m_overlayRepresentation = m_parent->m_representationFactory->ProduceOverlay(m_mailbox);
+ if (!m_overlayRepresentation) {
+ LOG(ERROR) << "ProduceOverlay() failed";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+SkSurface *NativeSkiaOutputDevice::Buffer::beginWriteSkia()
+{
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_presentCount);
+ DCHECK(m_endSemaphores.empty());
+
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ SkSurfaceProps surface_props{ 0, kUnknown_SkPixelGeometry };
+
+ // Buffer queue is internal to GPU proc and handles texture initialization,
+ // so allow uncleared access.
+ m_scopedSkiaWriteAccess = m_skiaRepresentation->BeginScopedWriteAccess(
+ m_shape.sampleCount, surface_props, &beginSemaphores, &m_endSemaphores,
+ gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
+ DCHECK(m_scopedSkiaWriteAccess);
+ if (!beginSemaphores.empty()) {
+ m_scopedSkiaWriteAccess->surface()->wait(beginSemaphores.size(), beginSemaphores.data(),
+ /*deleteSemaphoresAfterWait=*/false);
+ }
+ return m_scopedSkiaWriteAccess->surface();
+}
+
+void NativeSkiaOutputDevice::Buffer::endWriteSkia(bool force_flush)
+{
+ // The Flush now takes place in finishPaintCurrentBuffer on the CPU side.
+ // check if end_semaphores is not empty then flush here
+ DCHECK(m_scopedSkiaWriteAccess);
+ if (!m_endSemaphores.empty() || force_flush) {
+ GrFlushInfo flush_info = {};
+ flush_info.fNumSemaphores = m_endSemaphores.size();
+ flush_info.fSignalSemaphores = m_endSemaphores.data();
+ auto *direct_context =
+ m_scopedSkiaWriteAccess->surface()->recordingContext()->asDirectContext();
+ DCHECK(direct_context);
+ direct_context->flush(m_scopedSkiaWriteAccess->surface(), {});
+ m_scopedSkiaWriteAccess->ApplyBackendSurfaceEndState();
+ direct_context->flush(m_scopedSkiaWriteAccess->surface(), flush_info, nullptr);
+ direct_context->submit();
+ }
+ m_scopedSkiaWriteAccess.reset();
+ m_endSemaphores.clear();
+
+ // SkiaRenderer always draws the full frame.
+ m_skiaRepresentation->SetCleared();
+}
+
+std::vector<GrBackendSemaphore> NativeSkiaOutputDevice::Buffer::takeEndWriteSkiaSemaphores()
+{
+ return std::exchange(m_endSemaphores, {});
+}
+
+void NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread()
+{
+ if (!m_scopedSkiaReadAccess) {
+ m_skImageMutex.unlock();
+ return;
+ }
+
+ m_cachedSkImage = m_scopedSkiaReadAccess->CreateSkImage(m_parent->m_contextState.get());
+ m_skImageMutex.unlock();
+ if (!m_cachedSkImage)
+ qWarning("SKIA: Failed to create SkImage.");
+}
+
+void NativeSkiaOutputDevice::Buffer::beginPresent()
+{
+ if (++m_presentCount != 1) {
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
+ return;
+ }
+
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_scopedOverlayReadAccess && !m_scopedSkiaReadAccess);
+
+ if (m_overlayRepresentation) {
+ m_scopedOverlayReadAccess = m_overlayRepresentation->BeginScopedReadAccess();
+ DCHECK(m_scopedOverlayReadAccess);
+ m_acquireFence = TakeGpuFence(m_scopedOverlayReadAccess->TakeAcquireFence());
+ } else {
+ DCHECK(m_skiaRepresentation);
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ m_scopedSkiaReadAccess =
+ m_skiaRepresentation->BeginScopedReadAccess(&beginSemaphores, nullptr);
+ DCHECK(m_scopedSkiaReadAccess);
+ if (!beginSemaphores.empty())
+ qWarning("SKIA: Unexpected semaphores while reading texture, wait is not implemented.");
+
+ m_skImageMutex.tryLock();
+ m_parent->m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread,
+ base::Unretained(this)));
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::endPresent()
+{
+ if (!m_presentCount)
+ return;
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
+ if (--m_presentCount)
+ return;
+
+ if (m_scopedOverlayReadAccess) {
+ DCHECK(!m_scopedSkiaReadAccess);
+ m_scopedOverlayReadAccess.reset();
+ } else if (m_scopedSkiaReadAccess) {
+ DCHECK(!m_scopedOverlayReadAccess);
+ QMutexLocker locker(&m_skImageMutex);
+ m_scopedSkiaReadAccess.reset();
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::freeTexture()
+{
+ if (textureCleanupCallback) {
+ textureCleanupCallback();
+ textureCleanupCallback = nullptr;
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::createFence()
+{
+ // For some reason we still need to create this, but we do not need to wait on it.
+ if (m_parent->m_contextState->gr_context_type() == gpu::GrContextType::kGL)
+ m_fence = gl::GLFence::Create();
+}
+
+void NativeSkiaOutputDevice::Buffer::consumeFence()
+{
+ if (m_acquireFence) {
+ m_acquireFence->Wait();
+ m_acquireFence.reset();
+ }
+}
+
+sk_sp<SkImage> NativeSkiaOutputDevice::Buffer::skImage()
+{
+ QMutexLocker locker(&m_skImageMutex);
+ return m_cachedSkImage;
+}
+#if defined(USE_OZONE)
+scoped_refptr<gfx::NativePixmap> NativeSkiaOutputDevice::Buffer::nativePixmap()
+{
+ DCHECK(m_presentCount);
+ if (!m_scopedOverlayReadAccess)
+ return nullptr;
+
+ return m_scopedOverlayReadAccess->GetNativePixmap();
+}
+#elif defined(Q_OS_WIN)
+absl::optional<gl::DCLayerOverlayImage> NativeSkiaOutputDevice::Buffer::overlayImage() const
+{
+ DCHECK(m_presentCount);
+ return m_scopedOverlayReadAccess->GetDCLayerOverlayImage();
+}
+#elif defined(Q_OS_MACOS)
+gfx::ScopedIOSurface NativeSkiaOutputDevice::Buffer::ioSurface() const
+{
+ DCHECK(m_presentCount);
+ return m_scopedOverlayReadAccess->GetIOSurface();
+}
+#endif
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
new file mode 100644
index 000000000..2c35cef77
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.h
@@ -0,0 +1,183 @@
+// 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
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_H
+
+#include "compositor.h"
+
+#include "base/task/single_thread_task_runner.h"
+#include "components/viz/service/display_embedder/skia_output_device.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/config/gpu_preferences.h"
+
+#include <QMutex>
+
+#if defined(Q_OS_WIN)
+#include "ui/gl/dc_layer_overlay_image.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "ui/gfx/mac/io_surface.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
+
+namespace gl {
+class GLFence;
+}
+
+namespace gfx {
+class GpuFence;
+class NativePixmap;
+}
+
+namespace gpu {
+class SharedImageFactory;
+class SharedImageRepresentationFactory;
+}
+
+namespace viz {
+class SkiaOutputSurfaceDependency;
+}
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDevice : public viz::SkiaOutputDevice, public Compositor
+{
+public:
+ NativeSkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDevice() override;
+
+ // Overridden from SkiaOutputDevice.
+ void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override;
+ bool Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &color_space,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform) override;
+ void Present(const absl::optional<gfx::Rect>& update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame) 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;
+ void releaseTexture() override;
+ void releaseResources() override;
+ bool textureIsFlipped() override;
+ QSize size() override;
+ bool requiresAlphaChannel() override;
+ float devicePixelRatio() override;
+
+protected:
+ struct Shape
+ {
+ SkImageInfo imageInfo;
+ float devicePixelRatio;
+ gfx::ColorSpace colorSpace;
+ int sampleCount;
+
+ bool operator==(const Shape &that) const
+ {
+ return (imageInfo == that.imageInfo &&
+ devicePixelRatio == that.devicePixelRatio &&
+ colorSpace == that.colorSpace &&
+ sampleCount == that.sampleCount);
+ }
+ bool operator!=(const Shape &that) const { return !(*this == that); }
+ };
+
+ class Buffer
+ {
+ public:
+ Buffer(NativeSkiaOutputDevice *parent);
+ ~Buffer();
+
+ bool initialize();
+ SkSurface *beginWriteSkia();
+ void endWriteSkia(bool force_flush);
+ std::vector<GrBackendSemaphore> takeEndWriteSkiaSemaphores();
+ void beginPresent();
+ void endPresent();
+ void freeTexture();
+ void createFence();
+ void consumeFence();
+
+ sk_sp<SkImage> skImage();
+#if defined(USE_OZONE)
+ scoped_refptr<gfx::NativePixmap> nativePixmap();
+#elif defined(Q_OS_WIN)
+ absl::optional<gl::DCLayerOverlayImage> overlayImage() const;
+#elif defined(Q_OS_MACOS)
+ gfx::ScopedIOSurface ioSurface() const;
+#endif
+
+ const Shape &shape() const { return m_shape; }
+ viz::SharedImageFormat sharedImageFormat() const { return m_skiaRepresentation->format(); }
+
+ std::function<void()> textureCleanupCallback;
+
+ private:
+ void createSkImageOnGPUThread();
+
+ NativeSkiaOutputDevice *m_parent;
+ Shape m_shape;
+ uint64_t m_estimatedSize = 0; // FIXME: estimate size
+ std::unique_ptr<gfx::GpuFence> m_acquireFence;
+ std::unique_ptr<gl::GLFence> m_fence;
+ gpu::Mailbox m_mailbox;
+ std::unique_ptr<gpu::SkiaImageRepresentation> m_skiaRepresentation;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedWriteAccess> m_scopedSkiaWriteAccess;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedReadAccess> m_scopedSkiaReadAccess;
+ std::unique_ptr<gpu::OverlayImageRepresentation> m_overlayRepresentation;
+ std::unique_ptr<gpu::OverlayImageRepresentation::ScopedReadAccess>
+ m_scopedOverlayReadAccess;
+ std::vector<GrBackendSemaphore> m_endSemaphores;
+ int m_presentCount = 0;
+
+ mutable QMutex m_skImageMutex;
+ sk_sp<SkImage> m_cachedSkImage;
+ };
+
+protected:
+ scoped_refptr<gpu::SharedContextState> m_contextState;
+ std::unique_ptr<Buffer> m_frontBuffer;
+ bool m_readyWithTexture = false;
+ bool m_isNativeBufferSupported = true;
+
+private:
+ friend class NativeSkiaOutputDevice::Buffer;
+
+ void SwapBuffersFinished();
+
+ mutable QMutex m_mutex;
+ Shape m_shape;
+ std::unique_ptr<Buffer> m_middleBuffer;
+ std::unique_ptr<Buffer> m_backBuffer;
+ viz::OutputSurfaceFrame m_frame;
+ bool m_readyToUpdate = false;
+ bool m_requiresAlpha;
+ scoped_refptr<base::SingleThreadTaskRunner> m_gpuTaskRunner;
+
+ const raw_ptr<gpu::SharedImageFactory> m_factory;
+ const raw_ptr<gpu::SharedImageRepresentationFactory> m_representationFactory;
+ const raw_ptr<viz::SkiaOutputSurfaceDependency> m_deps;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !NATIVE_SKIA_OUTPUT_DEVICE_H
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
new file mode 100644
index 000000000..2f1ed5f61
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -0,0 +1,89 @@
+// 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
+
+#include "native_skia_output_device_direct3d11.h"
+
+#include <QtCore/private/qsystemerror_p.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+#include <d3d11_1.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceDirect3D11::NativeSkiaOutputDeviceDirect3D11(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceDirect3D11::~NativeSkiaOutputDeviceDirect3D11() { }
+
+QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+ absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+
+ QSGRendererInterface *ri = win->rendererInterface();
+
+ HRESULT status = S_OK;
+ HANDLE sharedHandle = nullptr;
+ IDXGIResource1 *resource = nullptr;
+ if (!overlayImage->nv12_texture()) {
+ qWarning("No D3D texture.");
+ return nullptr;
+ }
+ status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
+ (void **)&resource);
+ Q_ASSERT(status == S_OK);
+ status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
+ Q_ASSERT(status == S_OK);
+ Q_ASSERT(sharedHandle);
+ resource->Release();
+
+ // Pass texture between two D3D devices:
+ ID3D11Device1 *device = static_cast<ID3D11Device1 *>(
+ ri->getResource(win, QSGRendererInterface::DeviceResource));
+
+ ID3D11Texture2D *qtTexture;
+ status = device->OpenSharedResource1(sharedHandle, __uuidof(ID3D11Texture2D),
+ (void **)&qtTexture);
+ if (status != S_OK) {
+ qWarning("Failed to share D3D11 texture (%s). This will result in failed rendering. Report "
+ "the bug, and try restarting with QTWEBENGINE_CHROMIUM_FLAGS=--disble-gpu",
+ qPrintable(QSystemError::windowsComString(status)));
+ ::CloseHandle(sharedHandle);
+ return nullptr;
+ }
+
+ Q_ASSERT(qtTexture);
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture =
+ QNativeInterface::QSGD3D11Texture::fromNative(qtTexture, win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [qtTexture, sharedHandle]() {
+ qtTexture->Release();
+ ::CloseHandle(sharedHandle);
+ };
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.h b/src/core/compositor/native_skia_output_device_direct3d11.h
new file mode 100644
index 000000000..33cf1bcd6
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_direct3d11.h
@@ -0,0 +1,28 @@
+// 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
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceDirect3D11 final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceDirect3D11(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceDirect3D11() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
diff --git a/src/core/compositor/native_skia_output_device_mac.mm b/src/core/compositor/native_skia_output_device_mac.mm
new file mode 100644
index 000000000..bf21ef8d7
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_mac.mm
@@ -0,0 +1,97 @@
+// 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
+
+// This is a workaround to be able to include Qt headers without
+// "redefinition of 'NSString' as different kind of symbol" errors.
+// TODO: Remove this when namespace ambiguity issues are fixed properly,
+// see get_forward_declaration_macro() in cmake/Functions.cmake
+#undef Q_FORWARD_DECLARE_OBJC_CLASS
+
+#import <AppKit/AppKit.h>
+#import <IOSurface/IOSurface.h>
+#import <Metal/Metal.h>
+
+#include <QtGui/qtguiglobal.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgrendererinterface.h>
+#include <QtQuick/qsgtexture.h>
+
+#if QT_CONFIG(opengl)
+#include <OpenGL/OpenGL.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtOpenGL/qopengltextureblitter.h>
+#include <QtOpenGL/qopenglframebufferobject.h>
+#endif
+
+namespace QtWebEngineCore {
+
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioSurfacePlane,
+ const QSize &size, QQuickWindow::CreateTextureOptions texOpts)
+{
+ auto desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
+ width:size.width()
+ height:size.height()
+ mipmapped:false];
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ auto device = (__bridge id<MTLDevice>)(ri->getResource(win, QSGRendererInterface::DeviceResource));
+ id<MTLTexture> texture = [device newTextureWithDescriptor:desc
+ iosurface:ioSurface
+ plane:ioSurfacePlane];
+ return QNativeInterface::QSGMetalTexture::fromNative(texture, win, size, texOpts);
+}
+
+void releaseMetalTexture(void *texture)
+{
+ [static_cast<id<MTLTexture>>(texture) release];
+}
+
+#if QT_CONFIG(opengl)
+uint32_t makeCGLTexture(QQuickWindow *win, IOSurfaceRef ioSurface, const QSize &size)
+{
+ const int width = size.width();
+ const int height = size.height();
+
+ auto glContext = QOpenGLContext::currentContext();
+ auto glFun = glContext->extraFunctions();
+ auto nscontext = glContext->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
+ CGLContextObj cglContext = [nscontext CGLContextObj];
+
+ win->beginExternalCommands();
+ // Bind the IO surface to a texture
+ GLuint glTexture;
+ glFun->glGenTextures(1, &glTexture);
+ glFun->glBindTexture(GL_TEXTURE_RECTANGLE_ARB, glTexture);
+ CGLTexImageIOSurface2D(cglContext, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, width, height, GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV, ioSurface, 0);
+ glFun->glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ glFun->glViewport(0, 0, width, height);
+
+ // The bound IO surface is a weird dynamic bind, so take a snapshot of it to a normal texture
+ {
+ QOpenGLFramebufferObject fbo(width, height, GL_TEXTURE_2D);
+ auto success = fbo.bind();
+ Q_ASSERT(success);
+
+ QOpenGLTextureBlitter blitter;
+ success = blitter.create();
+ Q_ASSERT(success);
+ glFun->glDisable(GL_BLEND);
+ glFun->glDisable(GL_SCISSOR_TEST);
+ blitter.bind(GL_TEXTURE_RECTANGLE_ARB);
+ blitter.blit(glTexture, {}, QOpenGLTextureBlitter::OriginBottomLeft);
+ blitter.release();
+ blitter.destroy();
+
+ glFun->glDeleteTextures(1, &glTexture);
+ glTexture = fbo.takeTexture();
+ fbo.release();
+ }
+ win->endExternalCommands();
+
+ return glTexture;
+}
+#endif // QT_CONFIG(opengl)
+
+} // namespace
diff --git a/src/core/compositor/native_skia_output_device_metal.cpp b/src/core/compositor/native_skia_output_device_metal.cpp
new file mode 100644
index 000000000..a9d6e4fd5
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_metal.cpp
@@ -0,0 +1,66 @@
+// 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
+
+#include "native_skia_output_device_metal.h"
+
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceMetal::NativeSkiaOutputDeviceMetal(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceMetal::~NativeSkiaOutputDeviceMetal() { }
+
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioSurfacePlane,
+ const QSize &size, QQuickWindow::CreateTextureOptions texOpts);
+void releaseMetalTexture(void *texture);
+
+QSGTexture *NativeSkiaOutputDeviceMetal::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+ gfx::ScopedIOSurface ioSurface = m_frontBuffer->ioSurface();
+ if (!ioSurface) {
+ qWarning("No IOSurface.");
+ return nullptr;
+ }
+
+ // This is a workaround to not to release metal texture too early.
+ // In RHI, QMetalTexture wraps MTLTexture. QMetalTexture seems to be only destructed after the
+ // next MTLTexture is imported. The "old" MTLTexture can be still pontentially used by RHI
+ // while QMetalTexture is not destructed. Metal Validation Layer also warns about it.
+ // Delay releasing MTLTexture after the next one is presented.
+ if (m_currentMetalTexture) {
+ m_frontBuffer->textureCleanupCallback = [texture = m_currentMetalTexture]() {
+ releaseMetalTexture(texture);
+ };
+ m_currentMetalTexture = nullptr;
+ }
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *qsgTexture = makeMetalTexture(win, ioSurface.get(), /* plane */ 0, size(), texOpts);
+
+ auto ni = qsgTexture->nativeInterface<QNativeInterface::QSGMetalTexture>();
+ m_currentMetalTexture = ni->nativeTexture();
+
+ return qsgTexture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_metal.h b/src/core/compositor/native_skia_output_device_metal.h
new file mode 100644
index 000000000..8e8d0fab8
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_metal.h
@@ -0,0 +1,31 @@
+// 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
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceMetal final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceMetal(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceMetal() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+
+private:
+ void *m_currentMetalTexture = nullptr;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
new file mode 100644
index 000000000..058573b9e
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -0,0 +1,86 @@
+// 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
+
+#include "native_skia_output_device_opengl.h"
+
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceOpenGL::~NativeSkiaOutputDeviceOpenGL() { }
+
+#if defined(Q_OS_MACOS)
+uint32_t makeCGLTexture(QQuickWindow *win, IOSurfaceRef ioSurface, const QSize &size);
+#endif
+
+QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+#if defined(USE_OZONE)
+ scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
+ if (!nativePixmap) {
+ qWarning("No native pixmap.");
+ return nullptr;
+ }
+#elif defined(Q_OS_WIN)
+ auto overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+#elif defined(Q_OS_MACOS)
+ gfx::ScopedIOSurface ioSurface = m_frontBuffer->ioSurface();
+ if (!ioSurface) {
+ qWarning("No IOSurface.");
+ return nullptr;
+ }
+#endif
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture = nullptr;
+
+#if defined(USE_OZONE)
+ // TODO(QTBUG-112281): Add ANGLE support to Linux.
+ QT_NOT_YET_IMPLEMENTED
+#elif defined(Q_OS_WIN)
+ // TODO: Add WGL support over ANGLE.
+ QT_NOT_YET_IMPLEMENTED
+#elif defined(Q_OS_MACOS)
+ uint32_t glTexture = makeCGLTexture(win, ioSurface.get(), size());
+ texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [glTexture]() {
+ auto *glContext = QOpenGLContext::currentContext();
+ if (!glContext)
+ return;
+ auto glFun = glContext->functions();
+ glFun->glDeleteTextures(1, &glTexture);
+ };
+#endif
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_opengl.h b/src/core/compositor/native_skia_output_device_opengl.h
new file mode 100644
index 000000000..233f51df9
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_opengl.h
@@ -0,0 +1,28 @@
+// 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
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceOpenGL final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceOpenGL(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceOpenGL() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
new file mode 100644
index 000000000..b775276f6
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -0,0 +1,309 @@
+// 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
+
+#include "native_skia_output_device_vulkan.h"
+
+#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
+#include "ui/base/ozone_buildflags.h"
+
+#include <QtGui/qvulkaninstance.h>
+#include <QtGui/qvulkanfunctions.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+#if defined(USE_OZONE)
+#if BUILDFLAG(IS_OZONE_X11)
+// We need to define USE_VULKAN_XCB for proper vulkan function pointers.
+// Avoiding it may lead to call wrong vulkan functions.
+// This is originally defined in chromium/gpu/vulkan/BUILD.gn.
+#define USE_VULKAN_XCB
+#endif // BUILDFLAG(IS_OZONE_X11)
+#include "gpu/vulkan/vulkan_function_pointers.h"
+#include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#include "third_party/skia/include/gpu/vk/GrVkTypes.h"
+#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
+#endif // defined(USE_OZONE)
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceVulkan::NativeSkiaOutputDeviceVulkan(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceVulkan::~NativeSkiaOutputDeviceVulkan() { }
+
+QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+#if defined(USE_OZONE)
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kVulkan);
+
+ GrVkImageInfo vkImageInfo;
+ scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
+ if (!nativePixmap) {
+ if (m_isNativeBufferSupported) {
+ qWarning("VULKAN: No NativePixmap.");
+ return nullptr;
+ }
+
+ sk_sp<SkImage> skImage = m_frontBuffer->skImage();
+ if (!skImage) {
+ qWarning("VULKAN: No SkImage.");
+ return nullptr;
+ }
+
+ if (!skImage->isTextureBacked()) {
+ qWarning("VULKAN: SkImage is not backed by GPU texture.");
+ return nullptr;
+ }
+
+ GrBackendTexture backendTexture;
+ bool success = SkImages::GetBackendTextureFromImage(skImage, &backendTexture, false);
+ if (!success || !backendTexture.isValid()) {
+ qWarning("VULKAN: Failed to retrieve backend texture from SkImage.");
+ return nullptr;
+ }
+
+ if (backendTexture.backend() != GrBackendApi::kVulkan) {
+ qWarning("VULKAN: Backend texture is not a Vulkan texture.");
+ return nullptr;
+ }
+
+ GrBackendTextures::GetVkImageInfo(backendTexture, &vkImageInfo);
+
+ if (vkImageInfo.fAlloc.fMemory == VK_NULL_HANDLE) {
+ qWarning("VULKAN: Unable to access Vulkan memory.");
+ return nullptr;
+ }
+ }
+#elif defined(Q_OS_WIN)
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
+
+ absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+#endif
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ VkDevice qtVulkanDevice =
+ *static_cast<VkDevice *>(ri->getResource(win, QSGRendererInterface::DeviceResource));
+ VkPhysicalDevice qtPhysicalDevice = *static_cast<VkPhysicalDevice *>(
+ ri->getResource(win, QSGRendererInterface::PhysicalDeviceResource));
+ QVulkanFunctions *f = win->vulkanInstance()->functions();
+ QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(qtVulkanDevice);
+
+ VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ VkPhysicalDeviceProperties deviceProperties;
+ f->vkGetPhysicalDeviceProperties(qtPhysicalDevice, &deviceProperties);
+ if (deviceProperties.vendorID == 0x10DE) {
+ // FIXME: This is a workaround for Nvidia driver.
+ // The imported image is empty if the initialLayout is not
+ // VK_IMAGE_LAYOUT_PREINITIALIZED.
+ imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ }
+
+ VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
+ };
+#if defined(USE_OZONE)
+ VkSubresourceLayout planeLayout = {};
+ VkImageDrmFormatModifierExplicitCreateInfoEXT modifierInfo = {
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
+ };
+ base::ScopedFD scopedFd;
+
+ if (nativePixmap) {
+ gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
+ if (nativePixmapHandle.planes.size() != 1)
+ qFatal("VULKAN: Multiple planes are not supported.");
+
+ planeLayout.offset = nativePixmapHandle.planes[0].offset;
+ planeLayout.size = 0;
+ planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
+ planeLayout.arrayPitch = 0;
+ planeLayout.depthPitch = 0;
+
+ modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
+ modifierInfo.drmFormatModifierPlaneCount = 1;
+ modifierInfo.pPlaneLayouts = &planeLayout;
+
+ externalMemoryImageCreateInfo.pNext = &modifierInfo;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+
+ scopedFd = std::move(nativePixmapHandle.planes[0].fd);
+ } else {
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
+ exportInfo.pNext = nullptr;
+ exportInfo.memory = vkImageInfo.fAlloc.fMemory;
+ exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
+ gpu::VulkanDeviceQueue *vulkanDeviceQueue =
+ m_contextState->vk_context_provider()->GetDeviceQueue();
+ VkDevice vulkanDevice = vulkanDeviceQueue->GetVulkanDevice();
+
+ int fd = -1;
+ if (vfp->vkGetMemoryFdKHR(vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
+ qFatal("VULKAN: Unable to extract file descriptor out of external VkImage.");
+
+ scopedFd.reset(fd);
+ }
+
+ if (!scopedFd.is_valid())
+ qFatal("VULKAN: Unable to extract file descriptor.");
+#elif defined(Q_OS_WIN)
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+
+ HRESULT status = S_OK;
+ HANDLE sharedHandle = nullptr;
+ IDXGIResource1 *resource = nullptr;
+ if (!overlayImage->nv12_texture()) {
+ qWarning("VULKAN: No D3D texture.");
+ return nullptr;
+ }
+ status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
+ (void **)&resource);
+ Q_ASSERT(status == S_OK);
+ status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
+ Q_ASSERT(status == S_OK);
+ resource->Release();
+
+ if (!sharedHandle)
+ qFatal("VULKAN: Unable to extract shared handle.");
+#endif
+
+ constexpr VkImageUsageFlags kUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+
+ VkImageCreateInfo importedImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
+ importedImageCreateInfo.pNext = &externalMemoryImageCreateInfo;
+ importedImageCreateInfo.flags = 0;
+ importedImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ importedImageCreateInfo.format = gpu::ToVkFormatSinglePlanar(m_frontBuffer->sharedImageFormat());
+ importedImageCreateInfo.extent.width = static_cast<uint32_t>(size().width());
+ importedImageCreateInfo.extent.height = static_cast<uint32_t>(size().height());
+ importedImageCreateInfo.extent.depth = 1;
+ importedImageCreateInfo.mipLevels = 1;
+ importedImageCreateInfo.arrayLayers = 1;
+ importedImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ importedImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ importedImageCreateInfo.usage = kUsage;
+ importedImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ importedImageCreateInfo.queueFamilyIndexCount = 0;
+ importedImageCreateInfo.pQueueFamilyIndices = nullptr;
+ importedImageCreateInfo.initialLayout = imageLayout;
+
+#if defined(USE_OZONE)
+ if (nativePixmap)
+ importedImageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+ else
+ importedImageCreateInfo.tiling = vkImageInfo.fImageTiling;
+#endif
+
+ VkResult result;
+ VkImage importedImage = VK_NULL_HANDLE;
+ result = df->vkCreateImage(qtVulkanDevice, &importedImageCreateInfo, nullptr /* pAllocator */,
+ &importedImage);
+ if (result != VK_SUCCESS)
+ qFatal() << "VULKAN: vkCreateImage failed result:" << result;
+
+#if defined(USE_OZONE)
+ VkImportMemoryFdInfoKHR importMemoryHandleInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR
+ };
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+ importMemoryHandleInfo.fd = scopedFd.release();
+
+ if (nativePixmap)
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+#elif defined(Q_OS_WIN)
+ VkImportMemoryWin32HandleInfoKHR importMemoryHandleInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR
+ };
+ importMemoryHandleInfo.pNext = nullptr;
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+ importMemoryHandleInfo.handle = sharedHandle;
+#endif
+
+ VkMemoryDedicatedAllocateInfoKHR dedicatedMemoryInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR
+ };
+ dedicatedMemoryInfo.pNext = &importMemoryHandleInfo;
+ dedicatedMemoryInfo.image = importedImage;
+
+ VkMemoryAllocateInfo memoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
+ memoryAllocateInfo.pNext = &dedicatedMemoryInfo;
+
+ VkMemoryRequirements requirements;
+ df->vkGetImageMemoryRequirements(qtVulkanDevice, importedImage, &requirements);
+ if (!requirements.memoryTypeBits)
+ qFatal("VULKAN: vkGetImageMemoryRequirements failed.");
+
+ VkPhysicalDeviceMemoryProperties memoryProperties;
+ f->vkGetPhysicalDeviceMemoryProperties(qtPhysicalDevice, &memoryProperties);
+ constexpr VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ constexpr uint32_t kMaxIndex = 31;
+ uint32_t memoryTypeIndex = kMaxIndex + 1;
+ for (uint32_t i = 0; i <= kMaxIndex; i++) {
+ if (((1u << i) & requirements.memoryTypeBits) == 0)
+ continue;
+ if ((memoryProperties.memoryTypes[i].propertyFlags & flags) != flags)
+ continue;
+ memoryTypeIndex = i;
+ break;
+ }
+
+ if (memoryTypeIndex > kMaxIndex)
+ qFatal("VULKAN: Cannot find valid memory type index.");
+
+ memoryAllocateInfo.allocationSize = requirements.size;
+ memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
+
+ VkDeviceMemory importedImageMemory = VK_NULL_HANDLE;
+ result = df->vkAllocateMemory(qtVulkanDevice, &memoryAllocateInfo, nullptr /* pAllocator */,
+ &importedImageMemory);
+ if (result != VK_SUCCESS)
+ qFatal() << "VULKAN: vkAllocateMemory failed result:" << result;
+
+ df->vkBindImageMemory(qtVulkanDevice, importedImage, importedImageMemory, 0);
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture = QNativeInterface::QSGVulkanTexture::fromNative(importedImage, imageLayout,
+ win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [=]() {
+ df->vkDestroyImage(qtVulkanDevice, importedImage, nullptr);
+ df->vkFreeMemory(qtVulkanDevice, importedImageMemory, nullptr);
+#if defined(Q_OS_WIN)
+ ::CloseHandle(sharedHandle);
+#endif
+ };
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_vulkan.h b/src/core/compositor/native_skia_output_device_vulkan.h
new file mode 100644
index 000000000..bead0cc11
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_vulkan.h
@@ -0,0 +1,28 @@
+// 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
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceVulkan final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceVulkan(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceVulkan() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
diff --git a/src/core/compositor/stream_video_node.cpp b/src/core/compositor/stream_video_node.cpp
deleted file mode 100644
index 29922f866..000000000
--- a/src/core/compositor/stream_video_node.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "stream_video_node.h"
-
-#include <QtQuick/qsgtexture.h>
-
-namespace QtWebEngineCore {
-
-class StreamVideoMaterialShader : public QSGMaterialShader
-{
-public:
- StreamVideoMaterialShader(TextureTarget target) : m_target(target) { }
- virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
-
- char const *const *attributeNames() const override {
- static const char *names[] = {
- "a_position",
- "a_texCoord",
- 0
- };
- return names;
- }
-
-protected:
- const char *vertexShader() const override {
- // Keep in sync with cc::VertexShaderVideoTransform
- static const char *shader =
- "attribute highp vec4 a_position;\n"
- "attribute mediump vec2 a_texCoord;\n"
- "uniform highp mat4 matrix;\n"
- "uniform highp mat4 texMatrix;\n"
- "varying mediump vec2 v_texCoord;\n"
- "void main() {\n"
- " gl_Position = matrix * a_position;\n"
- " v_texCoord = vec4(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)).xy;\n"
- "}";
- return shader;
- }
-
- const char *fragmentShader() const override {
- // Keep in sync with cc::FragmentShaderRGBATexAlpha
- static const char *shaderExternal =
- "#extension GL_OES_EGL_image_external : require\n"
- "varying mediump vec2 v_texCoord;\n"
- "uniform samplerExternalOES s_texture;\n"
- "uniform lowp float alpha;\n"
- "void main() {\n"
- " lowp vec4 texColor = texture2D(s_texture, v_texCoord);\n"
- " gl_FragColor = texColor * alpha;\n"
- "}";
- static const char *shader2DRect =
- "#extension GL_ARB_texture_rectangle : require\n"
- "varying mediump vec2 v_texCoord;\n"
- "uniform sampler2DRect s_texture;\n"
- "uniform lowp float alpha;\n"
- "void main() {\n"
- " lowp vec4 texColor = texture2DRect(s_texture, v_texCoord);\n"
- " gl_FragColor = texColor * alpha;\n"
- "}";
- if (m_target == ExternalTarget)
- return shaderExternal;
- else
- return shader2DRect;
- }
-
- virtual void initialize() {
- m_id_matrix = program()->uniformLocation("matrix");
- m_id_sTexture = program()->uniformLocation("s_texture");
- m_id_texMatrix = program()->uniformLocation("texMatrix");
- m_id_opacity = program()->uniformLocation("alpha");
- }
-
- int m_id_matrix;
- int m_id_texMatrix;
- int m_id_sTexture;
- int m_id_opacity;
- TextureTarget m_target;
-};
-
-void StreamVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
-{
- Q_UNUSED(oldMaterial);
-
- StreamVideoMaterial *mat = static_cast<StreamVideoMaterial *>(newMaterial);
- program()->setUniformValue(m_id_sTexture, 0);
-
- mat->m_texture->bind();
-
- if (state.isOpacityDirty())
- program()->setUniformValue(m_id_opacity, state.opacity());
-
- if (state.isMatrixDirty())
- program()->setUniformValue(m_id_matrix, state.combinedMatrix());
-
- program()->setUniformValue(m_id_texMatrix, mat->m_texMatrix);
-}
-
-StreamVideoMaterial::StreamVideoMaterial(QSGTexture *texture, TextureTarget target)
- : m_texture(texture)
- , m_target(target)
-{
-}
-
-QSGMaterialShader *StreamVideoMaterial::createShader() const
-{
- return new StreamVideoMaterialShader(m_target);
-}
-
-StreamVideoNode::StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target)
- : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
- , m_flip(flip)
-{
- setGeometry(&m_geometry);
- setFlag(QSGNode::OwnsMaterial);
- m_material = new StreamVideoMaterial(texture, target);
- setMaterial(m_material);
-}
-
-void StreamVideoNode::setRect(const QRectF &rect)
-{
- if (m_flip)
- QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 1, 1, -1));
- else
- QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
-}
-
-void StreamVideoNode::setTextureMatrix(const QMatrix4x4 &matrix)
-{
- m_material->m_texMatrix = matrix;
-}
-
-} // namespace
diff --git a/src/core/compositor/stream_video_node.h b/src/core/compositor/stream_video_node.h
deleted file mode 100644
index 9d937791f..000000000
--- a/src/core/compositor/stream_video_node.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef STREAM_VIDEO_NODE_H
-#define STREAM_VIDEO_NODE_H
-
-#include <QtQuick/qsgmaterial.h>
-#include <QtQuick/qsgnode.h>
-
-QT_FORWARD_DECLARE_CLASS(QSGTexture)
-
-namespace QtWebEngineCore {
-
-// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawStreamVideoQuad.
-// Their behavior should stay as close as possible to GLRenderer.
-
-enum TextureTarget { ExternalTarget, RectangleTarget };
-
-class StreamVideoMaterial : public QSGMaterial
-{
-public:
- StreamVideoMaterial(QSGTexture *texture, TextureTarget target);
-
- QSGMaterialType *type() const override
- {
- static QSGMaterialType theType;
- return &theType;
- }
-
- QSGMaterialShader *createShader() const override;
-
- QSGTexture *m_texture;
- QMatrix4x4 m_texMatrix;
- TextureTarget m_target;
-};
-
-class StreamVideoNode : public QSGGeometryNode
-{
-public:
- StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target);
- void setRect(const QRectF &rect);
- void setTextureMatrix(const QMatrix4x4 &matrix);
-
-private:
- QSGGeometry m_geometry;
- bool m_flip;
- StreamVideoMaterial *m_material;
-};
-
-} // namespace
-
-#endif // STREAM_VIDEO_NODE_H
diff --git a/src/core/compositor/vulkan_implementation_qt.cpp b/src/core/compositor/vulkan_implementation_qt.cpp
new file mode 100644
index 000000000..2f2259666
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.cpp
@@ -0,0 +1,162 @@
+// Copyright (C) 2022 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 "vulkan_implementation_qt.h"
+
+#include "base/environment.h"
+#include "base/logging.h"
+#include "gpu/vulkan/vulkan_image.h"
+#include "gpu/vulkan/vulkan_surface.h"
+#include "gpu/vulkan/vulkan_util.h"
+#include "ui/gfx/gpu_fence.h"
+
+#include <vulkan/vulkan.h>
+
+namespace gpu {
+
+VulkanImplementationQt::VulkanImplementationQt() : VulkanImplementation(false) { }
+
+VulkanImplementationQt::~VulkanImplementationQt() = default;
+
+bool VulkanImplementationQt::InitializeVulkanInstance(bool /*using_surface*/)
+{
+ std::vector<const char *> required_extensions = {
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+ };
+
+ auto env = base::Environment::Create();
+ std::string vulkan_path;
+ if (!env->GetVar("QT_VULKAN_LIB", &vulkan_path)) {
+#if BUILDFLAG(IS_WIN)
+ vulkan_path = "vulkan-1.dll";
+#else
+ vulkan_path = "libvulkan.so.1";
+#endif
+ }
+
+ if (!vulkan_instance_.Initialize(base::FilePath::FromUTF8Unsafe(vulkan_path),
+ required_extensions, {})) {
+ LOG(ERROR) << "Failed to initialize vulkan instance";
+ return false;
+ }
+
+ return true;
+}
+
+VulkanInstance *VulkanImplementationQt::GetVulkanInstance()
+{
+ return &vulkan_instance_;
+}
+
+std::unique_ptr<VulkanSurface>
+VulkanImplementationQt::CreateViewSurface(gfx::AcceleratedWidget /*window*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+bool VulkanImplementationQt::GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice /*device*/,
+ const std::vector<VkQueueFamilyProperties> & /*queue_family_properties*/,
+ uint32_t /*queue_family_index*/)
+{
+ NOTREACHED();
+ return true;
+}
+
+std::vector<const char *> VulkanImplementationQt::GetRequiredDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
+#endif
+ };
+}
+
+std::vector<const char *> VulkanImplementationQt::GetOptionalDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+ VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
+ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
+ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
+#endif
+ };
+}
+
+VkFence VulkanImplementationQt::CreateVkFenceForGpuFence(VkDevice /*vk_device*/)
+{
+ NOTREACHED();
+ return VK_NULL_HANDLE;
+}
+
+std::unique_ptr<gfx::GpuFence>
+VulkanImplementationQt::ExportVkFenceToGpuFence(VkDevice /*vk_device*/, VkFence /*vk_fence*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+VkSemaphore VulkanImplementationQt::ImportSemaphoreHandle(VkDevice vk_device,
+ SemaphoreHandle sync_handle)
+{
+ return ImportVkSemaphoreHandle(vk_device, std::move(sync_handle));
+}
+
+VkExternalSemaphoreHandleTypeFlagBits VulkanImplementationQt::GetExternalSemaphoreHandleType()
+{
+#if BUILDFLAG(IS_WIN)
+ return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+#else
+ return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+#endif
+}
+
+bool VulkanImplementationQt::CanImportGpuMemoryBuffer(
+ VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferType memory_buffer_type)
+{
+#if BUILDFLAG(IS_LINUX)
+ const auto &enabled_extensions = device_queue->enabled_extensions();
+ return gfx::HasExtension(enabled_extensions,
+ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME) &&
+ gfx::HasExtension(enabled_extensions,
+ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME) &&
+ memory_buffer_type == gfx::GpuMemoryBufferType::NATIVE_PIXMAP;
+#else
+ return false;
+#endif
+}
+
+std::unique_ptr<VulkanImage> VulkanImplementationQt::CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferHandle gmb_handle,
+ gfx::Size size,
+ VkFormat vk_format,
+ const gfx::ColorSpace &)
+{
+#if BUILDFLAG(IS_LINUX)
+ constexpr auto kUsage =
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ auto tiling = gmb_handle.native_pixmap_handle.modifier ==
+ gfx::NativePixmapHandle::kNoModifier
+ ? VK_IMAGE_TILING_OPTIMAL
+ : VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+ return gpu::VulkanImage::CreateFromGpuMemoryBufferHandle(
+ device_queue, std::move(gmb_handle), size, vk_format, kUsage, /*flags=*/0,
+ tiling, VK_QUEUE_FAMILY_EXTERNAL);
+#else
+ NOTIMPLEMENTED();
+ return nullptr;
+#endif
+}
+
+} // namespace gpu
diff --git a/src/core/compositor/vulkan_implementation_qt.h b/src/core/compositor/vulkan_implementation_qt.h
new file mode 100644
index 000000000..88983331f
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 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 VULKAN_IMPLEMENTATION_QT_H
+#define VULKAN_IMPLEMENTATION_QT_H
+
+#include "gpu/vulkan/vulkan_implementation.h"
+#include "gpu/vulkan/vulkan_instance.h"
+
+namespace gpu {
+
+class VulkanImplementationQt : public VulkanImplementation
+{
+public:
+ VulkanImplementationQt();
+ ~VulkanImplementationQt() override;
+
+ // Overridden from VulkanImplementation.
+ bool InitializeVulkanInstance(bool using_surface) override;
+ VulkanInstance *GetVulkanInstance() override;
+ std::unique_ptr<VulkanSurface> CreateViewSurface(gfx::AcceleratedWidget window) override;
+ bool GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice device,
+ const std::vector<VkQueueFamilyProperties> &queue_family_properties,
+ uint32_t queue_family_index) override;
+ std::vector<const char *> GetRequiredDeviceExtensions() override;
+ std::vector<const char *> GetOptionalDeviceExtensions() override;
+ VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
+ std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(VkDevice vk_device,
+ VkFence vk_fence) override;
+ VkSemaphore ImportSemaphoreHandle(VkDevice vk_device, SemaphoreHandle handle) override;
+ VkExternalSemaphoreHandleTypeFlagBits GetExternalSemaphoreHandleType() override;
+ bool CanImportGpuMemoryBuffer(VulkanDeviceQueue* device_queue,
+ gfx::GpuMemoryBufferType memory_buffer_type) override;
+ std::unique_ptr<VulkanImage> CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferHandle gmb_handle,
+ gfx::Size size, VkFormat vk_format,
+ const gfx::ColorSpace &color_space) override;
+
+private:
+ VulkanInstance vulkan_instance_;
+};
+
+} // namespace gpu
+
+#endif // VULKAN_IMPLEMENTATION_QT_H
diff --git a/src/core/compositor/yuv_video_node.cpp b/src/core/compositor/yuv_video_node.cpp
deleted file mode 100644
index 4a436d952..000000000
--- a/src/core/compositor/yuv_video_node.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-// Based on cc/output/gl_renderer.cc and cc/output/shader.cc:
-// Copyright 2011 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 "yuv_video_node.h"
-
-#include <QtGui/qopenglcontext.h>
-#include <QtGui/qopenglfunctions.h>
-#include <QtQuick/qsgtexture.h>
-
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/color_transform.h"
-
-namespace QtWebEngineCore {
-
-class YUVVideoMaterialShader : public QSGMaterialShader
-{
-public:
- YUVVideoMaterialShader(const gfx::ColorSpace &colorSpace)
- {
- static const char *shaderHead =
- "varying mediump vec2 v_yaTexCoord;\n"
- "varying mediump vec2 v_uvTexCoord;\n"
- "uniform sampler2D y_texture;\n"
- "uniform sampler2D u_texture;\n"
- "uniform sampler2D v_texture;\n"
- "uniform mediump float alpha;\n"
- "uniform mediump vec4 ya_clamp_rect;\n"
- "uniform mediump vec4 uv_clamp_rect;\n";
- static const char *shader =
- "void main() {\n"
- " mediump vec2 ya_clamped =\n"
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
- " mediump vec2 uv_clamped =\n"
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
- " mediump vec3 rgb = DoColorConversion(yuv);\n"
- " gl_FragColor = vec4(rgb, 1.0) * alpha;\n"
- "}";
- // Invalid or unspecified color spaces should be treated as REC709.
- gfx::ColorSpace src = colorSpace.IsValid() ? colorSpace : gfx::ColorSpace::CreateREC709();
- gfx::ColorSpace dst = gfx::ColorSpace::CreateSRGB();
- std::unique_ptr<gfx::ColorTransform> transform =
- gfx::ColorTransform::NewColorTransform(src, dst, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
-
- QByteArray header(shaderHead);
- if (QOpenGLContext::currentContext()->isOpenGLES())
- header = QByteArray("precision mediump float;\n") + header;
-
- m_csShader = QByteArray::fromStdString(transform->GetShaderSource());
- m_fragmentShader = header + m_csShader + QByteArray(shader);
- }
- void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
-
- char const *const *attributeNames() const override {
- static const char *names[] = {
- "a_position",
- "a_texCoord",
- 0
- };
- return names;
- }
-
-protected:
- const char *vertexShader() const override {
- // Keep in sync with logic in VertexShader in components/viz/service/display/shader.cc
- const char *shader =
- "attribute highp vec4 a_position;\n"
- "attribute mediump vec2 a_texCoord;\n"
- "uniform highp mat4 matrix;\n"
- "varying mediump vec2 v_yaTexCoord;\n"
- "varying mediump vec2 v_uvTexCoord;\n"
- "uniform mediump vec2 yaTexScale;\n"
- "uniform mediump vec2 yaTexOffset;\n"
- "uniform mediump vec2 uvTexScale;\n"
- "uniform mediump vec2 uvTexOffset;\n"
- "void main() {\n"
- " gl_Position = matrix * a_position;\n"
- " v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;\n"
- " v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;\n"
- "}";
- return shader;
- }
-
- const char *fragmentShader() const override {
- return m_fragmentShader.constData();
- }
-
- void initialize() override {
- m_id_matrix = program()->uniformLocation("matrix");
- m_id_yaTexScale = program()->uniformLocation("yaTexScale");
- m_id_uvTexScale = program()->uniformLocation("uvTexScale");
- m_id_yaTexOffset = program()->uniformLocation("yaTexOffset");
- m_id_uvTexOffset = program()->uniformLocation("uvTexOffset");
- m_id_yaClampRect = program()->uniformLocation("ya_clamp_rect");
- m_id_uvClampRect = program()->uniformLocation("uv_clamp_rect");
- m_id_yTexture = program()->uniformLocation("y_texture");
- m_id_uTexture = program()->uniformLocation("u_texture");
- m_id_vTexture = program()->uniformLocation("v_texture");
- m_id_yuvMatrix = program()->uniformLocation("yuv_matrix");
- m_id_yuvAdjust = program()->uniformLocation("yuv_adj");
- m_id_opacity = program()->uniformLocation("alpha");
- }
-
- int m_id_matrix;
- int m_id_yaTexScale;
- int m_id_uvTexScale;
- int m_id_yaTexOffset;
- int m_id_uvTexOffset;
- int m_id_yaClampRect;
- int m_id_uvClampRect;
- int m_id_yTexture;
- int m_id_uTexture;
- int m_id_vTexture;
- int m_id_yuvMatrix;
- int m_id_yuvAdjust;
- int m_id_opacity;
- QByteArray m_csShader;
- QByteArray m_fragmentShader;
-};
-
-class YUVAVideoMaterialShader : public YUVVideoMaterialShader
-{
-public:
- YUVAVideoMaterialShader(const gfx::ColorSpace &colorSpace) : YUVVideoMaterialShader(colorSpace)
- {
- static const char *shaderHead =
- "varying mediump vec2 v_yaTexCoord;\n"
- "varying mediump vec2 v_uvTexCoord;\n"
- "uniform sampler2D y_texture;\n"
- "uniform sampler2D u_texture;\n"
- "uniform sampler2D v_texture;\n"
- "uniform sampler2D a_texture;\n"
- "uniform mediump float alpha;\n"
- "uniform mediump vec4 ya_clamp_rect;\n"
- "uniform mediump vec4 uv_clamp_rect;\n";
- static const char *shader =
- "void main() {\n"
- " mediump vec2 ya_clamped =\n"
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
- " mediump vec2 uv_clamped =\n"
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
- " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n"
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
- " mediump vec3 rgb = DoColorConversion(yuv);\n"
- " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n"
- "}";
- QByteArray header(shaderHead);
- if (QOpenGLContext::currentContext()->isOpenGLES())
- header = QByteArray("precision mediump float;\n") + header;
- m_fragmentShader = header + m_csShader + QByteArray(shader);
- }
- void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
-
-protected:
- void initialize() override {
- // YUVVideoMaterialShader has a subset of the uniforms.
- YUVVideoMaterialShader::initialize();
- m_id_aTexture = program()->uniformLocation("a_texture");
- }
-
- int m_id_aTexture;
-};
-
-void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
-{
- Q_UNUSED(oldMaterial);
-
- // Keep logic in sync with logic in GLRenderer::DrawYUVVideoQuad:
-
- YUVVideoMaterial *mat = static_cast<YUVVideoMaterial *>(newMaterial);
- program()->setUniformValue(m_id_yTexture, 0);
- program()->setUniformValue(m_id_uTexture, 1);
- program()->setUniformValue(m_id_vTexture, 2);
-
- QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
-
- glFuncs.glActiveTexture(GL_TEXTURE1);
- mat->m_uTexture->bind();
- glFuncs.glActiveTexture(GL_TEXTURE2);
- mat->m_vTexture->bind();
- glFuncs.glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
- mat->m_yTexture->bind();
-
- const QSizeF yaSizeScale(1.0f / mat->m_yaTexSize.width(), 1.0f / mat->m_yaTexSize.height());
- const QSizeF uvSizeScale(1.0f / mat->m_uvTexSize.width(), 1.0f / mat->m_uvTexSize.height());
-
- const QPointF yaTexOffset(mat->m_yaTexCoordRect.left() * yaSizeScale.width(), mat->m_yaTexCoordRect.top() * yaSizeScale.height());
- const QPointF uvTexOffset(mat->m_uvTexCoordRect.left() * uvSizeScale.width(), mat->m_uvTexCoordRect.top() * uvSizeScale.height());
- const QSizeF yaTexScale(mat->m_yaTexCoordRect.width() * yaSizeScale.width(), mat->m_yaTexCoordRect.height() * yaSizeScale.height());
- const QSizeF uvTexScale(mat->m_uvTexCoordRect.width() * uvSizeScale.width(), mat->m_uvTexCoordRect.height() * uvSizeScale.height());
- program()->setUniformValue(m_id_yaTexOffset, yaTexOffset);
- program()->setUniformValue(m_id_uvTexOffset, uvTexOffset);
- program()->setUniformValue(m_id_yaTexScale, yaTexScale);
- program()->setUniformValue(m_id_uvTexScale, uvTexScale);
- QRectF yaClampRect(yaTexOffset, yaTexScale);
- QRectF uvClampRect(uvTexOffset, uvTexScale);
- yaClampRect = yaClampRect.marginsRemoved(QMarginsF(yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f,
- yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f));
- uvClampRect = uvClampRect.marginsRemoved(QMarginsF(uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f,
- uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f));
-
- const QVector4D yaClampV(yaClampRect.left(), yaClampRect.top(), yaClampRect.right(), yaClampRect.bottom());
- const QVector4D uvClampV(uvClampRect.left(), uvClampRect.top(), uvClampRect.right(), uvClampRect.bottom());
- program()->setUniformValue(m_id_yaClampRect, yaClampV);
- program()->setUniformValue(m_id_uvClampRect, uvClampV);
-
- if (state.isOpacityDirty())
- program()->setUniformValue(m_id_opacity, state.opacity());
-
- if (state.isMatrixDirty())
- program()->setUniformValue(m_id_matrix, state.combinedMatrix());
-}
-
-void YUVAVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
-{
- YUVVideoMaterialShader::updateState(state, newMaterial, oldMaterial);
-
- YUVAVideoMaterial *mat = static_cast<YUVAVideoMaterial *>(newMaterial);
- program()->setUniformValue(m_id_aTexture, 3);
-
- QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
-
- glFuncs.glActiveTexture(GL_TEXTURE3);
- mat->m_aTexture->bind();
-
- // Reset the default texture unit.
- glFuncs.glActiveTexture(GL_TEXTURE0);
-}
-
-
-YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace,
- float rMul, float rOff)
- : m_yTexture(yTexture)
- , m_uTexture(uTexture)
- , m_vTexture(vTexture)
- , m_yaTexCoordRect(yaTexCoordRect)
- , m_uvTexCoordRect(uvTexCoordRect)
- , m_yaTexSize(yaTexSize)
- , m_uvTexSize(uvTexSize)
- , m_colorSpace(colorspace)
- , m_resourceMultiplier(rMul)
- , m_resourceOffset(rOff)
-{
-}
-
-QSGMaterialShader *YUVVideoMaterial::createShader() const
-{
- return new YUVVideoMaterialShader(m_colorSpace);
-}
-
-int YUVVideoMaterial::compare(const QSGMaterial *other) const
-{
- const YUVVideoMaterial *m = static_cast<const YUVVideoMaterial *>(other);
- if (int diff = m_yTexture->textureId() - m->m_yTexture->textureId())
- return diff;
- if (int diff = m_uTexture->textureId() - m->m_uTexture->textureId())
- return diff;
- return m_vTexture->textureId() - m->m_vTexture->textureId();
-}
-
-YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace,
- float rMul, float rOff)
- : YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace, rMul, rOff)
- , m_aTexture(aTexture)
-{
- setFlag(Blending, aTexture);
-}
-
-QSGMaterialShader *YUVAVideoMaterial::createShader() const
-{
- return new YUVAVideoMaterialShader(m_colorSpace);
-}
-
-int YUVAVideoMaterial::compare(const QSGMaterial *other) const
-{
- if (int diff = YUVVideoMaterial::compare(other))
- return diff;
- const YUVAVideoMaterial *m = static_cast<const YUVAVideoMaterial *>(other);
- return (m_aTexture ? m_aTexture->textureId() : 0) - (m->m_aTexture ? m->m_aTexture->textureId() : 0);
-}
-
-YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace, float rMul, float rOff)
- : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
-{
- setGeometry(&m_geometry);
- setFlag(QSGNode::OwnsMaterial);
- if (aTexture)
- m_material = new YUVAVideoMaterial(yTexture, uTexture, vTexture, aTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace, rMul, rOff);
- else
- m_material = new YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace, rMul, rOff);
- setMaterial(m_material);
-}
-
-void YUVVideoNode::setRect(const QRectF &rect)
-{
- QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
-}
-
-} // namespace
diff --git a/src/core/compositor/yuv_video_node.h b/src/core/compositor/yuv_video_node.h
deleted file mode 100644
index dca8fa5e2..000000000
--- a/src/core/compositor/yuv_video_node.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef YUV_VIDEO_NODE_H
-#define YUV_VIDEO_NODE_H
-
-#include <QtQuick/qsgmaterial.h>
-#include <QtQuick/qsgnode.h>
-
-#include "ui/gfx/color_space.h"
-
-QT_FORWARD_DECLARE_CLASS(QSGTexture)
-
-namespace QtWebEngineCore {
-
-// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawYUVVideoQuad.
-// Their behavior should stay as close as possible to GLRenderer.
-
-class YUVVideoMaterial : public QSGMaterial
-{
-public:
- YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace, float rMul, float rOff);
-
- QSGMaterialType *type() const override
- {
- static QSGMaterialType theType;
- return &theType;
- }
-
- QSGMaterialShader *createShader() const override;
- int compare(const QSGMaterial *other) const override;
-
- QSGTexture *m_yTexture;
- QSGTexture *m_uTexture;
- QSGTexture *m_vTexture;
- QRectF m_yaTexCoordRect;
- QRectF m_uvTexCoordRect;
- QSizeF m_yaTexSize;
- QSizeF m_uvTexSize;
- gfx::ColorSpace m_colorSpace;
- float m_resourceMultiplier;
- float m_resourceOffset;
-};
-
-class YUVAVideoMaterial : public YUVVideoMaterial
-{
-public:
- YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace, float rMul, float rOff);
-
- QSGMaterialType *type() const override
- {
- static QSGMaterialType theType;
- return &theType;
- }
-
- QSGMaterialShader *createShader() const override;
- int compare(const QSGMaterial *other) const override;
-
- QSGTexture *m_aTexture;
-};
-
-class YUVVideoNode : public QSGGeometryNode
-{
-public:
- YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
- const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- const gfx::ColorSpace &colorspace, float rMul, float rOff);
- void setRect(const QRectF &rect);
-
-private:
- QSGGeometry m_geometry;
- YUVVideoMaterial *m_material;
-};
-
-} // namespace
-
-#endif // YUV_VIDEO_NODE_H