summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorArvid Nilsson <anilsson@blackberry.com>2013-12-13 15:57:26 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-31 17:31:13 +0100
commita4b0e2183c23c0173167833c75f0e2970f3ab524 (patch)
tree43d60fee79115c6634991696e3db1c152eafcc4a /src/core
parentf55df93be18e990d6f8daf7f691c75303c57ad5f (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.cpp29
-rw-r--r--src/core/delegated_frame_node.h14
-rw-r--r--src/core/render_widget_host_view_qt.cpp53
-rw-r--r--src/core/render_widget_host_view_qt.h9
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h4
-rw-r--r--src/core/web_contents_adapter.cpp12
-rw-r--r--src/core/web_contents_adapter.h3
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: