diff options
author | Arvid Nilsson <anilsson@blackberry.com> | 2013-12-13 15:57:26 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-31 17:31:13 +0100 |
commit | a4b0e2183c23c0173167833c75f0e2970f3ab524 (patch) | |
tree | 43d60fee79115c6634991696e3db1c152eafcc4a /src/core | |
parent | f55df93be18e990d6f8daf7f691c75303c57ad5f (diff) |
Quick: Support reparenting
To support reparenting, we make the compositing surface independent of
the window by using gfx::TEXTURE_TRANSPORT. We also need to be able to
keep frame data across window changes so we can reconstruct the QSGNode
tree in a new context, so extract that data into DelegatedFrameNodeData
class. Any context-specific data is still stored in DelegatedFrameNode.
Also hook up window changes to WebContents::WasShown/Hidden for Quick.
Remove checking of Qt isVisible state, this mechanism is used to sync
Chromium with Qt, not the other way around. WasShown/Hidden is
orthogonal to Show/Hide, and can use different triggers. However for
Widgets it probably makes sense to hook both up to widget visibility.
Change-Id: I1ef4b50cd61b8e54b791e03f0b41929c42fec8bf
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/delegated_frame_node.cpp | 29 | ||||
-rw-r--r-- | src/core/delegated_frame_node.h | 14 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 53 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.h | 9 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt_delegate.h | 4 | ||||
-rw-r--r-- | src/core/web_contents_adapter.cpp | 12 | ||||
-rw-r--r-- | src/core/web_contents_adapter.h | 3 |
7 files changed, 73 insertions, 51 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index c770f388d..c7d3d7e27 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -293,7 +293,7 @@ void DelegatedFrameNode::preprocess() // We can now wait for the Chromium GPU thread to produce textures that will be // rendered on our quads and fetch the IDs from the mailboxes we were given. QList<MailboxTexture *> mailboxesToFetch; - Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, m_mailboxTextures.values()) + Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, m_data->mailboxTextures.values()) if (mailboxTexture->needsToFetch()) mailboxesToFetch.append(mailboxTexture.data()); @@ -315,13 +315,18 @@ void DelegatedFrameNode::preprocess() renderPass->grab(); } -void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::TransferableResourceArray *resourcesToRelease) +void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease) { + m_data = data; + cc::DelegatedFrameData* frameData = m_data->frameData.get(); + if (!frameData) + return; + // Keep the old texture lists around to find the ones we can re-use. QList<QSharedPointer<RenderPassTexture> > oldRenderPassTextures; m_renderPassTextures.swap(oldRenderPassTextures); - QMap<int, QSharedPointer<MailboxTexture> > mailboxTextureCandidates; - m_mailboxTextures.swap(mailboxTextureCandidates); + QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextureCandidates; + m_data->mailboxTextures.swap(mailboxTextureCandidates); // A frame's resource_list only contains the new resources to be added to the scene. Quads can // still reference resources that were added in previous frames. Add them to the list of @@ -332,6 +337,8 @@ void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::Transfera mailboxTextureCandidates[res.id] = QSharedPointer<MailboxTexture>(new MailboxTexture(res)); } + frameData->resource_list.clear(); + // The RenderPasses list is actually a tree where a parent RenderPass is connected // to its dependencies through a RenderPass::Id reference in one or more RenderPassQuads. // The list is already ordered with intermediate RenderPasses placed before their @@ -392,7 +399,7 @@ void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::Transfera break; } case cc::DrawQuad::TEXTURE_CONTENT: { const cc::TextureDrawQuad *tquad = cc::TextureDrawQuad::MaterialCast(quad); - QSharedPointer<MailboxTexture> &texture = m_mailboxTextures[tquad->resource_id] = mailboxTextureCandidates.take(tquad->resource_id); + QSharedPointer<MailboxTexture> &texture = m_data->mailboxTextures[tquad->resource_id] = mailboxTextureCandidates.take(tquad->resource_id); Q_ASSERT(texture); // FIXME: TransferableResource::size isn't always set properly for TextureDrawQuads, use the size of its DrawQuad::rect instead. @@ -431,7 +438,7 @@ void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::Transfera break; } case cc::DrawQuad::TILED_CONTENT: { const cc::TileDrawQuad *tquad = cc::TileDrawQuad::MaterialCast(quad); - QSharedPointer<MailboxTexture> &texture = m_mailboxTextures[tquad->resource_id] = mailboxTextureCandidates.take(tquad->resource_id); + QSharedPointer<MailboxTexture> &texture = m_data->mailboxTextures[tquad->resource_id] = mailboxTextureCandidates.take(tquad->resource_id); Q_ASSERT(texture); if (!quad->visible_rect.IsEmpty() && !quad->opaque_rect.Contains(quad->visible_rect)) @@ -449,16 +456,16 @@ void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::Transfera break; } case cc::DrawQuad::YUV_VIDEO_CONTENT: { const cc::YUVVideoDrawQuad *vquad = cc::YUVVideoDrawQuad::MaterialCast(quad); - QSharedPointer<MailboxTexture> &yTexture = m_mailboxTextures[vquad->y_plane_resource_id] = mailboxTextureCandidates.take(vquad->y_plane_resource_id); - QSharedPointer<MailboxTexture> &uTexture = m_mailboxTextures[vquad->u_plane_resource_id] = mailboxTextureCandidates.take(vquad->u_plane_resource_id); - QSharedPointer<MailboxTexture> &vTexture = m_mailboxTextures[vquad->v_plane_resource_id] = mailboxTextureCandidates.take(vquad->v_plane_resource_id); + QSharedPointer<MailboxTexture> &yTexture = m_data->mailboxTextures[vquad->y_plane_resource_id] = mailboxTextureCandidates.take(vquad->y_plane_resource_id); + QSharedPointer<MailboxTexture> &uTexture = m_data->mailboxTextures[vquad->u_plane_resource_id] = mailboxTextureCandidates.take(vquad->u_plane_resource_id); + QSharedPointer<MailboxTexture> &vTexture = m_data->mailboxTextures[vquad->v_plane_resource_id] = mailboxTextureCandidates.take(vquad->v_plane_resource_id); Q_ASSERT(yTexture && uTexture && vTexture); // Do not use a reference for this one, it might be null. QSharedPointer<MailboxTexture> aTexture; // This currently requires --enable-vp8-alpha-playback and needs a video with alpha data to be triggered. if (vquad->a_plane_resource_id) - aTexture = m_mailboxTextures[vquad->a_plane_resource_id] = mailboxTextureCandidates.take(vquad->a_plane_resource_id); + aTexture = m_data->mailboxTextures[vquad->a_plane_resource_id] = mailboxTextureCandidates.take(vquad->a_plane_resource_id); YUVVideoNode *videoNode = new YUVVideoNode(yTexture.data(), uTexture.data(), vTexture.data(), aTexture.data(), toQt(vquad->tex_scale)); videoNode->setRect(toQt(quad->rect)); @@ -481,7 +488,7 @@ void DelegatedFrameNode::commit(cc::DelegatedFrameData *frameData, cc::Transfera // for us (mainly to clean the output of --enable-gpu-service-logging). mailboxTexture->resource().sync_point = 0; - resourcesToRelease->push_back(mailboxTexture->resource()); + resourcesToRelease->push_back(mailboxTexture->resource().ToReturnedResource()); } } diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index b73370874..2a4ae53d0 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -42,9 +42,11 @@ #ifndef DELEGATED_FRAME_NODE_H #define DELEGATED_FRAME_NODE_H +#include "base/memory/scoped_ptr.h" #include "cc/resources/transferable_resource.h" #include <QMutex> #include <QSGNode> +#include <QSharedData> #include <QSharedPointer> #include <QWaitCondition> @@ -61,17 +63,25 @@ class DelegatedFrameData; class MailboxTexture; class RenderPassTexture; +// Separating this data allows another DelegatedFrameNode to reconstruct the QSGNode tree from the mailbox textures +// and render pass information. +class DelegatedFrameNodeData : public QSharedData { +public: + QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextures; + scoped_ptr<cc::DelegatedFrameData> frameData; +}; + class DelegatedFrameNode : public QSGNode { public: DelegatedFrameNode(QQuickWindow *window); ~DelegatedFrameNode(); void preprocess(); - void commit(cc::DelegatedFrameData *frameData, cc::TransferableResourceArray *resourcesToRelease); + void commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease); private: + QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_data; QQuickWindow *m_window; QList<QSharedPointer<RenderPassTexture> > m_renderPassTextures; - QMap<int, QSharedPointer<MailboxTexture> > m_mailboxTextures; int m_numPendingSyncPoints; QWaitCondition m_mailboxesFetchedWaitCond; QMutex m_mutex; diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 0e85c5857..9279c57b0 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -141,11 +141,12 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget : m_host(content::RenderWidgetHostImpl::From(widget)) , m_gestureRecognizer(ui::GestureRecognizer::Create(this)) , m_backingStore(0) + , m_frameNodeData(new DelegatedFrameNodeData) + , m_needsDelegatedFrameAck(false) , m_adapterClient(0) , m_anchorPositionWithinSelection(0) , m_cursorPositionWithinSelection(0) , m_initPending(false) - , m_readyForSurface(false) { m_host->SetView(this); } @@ -244,8 +245,7 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView() const gfx::NativeViewId RenderWidgetHostViewQt::GetNativeViewId() const { - const_cast<RenderWidgetHostViewQt *>(this)->m_readyForSurface = true; - return m_delegate->nativeWindowIdForCompositor(); + return 0; } gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible() @@ -333,17 +333,11 @@ gfx::NativeView RenderWidgetHostViewQt::BuildInputMethodsGtkMenu() void RenderWidgetHostViewQt::WasShown() { - if (m_delegate->isVisible()) - return; - m_host->WasShown(); } void RenderWidgetHostViewQt::WasHidden() { - if (!m_delegate->isVisible()) - return; - m_host->WasHidden(); } @@ -584,10 +578,12 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&) void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { - Q_ASSERT(!m_pendingFrameData); - Q_ASSERT(frame->delegated_frame_data); + Q_ASSERT(!m_needsDelegatedFrameAck); + m_needsDelegatedFrameAck = true; m_pendingOutputSurfaceId = output_surface_id; - m_pendingFrameData = frame->delegated_frame_data.Pass(); + Q_ASSERT(frame->delegated_frame_data); + Q_ASSERT(!m_frameNodeData->frameData || m_frameNodeData->frameData->resource_list.empty()); + m_frameNodeData->frameData = frame->delegated_frame_data.Pass(); m_delegate->update(); } @@ -611,12 +607,9 @@ gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow() gfx::GLSurfaceHandle RenderWidgetHostViewQt::GetCompositingSurface() { - gfx::NativeViewId nativeViewId = GetNativeViewId(); -#if defined(OS_WIN) - return nativeViewId ? gfx::GLSurfaceHandle(reinterpret_cast<gfx::PluginWindowHandle>(nativeViewId), gfx::NATIVE_TRANSPORT) : gfx::GLSurfaceHandle(); -#else - return nativeViewId ? gfx::GLSurfaceHandle(nativeViewId, gfx::NATIVE_TRANSPORT) : gfx::GLSurfaceHandle(); -#endif + if (!m_delegate->supportsHardwareAcceleration()) + return gfx::GLSurfaceHandle(); + return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); } void RenderWidgetHostViewQt::SetHasHorizontalScrollbar(bool) { } @@ -648,20 +641,19 @@ void RenderWidgetHostViewQt::paint(QPainter *painter, const QRectF& boundingRect QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode, QQuickWindow *window) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) - if (!m_pendingFrameData) - return oldNode; - DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode); if (!frameNode) frameNode = new DelegatedFrameNode(window); - frameNode->commit(m_pendingFrameData.get(), &m_resourcesToRelease); - m_pendingFrameData.reset(); + frameNode->commit(m_frameNodeData.data(), &m_resourcesToRelease); // 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. - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&RenderWidgetHostViewQt::sendDelegatedFrameAck, AsWeakPtr())); + if (m_needsDelegatedFrameAck) { + m_needsDelegatedFrameAck = false; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&RenderWidgetHostViewQt::sendDelegatedFrameAck, AsWeakPtr())); + } return frameNode; #else @@ -743,11 +735,10 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) co } } -void RenderWidgetHostViewQt::compositingSurfaceUpdated() +void RenderWidgetHostViewQt::windowChanged() { - // Don't report an update until we get asked at least once. - if (m_readyForSurface) - m_host->CompositingSurfaceUpdated(); + if (m_delegate->window()) + m_host->NotifyScreenInfoChanged(); } void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { @@ -767,12 +758,10 @@ void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWit void RenderWidgetHostViewQt::sendDelegatedFrameAck() { cc::CompositorFrameAck ack; - cc::TransferableResource::ReturnResources(m_resourcesToRelease, &ack.resources); + m_resourcesToRelease.swap(ack.resources); content::RenderWidgetHostImpl::SendSwapCompositorFrameAck( m_host->GetRoutingID(), m_pendingOutputSurfaceId, m_host->GetProcess()->GetID(), ack); - - m_resourcesToRelease.clear(); } void RenderWidgetHostViewQt::Paint(const gfx::Rect& damage_rect) diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 6938b7060..861315e8a 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -48,6 +48,7 @@ #include "base/memory/weak_ptr.h" #include "cc/resources/transferable_resource.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" +#include "delegated_frame_node.h" #include "ui/base/gestures/gesture_recognizer.h" #include "ui/base/gestures/gesture_types.h" #include <QMap> @@ -171,7 +172,7 @@ public: virtual void notifyResize() Q_DECL_OVERRIDE; virtual bool forwardEvent(QEvent *) Q_DECL_OVERRIDE; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE; - virtual void compositingSurfaceUpdated() Q_DECL_OVERRIDE; + virtual void windowChanged() Q_DECL_OVERRIDE; void handleMouseEvent(QMouseEvent*); void handleKeyEvent(QKeyEvent*); @@ -221,8 +222,9 @@ private: scoped_ptr<RenderWidgetHostViewQtDelegate> m_delegate; BackingStoreQt *m_backingStore; - scoped_ptr<cc::DelegatedFrameData> m_pendingFrameData; - cc::TransferableResourceArray m_resourcesToRelease; + QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_frameNodeData; + cc::ReturnedResourceArray m_resourcesToRelease; + bool m_needsDelegatedFrameAck; uint32 m_pendingOutputSurfaceId; WebContentsAdapterClient *m_adapterClient; @@ -234,7 +236,6 @@ private: size_t m_cursorPositionWithinSelection; bool m_initPending; - bool m_readyForSurface; }; #endif // RENDER_WIDGET_HOST_VIEW_QT_H diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 74151fdbf..7ed895f0b 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -68,7 +68,7 @@ public: virtual void notifyResize() = 0; virtual bool forwardEvent(QEvent *) = 0; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const = 0; - virtual void compositingSurfaceUpdated() = 0; + virtual void windowChanged() = 0; }; class QWEBENGINE_EXPORT RenderWidgetHostViewQtDelegate { @@ -82,12 +82,12 @@ public: virtual void show() = 0; virtual void hide() = 0; virtual bool isVisible() const = 0; - virtual WId nativeWindowIdForCompositor() const = 0; virtual QWindow* window() const = 0; virtual void update(const QRect& rect = QRect()) = 0; virtual void updateCursor(const QCursor &) = 0; virtual void resize(int width, int height) = 0; virtual void inputMethodStateChanged(bool editorVisible) = 0; + virtual bool supportsHardwareAcceleration() const = 0; }; #endif // RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_H diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 4c197090c..dfd924e66 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -415,6 +415,18 @@ quint64 WebContentsAdapter::fetchDocumentInnerText() return d->lastRequestId; } +void WebContentsAdapter::wasShown() +{ + Q_D(WebContentsAdapter); + d->webContents->WasShown(); +} + +void WebContentsAdapter::wasHidden() +{ + Q_D(WebContentsAdapter); + d->webContents->WasHidden(); +} + void WebContentsAdapter::dpiScaleChanged() { Q_D(WebContentsAdapter); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index e70aae259..f39599d93 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -89,6 +89,9 @@ public: quint64 fetchDocumentMarkup(); quint64 fetchDocumentInnerText(); + void wasShown(); + void wasHidden(); + void dpiScaleChanged(); private: |