| Index: cc/layers/surface_layer.cc
|
| diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc
|
| index ba577a00d58e7abd952b794ed1dd04d8f98640d3..2d8b0e1baff7d54a766aada5bac2114ae688dc03 100644
|
| --- a/cc/layers/surface_layer.cc
|
| +++ b/cc/layers/surface_layer.cc
|
| @@ -4,10 +4,48 @@
|
|
|
| #include "cc/layers/surface_layer.h"
|
|
|
| +#include "cc/base/swap_promise.h"
|
| #include "cc/layers/surface_layer_impl.h"
|
| +#include "cc/surfaces/surface_manager.h"
|
| +#include "cc/trees/layer_tree_host.h"
|
|
|
| namespace cc {
|
|
|
| +// This only works with threaded compositing disabled, as the swap promise could
|
| +// be destroyed on either the impl or main thread.
|
| +class SatisfySwapPromise : public SwapPromise,
|
| + public base::SupportsWeakPtr<SatisfySwapPromise> {
|
| + public:
|
| + SatisfySwapPromise(SurfaceSequence sequence,
|
| + LayerTreeHost* host,
|
| + SurfaceHolder::SatisfyCallback satisfy_callback)
|
| + : sequence_(sequence), host_(host), satisfy_callback_(satisfy_callback) {}
|
| +
|
| + SurfaceSequence RemoveSequence() {
|
| + SurfaceSequence last_sequence = sequence_;
|
| + sequence_ = SurfaceSequence();
|
| + return last_sequence;
|
| + }
|
| +
|
| + LayerTreeHost* host() { return host_; }
|
| +
|
| + private:
|
| + void DidSwap(CompositorFrameMetadata* metadata) override {
|
| + if (!sequence_.is_null())
|
| + metadata->satisfies_sequences.push_back(sequence_.sequence);
|
| + }
|
| +
|
| + void DidNotSwap(DidNotSwapReason reason) override {
|
| + if (!sequence_.is_null())
|
| + satisfy_callback_.Run(sequence_);
|
| + }
|
| + int64 TraceId() const override { return 0; }
|
| +
|
| + SurfaceSequence sequence_;
|
| + LayerTreeHost* host_;
|
| + SurfaceHolder::SatisfyCallback satisfy_callback_;
|
| +};
|
| +
|
| scoped_refptr<SurfaceLayer> SurfaceLayer::Create() {
|
| return make_scoped_refptr(new SurfaceLayer);
|
| }
|
| @@ -15,10 +53,17 @@ scoped_refptr<SurfaceLayer> SurfaceLayer::Create() {
|
| SurfaceLayer::SurfaceLayer() : Layer() {
|
| }
|
|
|
| -SurfaceLayer::~SurfaceLayer() {}
|
| +SurfaceLayer::~SurfaceLayer() {
|
| + DCHECK(!layer_tree_host());
|
| + DCHECK(destroy_sequence_.is_null());
|
| +}
|
| +
|
| +void SurfaceLayer::SetSurfaceId(scoped_refptr<SurfaceHolder> surface_holder) {
|
| + SatisfyDestroySequence();
|
| + surface_holder_ = surface_holder;
|
| + last_swap_promise_.reset();
|
| + CreateNewDestroySequence();
|
|
|
| -void SurfaceLayer::SetSurfaceId(SurfaceId surface_id) {
|
| - surface_id_ = surface_id;
|
| UpdateDrawsContent(HasDrawableContent());
|
| SetNeedsPushProperties();
|
| }
|
| @@ -28,14 +73,58 @@ scoped_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
|
| }
|
|
|
| bool SurfaceLayer::HasDrawableContent() const {
|
| - return !surface_id_.is_null() && Layer::HasDrawableContent();
|
| + return surface_holder_.get() && !surface_holder_->surface_id().is_null() &&
|
| + Layer::HasDrawableContent();
|
| +}
|
| +
|
| +void SurfaceLayer::SetLayerTreeHost(LayerTreeHost* host) {
|
| + if (layer_tree_host() == host) {
|
| + Layer::SetLayerTreeHost(host);
|
| + return;
|
| + }
|
| +
|
| + SatisfyDestroySequence();
|
| + Layer::SetLayerTreeHost(host);
|
| + CreateNewDestroySequence();
|
| }
|
|
|
| void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
|
| Layer::PushPropertiesTo(layer);
|
| SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
|
|
|
| - layer_impl->SetSurfaceId(surface_id_);
|
| + layer_impl->SetSurfaceId(surface_holder_.get() ? surface_holder_->surface_id()
|
| + : SurfaceId());
|
| +}
|
| +
|
| +void SurfaceLayer::CreateNewDestroySequence() {
|
| + DCHECK(destroy_sequence_.is_null());
|
| + if (layer_tree_host() && surface_holder_.get()) {
|
| + if (last_swap_promise_ && last_swap_promise_->host() == layer_tree_host()) {
|
| + // Last swap promise hasn't been submitted yet, so reuse its
|
| + // SurfaceSequence instead of creating a new one. This allows the layer
|
| + // to be removed from and added back to a tree in the course of a commit
|
| + // and avoid requiring a new sequence.
|
| + destroy_sequence_ = last_swap_promise_->RemoveSequence();
|
| + DCHECK(!destroy_sequence_.is_null());
|
| + last_swap_promise_.reset();
|
| + } else {
|
| + destroy_sequence_ = layer_tree_host()->CreateSurfaceSequence();
|
| + surface_holder_->AddSurfaceSequence(destroy_sequence_);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void SurfaceLayer::SatisfyDestroySequence() {
|
| + if (!layer_tree_host() || !surface_holder_.get())
|
| + return;
|
| + DCHECK(!destroy_sequence_.is_null());
|
| + scoped_ptr<SatisfySwapPromise> satisfy(
|
| + new SatisfySwapPromise(destroy_sequence_,
|
| + layer_tree_host(),
|
| + surface_holder_->satisfy_callback()));
|
| + last_swap_promise_ = satisfy->AsWeakPtr();
|
| + layer_tree_host()->QueueSwapPromise(satisfy.Pass());
|
| + destroy_sequence_ = SurfaceSequence();
|
| }
|
|
|
| } // namespace cc
|
|
|