summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-23 07:36:51 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-23 07:36:51 +0000
commit48871fc98f70938072ce94106e75b13fc3e82f42 (patch)
treeae290c35236fc39848ca63ea7e3031f8e3cb59ef
parent4c38c371c94de6a89bc1e1c698de477b6db9fb4c (diff)
downloadchromium_src-48871fc98f70938072ce94106e75b13fc3e82f42.zip
chromium_src-48871fc98f70938072ce94106e75b13fc3e82f42.tar.gz
chromium_src-48871fc98f70938072ce94106e75b13fc3e82f42.tar.bz2
Activate LayerImpl tree with sync+push instead of pointer swap
This changes the activation model to do a push + sync from the pending -> active tree instead of just doing a pointer swap. This fixes behavior for video and scrollbar animations and allows for recycling of the LayerImpl tree from commit to commit. There are several changes: *) The tree synchronization code is templatized to support Layer->LayerImpl and LayerImpl->LayerImpl tree syncs. All LayerImpl subclasses now support a createLayerImpl() call to construct a LayerImpl of matching dynamic type and a LayerImpl::pushPropertiesTo(LayerImpl*) to sync properties. The structural syncing stuff is identical to the existing Layer->LayerImpl sync *) Video layer's provider flow is tweaked. Instead of the VideoLayerImpl being the VideoFrameProvider::Client, a new object VideoFrameProviderClientImpl is. This is constructed initially on the pending tree and associated with the VideoFrameProvider during initial commit (since that happens with the main thread blocked). A reference to this object is passed to the active tree, which then registers itself for setNeedsRedraw notifications when it becomes active. On shutdown, the pending layer's destructor (which always happens first) unhooks the VFPCI from the VideoFrameProvider. This step has to happen during the pending tree commit, not activation, since it has to happen on the impl thread with the main thread blocked. The active VideoLayerImpl can then proceed with a VFPCI that isn't wired up to a VFP until the pending tree is activated, at which point it tears down the VFPCI as well. *) Scrollbar layer IDs are hooked up on the impl thread as well so we can set up the pointers during LayerImpl->LayerImpl tree syncs *) Picture layer syncing is largely unchanged, except that there's new code to do a PictureLayerImpl -> PictureLayerImpl sync. This step simply replaces the active layer's pile and tilings with the pending tree's. BUG=169143 Review URL: https://chromiumcodereview.appspot.com/11882037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178267 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/delegated_renderer_layer_impl.cc5
-rw-r--r--cc/delegated_renderer_layer_impl.h2
-rw-r--r--cc/heads_up_display_layer_impl.cc16
-rw-r--r--cc/heads_up_display_layer_impl.h3
-rw-r--r--cc/io_surface_layer_impl.cc13
-rw-r--r--cc/io_surface_layer_impl.h3
-rw-r--r--cc/layer.cc6
-rw-r--r--cc/layer.h6
-rw-r--r--cc/layer_impl.cc81
-rw-r--r--cc/layer_impl.h19
-rw-r--r--cc/layer_tree_host_impl.cc39
-rw-r--r--cc/layer_tree_host_impl.h11
-rw-r--r--cc/layer_tree_host_impl_unittest.cc2
-rw-r--r--cc/layer_tree_impl.cc8
-rw-r--r--cc/layer_tree_impl.h4
-rw-r--r--cc/nine_patch_layer_impl.cc17
-rw-r--r--cc/nine_patch_layer_impl.h3
-rw-r--r--cc/picture_layer.cc2
-rw-r--r--cc/picture_layer_impl.cc81
-rw-r--r--cc/picture_layer_impl.h8
-rw-r--r--cc/picture_layer_tiling_set.cc6
-rw-r--r--cc/picture_layer_tiling_set.h5
-rw-r--r--cc/picture_pile.cc1
-rw-r--r--cc/picture_pile_impl.cc5
-rw-r--r--cc/picture_pile_impl.h2
-rw-r--r--cc/scrollbar_animation_controller.h1
-rw-r--r--cc/scrollbar_layer_impl.cc27
-rw-r--r--cc/scrollbar_layer_impl.h10
-rw-r--r--cc/solid_color_layer_impl.cc5
-rw-r--r--cc/solid_color_layer_impl.h3
-rw-r--r--cc/texture_layer_impl.cc23
-rw-r--r--cc/texture_layer_impl.h3
-rw-r--r--cc/tiled_layer_impl.cc23
-rw-r--r--cc/tiled_layer_impl.h3
-rw-r--r--cc/tree_synchronizer.cc112
-rw-r--r--cc/tree_synchronizer.h13
-rw-r--r--cc/tree_synchronizer_unittest.cc2
-rw-r--r--cc/video_frame_provider_client_impl.cc87
-rw-r--r--cc/video_frame_provider_client_impl.h62
-rw-r--r--cc/video_layer_impl.cc104
-rw-r--r--cc/video_layer_impl.h29
42 files changed, 687 insertions, 170 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 58bd4ac..02a8b88 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -301,6 +301,8 @@
'tree_synchronizer.h',
'util.h',
'video_frame_provider.h',
+ 'video_frame_provider_client_impl.cc',
+ 'video_frame_provider_client_impl.h',
'video_layer.cc',
'video_layer.h',
'video_layer_impl.cc',
diff --git a/cc/delegated_renderer_layer_impl.cc b/cc/delegated_renderer_layer_impl.cc
index 3c7734f..483a256 100644
--- a/cc/delegated_renderer_layer_impl.cc
+++ b/cc/delegated_renderer_layer_impl.cc
@@ -60,6 +60,11 @@ void DelegatedRendererLayerImpl::ClearRenderPasses() {
render_passes_in_draw_order_.clear();
}
+scoped_ptr<LayerImpl> DelegatedRendererLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return DelegatedRendererLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
void DelegatedRendererLayerImpl::didLoseOutputSurface() {
ClearRenderPasses();
}
diff --git a/cc/delegated_renderer_layer_impl.h b/cc/delegated_renderer_layer_impl.h
index ceaed30..e06adab 100644
--- a/cc/delegated_renderer_layer_impl.h
+++ b/cc/delegated_renderer_layer_impl.h
@@ -5,6 +5,7 @@
#ifndef CC_DELEGATED_RENDERER_LAYER_IMPL_H_
#define CC_DELEGATED_RENDERER_LAYER_IMPL_H_
+#include "base/memory/scoped_ptr.h"
#include "cc/cc_export.h"
#include "cc/layer_impl.h"
#include "cc/scoped_ptr_vector.h"
@@ -20,6 +21,7 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl {
virtual ~DelegatedRendererLayerImpl();
// LayerImpl overrides.
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
virtual bool hasDelegatedContent() const OVERRIDE;
virtual bool hasContributingDelegatedRenderPasses() const OVERRIDE;
virtual RenderPass::Id firstContributingRenderPassId() const OVERRIDE;
diff --git a/cc/heads_up_display_layer_impl.cc b/cc/heads_up_display_layer_impl.cc
index eb1fb61..e581a57 100644
--- a/cc/heads_up_display_layer_impl.cc
+++ b/cc/heads_up_display_layer_impl.cc
@@ -75,6 +75,22 @@ HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl()
{
}
+scoped_ptr<LayerImpl> HeadsUpDisplayLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return HeadsUpDisplayLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void HeadsUpDisplayLayerImpl::pushPropertiesTo(LayerImpl* layerImpl)
+{
+ LayerImpl::pushPropertiesTo(layerImpl);
+
+ if (!m_fontAtlas)
+ return;
+
+ HeadsUpDisplayLayerImpl* hudLayerImpl = static_cast<HeadsUpDisplayLayerImpl*>(layerImpl);
+ hudLayerImpl->setFontAtlas(m_fontAtlas.Pass());
+}
+
void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas)
{
m_fontAtlas = fontAtlas.Pass();
diff --git a/cc/heads_up_display_layer_impl.h b/cc/heads_up_display_layer_impl.h
index 67b2779..6e5a30d 100644
--- a/cc/heads_up_display_layer_impl.h
+++ b/cc/heads_up_display_layer_impl.h
@@ -33,6 +33,9 @@ public:
void setFontAtlas(scoped_ptr<FontAtlas>);
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void willDraw(ResourceProvider*) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
void updateHudTexture(ResourceProvider*);
diff --git a/cc/io_surface_layer_impl.cc b/cc/io_surface_layer_impl.cc
index 9ea69e2..bf796fd 100644
--- a/cc/io_surface_layer_impl.cc
+++ b/cc/io_surface_layer_impl.cc
@@ -37,6 +37,19 @@ IOSurfaceLayerImpl::~IOSurfaceLayerImpl()
context3d->deleteTexture(m_ioSurfaceTextureId);
}
+scoped_ptr<LayerImpl> IOSurfaceLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return IOSurfaceLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void IOSurfaceLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+
+ IOSurfaceLayerImpl* ioSurfaceLayer = static_cast<IOSurfaceLayerImpl*>(layer);
+ ioSurfaceLayer->setIOSurfaceProperties(m_ioSurfaceId, m_ioSurfaceSize);
+}
+
void IOSurfaceLayerImpl::willDraw(ResourceProvider* resourceProvider)
{
LayerImpl::willDraw(resourceProvider);
diff --git a/cc/io_surface_layer_impl.h b/cc/io_surface_layer_impl.h
index 1ca671d..9d1e2c4 100644
--- a/cc/io_surface_layer_impl.h
+++ b/cc/io_surface_layer_impl.h
@@ -21,6 +21,9 @@ public:
void setIOSurfaceProperties(unsigned ioSurfaceId, const gfx::Size&);
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void willDraw(ResourceProvider*) OVERRIDE;
diff --git a/cc/layer.cc b/cc/layer.cc
index a742d07..8581a40 100644
--- a/cc/layer.cc
+++ b/cc/layer.cc
@@ -284,6 +284,12 @@ void Layer::setChildren(const LayerList& children)
addChild(children[i]);
}
+Layer* Layer::childAt(size_t index)
+{
+ DCHECK_LT(index, m_children.size());
+ return m_children[index].get();
+}
+
void Layer::setAnchorPoint(const gfx::PointF& anchorPoint)
{
if (m_anchorPoint == anchorPoint)
diff --git a/cc/layer.h b/cc/layer.h
index a510ab6..0c1670f 100644
--- a/cc/layer.h
+++ b/cc/layer.h
@@ -67,6 +67,7 @@ public:
void setChildren(const LayerList&);
const LayerList& children() const { return m_children; }
+ Layer* childAt(size_t index);
void setAnchorPoint(const gfx::PointF&);
gfx::PointF anchorPoint() const { return m_anchorPoint; }
@@ -291,6 +292,9 @@ public:
virtual bool canClipSelf() const;
+ // Constructs a LayerImpl of the correct runtime type for this Layer type.
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl);
+
protected:
friend class LayerImpl;
friend class TreeSynchronizer;
@@ -315,8 +319,6 @@ protected:
scoped_refptr<Layer> m_maskLayer;
- // Constructs a LayerImpl of the correct runtime type for this Layer type.
- virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl);
int m_layerId;
// When true, the layer is about to perform an update. Any commit requests
diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc
index c3aa793..f9102eb 100644
--- a/cc/layer_impl.cc
+++ b/cc/layer_impl.cc
@@ -36,6 +36,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* treeImpl, int id)
, m_shouldScrollOnMainThread(false)
, m_haveWheelEventHandlers(false)
, m_backgroundColor(0)
+ , m_stackingOrderChanged(false)
, m_doubleSided(true)
, m_layerPropertyChanged(false)
, m_layerSurfacePropertyChanged(false)
@@ -81,6 +82,12 @@ void LayerImpl::addChild(scoped_ptr<LayerImpl> child)
layerTreeImpl()->SetNeedsUpdateDrawProperties();
}
+LayerImpl* LayerImpl::childAt(size_t index) const
+{
+ DCHECK_LT(index, m_children.size());
+ return m_children[index];
+}
+
scoped_ptr<LayerImpl> LayerImpl::removeChild(LayerImpl* child)
{
for (ScopedPtrVector<LayerImpl>::iterator it = m_children.begin(); it != m_children.end(); ++it) {
@@ -304,6 +311,66 @@ bool LayerImpl::areVisibleResourcesReady() const
return true;
}
+scoped_ptr<LayerImpl> LayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return LayerImpl::create(treeImpl, m_layerId);
+}
+
+void LayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ layer->setAnchorPoint(m_anchorPoint);
+ layer->setAnchorPointZ(m_anchorPointZ);
+ layer->setBackgroundColor(m_backgroundColor);
+ layer->setBounds(m_bounds);
+ layer->setContentBounds(contentBounds());
+ layer->setContentsScale(contentsScaleX(), contentsScaleY());
+ layer->setDebugName(m_debugName);
+ layer->setDoubleSided(m_doubleSided);
+ layer->setDrawCheckerboardForMissingTiles(m_drawCheckerboardForMissingTiles);
+ layer->setForceRenderSurface(m_forceRenderSurface);
+ layer->setDrawsContent(drawsContent());
+ layer->setFilters(filters());
+ layer->setFilter(filter());
+ layer->setBackgroundFilters(backgroundFilters());
+ layer->setMasksToBounds(m_masksToBounds);
+ layer->setShouldScrollOnMainThread(m_shouldScrollOnMainThread);
+ layer->setHaveWheelEventHandlers(m_haveWheelEventHandlers);
+ layer->setNonFastScrollableRegion(m_nonFastScrollableRegion);
+ layer->setTouchEventHandlerRegion(m_touchEventHandlerRegion);
+ layer->setContentsOpaque(m_contentsOpaque);
+ if (!opacityIsAnimating())
+ layer->setOpacity(m_opacity);
+ layer->setPosition(m_position);
+ layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLayers);
+ layer->setFixedToContainerLayer(m_fixedToContainerLayer);
+ layer->setPreserves3D(preserves3D());
+ layer->setUseParentBackfaceVisibility(m_useParentBackfaceVisibility);
+ layer->setSublayerTransform(m_sublayerTransform);
+ if (!transformIsAnimating())
+ layer->setTransform(m_transform);
+
+ layer->setScrollable(m_scrollable);
+ layer->setScrollOffset(m_scrollOffset);
+ layer->setMaxScrollOffset(m_maxScrollOffset);
+
+ // If the main thread commits multiple times before the impl thread actually draws, then damage tracking
+ // will become incorrect if we simply clobber the updateRect here. The LayerImpl's updateRect needs to
+ // accumulate (i.e. union) any update changes that have occurred on the main thread.
+ m_updateRect.Union(layer->updateRect());
+ layer->setUpdateRect(m_updateRect);
+
+ layer->setScrollDelta(layer->scrollDelta() - layer->sentScrollDelta());
+ layer->setSentScrollDelta(gfx::Vector2d());
+
+ layer->setStackingOrderChanged(m_stackingOrderChanged);
+
+ m_layerAnimationController->pushAnimationUpdatesTo(layer->layerAnimationController());
+
+ // Reset any state that should be cleared for the next update.
+ m_stackingOrderChanged = false;
+ m_updateRect = gfx::RectF();
+}
+
std::string LayerImpl::indentString(int indent)
{
std::string str;
@@ -407,9 +474,10 @@ base::DictionaryValue* LayerImpl::layerTreeAsJson() const
void LayerImpl::setStackingOrderChanged(bool stackingOrderChanged)
{
- // We don't need to store this flag; we only need to track that the change occurred.
- if (stackingOrderChanged)
+ if (stackingOrderChanged) {
+ m_stackingOrderChanged = true;
noteLayerPropertyChangedForSubtree();
+ }
}
bool LayerImpl::layerSurfacePropertyChanged() const
@@ -562,6 +630,11 @@ scoped_ptr<LayerImpl> LayerImpl::takeReplicaLayer()
return m_replicaLayer.Pass();
}
+ScrollbarLayerImpl* LayerImpl::toScrollbarLayer()
+{
+ return 0;
+}
+
void LayerImpl::setDrawsContent(bool drawsContent)
{
if (m_drawsContent == drawsContent)
@@ -877,11 +950,15 @@ void LayerImpl::didBecomeActive()
void LayerImpl::setHorizontalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
{
m_horizontalScrollbarLayer = scrollbarLayer;
+ if (m_horizontalScrollbarLayer)
+ m_horizontalScrollbarLayer->setScrollLayerId(id());
}
void LayerImpl::setVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
{
m_verticalScrollbarLayer = scrollbarLayer;
+ if (m_verticalScrollbarLayer)
+ m_verticalScrollbarLayer->setScrollLayerId(id());
}
} // namespace cc
diff --git a/cc/layer_impl.h b/cc/layer_impl.h
index 3c8c040..c05fb553 100644
--- a/cc/layer_impl.h
+++ b/cc/layer_impl.h
@@ -67,17 +67,23 @@ public:
LayerImpl* parent() { return m_parent; }
const LayerImpl* parent() const { return m_parent; }
const LayerList& children() const { return m_children; }
+ LayerList& children() { return m_children; }
+ LayerImpl* childAt(size_t index) const;
void addChild(scoped_ptr<LayerImpl>);
scoped_ptr<LayerImpl> removeChild(LayerImpl* child);
void removeAllChildren();
+ void setParent(LayerImpl* parent) { m_parent = parent; }
+ void clearChildList(); // Warning: This does not preserve tree structure invariants.
void setMaskLayer(scoped_ptr<LayerImpl>);
LayerImpl* maskLayer() { return m_maskLayer.get(); }
const LayerImpl* maskLayer() const { return m_maskLayer.get(); }
+ scoped_ptr<LayerImpl> takeMaskLayer();
void setReplicaLayer(scoped_ptr<LayerImpl>);
LayerImpl* replicaLayer() { return m_replicaLayer.get(); }
const LayerImpl* replicaLayer() const { return m_replicaLayer.get(); }
+ scoped_ptr<LayerImpl> takeReplicaLayer();
bool hasMask() const { return m_maskLayer; }
bool hasReplica() const { return m_replicaLayer; }
@@ -101,6 +107,8 @@ public:
virtual RenderPass::Id firstContributingRenderPassId() const;
virtual RenderPass::Id nextContributingRenderPassId(RenderPass::Id) const;
+ virtual ScrollbarLayerImpl* toScrollbarLayer();
+
// Returns true if this layer has content to draw.
void setDrawsContent(bool);
bool drawsContent() const { return m_drawsContent; }
@@ -296,6 +304,9 @@ public:
virtual bool areVisibleResourcesReady() const;
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*);
+ virtual void pushPropertiesTo(LayerImpl*);
+
protected:
LayerImpl(LayerTreeImpl* layerImpl, int);
@@ -308,13 +319,6 @@ protected:
static std::string indentString(int indent);
private:
- scoped_ptr<LayerImpl> takeMaskLayer();
- scoped_ptr<LayerImpl> takeReplicaLayer();
-
- void setParent(LayerImpl* parent) { m_parent = parent; }
- friend class TreeSynchronizer;
- void clearChildList(); // Warning: This does not preserve tree structure invariants and so is only exposed to the tree synchronizer.
-
void updateScrollbarPositions();
void noteLayerSurfacePropertyChanged();
@@ -350,6 +354,7 @@ private:
Region m_nonFastScrollableRegion;
Region m_touchEventHandlerRegion;
SkColor m_backgroundColor;
+ bool m_stackingOrderChanged;
// Whether the "back" of this layer should draw.
bool m_doubleSided;
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc
index e7c5395..90dcb89 100644
--- a/cc/layer_tree_host_impl.cc
+++ b/cc/layer_tree_host_impl.cc
@@ -39,6 +39,7 @@
#include "cc/solid_color_draw_quad.h"
#include "cc/texture_uploader.h"
#include "cc/top_controls_manager.h"
+#include "cc/tree_synchronizer.h"
#include "cc/util.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/vector2d_conversions.h"
@@ -174,8 +175,9 @@ LayerTreeHostImpl::~LayerTreeHostImpl()
// The layer trees must be destroyed before the layer tree host. We've
// made a contract with our animation controllers that the registrar
// will outlive them, and we must make good.
- m_activeTree.reset();
+ m_recycleTree.reset();
m_pendingTree.reset();
+ m_activeTree.reset();
}
}
@@ -194,9 +196,6 @@ void LayerTreeHostImpl::commitComplete()
if (m_settings.implSidePainting)
updateDrawProperties();
- // Recompute max scroll position; must be after layer content bounds are
- // updated.
- updateMaxScrollOffset();
m_client->sendManagedMemoryStats();
}
@@ -932,7 +931,10 @@ static LayerImpl* findScrollLayerForContentLayer(LayerImpl* layerImpl)
void LayerTreeHostImpl::createPendingTree()
{
CHECK(!m_pendingTree);
- m_pendingTree = LayerTreeImpl::create(this);
+ if (m_recycleTree)
+ m_recycleTree.swap(m_pendingTree);
+ else
+ m_pendingTree = LayerTreeImpl::create(this);
m_client->onCanDrawStateChanged(canDraw());
m_client->onHasPendingTreeStateChanged(pendingTree());
}
@@ -963,9 +965,26 @@ void LayerTreeHostImpl::activatePendingTree()
CHECK(m_pendingTree);
m_activeTree->PushPersistedState(m_pendingTree.get());
- m_activeTree.swap(m_pendingTree);
- // TODO(enne): consider recycling this tree to prevent layer churn
- m_pendingTree.reset();
+ m_activeTree->SetRootLayer(TreeSynchronizer::synchronizeTrees(m_pendingTree->RootLayer(), m_activeTree->DetachLayerTree(), m_activeTree.get()));
+ TreeSynchronizer::pushProperties(m_pendingTree->RootLayer(), m_activeTree->RootLayer());
+ DCHECK(!m_recycleTree);
+
+ // This should match the property synchronization in
+ // LayerTreeHost::finishCommitOnImplThread().
+ m_activeTree->set_source_frame_number(m_pendingTree->source_frame_number());
+ m_activeTree->set_background_color(m_pendingTree->background_color());
+ m_activeTree->set_has_transparent_background(m_pendingTree->has_transparent_background());
+ if (m_pendingTree->ContentsTexturesPurged())
+ m_activeTree->SetContentsTexturesPurged();
+ else
+ m_activeTree->ResetContentsTexturesPurged();
+
+ // Now that we've synced everything from the pending tree to the active
+ // tree, rename the pending tree the recycle tree so we can reuse it on the
+ // next sync.
+ m_pendingTree.swap(m_recycleTree);
+ m_recycleTree->ClearRenderSurfaces();
+
m_activeTree->DidBecomeActive();
m_client->onCanDrawStateChanged(canDraw());
@@ -1003,6 +1022,8 @@ bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurfa
sendDidLoseOutputSurfaceRecursive(activeTree()->RootLayer());
if (pendingTree() && pendingTree()->RootLayer())
sendDidLoseOutputSurfaceRecursive(pendingTree()->RootLayer());
+ if (m_recycleTree && m_recycleTree->RootLayer())
+ sendDidLoseOutputSurfaceRecursive(m_recycleTree->RootLayer());
// Note: order is important here.
m_renderer.reset();
@@ -1117,8 +1138,6 @@ void LayerTreeHostImpl::setPageScaleDelta(float delta)
void LayerTreeHostImpl::updateMaxScrollOffset()
{
activeTree()->UpdateMaxScrollOffset();
- if (pendingTree())
- pendingTree()->UpdateMaxScrollOffset();
}
void LayerTreeHostImpl::setNeedsUpdateDrawProperties()
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index 649fc7f..5c8ab15 100644
--- a/cc/layer_tree_host_impl.h
+++ b/cc/layer_tree_host_impl.h
@@ -169,6 +169,7 @@ public:
const LayerTreeImpl* activeTree() const { return m_activeTree.get(); }
LayerTreeImpl* pendingTree() { return m_pendingTree.get(); }
const LayerTreeImpl* pendingTree() const { return m_pendingTree.get(); }
+ const LayerTreeImpl* recycleTree() const { return m_recycleTree.get(); }
void createPendingTree();
void checkForCompletedTileUploads();
virtual void activatePendingTreeIfNeeded();
@@ -315,9 +316,17 @@ private:
scoped_ptr<Renderer> m_renderer;
scoped_ptr<TileManager> m_tileManager;
- scoped_ptr<LayerTreeImpl> m_pendingTree;
+ // Tree currently being drawn.
scoped_ptr<LayerTreeImpl> m_activeTree;
+ // In impl-side painting mode, tree with possibly incomplete rasterized
+ // content. May be promoted to active by activatePendingTreeIfNeeded().
+ scoped_ptr<LayerTreeImpl> m_pendingTree;
+
+ // In impl-side painting mode, inert tree with layers that can be recycled
+ // by the next sync from the main thread.
+ scoped_ptr<LayerTreeImpl> m_recycleTree;
+
bool m_scrollDeltaIsInViewportSpace;
LayerTreeSettings m_settings;
LayerTreeDebugState m_debugState;
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc
index 062588a..6993fa4 100644
--- a/cc/layer_tree_host_impl_unittest.cc
+++ b/cc/layer_tree_host_impl_unittest.cc
@@ -1521,9 +1521,9 @@ TEST_P(LayerTreeHostImplTest, scrollEventBubbling)
child->setScrollable(false);
root->addChild(child.Pass());
+ m_hostImpl->setViewportSize(surfaceSize, surfaceSize);
m_hostImpl->activeTree()->SetRootLayer(root.Pass());
m_hostImpl->activeTree()->DidBecomeActive();
- m_hostImpl->setViewportSize(surfaceSize, surfaceSize);
initializeRendererAndDrawFrame();
{
gfx::Vector2d scrollDelta(0, 4);
diff --git a/cc/layer_tree_impl.cc b/cc/layer_tree_impl.cc
index 328116a..a2e2b3f 100644
--- a/cc/layer_tree_impl.cc
+++ b/cc/layer_tree_impl.cc
@@ -234,6 +234,10 @@ void LayerTreeImpl::ResetContentsTexturesPurged() {
layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
}
+Proxy* LayerTreeImpl::proxy() const {
+ return layer_tree_host_impl_->proxy();
+}
+
const LayerTreeSettings& LayerTreeImpl::settings() const {
return layer_tree_host_impl_->settings();
}
@@ -266,6 +270,10 @@ bool LayerTreeImpl::IsPendingTree() const {
return layer_tree_host_impl_->pendingTree() == this;
}
+bool LayerTreeImpl::IsRecycleTree() const {
+ return layer_tree_host_impl_->recycleTree() == this;
+}
+
LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
LayerTreeImpl* tree = layer_tree_host_impl_->activeTree();
if (!tree)
diff --git a/cc/layer_tree_impl.h b/cc/layer_tree_impl.h
index bae0cb9..8c7fd9d 100644
--- a/cc/layer_tree_impl.h
+++ b/cc/layer_tree_impl.h
@@ -55,6 +55,7 @@ class CC_EXPORT LayerTreeImpl {
PaintTimeCounter* paint_time_counter() const;
bool IsActiveTree() const;
bool IsPendingTree() const;
+ bool IsRecycleTree() const;
LayerImpl* FindActiveTreeLayerById(int id);
LayerImpl* FindPendingTreeLayerById(int id);
int MaxTextureSize() const;
@@ -139,6 +140,9 @@ class CC_EXPORT LayerTreeImpl {
void SetContentsTexturesPurged();
void ResetContentsTexturesPurged();
+ // Useful for debug assertions, probably shouldn't be used for anything else.
+ Proxy* proxy() const;
+
protected:
LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl);
diff --git a/cc/nine_patch_layer_impl.cc b/cc/nine_patch_layer_impl.cc
index bc23e85..0fa0317 100644
--- a/cc/nine_patch_layer_impl.cc
+++ b/cc/nine_patch_layer_impl.cc
@@ -27,6 +27,23 @@ ResourceProvider::ResourceId NinePatchLayerImpl::contentsResourceId() const
return 0;
}
+scoped_ptr<LayerImpl> NinePatchLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return NinePatchLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void NinePatchLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+ NinePatchLayerImpl* layerImpl = static_cast<NinePatchLayerImpl*>(layer);
+
+ if (!m_resourceId)
+ return;
+
+ layerImpl->setResourceId(m_resourceId);
+ layerImpl->setLayout(m_imageBounds, m_imageAperture);
+}
+
void NinePatchLayerImpl::willDraw(ResourceProvider* resourceProvider)
{
}
diff --git a/cc/nine_patch_layer_impl.h b/cc/nine_patch_layer_impl.h
index 6a10389..8b693ac 100644
--- a/cc/nine_patch_layer_impl.h
+++ b/cc/nine_patch_layer_impl.h
@@ -28,6 +28,9 @@ public:
void setResourceId(unsigned id) { m_resourceId = id; }
void setLayout(const gfx::Size& imageBounds, const gfx::Rect& aperture);
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void willDraw(ResourceProvider*) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void didDraw(ResourceProvider*) OVERRIDE;
diff --git a/cc/picture_layer.cc b/cc/picture_layer.cc
index 9114d6f..606cf2e 100644
--- a/cc/picture_layer.cc
+++ b/cc/picture_layer.cc
@@ -36,7 +36,7 @@ void PictureLayer::pushPropertiesTo(LayerImpl* base_layer) {
PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
layer_impl->SetIsMask(is_mask_);
- layer_impl->tilings_.SetLayerBounds(bounds());
+ layer_impl->CreateTilingSet();
layer_impl->invalidation_.Clear();
layer_impl->invalidation_.Swap(pile_invalidation_);
pile_->PushPropertiesTo(layer_impl->pile_);
diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc
index 238f01d..987f972 100644
--- a/cc/picture_layer_impl.cc
+++ b/cc/picture_layer_impl.cc
@@ -25,7 +25,6 @@ namespace cc {
PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* treeImpl, int id)
: LayerImpl(treeImpl, id),
- tilings_(this),
pile_(PicturePileImpl::Create()),
last_update_time_(0),
last_content_scale_(0),
@@ -40,6 +39,36 @@ const char* PictureLayerImpl::layerTypeAsString() const {
return "PictureLayer";
}
+scoped_ptr<LayerImpl> PictureLayerImpl::createLayerImpl(
+ LayerTreeImpl* treeImpl) {
+ return PictureLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void PictureLayerImpl::CreateTilingSet() {
+ DCHECK(layerTreeImpl()->IsPendingTree());
+ DCHECK(!tilings_);
+ tilings_.reset(new PictureLayerTilingSet(this));
+ tilings_->SetLayerBounds(bounds());
+}
+
+void PictureLayerImpl::TransferTilingSet(scoped_ptr<PictureLayerTilingSet> tilings) {
+ DCHECK(layerTreeImpl()->IsActiveTree());
+ tilings->SetClient(this);
+ tilings_ = tilings.Pass();
+}
+
+void PictureLayerImpl::pushPropertiesTo(LayerImpl* base_layer) {
+ LayerImpl::pushPropertiesTo(base_layer);
+
+ PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+
+ layer_impl->SetIsMask(is_mask_);
+ layer_impl->TransferTilingSet(tilings_.Pass());
+ layer_impl->pile_ = pile_;
+ pile_ = PicturePileImpl::Create();
+}
+
+
void PictureLayerImpl::appendQuads(QuadSink& quadSink,
AppendQuadsData& appendQuadsData) {
const gfx::Rect& rect = visibleContentRect();
@@ -56,7 +85,7 @@ void PictureLayerImpl::appendQuads(QuadSink& quadSink,
bool useAA = !isAxisAlignedInTarget;
if (showDebugBorders()) {
- for (PictureLayerTilingSet::Iterator iter(&tilings_,
+ for (PictureLayerTilingSet::Iterator iter(tilings_.get(),
contentsScaleX(),
rect,
ideal_contents_scale_);
@@ -84,7 +113,7 @@ void PictureLayerImpl::appendQuads(QuadSink& quadSink,
// unused can be considered for removal.
std::vector<PictureLayerTiling*> seen_tilings;
- for (PictureLayerTilingSet::Iterator iter(&tilings_,
+ for (PictureLayerTilingSet::Iterator iter(tilings_.get(),
contentsScaleX(),
rect,
ideal_contents_scale_);
@@ -162,7 +191,7 @@ void PictureLayerImpl::didUpdateTransforms() {
time_delta = current_time - last_update_time_;
}
WhichTree tree = layerTreeImpl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
- tilings_.UpdateTilePriorities(
+ tilings_->UpdateTilePriorities(
tree,
layerTreeImpl()->device_viewport_size(),
last_content_scale_,
@@ -179,11 +208,13 @@ void PictureLayerImpl::didUpdateTransforms() {
}
void PictureLayerImpl::didBecomeActive() {
- tilings_.DidBecomeActive();
+ LayerImpl::didBecomeActive();
+ tilings_->DidBecomeActive();
}
void PictureLayerImpl::didLoseOutputSurface() {
- tilings_.RemoveAllTilings();
+ if (tilings_)
+ tilings_->RemoveAllTilings();
}
void PictureLayerImpl::calculateContentsScale(
@@ -192,7 +223,7 @@ void PictureLayerImpl::calculateContentsScale(
float* contents_scale_y,
gfx::Size* content_bounds) {
if (!drawsContent()) {
- DCHECK(!tilings_.num_tilings());
+ DCHECK(!tilings_->num_tilings());
return;
}
@@ -208,8 +239,8 @@ void PictureLayerImpl::calculateContentsScale(
// tilings (and then map back to floating point texture coordinates), the
// contents scale must be at least as large as the largest of the tilings.
float max_contents_scale = min_contents_scale;
- for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
- const PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+ const PictureLayerTiling* tiling = tilings_->tiling_at(i);
max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
}
@@ -256,26 +287,26 @@ void PictureLayerImpl::SyncFromActiveLayer() {
}
void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
- tilings_.CloneAll(other->tilings_, invalidation_);
- DCHECK(bounds() == tilings_.LayerBounds());
+ tilings_->CloneAll(*other->tilings_, invalidation_);
+ DCHECK(bounds() == tilings_->LayerBounds());
}
void PictureLayerImpl::SyncTiling(
const PictureLayerTiling* tiling) {
- tilings_.Clone(tiling, invalidation_);
+ tilings_->Clone(tiling, invalidation_);
}
void PictureLayerImpl::SetIsMask(bool is_mask) {
if (is_mask_ == is_mask)
return;
is_mask_ = is_mask;
- tilings_.RemoveAllTiles();
+ tilings_->RemoveAllTiles();
}
ResourceProvider::ResourceId PictureLayerImpl::contentsResourceId() const {
gfx::Rect content_rect(gfx::Point(), contentBounds());
float scale = contentsScaleX();
- for (PictureLayerTilingSet::Iterator iter(&tilings_,
+ for (PictureLayerTilingSet::Iterator iter(tilings_.get(),
scale,
content_rect,
ideal_contents_scale_);
@@ -295,8 +326,8 @@ ResourceProvider::ResourceId PictureLayerImpl::contentsResourceId() const {
bool PictureLayerImpl::areVisibleResourcesReady() const {
const gfx::Rect& rect = visibleContentRect();
- for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
- const PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+ const PictureLayerTiling* tiling = tilings_->tiling_at(i);
// Ignore non-high resolution tilings.
if (tiling->resolution() != HIGH_RESOLUTION)
@@ -320,7 +351,7 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
if (contents_scale < layerTreeImpl()->settings().minimumContentsScale)
return NULL;
- PictureLayerTiling* tiling = tilings_.AddTiling(
+ PictureLayerTiling* tiling = tilings_->AddTiling(
contents_scale,
TileSize());
@@ -381,8 +412,8 @@ void PictureLayerImpl::ManageTilings(float ideal_contents_scale) {
if (layerTreeImpl()->IsPendingTree() &&
!layerTreeImpl()->PinchGestureActive()) {
std::vector<PictureLayerTiling*> remove_list;
- for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_->tiling_at(i);
if (tiling->contents_scale() == ideal_contents_scale)
continue;
if (tiling->contents_scale() == low_res_contents_scale)
@@ -391,14 +422,14 @@ void PictureLayerImpl::ManageTilings(float ideal_contents_scale) {
}
for (size_t i = 0; i < remove_list.size(); ++i)
- tilings_.Remove(remove_list[i]);
+ tilings_->Remove(remove_list[i]);
}
// Find existing tilings closest to ideal high / low res.
PictureLayerTiling* high_res = NULL;
PictureLayerTiling* low_res = NULL;
- for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_->tiling_at(i);
if (!high_res || IsCloserToThan(tiling, high_res, ideal_contents_scale))
high_res = tiling;
if (!low_res || IsCloserToThan(tiling, low_res, low_res_contents_scale))
@@ -442,8 +473,8 @@ void PictureLayerImpl::CleanUpUnusedTilings(
std::vector<PictureLayerTiling*> used_tilings) {
std::vector<PictureLayerTiling*> to_remove;
- for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_->tiling_at(i);
// Don't remove the current high or low res tilinig.
if (tiling->resolution() != NON_IDEAL_RESOLUTION)
continue;
@@ -453,7 +484,7 @@ void PictureLayerImpl::CleanUpUnusedTilings(
}
for (size_t i = 0; i < to_remove.size(); ++i)
- tilings_.Remove(to_remove[i]);
+ tilings_->Remove(to_remove[i]);
}
} // namespace cc
diff --git a/cc/picture_layer_impl.h b/cc/picture_layer_impl.h
index 91fa2e79..b4a9729 100644
--- a/cc/picture_layer_impl.h
+++ b/cc/picture_layer_impl.h
@@ -29,6 +29,9 @@ public:
// LayerImpl overrides.
virtual const char* layerTypeAsString() const OVERRIDE;
+ virtual scoped_ptr<LayerImpl> createLayerImpl(
+ LayerTreeImpl* treeImpl) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl* layer) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void dumpLayerProperties(std::string*, int indent) const OVERRIDE;
virtual void didUpdateTransforms() OVERRIDE;
@@ -50,6 +53,9 @@ public:
void SyncFromActiveLayer();
void SyncTiling(const PictureLayerTiling* tiling);
+ void CreateTilingSet();
+ void TransferTilingSet(scoped_ptr<PictureLayerTilingSet> tilings);
+
// Mask-related functions
void SetIsMask(bool is_mask);
virtual ResourceProvider::ResourceId contentsResourceId() const OVERRIDE;
@@ -64,7 +70,7 @@ protected:
void ManageTilings(float ideal_contents_scale);
void CleanUpUnusedTilings(std::vector<PictureLayerTiling*> used_tilings);
- PictureLayerTilingSet tilings_;
+ scoped_ptr<PictureLayerTilingSet> tilings_;
scoped_refptr<PicturePileImpl> pile_;
Region invalidation_;
diff --git a/cc/picture_layer_tiling_set.cc b/cc/picture_layer_tiling_set.cc
index 638eaff..2e96ded 100644
--- a/cc/picture_layer_tiling_set.cc
+++ b/cc/picture_layer_tiling_set.cc
@@ -26,6 +26,12 @@ PictureLayerTilingSet::PictureLayerTilingSet(
PictureLayerTilingSet::~PictureLayerTilingSet() {
}
+void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) {
+ client_ = client;
+ for (size_t i = 0; i < tilings_.size(); ++i)
+ tilings_[i]->SetClient(client_);
+}
+
void PictureLayerTilingSet::CloneAll(
const PictureLayerTilingSet& other,
const Region& invalidation) {
diff --git a/cc/picture_layer_tiling_set.h b/cc/picture_layer_tiling_set.h
index 1c8467b..a962290 100644
--- a/cc/picture_layer_tiling_set.h
+++ b/cc/picture_layer_tiling_set.h
@@ -14,9 +14,11 @@ namespace cc {
class CC_EXPORT PictureLayerTilingSet {
public:
- PictureLayerTilingSet(PictureLayerTilingClient* client);
+ explicit PictureLayerTilingSet(PictureLayerTilingClient* client);
~PictureLayerTilingSet();
+ void SetClient(PictureLayerTilingClient* client);
+
// Shallow copies all data (except client and bounds from other).
void CloneAll(
const PictureLayerTilingSet& other,
@@ -104,7 +106,6 @@ class CC_EXPORT PictureLayerTilingSet {
PictureLayerTilingClient* client_;
gfx::Size layer_bounds_;
ScopedPtrVector<PictureLayerTiling> tilings_;
- Region invalidation_;
friend class Iterator;
};
diff --git a/cc/picture_pile.cc b/cc/picture_pile.cc
index fcf746a..362070e 100644
--- a/cc/picture_pile.cc
+++ b/cc/picture_pile.cc
@@ -38,6 +38,7 @@ void PicturePile::Update(
if (!(*i)->HasRecording())
(*i)->Record(painter, stats);
}
+ DCHECK(!pile_.empty());
}
class FullyContainedPredicate {
diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc
index 4155664..e0afe32 100644
--- a/cc/picture_pile_impl.cc
+++ b/cc/picture_pile_impl.cc
@@ -99,6 +99,11 @@ void PicturePileImpl::GatherPixelRefs(
}
}
+void PicturePileImpl::PushPropertiesTo(PicturePileImpl* other) {
+ PicturePileBase::PushPropertiesTo(other);
+ other->clones_ = clones_;
+}
+
skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() {
TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture");
diff --git a/cc/picture_pile_impl.h b/cc/picture_pile_impl.h
index 5ca526f..c5a7b41 100644
--- a/cc/picture_pile_impl.h
+++ b/cc/picture_pile_impl.h
@@ -38,6 +38,8 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
void GatherPixelRefs(const gfx::Rect&, std::list<skia::LazyPixelRef*>&);
+ void PushPropertiesTo(PicturePileImpl* other);
+
skia::RefPtr<SkPicture> GetFlattenedPicture();
private:
diff --git a/cc/scrollbar_animation_controller.h b/cc/scrollbar_animation_controller.h
index b560490..6345618 100644
--- a/cc/scrollbar_animation_controller.h
+++ b/cc/scrollbar_animation_controller.h
@@ -21,7 +21,6 @@ public:
virtual void didPinchGestureUpdate(base::TimeTicks) = 0;
virtual void didPinchGestureEnd(base::TimeTicks) = 0;
virtual void didUpdateScrollOffset(base::TimeTicks) = 0;
-
};
} // namespace cc
diff --git a/cc/scrollbar_layer_impl.cc b/cc/scrollbar_layer_impl.cc
index f82a1dc..b57bb25 100644
--- a/cc/scrollbar_layer_impl.cc
+++ b/cc/scrollbar_layer_impl.cc
@@ -28,6 +28,7 @@ ScrollbarLayerImpl::ScrollbarLayerImpl(LayerTreeImpl* treeImpl, int id)
, m_currentPos(0)
, m_totalSize(0)
, m_maximum(0)
+ , m_scrollLayerId(-1)
, m_scrollbarOverlayStyle(WebScrollbar::ScrollbarOverlayStyleDefault)
, m_orientation(WebScrollbar::Horizontal)
, m_controlSize(WebScrollbar::RegularScrollbar)
@@ -45,6 +46,11 @@ ScrollbarLayerImpl::~ScrollbarLayerImpl()
{
}
+ScrollbarLayerImpl* ScrollbarLayerImpl::toScrollbarLayer()
+{
+ return this;
+}
+
void ScrollbarLayerImpl::setScrollbarGeometry(scoped_ptr<ScrollbarGeometryFixedThumb> geometry)
{
m_geometry = geometry.Pass();
@@ -101,6 +107,27 @@ gfx::Rect ScrollbarLayerImpl::scrollbarLayerRectToContentRect(const gfx::Rect& l
return gfx::ToEnclosingRect(contentRect);
}
+scoped_ptr<LayerImpl> ScrollbarLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return ScrollbarLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void ScrollbarLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+
+ ScrollbarLayerImpl* scrollbarLayer = static_cast<ScrollbarLayerImpl*>(layer);
+
+ if (!scrollbarLayer->scrollbarGeometry())
+ scrollbarLayer->setScrollbarGeometry(ScrollbarGeometryFixedThumb::create(make_scoped_ptr(m_geometry->clone())));
+
+ scrollbarLayer->setScrollbarData(&m_scrollbar);
+
+ scrollbarLayer->setBackTrackResourceId(m_backTrackResourceId);
+ scrollbarLayer->setForeTrackResourceId(m_foreTrackResourceId);
+ scrollbarLayer->setThumbResourceId(m_thumbResourceId);
+}
+
void ScrollbarLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData)
{
bool premultipledAlpha = false;
diff --git a/cc/scrollbar_layer_impl.h b/cc/scrollbar_layer_impl.h
index 8b194a2..19d9763 100644
--- a/cc/scrollbar_layer_impl.h
+++ b/cc/scrollbar_layer_impl.h
@@ -20,6 +20,10 @@ public:
static scoped_ptr<ScrollbarLayerImpl> create(LayerTreeImpl* treeImpl, int id);
virtual ~ScrollbarLayerImpl();
+ virtual ScrollbarLayerImpl* toScrollbarLayer() OVERRIDE;
+ int scrollLayerId() const { return m_scrollLayerId; }
+ void setScrollLayerId(int id) { m_scrollLayerId = id; }
+
ScrollbarGeometryFixedThumb* scrollbarGeometry() const { return m_geometry.get(); }
void setScrollbarGeometry(scoped_ptr<ScrollbarGeometryFixedThumb>);
void setScrollbarData(WebKit::WebScrollbar*);
@@ -28,7 +32,6 @@ public:
void setForeTrackResourceId(ResourceProvider::ResourceId id) { m_foreTrackResourceId = id; }
void setThumbResourceId(ResourceProvider::ResourceId id) { m_thumbResourceId = id; }
- void setOwningLayer(LayerImpl* owningLayer);
// ScrollbarLayerImplBase implementation.
virtual float currentPos() const OVERRIDE;
@@ -41,6 +44,9 @@ public:
virtual WebKit::WebScrollbar::Orientation orientation() const OVERRIDE;
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void didLoseOutputSurface() OVERRIDE;
@@ -93,6 +99,8 @@ private:
int m_totalSize;
int m_maximum;
+ int m_scrollLayerId;
+
// Data to implement Scrollbar
WebKit::WebScrollbar::ScrollbarOverlayStyle m_scrollbarOverlayStyle;
WebKit::WebVector<WebKit::WebRect> m_tickmarks;
diff --git a/cc/solid_color_layer_impl.cc b/cc/solid_color_layer_impl.cc
index 1d5ed51..1872c76 100644
--- a/cc/solid_color_layer_impl.cc
+++ b/cc/solid_color_layer_impl.cc
@@ -19,6 +19,11 @@ SolidColorLayerImpl::~SolidColorLayerImpl()
{
}
+scoped_ptr<LayerImpl> SolidColorLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return SolidColorLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
void SolidColorLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData)
{
SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQuadState());
diff --git a/cc/solid_color_layer_impl.h b/cc/solid_color_layer_impl.h
index ae1dcdc..af52c2f 100644
--- a/cc/solid_color_layer_impl.h
+++ b/cc/solid_color_layer_impl.h
@@ -5,6 +5,7 @@
#ifndef CC_SOLID_COLOR_LAYER_IMPL_H_
#define CC_SOLID_COLOR_LAYER_IMPL_H_
+#include "base/memory/scoped_ptr.h"
#include "cc/cc_export.h"
#include "cc/layer_impl.h"
@@ -18,6 +19,8 @@ public:
}
virtual ~SolidColorLayerImpl();
+ // LayerImpl overrides.
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
protected:
diff --git a/cc/texture_layer_impl.cc b/cc/texture_layer_impl.cc
index 6ea69bc..279decc 100644
--- a/cc/texture_layer_impl.cc
+++ b/cc/texture_layer_impl.cc
@@ -54,6 +54,29 @@ void TextureLayerImpl::setTextureMailbox(const TextureMailbox& mailbox)
m_hasPendingMailbox = true;
}
+scoped_ptr<LayerImpl> TextureLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return TextureLayerImpl::create(treeImpl, id(), m_usesMailbox).PassAs<LayerImpl>();
+}
+
+void TextureLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+
+ TextureLayerImpl* textureLayer = static_cast<TextureLayerImpl*>(layer);
+ textureLayer->setFlipped(m_flipped);
+ textureLayer->setUVTopLeft(m_uvTopLeft);
+ textureLayer->setUVBottomRight(m_uvBottomRight);
+ textureLayer->setVertexOpacity(m_vertexOpacity);
+ textureLayer->setPremultipliedAlpha(m_premultipliedAlpha);
+ if (m_usesMailbox) {
+ textureLayer->setTextureMailbox(m_pendingTextureMailbox);
+ } else {
+ textureLayer->setTextureId(m_textureId);
+ }
+}
+
+
void TextureLayerImpl::willDraw(ResourceProvider* resourceProvider)
{
if (!m_usesMailbox) {
diff --git a/cc/texture_layer_impl.h b/cc/texture_layer_impl.h
index 409afdf..ba6f704 100644
--- a/cc/texture_layer_impl.h
+++ b/cc/texture_layer_impl.h
@@ -21,6 +21,9 @@ public:
}
virtual ~TextureLayerImpl();
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void willDraw(ResourceProvider*) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void didDraw(ResourceProvider*) OVERRIDE;
diff --git a/cc/tiled_layer_impl.cc b/cc/tiled_layer_impl.cc
index f76faad..f84d32e 100644
--- a/cc/tiled_layer_impl.cc
+++ b/cc/tiled_layer_impl.cc
@@ -113,6 +113,29 @@ void TiledLayerImpl::getDebugBorderProperties(SkColor* color, float* width) cons
*width = DebugColors::TiledContentLayerBorderWidth(layerTreeImpl());
}
+scoped_ptr<LayerImpl> TiledLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
+{
+ return TiledLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
+}
+
+void TiledLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+
+ TiledLayerImpl* tiledLayer = static_cast<TiledLayerImpl*>(layer);
+
+ tiledLayer->setSkipsDraw(m_skipsDraw);
+ tiledLayer->setTilingData(*m_tiler);
+
+ for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != m_tiler->tiles().end(); ++iter) {
+ int i = iter->first.first;
+ int j = iter->first.second;
+ DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
+
+ tiledLayer->pushTileProperties(i, j, tile->resourceId(), tile->opaqueRect(), tile->contentsSwizzled());
+ }
+}
+
void TiledLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData)
{
const gfx::Rect& contentRect = visibleContentRect();
diff --git a/cc/tiled_layer_impl.h b/cc/tiled_layer_impl.h
index 81726b8..99206bf 100644
--- a/cc/tiled_layer_impl.h
+++ b/cc/tiled_layer_impl.h
@@ -21,6 +21,9 @@ public:
}
virtual ~TiledLayerImpl();
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
+
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual ResourceProvider::ResourceId contentsResourceId() const OVERRIDE;
diff --git a/cc/tree_synchronizer.cc b/cc/tree_synchronizer.cc
index 8a8953b..8c3a370 100644
--- a/cc/tree_synchronizer.cc
+++ b/cc/tree_synchronizer.cc
@@ -14,7 +14,27 @@
namespace cc {
-scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(Layer* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl)
+typedef ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap;
+typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap;
+
+void collectExistingLayerImplRecursive(ScopedPtrLayerImplMap& oldLayers, scoped_ptr<LayerImpl> layerImpl)
+{
+ if (!layerImpl)
+ return;
+
+ ScopedPtrVector<LayerImpl>& children = layerImpl->children();
+ for (ScopedPtrVector<LayerImpl>::iterator it = children.begin(); it != children.end(); ++it)
+ collectExistingLayerImplRecursive(oldLayers, children.take(it));
+
+ collectExistingLayerImplRecursive(oldLayers, layerImpl->takeMaskLayer());
+ collectExistingLayerImplRecursive(oldLayers, layerImpl->takeReplicaLayer());
+
+ int id = layerImpl->id();
+ oldLayers.set(id, layerImpl.Pass());
+}
+
+template <typename LayerType>
+scoped_ptr<LayerImpl> synchronizeTreesInternal(LayerType* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl)
{
DCHECK(treeImpl);
@@ -24,30 +44,25 @@ scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(Layer* layerRoot, scope
collectExistingLayerImplRecursive(oldLayers, oldLayerImplRoot.Pass());
- scoped_ptr<LayerImpl> newTree = synchronizeTreeRecursive(newLayers, oldLayers, layerRoot, treeImpl);
+ scoped_ptr<LayerImpl> newTree = synchronizeTreesRecursive(newLayers, oldLayers, layerRoot, treeImpl);
updateScrollbarLayerPointersRecursive(newLayers, layerRoot);
return newTree.Pass();
}
-void TreeSynchronizer::collectExistingLayerImplRecursive(ScopedPtrLayerImplMap& oldLayers, scoped_ptr<LayerImpl> layerImpl)
+scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(Layer* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl)
{
- if (!layerImpl)
- return;
-
- ScopedPtrVector<LayerImpl>& children = layerImpl->m_children;
- for (ScopedPtrVector<LayerImpl>::iterator it = children.begin(); it != children.end(); ++it)
- collectExistingLayerImplRecursive(oldLayers, children.take(it));
-
- collectExistingLayerImplRecursive(oldLayers, layerImpl->takeMaskLayer());
- collectExistingLayerImplRecursive(oldLayers, layerImpl->takeReplicaLayer());
+ return synchronizeTreesInternal(layerRoot, oldLayerImplRoot.Pass(), treeImpl);
+}
- int id = layerImpl->id();
- oldLayers.set(id, layerImpl.Pass());
+scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(LayerImpl* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl)
+{
+ return synchronizeTreesInternal(layerRoot, oldLayerImplRoot.Pass(), treeImpl);
}
-scoped_ptr<LayerImpl> TreeSynchronizer::reuseOrCreateLayerImpl(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer* layer, LayerTreeImpl* treeImpl)
+template <typename LayerType>
+scoped_ptr<LayerImpl> reuseOrCreateLayerImpl(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerType* layer, LayerTreeImpl* treeImpl)
{
scoped_ptr<LayerImpl> layerImpl = oldLayers.take(layer->id());
@@ -58,7 +73,8 @@ scoped_ptr<LayerImpl> TreeSynchronizer::reuseOrCreateLayerImpl(RawPtrLayerImplMa
return layerImpl.Pass();
}
-scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTreeRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer* layer, LayerTreeImpl* treeImpl)
+template <typename LayerType>
+scoped_ptr<LayerImpl> synchronizeTreesRecursiveInternal(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerType* layer, LayerTreeImpl* treeImpl)
{
if (!layer)
return scoped_ptr<LayerImpl>();
@@ -66,12 +82,11 @@ scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTreeRecursive(RawPtrLayerImpl
scoped_ptr<LayerImpl> layerImpl = reuseOrCreateLayerImpl(newLayers, oldLayers, layer, treeImpl);
layerImpl->clearChildList();
- const std::vector<scoped_refptr<Layer> >& children = layer->children();
- for (size_t i = 0; i < children.size(); ++i)
- layerImpl->addChild(synchronizeTreeRecursive(newLayers, oldLayers, children[i].get(), treeImpl));
+ for (size_t i = 0; i < layer->children().size(); ++i)
+ layerImpl->addChild(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->childAt(i), treeImpl));
- layerImpl->setMaskLayer(synchronizeTreeRecursive(newLayers, oldLayers, layer->maskLayer(), treeImpl));
- layerImpl->setReplicaLayer(synchronizeTreeRecursive(newLayers, oldLayers, layer->replicaLayer(), treeImpl));
+ layerImpl->setMaskLayer(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->maskLayer(), treeImpl));
+ layerImpl->setReplicaLayer(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->replicaLayer(), treeImpl));
// Remove all dangling pointers. The pointers will be setup later in updateScrollbarLayerPointersRecursive phase
layerImpl->setHorizontalScrollbarLayer(0);
@@ -80,16 +95,26 @@ scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTreeRecursive(RawPtrLayerImpl
return layerImpl.Pass();
}
-void TreeSynchronizer::updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, Layer* layer)
+scoped_ptr<LayerImpl> synchronizeTreesRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer* layer, LayerTreeImpl* treeImpl)
+{
+ return synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer, treeImpl);
+}
+
+scoped_ptr<LayerImpl> synchronizeTreesRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerImpl* layer, LayerTreeImpl* treeImpl)
+{
+ return synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer, treeImpl);
+}
+
+template <typename LayerType, typename ScrollbarLayerType>
+void updateScrollbarLayerPointersRecursiveInternal(const RawPtrLayerImplMap& newLayers, LayerType* layer)
{
if (!layer)
return;
- const std::vector<scoped_refptr<Layer> >& children = layer->children();
- for (size_t i = 0; i < children.size(); ++i)
- updateScrollbarLayerPointersRecursive(newLayers, children[i].get());
+ for (size_t i = 0; i < layer->children().size(); ++i)
+ updateScrollbarLayerPointersRecursiveInternal<LayerType, ScrollbarLayerType>(newLayers, layer->childAt(i));
- ScrollbarLayer* scrollbarLayer = layer->toScrollbarLayer();
+ ScrollbarLayerType* scrollbarLayer = layer->toScrollbarLayer();
if (!scrollbarLayer)
return;
@@ -107,7 +132,18 @@ void TreeSynchronizer::updateScrollbarLayerPointersRecursive(const RawPtrLayerIm
scrollLayerImpl->setVerticalScrollbarLayer(scrollbarLayerImpl);
}
-void TreeSynchronizer::pushProperties(Layer* layer, LayerImpl* layerImpl)
+void updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, Layer* layer)
+{
+ updateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayer>(newLayers, layer);
+}
+
+void updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, LayerImpl* layer)
+{
+ updateScrollbarLayerPointersRecursiveInternal<LayerImpl, ScrollbarLayerImpl>(newLayers, layer);
+}
+
+template <typename LayerType>
+void pushPropertiesInternal(LayerType* layer, LayerImpl* layerImpl)
{
if (!layer) {
DCHECK(!layerImpl);
@@ -117,16 +153,26 @@ void TreeSynchronizer::pushProperties(Layer* layer, LayerImpl* layerImpl)
DCHECK_EQ(layer->id(), layerImpl->id());
layer->pushPropertiesTo(layerImpl);
- pushProperties(layer->maskLayer(), layerImpl->maskLayer());
- pushProperties(layer->replicaLayer(), layerImpl->replicaLayer());
+ pushPropertiesInternal(layer->maskLayer(), layerImpl->maskLayer());
+ pushPropertiesInternal(layer->replicaLayer(), layerImpl->replicaLayer());
- const std::vector<scoped_refptr<Layer> >& children = layer->children();
const ScopedPtrVector<LayerImpl>& implChildren = layerImpl->children();
- DCHECK_EQ(children.size(), implChildren.size());
+ DCHECK_EQ(layer->children().size(), implChildren.size());
- for (size_t i = 0; i < children.size(); ++i) {
- pushProperties(children[i].get(), implChildren[i]);
+ for (size_t i = 0; i < layer->children().size(); ++i) {
+ pushPropertiesInternal(layer->childAt(i), implChildren[i]);
}
}
+void TreeSynchronizer::pushProperties(Layer* layer, LayerImpl* layerImpl)
+{
+ pushPropertiesInternal(layer, layerImpl);
+}
+
+void TreeSynchronizer::pushProperties(LayerImpl* layer, LayerImpl* layerImpl)
+{
+ pushPropertiesInternal(layer, layerImpl);
+}
+
+
} // namespace cc
diff --git a/cc/tree_synchronizer.h b/cc/tree_synchronizer.h
index 9059314..d0349c0 100644
--- a/cc/tree_synchronizer.h
+++ b/cc/tree_synchronizer.h
@@ -21,23 +21,16 @@ public:
// Accepts a Layer tree and returns a reference to a LayerImpl tree that duplicates the structure
// of the Layer tree, reusing the LayerImpls in the tree provided by oldLayerImplRoot if possible.
static scoped_ptr<LayerImpl> synchronizeTrees(Layer* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl*);
+ static scoped_ptr<LayerImpl> synchronizeTrees(LayerImpl* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl*);
- // Pushes properties from a Layer tree to a structurally equivalent
+ // Pushes properties from a Layer or LayerImpl tree to a structurally equivalent
// LayerImpl tree.
static void pushProperties(Layer* layerRoot, LayerImpl* layerImplRoot);
+ static void pushProperties(LayerImpl* layerRoot, LayerImpl* layerImplRoot);
private:
TreeSynchronizer(); // Not instantiable.
- typedef ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap;
- typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap;
-
- // Declared as static member functions so they can access functions on Layer as a friend class.
- static scoped_ptr<LayerImpl> reuseOrCreateLayerImpl(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer*, LayerTreeImpl*);
- static void collectExistingLayerImplRecursive(ScopedPtrLayerImplMap& oldLayers, scoped_ptr<LayerImpl>);
- static scoped_ptr<LayerImpl> synchronizeTreeRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer*, LayerTreeImpl*);
- static void updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, Layer*);
-
DISALLOW_COPY_AND_ASSIGN(TreeSynchronizer);
};
diff --git a/cc/tree_synchronizer_unittest.cc b/cc/tree_synchronizer_unittest.cc
index cc9409e..30c09f6 100644
--- a/cc/tree_synchronizer_unittest.cc
+++ b/cc/tree_synchronizer_unittest.cc
@@ -143,7 +143,7 @@ protected:
// return a null tree.
TEST_F(TreeSynchronizerTest, syncNullTree)
{
- scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(0, scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
+ scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(static_cast<Layer*>(NULL), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
EXPECT_TRUE(!layerImplTreeRoot.get());
}
diff --git a/cc/video_frame_provider_client_impl.cc b/cc/video_frame_provider_client_impl.cc
new file mode 100644
index 0000000..f8b16bb
--- /dev/null
+++ b/cc/video_frame_provider_client_impl.cc
@@ -0,0 +1,87 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/video_frame_provider_client_impl.h"
+
+#include "cc/math_util.h"
+#include "cc/video_layer_impl.h"
+
+namespace cc {
+
+// static
+scoped_refptr<VideoFrameProviderClientImpl>
+ VideoFrameProviderClientImpl::Create(
+ VideoFrameProvider* provider) {
+ return make_scoped_refptr(
+ new VideoFrameProviderClientImpl(provider));
+}
+
+VideoFrameProviderClientImpl::~VideoFrameProviderClientImpl() {}
+
+VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
+ VideoFrameProvider* provider)
+ : provider_(provider) {
+ // This only happens during a commit on the compositor thread while the main
+ // thread is blocked. That makes this a thread-safe call to set the video
+ // frame provider client that does not require a lock. The same is true of
+ // the call to Stop().
+ provider_->SetVideoFrameProviderClient(this);
+
+ // This matrix is the default transformation for stream textures, and flips
+ // on the Y axis.
+ stream_texture_matrix_ = gfx::Transform(
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, -1.0, 0.0, 1.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+}
+
+void VideoFrameProviderClientImpl::Stop() {
+ if (!provider_)
+ return;
+ provider_->SetVideoFrameProviderClient(NULL);
+ provider_ = NULL;
+}
+
+media::VideoFrame* VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame() {
+ provider_lock_.Acquire(); // Balanced by call to ReleaseLock().
+ if (!provider_)
+ return NULL;
+
+ return provider_->GetCurrentFrame();
+}
+
+void VideoFrameProviderClientImpl::PutCurrentFrame(media::VideoFrame* frame) {
+ provider_lock_.AssertAcquired();
+ provider_->PutCurrentFrame(frame);
+}
+
+void VideoFrameProviderClientImpl::ReleaseLock() {
+ provider_lock_.AssertAcquired();
+ provider_lock_.Release();
+}
+
+void VideoFrameProviderClientImpl::StopUsingProvider() {
+ // Block the provider from shutting down until this client is done
+ // using the frame.
+ base::AutoLock locker(provider_lock_);
+ provider_ = 0;
+}
+
+void VideoFrameProviderClientImpl::DidReceiveFrame() {
+ if (active_video_layer_)
+ active_video_layer_->setNeedsRedraw();
+}
+
+void VideoFrameProviderClientImpl::DidUpdateMatrix(const float* matrix) {
+ stream_texture_matrix_ = gfx::Transform(
+ matrix[0], matrix[4], matrix[8], matrix[12],
+ matrix[1], matrix[5], matrix[9], matrix[13],
+ matrix[2], matrix[6], matrix[10], matrix[14],
+ matrix[3], matrix[7], matrix[11], matrix[15]);
+ if (active_video_layer_)
+ active_video_layer_->setNeedsRedraw();
+}
+
+} // namespace cc
diff --git a/cc/video_frame_provider_client_impl.h b/cc/video_frame_provider_client_impl.h
new file mode 100644
index 0000000..70722b8
--- /dev/null
+++ b/cc/video_frame_provider_client_impl.h
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_VIDEO_FRAME_PROVIDER_CLIENT_IMPL_H_
+#define CC_VIDEO_FRAME_PROVIDER_CLIENT_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "cc/video_frame_provider.h"
+#include "ui/gfx/transform.h"
+
+namespace media {
+class VideoFrame;
+}
+
+namespace cc {
+class VideoLayerImpl;
+
+class VideoFrameProviderClientImpl :
+ public VideoFrameProvider::Client,
+ public base::RefCounted<VideoFrameProviderClientImpl> {
+ public:
+ static scoped_refptr<VideoFrameProviderClientImpl> Create(
+ VideoFrameProvider* provider);
+
+ void set_active_video_layer(VideoLayerImpl* video_layer) {
+ active_video_layer_ = video_layer;
+ }
+
+ void Stop();
+ bool Stopped() const { return !provider_; }
+
+ media::VideoFrame* AcquireLockAndCurrentFrame();
+ void PutCurrentFrame(media::VideoFrame* frame);
+ void ReleaseLock();
+ const gfx::Transform& stream_texture_matrix() const {
+ return stream_texture_matrix_;
+ }
+
+ // VideoFrameProvider::Client implementation.
+ virtual void StopUsingProvider() OVERRIDE; // Callable on any thread.
+ virtual void DidReceiveFrame() OVERRIDE; // Callable on impl thread.
+ virtual void DidUpdateMatrix(const float*) OVERRIDE; // Callable on impl thread.
+
+ private:
+ explicit VideoFrameProviderClientImpl(VideoFrameProvider* provider);
+ friend class base::RefCounted<VideoFrameProviderClientImpl>;
+ virtual ~VideoFrameProviderClientImpl();
+
+ VideoLayerImpl* active_video_layer_;
+
+ // Guards the destruction of provider_ and the frame that it provides
+ base::Lock provider_lock_;
+ VideoFrameProvider* provider_;
+
+ gfx::Transform stream_texture_matrix_;
+};
+
+} // namespace cc
+
+#endif // CC_VIDEO_FRAME_PROVIDER_CLIENT_IMPL_H_
diff --git a/cc/video_layer_impl.cc b/cc/video_layer_impl.cc
index b536bbe..8a624bfa 100644
--- a/cc/video_layer_impl.cc
+++ b/cc/video_layer_impl.cc
@@ -13,6 +13,7 @@
#include "cc/resource_provider.h"
#include "cc/stream_video_draw_quad.h"
#include "cc/texture_draw_quad.h"
+#include "cc/video_frame_provider_client_impl.h"
#include "cc/yuv_video_draw_quad.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "media/filters/skcanvas_video_renderer.h"
@@ -21,34 +22,36 @@
namespace cc {
-VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider)
+// static
+scoped_ptr<VideoLayerImpl> VideoLayerImpl::create(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider)
+{
+ scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(treeImpl, id));
+ layer->setProviderClientImpl(VideoFrameProviderClientImpl::Create(provider));
+ DCHECK(treeImpl->proxy()->isImplThread());
+ DCHECK(treeImpl->proxy()->isMainThreadBlocked());
+ return layer.Pass();
+}
+
+VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id)
: LayerImpl(treeImpl, id)
- , m_provider(provider)
, m_frame(0)
, m_format(GL_INVALID_VALUE)
, m_convertYUV(false)
, m_externalTextureResource(0)
{
- // This matrix is the default transformation for stream textures, and flips on the Y axis.
- m_streamTextureMatrix = gfx::Transform(
- 1.0, 0.0, 0.0, 0.0,
- 0.0, -1.0, 0.0, 1.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0);
-
- // This only happens during a commit on the compositor thread while the main
- // thread is blocked. That makes this a thread-safe call to set the video
- // frame provider client that does not require a lock. The same is true of
- // the call in the destructor.
- m_provider->SetVideoFrameProviderClient(this);
}
VideoLayerImpl::~VideoLayerImpl()
{
- // See comment in constructor for why this doesn't need a lock.
- if (m_provider) {
- m_provider->SetVideoFrameProviderClient(0);
- m_provider = 0;
+ if (!m_providerClientImpl->Stopped()) {
+ // In impl side painting, we may have a pending and active layer
+ // associated with the video provider at the same time. Both have a ref
+ // on the VideoFrameProviderClientImpl, but we stop when the first
+ // LayerImpl (the one on the pending tree) is destroyed since we know
+ // the main thread is blocked for this commit.
+ DCHECK(layerTreeImpl()->proxy()->isImplThread());
+ DCHECK(layerTreeImpl()->proxy()->isMainThreadBlocked());
+ m_providerClientImpl->Stop();
}
freePlaneData(layerTreeImpl()->resource_provider());
@@ -59,13 +62,22 @@ VideoLayerImpl::~VideoLayerImpl()
#endif
}
-void VideoLayerImpl::StopUsingProvider()
+scoped_ptr<LayerImpl> VideoLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
{
- // Block the provider from shutting down until this client is done
- // using the frame.
- base::AutoLock locker(m_providerLock);
- DCHECK(!m_frame);
- m_provider = 0;
+ return scoped_ptr<LayerImpl>(new VideoLayerImpl(treeImpl, id()));
+}
+
+void VideoLayerImpl::pushPropertiesTo(LayerImpl* layer)
+{
+ LayerImpl::pushPropertiesTo(layer);
+
+ VideoLayerImpl* other = static_cast<VideoLayerImpl*>(layer);
+ other->setProviderClientImpl(m_providerClientImpl);
+}
+
+void VideoLayerImpl::didBecomeActive()
+{
+ m_providerClientImpl->set_active_video_layer(this);
}
// Convert media::VideoFrame::Format to OpenGL enum values.
@@ -116,6 +128,7 @@ void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider)
{
LayerImpl::willDraw(resourceProvider);
+
// Explicitly acquire and release the provider mutex so it can be held from
// willDraw to didDraw. Since the compositor thread is in the middle of
// drawing, the layer will not be destroyed before didDraw is called.
@@ -123,26 +136,19 @@ void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider)
// is the GPU process locking it. As the GPU process can't cause the
// destruction of the provider (calling stopUsingProvider), holding this
// lock should not cause a deadlock.
- m_providerLock.Acquire();
+ m_frame = m_providerClientImpl->AcquireLockAndCurrentFrame();
willDrawInternal(resourceProvider);
freeUnusedPlaneData(resourceProvider);
if (!m_frame)
- m_providerLock.Release();
+ m_providerClientImpl->ReleaseLock();
}
void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
{
DCHECK(!m_externalTextureResource);
- if (!m_provider) {
- m_frame = 0;
- return;
- }
-
- m_frame = m_provider->GetCurrentFrame();
-
if (!m_frame)
return;
@@ -155,7 +161,7 @@ void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
DCHECK_EQ(m_frame->visible_rect().y(), 0);
if (m_format == GL_INVALID_VALUE) {
- m_provider->PutCurrentFrame(m_frame);
+ m_providerClientImpl->PutCurrentFrame(m_frame);
m_frame = 0;
return;
}
@@ -172,13 +178,13 @@ void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
m_format = GL_RGBA;
if (!allocatePlaneData(resourceProvider)) {
- m_provider->PutCurrentFrame(m_frame);
+ m_providerClientImpl->PutCurrentFrame(m_frame);
m_frame = 0;
return;
}
if (!copyPlaneData(resourceProvider)) {
- m_provider->PutCurrentFrame(m_frame);
+ m_providerClientImpl->PutCurrentFrame(m_frame);
m_frame = 0;
return;
}
@@ -255,7 +261,7 @@ void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad
}
case GL_TEXTURE_EXTERNAL_OES: {
// StreamTexture hardware decoder.
- gfx::Transform transform(m_streamTextureMatrix);
+ gfx::Transform transform(m_providerClientImpl->stream_texture_matrix());
transform.Scale(texWidthScale, texHeightScale);
scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::Create();
streamVideoQuad->SetNew(sharedQuadState, quadRect, opaqueRect, m_frame->texture_id(), transform);
@@ -285,10 +291,10 @@ void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider)
m_externalTextureResource = 0;
}
- m_provider->PutCurrentFrame(m_frame);
+ m_providerClientImpl->PutCurrentFrame(m_frame);
m_frame = 0;
- m_providerLock.Release();
+ m_providerClientImpl->ReleaseLock();
}
static gfx::Size videoFrameDimension(media::VideoFrame* frame, int plane) {
@@ -397,21 +403,6 @@ void VideoLayerImpl::freeUnusedPlaneData(ResourceProvider* resourceProvider)
m_framePlanes[i].freeData(resourceProvider);
}
-void VideoLayerImpl::DidReceiveFrame()
-{
- setNeedsRedraw();
-}
-
-void VideoLayerImpl::DidUpdateMatrix(const float matrix[16])
-{
- m_streamTextureMatrix = gfx::Transform(
- matrix[0], matrix[4], matrix[8], matrix[12],
- matrix[1], matrix[5], matrix[9], matrix[13],
- matrix[2], matrix[6], matrix[10], matrix[14],
- matrix[3], matrix[7], matrix[11], matrix[15]);
- setNeedsRedraw();
-}
-
void VideoLayerImpl::didLoseOutputSurface()
{
freePlaneData(layerTreeImpl()->resource_provider());
@@ -422,6 +413,11 @@ void VideoLayerImpl::setNeedsRedraw()
layerTreeImpl()->SetNeedsRedraw();
}
+void VideoLayerImpl::setProviderClientImpl(scoped_refptr<VideoFrameProviderClientImpl> providerClientImpl)
+{
+ m_providerClientImpl = providerClientImpl;
+}
+
const char* VideoLayerImpl::layerTypeAsString() const
{
return "VideoLayer";
diff --git a/cc/video_layer_impl.h b/cc/video_layer_impl.h
index 0ea274d..73d854a 100644
--- a/cc/video_layer_impl.h
+++ b/cc/video_layer_impl.h
@@ -21,29 +21,26 @@ class SkCanvasVideoRenderer;
namespace cc {
class LayerTreeHostImpl;
+class VideoFrameProviderClientImpl;
-class CC_EXPORT VideoLayerImpl : public LayerImpl
- , public VideoFrameProvider::Client {
+class CC_EXPORT VideoLayerImpl : public LayerImpl {
public:
- static scoped_ptr<VideoLayerImpl> create(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider)
- {
- return make_scoped_ptr(new VideoLayerImpl(treeImpl, id, provider));
- }
+ static scoped_ptr<VideoLayerImpl> create(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider);
virtual ~VideoLayerImpl();
+ // LayerImpl implementation.
+ virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl*) OVERRIDE;
+ virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
virtual void willDraw(ResourceProvider*) OVERRIDE;
virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE;
virtual void didDraw(ResourceProvider*) OVERRIDE;
-
- // VideoFrameProvider::Client implementation.
- virtual void StopUsingProvider() OVERRIDE; // Callable on any thread.
- virtual void DidReceiveFrame() OVERRIDE; // Callable on impl thread.
- virtual void DidUpdateMatrix(const float*) OVERRIDE; // Callable on impl thread.
-
+ virtual void didBecomeActive() OVERRIDE;
virtual void didLoseOutputSurface() OVERRIDE;
void setNeedsRedraw();
+ void setProviderClientImpl(scoped_refptr<VideoFrameProviderClientImpl>);
+
struct FramePlane {
ResourceProvider::ResourceId resourceId;
gfx::Size size;
@@ -56,7 +53,7 @@ public:
};
private:
- VideoLayerImpl(LayerTreeImpl*, int, VideoFrameProvider*);
+ VideoLayerImpl(LayerTreeImpl*, int);
virtual const char* layerTypeAsString() const OVERRIDE;
@@ -67,11 +64,7 @@ private:
void freeUnusedPlaneData(ResourceProvider*);
size_t numPlanes() const;
- // Guards the destruction of m_provider and the frame that it provides
- base::Lock m_providerLock;
- VideoFrameProvider* m_provider;
-
- gfx::Transform m_streamTextureMatrix;
+ scoped_refptr<VideoFrameProviderClientImpl> m_providerClientImpl;
media::VideoFrame* m_frame;
GLenum m_format;