summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/compositor.cpp170
-rw-r--r--src/core/compositor.h120
-rw-r--r--src/core/core_chromium.pri2
-rw-r--r--src/core/render_widget_host_view_qt.cpp85
-rw-r--r--src/core/render_widget_host_view_qt.h19
5 files changed, 303 insertions, 93 deletions
diff --git a/src/core/compositor.cpp b/src/core/compositor.cpp
new file mode 100644
index 00000000..20d956ab
--- /dev/null
+++ b/src/core/compositor.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** 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.h"
+
+#include "delegated_frame_node.h"
+
+#include <components/viz/common/resources/returned_resource.h>
+#include <content/public/browser/browser_thread.h>
+#include <services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h>
+
+namespace QtWebEngineCore {
+
+Compositor::Compositor()
+ : m_chromiumCompositorData(new ChromiumCompositorData)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ base::SingleThreadTaskRunner *taskRunner =
+ content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI).get();
+ m_beginFrameSource =
+ std::make_unique<viz::DelayBasedBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(taskRunner),
+ viz::BeginFrameSource::kNotRestartableId);
+}
+
+Compositor::~Compositor()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
+
+void Compositor::setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_viewDelegate = viewDelegate;
+}
+
+void Compositor::setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (m_frameSinkClient == frameSinkClient)
+ return;
+
+ // Accumulated resources belong to the old RendererCompositorFrameSink and
+ // should not be returned.
+ //
+ // TODO(juvaldma): Can there be a pending frame from the old client?
+ m_resourcesToRelease.clear();
+ m_frameSinkClient = frameSinkClient;
+}
+
+void Compositor::setNeedsBeginFrames(bool needsBeginFrames)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (m_needsBeginFrames == needsBeginFrames)
+ return;
+
+ if (needsBeginFrames)
+ m_beginFrameSource->AddObserver(this);
+ else
+ m_beginFrameSource->RemoveObserver(this);
+
+ m_needsBeginFrames = needsBeginFrames;
+}
+
+void Compositor::submitFrame(viz::CompositorFrame frame)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!m_havePendingFrame);
+
+ m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor;
+ m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData);
+ m_chromiumCompositorData->frameData = std::move(frame);
+ m_havePendingFrame = true;
+
+ // Tell viewDelegate to call updatePaintNode() soon.
+ m_viewDelegate->update();
+}
+
+QSGNode *Compositor::updatePaintNode(QSGNode *oldNode)
+{
+ // 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;
+
+ frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_viewDelegate);
+
+ if (m_havePendingFrame) {
+ m_havePendingFrame = false;
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
+ }
+
+ return frameNode;
+}
+
+void Compositor::notifyFrameCommitted()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_beginFrameSource->DidFinishFrame(this);
+ if (m_frameSinkClient)
+ m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourcesToRelease);
+ m_resourcesToRelease.clear();
+}
+
+bool Compositor::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
+ if (m_frameSinkClient)
+ m_frameSinkClient->OnBeginFrame(args);
+
+ return true;
+}
+
+void Compositor::OnBeginFrameSourcePausedChanged(bool)
+{
+ // 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.
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor.h b/src/core/compositor.h
new file mode 100644
index 00000000..4456c648
--- /dev/null
+++ b/src/core/compositor.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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_H
+#define COMPOSITOR_H
+
+#include <base/memory/weak_ptr.h>
+#include <components/viz/common/frame_sinks/begin_frame_source.h>
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+class QSGNode;
+QT_END_NAMESPACE
+
+namespace viz {
+class CompositorFrame;
+struct ReturnedResource;
+namespace mojom {
+class CompositorFrameSinkClient;
+} // namespace mojom
+} // namespace viz
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegate;
+class ChromiumCompositorData;
+
+// 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.
+//
+// Step 2. Once the new frame is ready to be rendered, Compositor will call
+// update() on the delegate.
+//
+// Step 3. Once the delegate 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
+{
+public:
+ explicit Compositor();
+ ~Compositor() override;
+
+ void setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate);
+ void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient);
+ void setNeedsBeginFrames(bool needsBeginFrames);
+
+ void submitFrame(viz::CompositorFrame frame);
+
+ QSGNode *updatePaintNode(QSGNode *oldNode);
+
+private:
+ void notifyFrameCommitted();
+
+ // viz::BeginFrameObserverBase
+ bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) override;
+ void OnBeginFrameSourcePausedChanged(bool paused) override;
+
+ std::vector<viz::ReturnedResource> m_resourcesToRelease;
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
+ RenderWidgetHostViewQtDelegate *m_viewDelegate = nullptr;
+ std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
+ viz::mojom::CompositorFrameSinkClient *m_frameSinkClient = nullptr;
+ bool m_havePendingFrame = false;
+ bool m_needsBeginFrames = false;
+
+ base::WeakPtrFactory<Compositor> m_weakPtrFactory{this};
+
+ DISALLOW_COPY_AND_ASSIGN(Compositor);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_H
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index a3f9f5c8..92ab80c6 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -53,6 +53,7 @@ SOURCES = \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
+ compositor.cpp \
content_client_qt.cpp \
content_browser_client_qt.cpp \
content_main_delegate_qt.cpp \
@@ -139,6 +140,7 @@ HEADERS = \
color_chooser_controller.h \
common/qt_messages.h \
common/user_script_data.h \
+ compositor.h \
content_client_qt.h \
content_browser_client_qt.h \
content_main_delegate_qt.h \
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 7d70da9e..a3c5b06d 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -43,7 +43,7 @@
#include "browser_accessibility_manager_qt.h"
#include "browser_accessibility_qt.h"
#include "chromium_overrides.h"
-#include "delegated_frame_node.h"
+#include "compositor.h"
#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
@@ -324,17 +324,12 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
, m_touchMotionStarted(false)
- , m_chromiumCompositorData(new ChromiumCompositorData)
- , m_needsDelegatedFrameAck(false)
+ , m_compositor(new Compositor)
, m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
- , m_rendererCompositorFrameSink(0)
, m_imeInProgress(false)
, m_receivedEmptyImeEvent(false)
, m_initPending(false)
- , m_beginFrameSource(nullptr)
- , m_needsBeginFrames(false)
- , m_addedFrameObserver(false)
, m_backgroundColor(SK_ColorWHITE)
, m_imState(0)
, m_anchorPositionWithinSelection(-1)
@@ -343,10 +338,6 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_emptyPreviousSelection(true)
, m_wheelAckPending(false)
{
- auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
- m_beginFrameSource.reset(new viz::DelayBasedBeginFrameSource(
- std::make_unique<viz::DelayBasedTimeSource>(task_runner), 0));
-
host()->SetView(this);
#ifndef QT_NO_ACCESSIBILITY
if (isAccessibilityEnabled()) {
@@ -377,6 +368,7 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate)
{
m_delegate.reset(delegate);
+ m_compositor->setViewDelegate(delegate);
}
void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterClient)
@@ -751,10 +743,7 @@ void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_te
void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSink)
{
- // Accumulated resources belong to the old RendererCompositorFrameSink and
- // should not be returned.
- m_resourcesToRelease.clear();
- m_rendererCompositorFrameSink = frameSink;
+ m_compositor->setFrameSinkClient(frameSink);
}
void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, viz::mojom::HitTestRegionListPtr)
@@ -769,11 +758,6 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
// FIXME: update frame_size and device_scale_factor?
// FIXME: showPrimarySurface()?
}
- Q_ASSERT(!m_needsDelegatedFrameAck);
- m_needsDelegatedFrameAck = true;
- m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData);
- m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor;
- m_chromiumCompositorData->frameData = std::move(frame);
// Force to process swap messages
uint32_t frame_token = frame.metadata.frame_token;
@@ -783,9 +767,9 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
// Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
float dpiScale = this->dpiScale();
if (dpiScale != 0 && dpiScale != 1)
- m_chromiumCompositorData->frameDevicePixelRatio /= dpiScale;
+ frame.metadata.device_scale_factor /= dpiScale;
- m_delegate->update();
+ m_compositor->submitFrame(std::move(frame));
if (m_loadVisuallyCommittedState == NotCommitted) {
m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
@@ -977,21 +961,7 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
{
- DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
- if (!frameNode)
- frameNode = new DelegatedFrameNode;
-
- frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_delegate.get());
-
- // This is possibly called from the Qt render thread, post the ack back to the UI
- // to tell the child compositors to release resources and trigger a new frame.
- if (m_needsDelegatedFrameAck) {
- m_needsDelegatedFrameAck = false;
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(&RenderWidgetHostViewQt::sendDelegatedFrameAck, AsWeakPtr()));
- }
-
- return frameNode;
+ return m_compositor->updatePaintNode(oldNode);
}
void RenderWidgetHostViewQt::notifyResize()
@@ -1192,15 +1162,6 @@ void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWit
m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, /*fixme: ?? */false);
}
-void RenderWidgetHostViewQt::sendDelegatedFrameAck()
-{
- m_beginFrameSource->DidFinishFrame(this);
- std::vector<viz::ReturnedResource> resources;
- m_resourcesToRelease.swap(resources);
- if (m_rendererCompositorFrameSink)
- m_rendererCompositorFrameSink->DidReceiveCompositorFrameAck(resources);
-}
-
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
{
auto result = m_gestureProvider.OnTouchEvent(motionEvent);
@@ -1713,37 +1674,7 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames)
{
- m_needsBeginFrames = needs_begin_frames;
- updateNeedsBeginFramesInternal();
-}
-
-void RenderWidgetHostViewQt::updateNeedsBeginFramesInternal()
-{
- Q_ASSERT(m_beginFrameSource);
-
- if (m_addedFrameObserver == m_needsBeginFrames)
- return;
-
- if (m_needsBeginFrames)
- m_beginFrameSource->AddObserver(this);
- else
- m_beginFrameSource->RemoveObserver(this);
- m_addedFrameObserver = m_needsBeginFrames;
-}
-
-bool RenderWidgetHostViewQt::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args)
-{
- m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
- if (m_rendererCompositorFrameSink)
- m_rendererCompositorFrameSink->OnBeginFrame(args);
- return true;
-}
-
-void RenderWidgetHostViewQt::OnBeginFrameSourcePausedChanged(bool paused)
-{
- // 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.
+ m_compositor->setNeedsBeginFrames(needs_begin_frames);
}
content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 664359eb..909b3bd8 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -58,8 +58,6 @@
#include <QtGui/qaccessible.h>
#include <QtGui/QTouchEvent>
-#include "delegated_frame_node.h"
-
QT_BEGIN_NAMESPACE
class QAccessibleInterface;
QT_END_NAMESPACE
@@ -71,6 +69,8 @@ class RenderWidgetHostImpl;
namespace QtWebEngineCore {
+class Compositor;
+
struct MultipleMouseClickHelper
{
QPoint lastPressPosition;
@@ -92,7 +92,6 @@ class RenderWidgetHostViewQt
, public ui::GestureProviderClient
, public RenderWidgetHostViewQtDelegateClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
- , public viz::BeginFrameObserverBase
#ifndef QT_NO_ACCESSIBILITY
, public QAccessible::ActivationObserver
#endif // QT_NO_ACCESSIBILITY
@@ -173,10 +172,6 @@ public:
void OnSelectionBoundsChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
void OnTextSelectionChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
- // cc::BeginFrameObserverBase implementation.
- bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
- void OnBeginFrameSourcePausedChanged(bool paused) override;
-
void handleMouseEvent(QMouseEvent*);
void handleKeyEvent(QKeyEvent*);
void handleWheelEvent(QWheelEvent*);
@@ -213,7 +208,6 @@ public:
gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; }
private:
- void sendDelegatedFrameAck();
void processMotionEvent(const ui::MotionEvent &motionEvent);
void clearPreviousTouchMotionState();
QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints);
@@ -234,15 +228,12 @@ private:
QList<QTouchEvent::TouchPoint> m_previousTouchPoints;
std::unique_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
- QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
- std::vector<viz::ReturnedResource> m_resourcesToRelease;
- bool m_needsDelegatedFrameAck;
+ std::unique_ptr<Compositor> m_compositor;
LoadVisuallyCommittedState m_loadVisuallyCommittedState;
QMetaObject::Connection m_adapterClientDestroyedConnection;
WebContentsAdapterClient *m_adapterClient;
MultipleMouseClickHelper m_clickHelper;
- viz::mojom::CompositorFrameSinkClient *m_rendererCompositorFrameSink;
bool m_imeInProgress;
bool m_receivedEmptyImeEvent;
@@ -250,10 +241,6 @@ private:
bool m_initPending;
- std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
- bool m_needsBeginFrames;
- bool m_addedFrameObserver;
-
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
SkColor m_backgroundColor;