diff options
42 files changed, 687 insertions, 170 deletions
@@ -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) @@ -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; |