diff options
-rw-r--r-- | cc/layer.cc | 16 | ||||
-rw-r--r-- | cc/layer.h | 2 | ||||
-rw-r--r-- | cc/layer_tree_host.cc | 7 | ||||
-rw-r--r-- | cc/layer_tree_host.h | 2 | ||||
-rw-r--r-- | cc/texture_layer.cc | 2 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 22 |
6 files changed, 48 insertions, 3 deletions
diff --git a/cc/layer.cc b/cc/layer.cc index 56ae606..a742d07 100644 --- a/cc/layer.cc +++ b/cc/layer.cc @@ -132,6 +132,22 @@ bool Layer::canClipSelf() const return false; } +bool Layer::blocksPendingCommitRecursive() const +{ + if (blocksPendingCommit()) + return true; + if (maskLayer() && maskLayer()->blocksPendingCommitRecursive()) + return true; + if (replicaLayer() && replicaLayer()->blocksPendingCommitRecursive()) + return true; + for (size_t i = 0; i < m_children.size(); ++i) + { + if (m_children[i]->blocksPendingCommitRecursive()) + return true; + } + return false; +} + void Layer::setParent(Layer* layer) { DCHECK(!layer || !layer->hasAncestor(this)); @@ -286,6 +286,8 @@ public: // compatible with the main thread running freely, such as a double-buffered // canvas that doesn't want to be triple-buffered across all three trees. virtual bool blocksPendingCommit() const; + // Returns true if anything in this tree blocksPendingCommit. + bool blocksPendingCommitRecursive() const; virtual bool canClipSelf() const; diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index b2f930a..5e56eb8 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -843,6 +843,13 @@ void LayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor) setNeedsCommit(); } +bool LayerTreeHost::blocksPendingCommit() const +{ + if (!m_rootLayer) + return false; + return m_rootLayer->blocksPendingCommitRecursive(); +} + void LayerTreeHost::animateLayers(base::TimeTicks time) { if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty()) diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h index 70c8cf4..c7bb565 100644 --- a/cc/layer_tree_host.h +++ b/cc/layer_tree_host.h @@ -203,6 +203,8 @@ public: skia::RefPtr<SkPicture> capturePicture(); + bool blocksPendingCommit() const; + protected: LayerTreeHost(LayerTreeHostClient*, const LayerTreeSettings&); bool initialize(scoped_ptr<Thread> implThread); diff --git a/cc/texture_layer.cc b/cc/texture_layer.cc index 6a981a0..575fd5f 100644 --- a/cc/texture_layer.cc +++ b/cc/texture_layer.cc @@ -195,7 +195,7 @@ bool TextureLayer::blocksPendingCommit() const // Double-buffered texture layers need to be blocked until they can be made // triple-buffered. Single-buffered layers already prevent draws, so // can block too for simplicity. - return true; + return drawsContent(); } bool TextureLayer::canClipSelf() const diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index 022f1eb..1cdcb55 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -720,8 +720,17 @@ void ThreadProxy::scheduledActionCommit() m_nextFrameIsNewlyCommittedFrameOnImplThread = true; - m_commitCompletionEventOnImplThread->signal(); - m_commitCompletionEventOnImplThread = 0; + if (m_layerTreeHost->settings().implSidePainting && m_layerTreeHost->blocksPendingCommit()) + { + // For some layer types in impl-side painting, the commit is held until + // the pending tree is activated. + TRACE_EVENT_INSTANT0("cc", "HoldCommit"); + } + else + { + m_commitCompletionEventOnImplThread->signal(); + m_commitCompletionEventOnImplThread = 0; + } // SetVisible kicks off the next scheduler action, so this must be last. m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); @@ -780,6 +789,15 @@ ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal } m_layerTreeHostImpl->didDrawAllLayers(frame); + // Check for tree activation. + if (m_commitCompletionEventOnImplThread && !m_layerTreeHostImpl->pendingTree()) + { + TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation"); + DCHECK(m_layerTreeHostImpl->settings().implSidePainting); + m_commitCompletionEventOnImplThread->signal(); + m_commitCompletionEventOnImplThread = 0; + } + // Check for a pending compositeAndReadback. if (m_readbackRequestOnImplThread) { m_readbackRequestOnImplThread->success = false; |