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.cpp87
-rw-r--r--src/core/compositor/chromium_gpu_helper.h73
-rw-r--r--src/core/compositor/compositor.cpp216
-rw-r--r--src/core/compositor/compositor.h204
-rw-r--r--src/core/compositor/compositor_resource.h123
-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/delegated_frame_node.cpp1101
-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.cpp55
-rw-r--r--src/core/compositor/display_gl_output_surface.h18
-rw-r--r--src/core/compositor/display_gl_output_surface_qsg.cpp121
-rw-r--r--src/core/compositor/display_producer.h69
-rw-r--r--src/core/compositor/display_software_output_surface.cpp103
-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/yuv_video_node.cpp352
-rw-r--r--src/core/compositor/yuv_video_node.h117
21 files changed, 362 insertions, 3339 deletions
diff --git a/src/core/compositor/chromium_gpu_helper.cpp b/src/core/compositor/chromium_gpu_helper.cpp
deleted file mode 100644
index 1ddbf75e5..000000000
--- a/src/core/compositor/chromium_gpu_helper.cpp
+++ /dev/null
@@ -1,87 +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"
-
-#include <QtGlobal> // We need this for Q_UNUSED
-
-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);
-}
diff --git a/src/core/compositor/chromium_gpu_helper.h b/src/core/compositor/chromium_gpu_helper.h
deleted file mode 100644
index e692b9b85..000000000
--- a/src/core/compositor/chromium_gpu_helper.h
+++ /dev/null
@@ -1,73 +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 "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);
-
-#endif // CHROMIUM_GPU_HELPER_H
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 82a9f7ee4..655126f20 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -39,149 +39,159 @@
#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/privileged/mojom/compositing/frame_sink_manager.mojom.h"
+#include <QHash>
+#include <QImage>
+#include <QMutex>
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::CreateSingleThreadTaskRunner({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);
+ return id1.client_id == id2.client_id && id1.sink_id == id2.sink_id;
+}
- if (m_frameSinkClient == frameSinkClient)
- return;
+// Compositor::Binding and Compositor::Bindings
- // 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;
-}
+struct Compositor::Binding
+{
+ const Id id;
+ Compositor *compositor = nullptr;
+ Observer *observer = nullptr;
+
+ Binding(Id id) : id(id) { }
+ ~Binding();
+};
-void Compositor::setNeedsBeginFrames(bool needsBeginFrames)
+class Compositor::BindingMap
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+public:
+ void lock() { m_mutex.lock(); }
- if (m_needsBeginFrames == needsBeginFrames)
- return;
+ void unlock() { m_mutex.unlock(); }
- if (needsBeginFrames)
- m_beginFrameSource->AddObserver(this);
- else
- m_beginFrameSource->RemoveObserver(this);
+ 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_needsBeginFrames = needsBeginFrames;
-}
+ void remove(Id id) { m_map.remove(id); }
+
+private:
+ QMutex m_mutex;
+ QHash<Id, Binding *> m_map;
+} static g_bindings;
-void Compositor::submitFrame(viz::CompositorFrame frame, base::OnceClosure callback)
+Compositor::Binding::~Binding()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- DCHECK(!m_submitCallback);
-
- m_pendingFrame = std::move(frame);
- m_submitCallback = std::move(callback);
- m_resourceTracker->submitResources(
- m_pendingFrame,
- base::BindOnce(&Compositor::runSubmitCallback, base::Unretained(this)));
+ g_bindings.remove(id);
}
-QSGNode *Compositor::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate)
+// Compositor::Observer
+
+void Compositor::Observer::bind(Id id)
{
- // 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.
-
- DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
- if (!frameNode)
- frameNode = new DelegatedFrameNode;
-
- if (!m_updatePaintNodeShouldCommit) {
- frameNode->commit(m_committedFrame, viz::CompositorFrame(), m_resourceTracker.get(), viewDelegate);
- return frameNode;
- }
- m_updatePaintNodeShouldCommit = false;
+ DCHECK(!m_binding);
+ g_bindings.lock();
+ m_binding = g_bindings.findOrCreate(id);
+ DCHECK(!m_binding->observer);
+ m_binding->observer = this;
+ g_bindings.unlock();
+}
- m_presentations.emplace(m_committedFrame.metadata.frame_token, viz::FrameTimingDetails{base::TimeTicks::Now()});
+void Compositor::Observer::unbind()
+{
+ 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_resourceTracker->commitResources();
- frameNode->commit(m_pendingFrame, m_committedFrame, m_resourceTracker.get(), viewDelegate);
- m_committedFrame = std::move(m_pendingFrame);
- m_pendingFrame = viz::CompositorFrame();
+Compositor::Handle<Compositor> Compositor::Observer::compositor()
+{
+ if (!m_binding)
+ return nullptr;
+ g_bindings.lock();
+ if (m_binding->compositor)
+ return m_binding->compositor; // delay unlock
+ g_bindings.unlock();
+ return nullptr;
+}
- m_taskRunner->PostTask(FROM_HERE,
- base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
+// Compositor
- return frameNode;
+void Compositor::bind(Id id)
+{
+ DCHECK(!m_binding);
+ g_bindings.lock();
+ m_binding = g_bindings.findOrCreate(id);
+ DCHECK(!m_binding->compositor);
+ m_binding->compositor = this;
+ g_bindings.unlock();
}
-void Compositor::runSubmitCallback()
+void Compositor::unbind()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- m_updatePaintNodeShouldCommit = true;
- std::move(m_submitCallback).Run();
+ 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::notifyFrameCommitted()
+Compositor::Handle<Compositor::Observer> Compositor::observer()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- m_beginFrameSource->DidFinishFrame(this);
- if (m_frameSinkClient)
- m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourceTracker->returnResources());
+ if (!m_binding)
+ return nullptr;
+ g_bindings.lock();
+ if (m_binding->observer)
+ return m_binding->observer; // delay unlock
+ g_bindings.unlock();
+ return nullptr;
}
-void Compositor::sendPresentationFeedback(uint frame_token)
+QImage Compositor::image()
{
- viz::FrameTimingDetails dummyDetails = {base::TimeTicks::Now()};
- m_presentations.emplace(frame_token, dummyDetails);
+ Q_UNREACHABLE();
+ return {};
}
-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();
- }
-
- return true;
+ Q_UNREACHABLE();
}
-void Compositor::OnBeginFrameSourcePausedChanged(bool)
+int Compositor::textureId()
{
- // 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 0;
}
+// static
+void Compositor::unlockBindings()
+{
+ g_bindings.unlock();
+}
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 36e62c17a..316178891 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -40,90 +40,154 @@
#ifndef COMPOSITOR_H
#define COMPOSITOR_H
-#include "base/memory/weak_ptr.h"
-#include "components/viz/common/frame_timing_details.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/quads/compositor_frame.h"
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qshareddata.h>
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qshareddata.h>
+#include "qtwebenginecoreglobal_p.h"
QT_BEGIN_NAMESPACE
-class QSGNode;
+class QImage;
+class QSize;
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 frame and
+// controlling frame swapping. Must be cast to a subclass to access
+// the frame as QImage or OpenGL texture, etc.
+class Q_WEBENGINECORE_PRIVATE_EXPORT Compositor
{
+ struct Binding;
+
public:
- explicit Compositor(content::RenderWidgetHost *host);
- ~Compositor() override;
+ // Identifies the implementation type.
+ enum class Type {
+ Software,
+ OpenGL,
+ };
+
+ // 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_PRIVATE_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() = default;
+
+ 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.
+ //
+ // In software mode, the image format can be either
+ // QImage::Format_ARGB32_Premultiplied or
+ // QImage::Format_RGBA8888_Premultiplied
+ //
+ // In OpenGL mode, the texture format is either GL_RGBA or GL_RGB.
+ virtual bool hasAlphaChannel() = 0;
+
+ // (Software) QImage of the frame.
+ //
+ // This is a big image so we should try not to make copies of it.
+ // In particular, the client should drop its QImage reference
+ // before calling swapFrame(), otherwise each swap will cause a
+ // detach.
+ virtual QImage image();
+
+ // (OpenGL) Wait on texture fence in Qt's current OpenGL context.
+ virtual void waitForTexture();
+
+ // (OpenGL) Texture of the frame.
+ virtual int textureId();
+
+protected:
+ Compositor(Type type) : m_type(type) { }
+ ~Compositor() = default;
- 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, viz::FrameTimingDetails> 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_tracker.cpp b/src/core/compositor/compositor_resource_tracker.cpp
deleted file mode 100644
index 1e7108571..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::PostTask(
- 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/delegated_frame_node.cpp b/src/core/compositor/delegated_frame_node.cpp
deleted file mode 100644
index f182a2c9e..000000000
--- a/src/core/compositor/delegated_frame_node.cpp
+++ /dev/null
@@ -1,1101 +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"
-
-#if QT_CONFIG(opengl)
-# include <QOpenGLContext>
-# include <QOpenGLFunctions>
-# include <QSGFlatColorMaterial>
-#endif
-#include <QSGTexture>
-#include <private/qsgadaptationlayer_p.h>
-
-#include <QSGImageNode>
-#include <QSGRectangleNode>
-
-#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
-
-#if QT_CONFIG(opengl)
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-QT_END_NAMESPACE
-#endif
-
-namespace QtWebEngineCore {
-#if QT_CONFIG(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
- friend class DelegatedFrameNode;
-};
-#endif // QT_CONFIG(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;
-
-#if QT_CONFIG(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_CONFIG(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);
- }
-#if QT_CONFIG(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_CONFIG(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);
- }
-
-#if QT_CONFIG(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_CONFIG(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;
-}
-
-#if QT_CONFIG(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);
-}
-#endif // QT_CONFIG(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) && QT_CONFIG(opengl)
- : m_contextShared(true)
-#endif
-{
- setFlag(UsePreprocess);
-#if defined(USE_OZONE) && QT_CONFIG(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;
-#if QT_CONFIG(opengl)
- if (quad->material == viz::DrawQuad::Material::kYuvVideoContent)
- return false;
-#ifdef GL_OES_EGL_image_external
- if (quad->material == viz::DrawQuad::Material::kStreamVideoContent)
- return false;
-#endif // GL_OES_EGL_image_external
-#endif // QT_CONFIG(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(false);
- 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::Material::kRenderPass: {
- 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::Material::kTextureContent: {
- const viz::TextureDrawQuad *tquad = viz::TextureDrawQuad::MaterialCast(quad);
- const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
- QSGTexture *texture =
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending(true), 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::Material::kSolidColor: {
- 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;
-#if QT_CONFIG(opengl)
- }
- case viz::DrawQuad::Material::kDebugBorder: {
- 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::Material::kTiledContent: {
- const viz::TileDrawQuad *tquad = viz::TileDrawQuad::MaterialCast(quad);
- const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
- nodeHandler->setupTextureContentNode(
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending(true), apiDelegate),
- toQt(quad->rect), toQt(tquad->tex_coord_rect),
- QSGImageNode::NoTransform, currentLayerChain);
- break;
-#if QT_CONFIG(opengl)
- }
- case viz::DrawQuad::Material::kYuvVideoContent: {
- 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(true)),
- initAndHoldTexture(uResource, quad->ShouldDrawWithBlending(true)),
- initAndHoldTexture(vResource, quad->ShouldDrawWithBlending(true)),
- aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending(true)) : 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::Material::kStreamVideoContent: {
- 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(true), 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_CONFIG(opengl)
- }
- case viz::DrawQuad::Material::kSurfaceContent:
- Q_UNREACHABLE();
- default:
- qWarning("Unimplemented quad material: %d", (int)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)
-{
-#if QT_CONFIG(opengl)
- return QSharedPointer<MailboxTexture>::create(resource, hasAlphaChannel, target);
-#else
- Q_UNREACHABLE();
-#endif
-}
-
-void DelegatedFrameNode::copyMailboxTextures()
-{
-#if QT_CONFIG(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
index ef12cc71b..05653149e 100644
--- a/src/core/compositor/display_gl_output_surface.cpp
+++ b/src/core/compositor/display_gl_output_surface.cpp
@@ -39,7 +39,7 @@
#include "display_gl_output_surface.h"
-#include "chromium_gpu_helper.h"
+#include "type_conversion.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/viz/service/display/display.h"
@@ -53,8 +53,10 @@
namespace QtWebEngineCore {
-DisplayGLOutputSurface::DisplayGLOutputSurface(scoped_refptr<viz::VizProcessContextProvider> contextProvider)
+DisplayGLOutputSurface::DisplayGLOutputSurface(
+ scoped_refptr<viz::VizProcessContextProvider> contextProvider)
: OutputSurface(contextProvider)
+ , Compositor(Compositor::Type::OpenGL)
, m_commandBuffer(contextProvider->command_buffer())
, m_gl(contextProvider->ContextGL())
, m_vizContextProvider(contextProvider)
@@ -65,18 +67,16 @@ DisplayGLOutputSurface::DisplayGLOutputSurface(scoped_refptr<viz::VizProcessCont
DisplayGLOutputSurface::~DisplayGLOutputSurface()
{
+ unbind();
m_vizContextProvider->SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback());
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);
+ bind(m_display->frame_sink_id());
}
// Triggered by ui::Compositor::SetVisible(true).
@@ -213,7 +213,8 @@ void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique
m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence));
}
- m_sink->scheduleUpdate();
+ if (auto obs = observer())
+ obs->readyToSwap();
}
void DisplayGLOutputSurface::swapBuffersOnVizThread()
@@ -297,4 +298,44 @@ gfx::OverlayTransform DisplayGLOutputSurface::GetDisplayTransform()
return gfx::OVERLAY_TRANSFORM_NONE;
}
+void DisplayGLOutputSurface::swapFrame()
+{
+ 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();
+ }
+}
+
+void DisplayGLOutputSurface::waitForTexture()
+{
+ if (m_frontBuffer && m_frontBuffer->fence) {
+ m_frontBuffer->fence->wait();
+ m_frontBuffer->fence.reset();
+ }
+}
+
+int DisplayGLOutputSurface::textureId()
+{
+ return m_frontBuffer ? m_frontBuffer->serviceId : 0;
+}
+
+QSize DisplayGLOutputSurface::size()
+{
+ return m_frontBuffer ? toQt(m_frontBuffer->shape.sizeInPixels) : QSize();
+}
+
+bool DisplayGLOutputSurface::hasAlphaChannel()
+{
+ return m_frontBuffer ? m_frontBuffer->shape.hasAlpha : false;
+}
+
+float DisplayGLOutputSurface::devicePixelRatio()
+{
+ return m_frontBuffer ? m_frontBuffer->shape.devicePixelRatio : 1;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h
index 67d987263..6b1b2e043 100644
--- a/src/core/compositor/display_gl_output_surface.h
+++ b/src/core/compositor/display_gl_output_surface.h
@@ -41,7 +41,7 @@
#define DISPLAY_GL_OUTPUT_SURFACE_H
#include "compositor_resource_fence.h"
-#include "display_frame_sink.h"
+#include "compositor.h"
#include "components/viz/common/display/update_vsync_parameters_callback.h"
#include "components/viz/service/display/output_surface.h"
@@ -49,6 +49,8 @@
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
+#include <QMutex>
+
namespace viz {
class Display;
class SyntheticBeginFrameSource;
@@ -56,9 +58,7 @@ class SyntheticBeginFrameSource;
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
+class DisplayGLOutputSurface final : public viz::OutputSurface, public Compositor
{
public:
DisplayGLOutputSurface(scoped_refptr<viz::VizProcessContextProvider> contextProvider);
@@ -87,8 +87,13 @@ public:
void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
gfx::OverlayTransform GetDisplayTransform() override;
- // Overridden from DisplayProducer.
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
+ // Overridden from Compositor.
+ void swapFrame() override;
+ void waitForTexture() override;
+ int textureId() override;
+ QSize size() override;
+ bool hasAlphaChannel() override;
+ float devicePixelRatio() override;
private:
struct Shape
@@ -135,7 +140,6 @@ private:
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;
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_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_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
index ba99799f0..218bff94a 100644
--- a/src/core/compositor/display_software_output_surface.cpp
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -39,7 +39,7 @@
#include "display_software_output_surface.h"
-#include "display_frame_sink.h"
+#include "compositor.h"
#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
@@ -49,28 +49,29 @@
#include <QMutex>
#include <QPainter>
-#include <QSGImageNode>
namespace QtWebEngineCore {
-class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice, public DisplayProducer
+class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice,
+ public Compositor
{
public:
+ Device();
~Device();
- // Called from DisplaySoftwareOutputSurface.
- void bind(viz::FrameSinkId frameSinkId);
-
// Overridden from viz::SoftwareOutputDevice.
void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
void OnSwapBuffers(SwapBuffersCallback swap_ack_callback) override;
- // Overridden from DisplayProducer.
- QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
+ // Overridden from Compositor.
+ void swapFrame() override;
+ QImage image() override;
+ float devicePixelRatio() override;
+ QSize size() override;
+ bool hasAlphaChannel() override;
private:
mutable QMutex m_mutex;
- scoped_refptr<DisplayFrameSink> m_sink;
float m_devicePixelRatio = 1.0;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
SwapBuffersCallback m_swapCompletionCallback;
@@ -78,16 +79,13 @@ private:
float m_imageDevicePixelRatio = 1.0;
};
-DisplaySoftwareOutputSurface::Device::~Device()
-{
- if (m_sink)
- m_sink->disconnect(this);
-}
+DisplaySoftwareOutputSurface::Device::Device()
+ : Compositor(Type::Software)
+{}
-void DisplaySoftwareOutputSurface::Device::bind(viz::FrameSinkId frameSinkId)
+DisplaySoftwareOutputSurface::Device::~Device()
{
- m_sink = DisplayFrameSink::findOrCreate(frameSinkId);
- m_sink->connect(this);
+ unbind();
}
void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
@@ -104,7 +102,8 @@ void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(SwapBuffersCallback swa
QMutexLocker locker(&m_mutex);
m_taskRunner = base::ThreadTaskRunnerHandle::Get();
m_swapCompletionCallback = std::move(swap_ack_callback);
- m_sink->scheduleUpdate();
+ if (auto obs = observer())
+ obs->readyToSwap();
}
inline QImage::Format imageFormat(SkColorType colorType)
@@ -120,41 +119,51 @@ 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 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();
+ 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();
+}
- QSizeF sizeInDips = QSizeF(m_image.size()) / m_imageDevicePixelRatio;
- node->setRect(QRectF(QPointF(0, 0), sizeInDips));
- node->setOwnsTexture(true);
- node->setTexture(delegate->createTextureFromImage(m_image));
+QImage DisplaySoftwareOutputSurface::Device::image()
+{
+ return m_image;
+}
+
+float DisplaySoftwareOutputSurface::Device::devicePixelRatio()
+{
+ return m_imageDevicePixelRatio;
+}
- return node;
+QSize DisplaySoftwareOutputSurface::Device::size()
+{
+ return m_image.size();
+}
+
+bool DisplaySoftwareOutputSurface::Device::hasAlphaChannel()
+{
+ return m_image.format() == QImage::Format_ARGB32_Premultiplied;
}
DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface()
diff --git a/src/core/compositor/stream_video_node.cpp b/src/core/compositor/stream_video_node.cpp
deleted file mode 100644
index fb9501f24..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) 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 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() override {
- 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/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