diff options
Diffstat (limited to 'chromium/ui/compositor/layer.cc')
-rw-r--r-- | chromium/ui/compositor/layer.cc | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/chromium/ui/compositor/layer.cc b/chromium/ui/compositor/layer.cc index ec9f20471ae..27efca014fd 100644 --- a/chromium/ui/compositor/layer.cc +++ b/chromium/ui/compositor/layer.cc @@ -308,7 +308,9 @@ void Layer::SetShowReflectedLayerSubtree(Layer* subtree_reflected_layer) { scoped_refptr<cc::MirrorLayer> new_layer = cc::MirrorLayer::Create(subtree_reflected_layer->cc_layer_); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return; + mirror_layer_ = std::move(new_layer); subtree_reflected_layer_ = subtree_reflected_layer; @@ -375,12 +377,20 @@ void Layer::Add(Layer* child) { } void Layer::Remove(Layer* child) { + base::WeakPtr<Layer> weak_this = weak_ptr_factory_.GetWeakPtr(); + base::WeakPtr<Layer> weak_child = child->weak_ptr_factory_.GetWeakPtr(); + // Current bounds are used to calculate offsets when layers are reparented. // Stop (and complete) an ongoing animation to update the bounds immediately. LayerAnimator* child_animator = child->animator_.get(); if (child_animator) child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); + // Do not proceed if |this| or |child| is released by an animation observer + // of |child|'s bounds animation. + if (!weak_this || !weak_child) + return; + Compositor* compositor = GetCompositor(); if (compositor) child->ResetCompositorForAnimatorsInTree(compositor); @@ -725,11 +735,19 @@ void Layer::SetName(const std::string& name) { cc_layer_->SetDebugName(name); } -void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { +bool Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { // Finish animations being handled by cc_layer_. if (animator_) { + base::WeakPtr<Layer> weak_this = weak_ptr_factory_.GetWeakPtr(); + animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); + if (!weak_this) + return false; + animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY); + if (!weak_this) + return false; + animator_->SwitchToLayer(new_layer); } @@ -781,12 +799,16 @@ void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { SetLayerFilters(); SetLayerBackgroundFilters(); + return true; } -void Layer::SwitchCCLayerForTest() { +bool Layer::SwitchCCLayerForTest() { scoped_refptr<cc::PictureLayer> new_layer = cc::PictureLayer::Create(this); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return false; + content_layer_ = std::move(new_layer); + return true; } // Note: The code that sets this flag would be responsible to unset it on that @@ -889,7 +911,9 @@ void Layer::SetTransferableResource( scoped_refptr<cc::TextureLayer> new_layer = cc::TextureLayer::CreateForMailbox(this); new_layer->SetFlipped(true); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return; + texture_layer_ = new_layer; // Reset the frame_size_in_dip_ so that SetTextureSize() will not early out, // the frame_size_in_dip_ was for a previous (different) |texture_layer_|. @@ -972,7 +996,9 @@ void Layer::SetShowReflectedSurface(const viz::SurfaceId& surface_id, if (!surface_layer_) { scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create(); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return; + surface_layer_ = new_layer; } @@ -1007,7 +1033,9 @@ void Layer::SetShowSolidColorContent() { return; scoped_refptr<cc::SolidColorLayer> new_layer = cc::SolidColorLayer::Create(); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return; + solid_color_layer_ = new_layer; transfer_resource_ = viz::TransferableResource(); @@ -1385,10 +1413,12 @@ void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds, reflecting_layer->MatchLayerSize(this); } -void Layer::SetTransformFromAnimation(const gfx::Transform& transform, +void Layer::SetTransformFromAnimation(const gfx::Transform& new_transform, PropertyChangeReason reason) { - const gfx::Transform old_transform = this->transform(); - cc_layer_->SetTransform(transform); + const gfx::Transform old_transform = transform(); + if (old_transform == new_transform) + return; + cc_layer_->SetTransform(new_transform); // Skip recomputing position if the subpixel offset does not need updating // which is the case if an explicit offset is set. @@ -1618,7 +1648,9 @@ void Layer::CreateSurfaceLayerIfNecessary() { return; scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create(); new_layer->SetSurfaceHitTestable(true); - SwitchToLayer(new_layer); + if (!SwitchToLayer(new_layer)) + return; + surface_layer_ = new_layer; } |