summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;