Index: ui/compositor/layer.cc |
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc |
index ac20550710eff3c762a72a6000170a9b61ae6ae6..b6f8ad484682481923d64da9e9dbbbc233f647c7 100644 |
--- a/ui/compositor/layer.cc |
+++ b/ui/compositor/layer.cc |
@@ -49,6 +49,42 @@ const ui::Layer* GetRoot(const ui::Layer* layer) { |
namespace ui { |
+class Layer::LayerMirror : public LayerDelegate, LayerObserver { |
+ public: |
+ LayerMirror(Layer* source, Layer* dest) |
+ : source_(source), dest_(dest) { |
+ dest->AddObserver(this); |
+ dest->set_delegate(this); |
+ } |
+ |
+ ~LayerMirror() override { |
+ dest_->RemoveObserver(this); |
+ dest_->set_delegate(nullptr); |
+ } |
+ |
+ Layer* dest() { return dest_; } |
+ |
+ // LayerDelegate: |
+ void OnPaintLayer(const PaintContext& context) override { |
+ if (auto* delegate = source_->delegate()) |
+ delegate->OnPaintLayer(context); |
+ } |
+ void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
+ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} |
+ |
+ // LayerObserver: |
+ void LayerDestroyed(Layer* layer) override { |
+ DCHECK_EQ(dest_, layer); |
+ source_->OnMirrorDestroyed(this); |
+ } |
+ |
+ private: |
+ Layer* const source_; |
+ Layer* const dest_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(LayerMirror); |
+}; |
+ |
Layer::Layer() |
: type_(LAYER_TEXTURED), |
compositor_(NULL), |
@@ -119,6 +155,52 @@ Layer::~Layer() { |
mailbox_release_callback_->Run(gpu::SyncToken(), false); |
} |
+std::unique_ptr<Layer> Layer::Clone() const { |
+ auto clone = base::MakeUnique<Layer>(type_); |
+ |
+ clone->SetTransform(GetTargetTransform()); |
+ clone->SetBounds(bounds_); |
+ clone->SetSubpixelPositionOffset(subpixel_position_offset_); |
+ clone->SetMasksToBounds(GetMasksToBounds()); |
+ clone->SetOpacity(GetTargetOpacity()); |
+ clone->SetVisible(GetTargetVisibility()); |
+ clone->SetFillsBoundsOpaquely(fills_bounds_opaquely_); |
+ clone->SetFillsBoundsCompletely(fills_bounds_completely_); |
+ clone->set_name(name_); |
+ |
+ // Background filters. |
+ clone->SetBackgroundBlur(background_blur_radius_); |
+ clone->SetBackgroundZoom(zoom_, zoom_inset_); |
+ |
+ // Filters. |
+ clone->SetLayerSaturation(layer_saturation_); |
+ clone->SetLayerBrightness(GetTargetBrightness()); |
+ clone->SetLayerGrayscale(GetTargetGrayscale()); |
+ clone->SetLayerInverted(layer_inverted_); |
+ if (alpha_shape_) |
+ clone->SetAlphaShape(base::MakeUnique<SkRegion>(*alpha_shape_)); |
+ |
+ // cc::Layer state. |
+ if (surface_layer_ && !surface_layer_->surface_id().is_null()) { |
+ clone->SetShowSurface( |
+ surface_layer_->surface_id(), |
+ surface_layer_->satisfy_callback(), |
+ surface_layer_->require_callback(), |
+ surface_layer_->surface_size(), |
+ surface_layer_->surface_scale(), |
+ frame_size_in_dip_); |
+ } else if (type_ == LAYER_SOLID_COLOR) { |
+ clone->SetColor(GetTargetColor()); |
+ } |
+ return clone; |
+} |
+ |
+std::unique_ptr<Layer> Layer::Mirror() { |
+ auto mirror = Clone(); |
+ mirrors_.emplace_back(base::MakeUnique<LayerMirror>(this, mirror.get())); |
+ return mirror; |
+} |
+ |
const Compositor* Layer::GetCompositor() const { |
return GetRoot(this)->compositor_; |
} |
@@ -238,7 +320,7 @@ void Layer::SetAnimator(LayerAnimator* animator) { |
} |
LayerAnimator* Layer::GetAnimator() { |
- if (!animator_.get()) |
+ if (!animator_) |
SetAnimator(LayerAnimator::CreateDefaultAnimator()); |
return animator_.get(); |
} |
@@ -248,7 +330,7 @@ void Layer::SetTransform(const gfx::Transform& transform) { |
} |
gfx::Transform Layer::GetTargetTransform() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::TRANSFORM)) { |
return animator_->GetTargetTransform(); |
} |
@@ -265,7 +347,7 @@ void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF& offset) { |
} |
gfx::Rect Layer::GetTargetBounds() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::BOUNDS)) { |
return animator_->GetTargetBounds(); |
} |
@@ -310,7 +392,7 @@ void Layer::SetLayerBrightness(float brightness) { |
} |
float Layer::GetTargetBrightness() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::BRIGHTNESS)) { |
return animator_->GetTargetBrightness(); |
} |
@@ -322,7 +404,7 @@ void Layer::SetLayerGrayscale(float grayscale) { |
} |
float Layer::GetTargetGrayscale() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::GRAYSCALE)) { |
return animator_->GetTargetGrayscale(); |
} |
@@ -411,7 +493,7 @@ void Layer::SetLayerBackgroundFilters() { |
} |
float Layer::GetTargetOpacity() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::OPACITY)) |
return animator_->GetTargetOpacity(); |
return opacity(); |
@@ -422,7 +504,7 @@ void Layer::SetVisible(bool visible) { |
} |
bool Layer::GetTargetVisibility() const { |
- if (animator_.get() && animator_->IsAnimatingProperty( |
+ if (animator_ && animator_->IsAnimatingProperty( |
LayerAnimationElement::VISIBILITY)) |
return animator_->GetTargetVisibility(); |
return visible_; |
@@ -486,7 +568,7 @@ void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) { |
void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { |
// Finish animations being handled by cc_layer_. |
- if (animator_.get()) { |
+ if (animator_) { |
animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); |
animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY); |
animator_->SwitchToLayer(new_layer); |
@@ -593,8 +675,11 @@ void Layer::SetShowSurface( |
frame_size_in_dip_ = frame_size_in_dip; |
RecomputeDrawsContentAndUVRect(); |
- for (auto& observer : observer_list_) |
- observer.SurfaceChanged(this); |
+ for (const auto& mirror : mirrors_) { |
+ mirror->dest()->SetShowSurface( |
+ surface_id, satisfy_callback, require_callback, |
+ surface_size, scale, frame_size_in_dip); |
+ } |
} |
void Layer::SetShowSolidColorContent() { |
@@ -651,9 +736,10 @@ void Layer::UpdateNinePatchOcclusion(const gfx::Rect& occlusion) { |
void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); } |
-SkColor Layer::GetTargetColor() { |
- if (GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR)) |
- return GetAnimator()->GetTargetColor(); |
+SkColor Layer::GetTargetColor() const { |
+ if (animator_ && animator_->IsAnimatingProperty( |
+ LayerAnimationElement::COLOR)) |
+ return animator_->GetTargetColor(); |
return cc_layer_->background_color(); |
} |
@@ -720,7 +806,7 @@ void Layer::SuppressPaint() { |
void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) { |
if (device_scale_factor_ == device_scale_factor) |
return; |
- if (animator_.get()) |
+ if (animator_) |
animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); |
device_scale_factor_ = device_scale_factor; |
RecomputeDrawsContentAndUVRect(); |
@@ -797,8 +883,9 @@ scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList( |
PaintContext(display_list.get(), device_scale_factor_, invalidation)); |
} |
display_list->Finalize(); |
- for (auto& observer : observer_list_) |
- observer.DidPaintLayer(this, invalidation); |
+ // TODO(domlaskowski): Move mirror invalidation to Layer::SchedulePaint. |
+ for (const auto& mirror : mirrors_) |
+ mirror->dest()->SchedulePaint(invalidation); |
return display_list; |
} |
@@ -916,6 +1003,11 @@ void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { |
// Always schedule a paint, even if we're invisible. |
SchedulePaint(gfx::Rect(bounds.size())); |
} |
+ |
+ if (sync_bounds_) { |
+ for (const auto& mirror : mirrors_) |
+ mirror->dest()->SetBounds(bounds); |
+ } |
} |
void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { |
@@ -1076,4 +1168,14 @@ void Layer::ResetCompositorForAnimatorsInTree(Compositor* compositor) { |
child->ResetCompositorForAnimatorsInTree(compositor); |
} |
+void Layer::OnMirrorDestroyed(LayerMirror* mirror) { |
+ const auto it = std::find_if(mirrors_.begin(), mirrors_.end(), |
+ [mirror](const std::unique_ptr<LayerMirror>& mirror_ptr) { |
+ return mirror_ptr.get() == mirror; |
+ }); |
+ |
+ DCHECK(it != mirrors_.end()); |
+ mirrors_.erase(it); |
+} |
+ |
} // namespace ui |