summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/compositor/compositor.cpp215
-rw-r--r--src/core/compositor/compositor.h185
-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.cpp122
-rw-r--r--src/core/compositor/display_producer.h69
-rw-r--r--src/core/compositor/display_software_output_surface.cpp91
-rw-r--r--src/core/core_chromium.pri7
-rw-r--r--src/core/render_widget_host_view_qt.cpp35
-rw-r--r--src/core/render_widget_host_view_qt.h17
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h10
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.cpp4
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.h5
-rw-r--r--src/core/web_contents_adapter_client.h2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp24
-rw-r--r--src/webengine/api/qquickwebengineview_p.h5
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h11
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp83
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h13
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp26
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h5
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h2
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp100
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h5
27 files changed, 691 insertions, 697 deletions
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
new file mode 100644
index 000000000..c45c02844
--- /dev/null
+++ b/src/core/compositor/compositor.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** 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.
+**
+** $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.h"
+
+#include "base/memory/ref_counted.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
+
+#include <QHash>
+#include <QImage>
+#include <QMutex>
+
+namespace QtWebEngineCore {
+
+// Compositor::Id
+
+Compositor::Id::Id(viz::FrameSinkId fid) : client_id(fid.client_id()), sink_id(fid.sink_id()) { }
+
+static size_t qHash(Compositor::Id id, size_t seed = 0)
+{
+ QtPrivate::QHashCombine hasher;
+ seed = hasher(seed, id.client_id);
+ seed = hasher(seed, id.sink_id);
+ return seed;
+}
+
+static bool operator==(Compositor::Id id1, Compositor::Id id2)
+{
+ return id1.client_id == id2.client_id && id1.sink_id == id2.sink_id;
+}
+
+// Compositor::Binding and Compositor::Bindings
+
+struct Compositor::Binding
+{
+ const Id id;
+ Compositor *compositor = nullptr;
+ Observer *observer = nullptr;
+
+ Binding(Id id) : id(id) { }
+ ~Binding();
+};
+
+class Compositor::BindingMap
+{
+public:
+ void lock() { m_mutex.lock(); }
+
+ void unlock() { m_mutex.unlock(); }
+
+ 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;
+ }
+
+ void remove(Id id) { m_map.remove(id); }
+
+private:
+ QMutex m_mutex;
+ QHash<Id, Binding *> m_map;
+} static g_bindings;
+
+Compositor::Binding::~Binding()
+{
+ g_bindings.remove(id);
+}
+
+// Compositor::Observer
+
+void Compositor::Observer::bind(Id id)
+{
+ DCHECK(!m_binding);
+ g_bindings.lock();
+ m_binding = g_bindings.findOrCreate(id);
+ DCHECK(!m_binding->observer);
+ m_binding->observer = this;
+ g_bindings.unlock();
+}
+
+void Compositor::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();
+}
+
+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;
+}
+
+// Compositor
+
+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::unbind()
+{
+ DCHECK(m_binding);
+ g_bindings.lock();
+ m_binding->compositor = nullptr;
+ if (m_binding->observer == nullptr)
+ delete m_binding;
+ m_binding = nullptr;
+ g_bindings.unlock();
+}
+
+Compositor::Handle<Compositor::Observer> Compositor::observer()
+{
+ if (!m_binding)
+ return nullptr;
+ g_bindings.lock();
+ if (m_binding->observer)
+ return m_binding->observer; // delay unlock
+ g_bindings.unlock();
+ return nullptr;
+}
+
+float Compositor::devicePixelRatio()
+{
+ Q_UNREACHABLE();
+ return 1;
+}
+
+QImage Compositor::image()
+{
+ Q_UNREACHABLE();
+ return {};
+}
+
+void Compositor::waitForTexture()
+{
+ Q_UNREACHABLE();
+}
+
+int Compositor::textureId()
+{
+ Q_UNREACHABLE();
+ return 0;
+}
+
+QSize Compositor::textureSize()
+{
+ Q_UNREACHABLE();
+ return {};
+}
+
+bool Compositor::hasAlphaChannel()
+{
+ Q_UNREACHABLE();
+ return false;
+}
+
+// static
+void Compositor::unlockBindings()
+{
+ g_bindings.unlock();
+}
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
new file mode 100644
index 000000000..d10cf2ef6
--- /dev/null
+++ b/src/core/compositor/compositor.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** 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.
+**
+** $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_H
+#define COMPOSITOR_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+QT_BEGIN_NAMESPACE
+class QImage;
+class QSize;
+QT_END_NAMESPACE
+
+namespace viz {
+class FrameSinkId;
+} // namespace viz
+
+namespace QtWebEngineCore {
+
+// Produces composited frames for display.
+//
+// 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:
+ // 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();
+
+ // (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) Properties of the current frame.
+ virtual int textureId();
+ virtual QSize textureSize();
+ virtual bool hasAlphaChannel();
+
+protected:
+ Compositor(Type type) : m_type(type) { }
+ ~Compositor() = default;
+
+private:
+ template<typename T>
+ friend class Handle;
+
+ class BindingMap;
+ static void unlockBindings();
+
+ const Type m_type;
+ Binding *m_binding = nullptr;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_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 4f63e5b69..f736bba79 100644
--- a/src/core/compositor/display_gl_output_surface.cpp
+++ b/src/core/compositor/display_gl_output_surface.cpp
@@ -39,6 +39,8 @@
#include "display_gl_output_surface.h"
+#include "type_conversion.h"
+
#include "base/threading/thread_task_runner_handle.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/output_surface_frame.h"
@@ -51,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)
@@ -63,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).
@@ -211,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()
@@ -295,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::textureSize()
+{
+ 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..678d0cf5c 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 textureSize() 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 2ed24ef1d..000000000
--- a/src/core/compositor/display_gl_output_surface_qsg.cpp
+++ /dev/null
@@ -1,122 +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);
- }
- int comparisonKey() const override { return 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..b1a357615 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,27 @@
#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;
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 +77,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 +100,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 +117,41 @@ 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;
+}
- return node;
+float DisplaySoftwareOutputSurface::Device::devicePixelRatio()
+{
+ return m_imageDevicePixelRatio;
}
DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface()
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index f2cedaf4a..14a65a39c 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -53,8 +53,8 @@ SOURCES = \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
+ compositor/compositor.cpp \
compositor/content_gpu_client_qt.cpp \
- compositor/display_frame_sink.cpp \
compositor/display_overrides.cpp \
compositor/display_software_output_surface.cpp \
content_client_qt.cpp \
@@ -157,8 +157,8 @@ HEADERS = \
color_chooser_controller.h \
common/qt_messages.h \
common/user_script_data.h \
+ compositor/compositor.h \
compositor/content_gpu_client_qt.h \
- compositor/display_frame_sink.h \
compositor/display_software_output_surface.h \
content_client_qt.h \
content_browser_client_qt.h \
@@ -293,8 +293,7 @@ qtConfig(webengine-printing-and-pdf) {
contains(QT_CONFIG, opengl) {
SOURCES += \
compositor/compositor_resource_fence.cpp \
- compositor/display_gl_output_surface.cpp \
- compositor/display_gl_output_surface_qsg.cpp
+ compositor/display_gl_output_surface.cpp
HEADERS += \
compositor/compositor_resource_fence.h \
compositor/display_gl_output_surface.h
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 27229df81..9be6fac9a 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -148,9 +148,6 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
m_uiCompositor->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); // null means offscreen
m_uiCompositor->SetRootLayer(m_rootLayer.get());
- m_displayFrameSink = DisplayFrameSink::findOrCreate(m_uiCompositor->frame_sink_id());
- m_displayFrameSink->connect(this);
-
if (host()->delegate() && host()->delegate()->GetInputEventRouter())
host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this);
@@ -172,8 +169,6 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
QObject::disconnect(m_adapterClientDestroyedConnection);
- m_displayFrameSink->disconnect(this);
-
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
@@ -707,36 +702,12 @@ void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::Rende
void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint()
{
- if (m_loadVisuallyCommittedState == NotCommitted) {
- m_loadVisuallyCommittedState = DidFirstVisuallyNonEmptyPaint;
- } else if (m_loadVisuallyCommittedState == DidFirstCompositorFrameSwap) {
- m_adapterClient->loadVisuallyCommitted();
- m_loadVisuallyCommittedState = NotCommitted;
- }
-}
-
-void RenderWidgetHostViewQt::scheduleUpdate()
-{
- m_taskRunner->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetHostViewQt::callUpdate, m_weakPtrFactory.GetWeakPtr()));
-}
-
-void RenderWidgetHostViewQt::callUpdate()
-{
- m_delegate->update();
-
- if (m_loadVisuallyCommittedState == NotCommitted) {
- m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
- } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) {
- m_adapterClient->loadVisuallyCommitted();
- m_loadVisuallyCommittedState = NotCommitted;
- }
+ m_adapterClient->didFirstVisuallyNonEmptyPaint();
}
-QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
+Compositor::Id RenderWidgetHostViewQt::compositorId()
{
- return m_displayFrameSink->updatePaintNode(oldNode, m_delegate.get());
+ return m_uiCompositor->frame_sink_id();
}
void RenderWidgetHostViewQt::notifyShown()
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 42c44b007..7ed01f424 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -40,7 +40,7 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_H
#define RENDER_WIDGET_HOST_VIEW_QT_H
-#include "compositor/display_frame_sink.h"
+#include "compositor/compositor.h"
#include "delegated_frame_host_client_qt.h"
#include "render_widget_host_view_qt_delegate.h"
@@ -81,15 +81,8 @@ class RenderWidgetHostViewQt
, public ui::GestureProviderClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
, public content::TextInputManager::Observer
- , public DisplayConsumer
{
public:
- enum LoadVisuallyCommittedState {
- NotCommitted,
- DidFirstVisuallyNonEmptyPaint,
- DidFirstCompositorFrameSwap
- };
-
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
~RenderWidgetHostViewQt();
@@ -172,11 +165,8 @@ public:
// Overridden from content::RenderFrameMetadataProvider::Observer
void OnRenderFrameMetadataChangedAfterActivation() override;
- // Overridden from DisplayConsumer
- void scheduleUpdate() override;
-
// Called from RenderWidgetHostViewQtDelegateClient.
- QSGNode *updatePaintNode(QSGNode *);
+ Compositor::Id compositorId();
void notifyShown();
void notifyHidden();
bool updateScreenInfo();
@@ -205,7 +195,6 @@ private:
bool isPopup() const;
content::RenderFrameHost *getFocusedFrameHost();
- void callUpdate();
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
ui::FilteredGestureProvider m_gestureProvider;
@@ -221,14 +210,12 @@ private:
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
DelegatedFrameHostClientQt m_delegatedFrameHostClient { this };
- LoadVisuallyCommittedState m_loadVisuallyCommittedState = NotCommitted;
// VIZ
content::ScreenInfo m_screenInfo;
std::unique_ptr<content::DelegatedFrameHost> m_delegatedFrameHost;
std::unique_ptr<ui::Layer> m_rootLayer;
std::unique_ptr<ui::Compositor> m_uiCompositor;
- scoped_refptr<DisplayFrameSink> m_displayFrameSink;
viz::ParentLocalSurfaceIdAllocator m_dfhLocalSurfaceIdAllocator;
viz::ParentLocalSurfaceIdAllocator m_uiCompositorLocalSurfaceIdAllocator;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 0afe258f1..f5227bd52 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -59,13 +59,8 @@
#include <QtGui/QImage>
QT_BEGIN_NAMESPACE
-class QSGImageNode;
-class QSGLayer;
-class QSGRectangleNode;
-class QSGTexture;
class QWheelEvent;
class QWindow;
-
QT_END_NAMESPACE
namespace QtWebEngineCore {
@@ -84,11 +79,6 @@ public:
virtual void hide() = 0;
virtual bool isVisible() const = 0;
virtual QWindow* window() const = 0;
- virtual QSGTexture *createTextureFromImage(const QImage &) = 0;
- virtual QSGLayer *createLayer() = 0;
- virtual QSGImageNode *createImageNode() = 0;
- virtual QSGRectangleNode *createRectangleNode() = 0;
- virtual void update() = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
virtual void move(const QPoint &) = 0;
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index d7674fd13..bee4bc4c2 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -204,9 +204,9 @@ RenderWidgetHostViewQtDelegateClient::RenderWidgetHostViewQtDelegateClient(
context && context->hasCapability(QPlatformInputContext::HiddenTextCapability);
}
-QSGNode *RenderWidgetHostViewQtDelegateClient::updatePaintNode(QSGNode *oldNode)
+Compositor::Id RenderWidgetHostViewQtDelegateClient::compositorId()
{
- return m_rwhv->updatePaintNode(oldNode);
+ return m_rwhv->compositorId();
}
void RenderWidgetHostViewQtDelegateClient::notifyShown()
diff --git a/src/core/render_widget_host_view_qt_delegate_client.h b/src/core/render_widget_host_view_qt_delegate_client.h
index bb14fe951..f67bed861 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.h
+++ b/src/core/render_widget_host_view_qt_delegate_client.h
@@ -51,14 +51,13 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_CLIENT_H
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_CLIENT_H
-#include "qtwebenginecoreglobal_p.h"
+#include "compositor/compositor.h"
#include <QtGui/QCursor>
#include <QtGui/QTouchEvent>
QT_BEGIN_NAMESPACE
class QEvent;
-class QSGNode;
class QVariant;
class QMouseEvent;
@@ -88,7 +87,7 @@ class Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegateClient
public:
RenderWidgetHostViewQtDelegateClient(RenderWidgetHostViewQt *rwhv);
- QSGNode *updatePaintNode(QSGNode *);
+ Compositor::Id compositorId();
void notifyShown();
void notifyHidden();
void visualPropertiesChanged();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 04df99f0e..78040cc8d 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -465,7 +465,7 @@ public:
virtual QColor backgroundColor() const = 0;
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
virtual void loadCommitted() = 0;
- virtual void loadVisuallyCommitted() = 0;
+ virtual void didFirstVisuallyNonEmptyPaint() = 0;
virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) = 0;
virtual void focusContainer() = 0;
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 7fddb16a9..8a426c887 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -482,11 +482,29 @@ void QQuickWebEngineViewPrivate::loadCommitted()
m_history->reset();
}
-void QQuickWebEngineViewPrivate::loadVisuallyCommitted()
+void QQuickWebEngineViewPrivate::didFirstVisuallyNonEmptyPaint()
{
#if QT_CONFIG(webengine_testsupport)
- if (m_testSupport)
- Q_EMIT m_testSupport->loadVisuallyCommitted();
+ if (m_loadVisuallyCommittedState == NotCommitted) {
+ m_loadVisuallyCommittedState = DidFirstVisuallyNonEmptyPaint;
+ } else if (m_loadVisuallyCommittedState == DidFirstCompositorFrameSwap) {
+ if (m_testSupport)
+ Q_EMIT m_testSupport->loadVisuallyCommitted();
+ m_loadVisuallyCommittedState = NotCommitted;
+ }
+#endif
+}
+
+void QQuickWebEngineViewPrivate::didCompositorFrameSwap()
+{
+#if QT_CONFIG(webengine_testsupport)
+ if (m_loadVisuallyCommittedState == NotCommitted) {
+ m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
+ } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) {
+ if (m_testSupport)
+ Q_EMIT m_testSupport->loadVisuallyCommitted();
+ m_loadVisuallyCommittedState = NotCommitted;
+ }
#endif
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 9dbb8cffc..86b7145db 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -59,6 +59,10 @@
#include "qquickwebengineprofile.h"
#include "qquickwebenginescript.h"
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegateQuick;
+}
+
QT_BEGIN_NAMESPACE
class QQmlWebChannel;
@@ -603,6 +607,7 @@ private:
Q_DECLARE_PRIVATE(QQuickWebEngineView)
QScopedPointer<QQuickWebEngineViewPrivate> d_ptr;
+ friend class QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick;
friend class QQuickContextMenuBuilder;
friend class QQuickWebEngineNewViewRequest;
friend class QQuickWebEngineFaviconProvider;
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 68d65410a..bfed75f45 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -115,7 +115,7 @@ public:
QColor backgroundColor() const override;
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override;
- void loadVisuallyCommitted() override;
+ void didFirstVisuallyNonEmptyPaint() override;
void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
@@ -173,6 +173,8 @@ public:
void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidgetBase) override;
void findTextFinished(const QWebEngineFindTextResult &result) override;
+ void didCompositorFrameSwap();
+
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
void setProfile(QQuickWebEngineProfile *profile);
@@ -223,12 +225,19 @@ public:
bool profileInitialized() const;
private:
+ enum LoadVisuallyCommittedState {
+ NotCommitted,
+ DidFirstVisuallyNonEmptyPaint,
+ DidFirstCompositorFrameSwap
+ };
+
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
QList<QQuickWebEngineScript *> m_userScripts;
QColor m_backgroundColor;
qreal m_zoomFactor;
bool m_ui2Enabled;
bool m_profileInitialized;
+ LoadVisuallyCommittedState m_loadVisuallyCommittedState = NotCommitted;
};
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index c0d4dd4a5..9ed660f2e 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -85,10 +85,12 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
}
#endif
+ bind(client->compositorId());
}
RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
{
+ unbind();
QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
}
@@ -167,30 +169,10 @@ QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
return QQuickItem::window();
}
-QSGTexture *RenderWidgetHostViewQtDelegateQuick::createTextureFromImage(const QImage &image)
+void RenderWidgetHostViewQtDelegateQuick::readyToSwap()
{
- return QQuickItem::window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
-}
-
-QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
- return renderContext->sceneGraphContext()->createLayer(renderContext);
-}
-
-QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
-{
- return QQuickItem::window()->createImageNode();
-}
-
-QSGRectangleNode *RenderWidgetHostViewQtDelegateQuick::createRectangleNode()
-{
- return QQuickItem::window()->createRectangleNode();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::update()
-{
- QQuickItem::update();
+ // Call update() on UI thread.
+ QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
}
void RenderWidgetHostViewQtDelegateQuick::updateCursor(const QCursor &cursor)
@@ -345,6 +327,8 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
disconnect(c);
m_windowConnections.clear();
if (value.window) {
+ m_windowConnections.append(connect(value.window, SIGNAL(beforeRendering()),
+ SLOT(onBeforeRendering()), Qt::DirectConnection));
m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
m_windowConnections.append(connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
if (!m_isPopup)
@@ -359,7 +343,58 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
- return m_client->updatePaintNode(oldNode);
+ auto comp = compositor();
+ if (!comp)
+ return nullptr;
+
+ QQuickWindow *win = QQuickItem::window();
+
+ // Delete old node before swapFrame to decrement refcount of
+ // QImage in software mode.
+ delete oldNode;
+ QSGImageNode *node = win->createImageNode();
+ node->setOwnsTexture(true);
+
+ comp->swapFrame();
+
+ if (comp->type() == Compositor::Type::Software) {
+ QImage image = comp->image();
+ float pixPerDip = comp->devicePixelRatio();
+ QSizeF sizeInDips = QSizeF(image.size()) / pixPerDip;
+ node->setRect(QRectF(QPointF(0, 0), sizeInDips));
+ node->setTexture(win->createTextureFromImage(image));
+ } else if (comp->type() == Compositor::Type::OpenGL) {
+ QSize texSize = comp->textureSize();
+ float pixPerDip = comp->devicePixelRatio();
+ QSizeF sizeInDips = QSizeF(texSize) / pixPerDip;
+ node->setRect(QRectF(QPointF(0, 0), sizeInDips));
+ QQuickWindow::CreateTextureOptions texOpts;
+ if (comp->hasAlphaChannel())
+ texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
+ int texId = comp->textureId();
+ node->setTexture(win->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
+ texId, 0, texSize, texOpts));
+ node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
+ } else {
+ Q_UNREACHABLE();
+ }
+
+#if QT_CONFIG(webengine_testsupport)
+ if (m_view)
+ QMetaObject::invokeMethod(
+ m_view, [view = m_view]() { view->d_ptr->didCompositorFrameSwap(); },
+ Qt::QueuedConnection);
+#endif
+
+ return node;
+}
+
+void RenderWidgetHostViewQtDelegateQuick::onBeforeRendering()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::OpenGL)
+ return;
+ comp->waitForTexture();
}
void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index feea10017..cb38ebd20 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -40,6 +40,7 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
+#include "compositor/compositor.h"
#include "render_widget_host_view_qt_delegate.h"
#include <QAccessibleObject>
@@ -55,7 +56,9 @@ namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateClient;
-class RenderWidgetHostViewQtDelegateQuick : public QQuickItem, public RenderWidgetHostViewQtDelegate
+class RenderWidgetHostViewQtDelegateQuick : public QQuickItem,
+ public RenderWidgetHostViewQtDelegate,
+ public Compositor::Observer
{
Q_OBJECT
public:
@@ -73,11 +76,6 @@ public:
void hide() override;
bool isVisible() const override;
QWindow* window() const override;
- QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
- QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
- void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
void move(const QPoint&) override { }
@@ -87,6 +85,8 @@ public:
void setClearColor(const QColor &) override { }
bool copySurface(const QRect &rect, const QSize &size, QImage &image) override;
+ void readyToSwap() override;
+
protected:
bool event(QEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
@@ -107,6 +107,7 @@ protected:
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private slots:
+ void onBeforeRendering();
void onWindowPosChanged();
void onHide();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index 1de4d8835..0b7e736ad 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -121,32 +121,6 @@ QWindow *RenderWidgetHostViewQtDelegateQuickWindow::window() const
return const_cast<RenderWidgetHostViewQtDelegateQuickWindow*>(this);
}
-QSGTexture *RenderWidgetHostViewQtDelegateQuickWindow::createTextureFromImage(const QImage &image)
-{
- return m_realDelegate->createTextureFromImage(image);
-}
-
-QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer()
-{
- return m_realDelegate->createLayer();
-}
-
-QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode()
-{
- return m_realDelegate->createImageNode();
-}
-
-QSGRectangleNode *RenderWidgetHostViewQtDelegateQuickWindow::createRectangleNode()
-{
- return m_realDelegate->createRectangleNode();
-}
-
-void RenderWidgetHostViewQtDelegateQuickWindow::update()
-{
- QQuickWindow::update();
- m_realDelegate->update();
-}
-
void RenderWidgetHostViewQtDelegateQuickWindow::updateCursor(const QCursor &cursor)
{
setCursor(cursor);
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index bebbfa439..cff189d1c 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -66,11 +66,6 @@ public:
void hide() override;
bool isVisible() const override;
QWindow* window() const override;
- QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
- QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
- void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
void move(const QPoint &screenPos) override;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 3ddf4b3d6..847684198 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -106,7 +106,7 @@ public:
QColor backgroundColor() const override;
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override { }
- void loadVisuallyCommitted() override { }
+ void didFirstVisuallyNonEmptyPaint() override { }
void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index a52fdef00..853553c47 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -56,14 +56,19 @@
namespace QtWebEngineCore {
-class RenderWidgetHostViewQuickItem : public QQuickItem {
+class RenderWidgetHostViewQuickItem : public QQuickItem, public Compositor::Observer
+{
public:
RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client)
{
setFlag(ItemHasContents, true);
// Mark that this item should receive focus when the parent QQuickWidget receives focus.
setFocus(true);
+
+ bind(client->compositorId());
}
+ ~RenderWidgetHostViewQuickItem() { unbind(); }
+
protected:
bool event(QEvent *event) override
{
@@ -84,17 +89,80 @@ protected:
{
m_client->forwardEvent(event);
}
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
+ void itemChange(ItemChange change, const ItemChangeData &value) override
{
- return m_client->updatePaintNode(oldNode);
+ QQuickItem::itemChange(change, value);
+ if (change == QQuickItem::ItemSceneChange) {
+ for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
+ disconnect(c);
+ m_windowConnections.clear();
+ if (value.window) {
+ m_windowConnections.append(connect(
+ value.window, &QQuickWindow::beforeRendering, this,
+ &RenderWidgetHostViewQuickItem::onBeforeRendering, Qt::DirectConnection));
+ }
+ }
}
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
+ {
+ auto comp = compositor();
+ if (!comp)
+ return nullptr;
+
+ QQuickWindow *win = QQuickItem::window();
+
+ // Delete old node before swapFrame to decrement refcount of
+ // QImage in software mode.
+ delete oldNode;
+ QSGImageNode *node = win->createImageNode();
+ node->setOwnsTexture(true);
+
+ comp->swapFrame();
+
+ if (comp->type() == Compositor::Type::Software) {
+ QImage image = comp->image();
+ float pixPerDip = comp->devicePixelRatio();
+ QSizeF sizeInDips = QSizeF(image.size()) / pixPerDip;
+ node->setRect(QRectF(QPointF(0, 0), sizeInDips));
+ node->setTexture(win->createTextureFromImage(image));
+ } else if (comp->type() == Compositor::Type::OpenGL) {
+ QSize texSize = comp->textureSize();
+ float pixPerDip = comp->devicePixelRatio();
+ QSizeF sizeInDips = QSizeF(texSize) / pixPerDip;
+ node->setRect(QRectF(QPointF(0, 0), sizeInDips));
+ QQuickWindow::CreateTextureOptions texOpts;
+ if (comp->hasAlphaChannel())
+ texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
+ int texId = comp->textureId();
+ node->setTexture(win->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
+ texId, 0, texSize, texOpts));
+ node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
+ } else {
+ Q_UNREACHABLE();
+ }
+ return node;
+ }
+ void onBeforeRendering()
+ {
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::OpenGL)
+ return;
+ comp->waitForTexture();
+ }
QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
{
return m_client->inputMethodQuery(query);
}
+ void readyToSwap() override
+ {
+ // Call update() on UI thread.
+ QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
+ }
+
private:
RenderWidgetHostViewQtDelegateClient *m_client;
+ QList<QMetaObject::Connection> m_windowConnections;
};
RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
@@ -293,32 +361,6 @@ QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
return root ? root->windowHandle() : 0;
}
-QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const QImage &image)
-{
- return quickWindow()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
-}
-
-QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
- return renderContext->sceneGraphContext()->createLayer(renderContext);
-}
-
-QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
-{
- return quickWindow()->createImageNode();
-}
-
-QSGRectangleNode *RenderWidgetHostViewQtDelegateWidget::createRectangleNode()
-{
- return quickWindow()->createRectangleNode();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::update()
-{
- m_rootItem->update();
-}
-
void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor)
{
QQuickWidget::setCursor(cursor);
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 034fdd65c..57b272183 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -79,11 +79,6 @@ public:
void hide() override;
bool isVisible() const override;
QWindow* window() const override;
- QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
- QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
- void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
void move(const QPoint &screenPos) override;