diff options
Diffstat (limited to 'src/core/compositor/compositor.h')
-rw-r--r-- | src/core/compositor/compositor.h | 238 |
1 files changed, 131 insertions, 107 deletions
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h index 36e62c17a..501559060 100644 --- a/src/core/compositor/compositor.h +++ b/src/core/compositor/compositor.h @@ -1,129 +1,153 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef COMPOSITOR_H #define COMPOSITOR_H -#include "base/memory/weak_ptr.h" -#include "components/viz/common/frame_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 <QtWebEngineCore/private/qtwebenginecoreglobal_p.h> QT_BEGIN_NAMESPACE -class QSGNode; +class QQuickWindow; +class QSize; +class QSGTexture; QT_END_NAMESPACE -namespace content { -class RenderWidgetHost; -} namespace viz { -struct ReturnedResource; -namespace mojom { -class CompositorFrameSinkClient; -} // namespace mojom +class FrameSinkId; } // namespace viz namespace QtWebEngineCore { -class CompositorResourceTracker; -class RenderWidgetHostViewQtDelegate; - -// Receives viz::CompositorFrames from child compositors and provides QSGNodes -// to the Qt Quick renderer. -// -// The life cycle of a frame: -// -// Step 1. A new CompositorFrame is received from child compositors and handed -// off to submitFrame(). The new frame will start off in a pending state. +// Produces composited frames for display. // -// Step 2. Once the new frame is ready to be rendered, Compositor will notify -// the client by running the callback given to submitFrame(). -// -// Step 3. Once the client is ready to render, updatePaintNode() should be -// called to receive the scene graph for the new frame. This call will commit -// the pending frame. Until the next frame is ready, all subsequent calls to -// updatePaintNode() will keep using this same committed frame. -// -// Step 4. The Compositor will return unneeded resources back to the child -// compositors. Go to step 1. -class Compositor final : private viz::BeginFrameObserverBase +// Used by quick/widgets libraries for accessing the frames and +// controlling frame swapping. +class Q_WEBENGINECORE_EXPORT Compositor { + struct Binding; + public: - explicit Compositor(content::RenderWidgetHost *host); - ~Compositor() override; + // Identifies the implementation type. + enum class Type { + Software, + OpenGL, // TODO: Legacy, remove it with DisplaySkiaOutputDevice! + Native + }; + + // Identifies a compositor. + // + // The purpose of assigning ids to compositors is to allow the + // corresponding observer to be registered before the compositor + // itself is created, which is necessary since the creation + // happens on a different thread in the depths of viz. + // + // (Maps to viz::FrameSinkId internally). + struct Id + { + quint32 client_id; + quint32 sink_id; + + Id(viz::FrameSinkId); + }; + + // Pointer to Compositor or Observer that holds a lock to prevent + // either from being unbound and destroyed. + template<typename T> + class Handle + { + public: + Handle(std::nullptr_t) : m_data(nullptr) { } + Handle(T *data) : m_data(data) { } + Handle(Handle &&that) : m_data(that.m_data) { that.m_data = nullptr; } + ~Handle() + { + if (m_data) + Compositor::unlockBindings(); + } + T *operator->() const { return m_data; } + T &operator*() const { return *m_data; } + explicit operator bool() const { return m_data; } + + private: + T *m_data; + }; + + // Observes the compositor corresponding to the given id. + // + // Only one observer can exist per compositor. + class Q_WEBENGINECORE_EXPORT Observer + { + public: + // Binding to compositor + void bind(Id id); + void unbind(); + + // Compositor if bound + Handle<Compositor> compositor(); + + // There's a new frame ready, time to swapFrame(). + virtual void readyToSwap() = 0; + + protected: + Observer() = default; + ~Observer() { if (m_binding) unbind(); } + + private: + Binding *m_binding = nullptr; + }; + + // Type determines which methods can be called. + Type type() const { return m_type; } + + // Binding to observer. + void bind(Id id); + void unbind(); + + // Observer if bound. + Handle<Observer> observer(); + + // Update to next frame if possible. + virtual void swapFrame() = 0; + + // Ratio of pixels to DIPs. + // + // Don't use the devicePixelRatio of QImage, it's always 1. + virtual float devicePixelRatio() = 0; + + // Size of frame in pixels. + virtual QSize size() = 0; + + // Whether frame needs an alpha channel. + virtual bool requiresAlphaChannel() = 0; + + // Wait on texture to be ready aka. sync. + virtual void waitForTexture(); + + // Release any held texture resources + virtual void releaseTexture(); + + // QSGTexture of the frame. + virtual QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions); + + // Is the texture produced upside down? + virtual bool textureIsFlipped(); + + // Release resources created in texture() + virtual void releaseResources(); + +protected: + Compositor(Type type) : m_type(type) { } + virtual ~Compositor() { if (m_binding) unbind(); } - void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient); - void setNeedsBeginFrames(bool needsBeginFrames); +private: + template<typename T> + friend class Handle; - void submitFrame(viz::CompositorFrame frame, base::OnceClosure callback); - QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate); + class BindingMap; + static void unlockBindings(); -private: - void runSubmitCallback(); - void notifyFrameCommitted(); - void sendPresentationFeedback(uint frame_token); - - // viz::BeginFrameObserverBase - bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) override; - void OnBeginFrameSourcePausedChanged(bool paused) override; - - viz::CompositorFrame m_committedFrame; - viz::CompositorFrame m_pendingFrame; - base::OnceClosure m_submitCallback; - std::unique_ptr<CompositorResourceTracker> m_resourceTracker; - content::RenderWidgetHost *m_host; - std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource; - base::flat_map<uint32_t, 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 |