1 // Copyright 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/layers/layer.h"
6
7 #include <algorithm>
8
9 #include "base/debug/trace_event.h"
10 #include "base/location.h"
11 #include "base/metrics/histogram.h"
12 #include "base/single_thread_task_runner.h"
13 #include "cc/animation/animation.h"
14 #include "cc/animation/animation_events.h"
15 #include "cc/animation/keyframed_animation_curve.h"
16 #include "cc/animation/layer_animation_controller.h"
17 #include "cc/layers/layer_client.h"
18 #include "cc/layers/layer_impl.h"
19 #include "cc/output/copy_output_request.h"
20 #include "cc/output/copy_output_result.h"
21 #include "cc/trees/layer_tree_host.h"
22 #include "cc/trees/layer_tree_impl.h"
23 #include "third_party/skia/include/core/SkImageFilter.h"
24 #include "ui/gfx/rect_conversions.h"
25
26 namespace cc {
27
28 static int s_next_layer_id = 1;
29
Create()30 scoped_refptr<Layer> Layer::Create() {
31 return make_scoped_refptr(new Layer());
32 }
33
Layer()34 Layer::Layer()
35 : needs_push_properties_(false),
36 num_dependents_need_push_properties_(false),
37 stacking_order_changed_(false),
38 layer_id_(s_next_layer_id++),
39 ignore_set_needs_commit_(false),
40 parent_(NULL),
41 layer_tree_host_(NULL),
42 scrollable_(false),
43 should_scroll_on_main_thread_(false),
44 have_wheel_event_handlers_(false),
45 user_scrollable_horizontal_(true),
46 user_scrollable_vertical_(true),
47 is_root_for_isolated_group_(false),
48 is_container_for_fixed_position_layers_(false),
49 is_drawable_(false),
50 hide_layer_and_subtree_(false),
51 masks_to_bounds_(false),
52 contents_opaque_(false),
53 double_sided_(true),
54 preserves_3d_(false),
55 use_parent_backface_visibility_(false),
56 draw_checkerboard_for_missing_tiles_(false),
57 force_render_surface_(false),
58 anchor_point_(0.5f, 0.5f),
59 background_color_(0),
60 compositing_reasons_(kCompositingReasonUnknown),
61 opacity_(1.f),
62 blend_mode_(SkXfermode::kSrcOver_Mode),
63 anchor_point_z_(0.f),
64 scroll_parent_(NULL),
65 clip_parent_(NULL),
66 replica_layer_(NULL),
67 raster_scale_(0.f),
68 client_(NULL) {
69 if (layer_id_ < 0) {
70 s_next_layer_id = 1;
71 layer_id_ = s_next_layer_id++;
72 }
73
74 layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
75 layer_animation_controller_->AddValueObserver(this);
76 layer_animation_controller_->set_value_provider(this);
77 }
78
~Layer()79 Layer::~Layer() {
80 // Our parent should be holding a reference to us so there should be no
81 // way for us to be destroyed while we still have a parent.
82 DCHECK(!parent());
83 // Similarly we shouldn't have a layer tree host since it also keeps a
84 // reference to us.
85 DCHECK(!layer_tree_host());
86
87 layer_animation_controller_->RemoveValueObserver(this);
88 layer_animation_controller_->remove_value_provider(this);
89
90 // Remove the parent reference from all children and dependents.
91 RemoveAllChildren();
92 if (mask_layer_.get()) {
93 DCHECK_EQ(this, mask_layer_->parent());
94 mask_layer_->RemoveFromParent();
95 }
96 if (replica_layer_.get()) {
97 DCHECK_EQ(this, replica_layer_->parent());
98 replica_layer_->RemoveFromParent();
99 }
100
101 RemoveFromScrollTree();
102 RemoveFromClipTree();
103 }
104
SetLayerTreeHost(LayerTreeHost * host)105 void Layer::SetLayerTreeHost(LayerTreeHost* host) {
106 if (layer_tree_host_ == host)
107 return;
108
109 layer_tree_host_ = host;
110
111 // When changing hosts, the layer needs to commit its properties to the impl
112 // side for the new host.
113 SetNeedsPushProperties();
114
115 for (size_t i = 0; i < children_.size(); ++i)
116 children_[i]->SetLayerTreeHost(host);
117
118 if (mask_layer_.get())
119 mask_layer_->SetLayerTreeHost(host);
120 if (replica_layer_.get())
121 replica_layer_->SetLayerTreeHost(host);
122
123 if (host) {
124 layer_animation_controller_->SetAnimationRegistrar(
125 host->animation_registrar());
126
127 if (host->settings().layer_transforms_should_scale_layer_contents)
128 reset_raster_scale_to_unknown();
129 }
130
131 if (host && layer_animation_controller_->has_any_animation())
132 host->SetNeedsCommit();
133 SetNeedsFilterContextIfNeeded();
134 }
135
SetNeedsUpdate()136 void Layer::SetNeedsUpdate() {
137 if (layer_tree_host_ && !ignore_set_needs_commit_)
138 layer_tree_host_->SetNeedsUpdateLayers();
139 }
140
SetNeedsCommit()141 void Layer::SetNeedsCommit() {
142 if (!layer_tree_host_)
143 return;
144
145 SetNeedsPushProperties();
146
147 if (ignore_set_needs_commit_)
148 return;
149
150 layer_tree_host_->SetNeedsCommit();
151 }
152
SetNeedsFullTreeSync()153 void Layer::SetNeedsFullTreeSync() {
154 if (!layer_tree_host_)
155 return;
156
157 layer_tree_host_->SetNeedsFullTreeSync();
158 }
159
SetNextCommitWaitsForActivation()160 void Layer::SetNextCommitWaitsForActivation() {
161 if (!layer_tree_host_)
162 return;
163
164 layer_tree_host_->SetNextCommitWaitsForActivation();
165 }
166
SetNeedsFilterContextIfNeeded()167 void Layer::SetNeedsFilterContextIfNeeded() {
168 if (!layer_tree_host_)
169 return;
170
171 if (!filters_.IsEmpty() || !background_filters_.IsEmpty() ||
172 !uses_default_blend_mode())
173 layer_tree_host_->set_needs_filter_context();
174 }
175
SetNeedsPushProperties()176 void Layer::SetNeedsPushProperties() {
177 if (needs_push_properties_)
178 return;
179 if (!parent_should_know_need_push_properties() && parent_)
180 parent_->AddDependentNeedsPushProperties();
181 needs_push_properties_ = true;
182 }
183
AddDependentNeedsPushProperties()184 void Layer::AddDependentNeedsPushProperties() {
185 DCHECK_GE(num_dependents_need_push_properties_, 0);
186
187 if (!parent_should_know_need_push_properties() && parent_)
188 parent_->AddDependentNeedsPushProperties();
189
190 num_dependents_need_push_properties_++;
191 }
192
RemoveDependentNeedsPushProperties()193 void Layer::RemoveDependentNeedsPushProperties() {
194 num_dependents_need_push_properties_--;
195 DCHECK_GE(num_dependents_need_push_properties_, 0);
196
197 if (!parent_should_know_need_push_properties() && parent_)
198 parent_->RemoveDependentNeedsPushProperties();
199 }
200
IsPropertyChangeAllowed() const201 bool Layer::IsPropertyChangeAllowed() const {
202 if (!layer_tree_host_)
203 return true;
204
205 if (!layer_tree_host_->settings().strict_layer_property_change_checking)
206 return true;
207
208 return !layer_tree_host_->in_paint_layer_contents();
209 }
210
LayerRectToContentRect(const gfx::RectF & layer_rect) const211 gfx::Rect Layer::LayerRectToContentRect(const gfx::RectF& layer_rect) const {
212 gfx::RectF content_rect =
213 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
214 // Intersect with content rect to avoid the extra pixel because for some
215 // values x and y, ceil((x / y) * y) may be x + 1.
216 content_rect.Intersect(gfx::Rect(content_bounds()));
217 return gfx::ToEnclosingRect(content_rect);
218 }
219
GetPicture() const220 skia::RefPtr<SkPicture> Layer::GetPicture() const {
221 return skia::RefPtr<SkPicture>();
222 }
223
SetParent(Layer * layer)224 void Layer::SetParent(Layer* layer) {
225 DCHECK(!layer || !layer->HasAncestor(this));
226
227 if (parent_should_know_need_push_properties()) {
228 if (parent_)
229 parent_->RemoveDependentNeedsPushProperties();
230 if (layer)
231 layer->AddDependentNeedsPushProperties();
232 }
233
234 parent_ = layer;
235 SetLayerTreeHost(parent_ ? parent_->layer_tree_host() : NULL);
236
237 if (!layer_tree_host_)
238 return;
239 const LayerTreeSettings& settings = layer_tree_host_->settings();
240 if (!settings.layer_transforms_should_scale_layer_contents)
241 return;
242
243 reset_raster_scale_to_unknown();
244 if (mask_layer_.get())
245 mask_layer_->reset_raster_scale_to_unknown();
246 if (replica_layer_.get() && replica_layer_->mask_layer_.get())
247 replica_layer_->mask_layer_->reset_raster_scale_to_unknown();
248 }
249
AddChild(scoped_refptr<Layer> child)250 void Layer::AddChild(scoped_refptr<Layer> child) {
251 InsertChild(child, children_.size());
252 }
253
InsertChild(scoped_refptr<Layer> child,size_t index)254 void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
255 DCHECK(IsPropertyChangeAllowed());
256 child->RemoveFromParent();
257 child->SetParent(this);
258 child->stacking_order_changed_ = true;
259
260 index = std::min(index, children_.size());
261 children_.insert(children_.begin() + index, child);
262 SetNeedsFullTreeSync();
263 }
264
RemoveFromParent()265 void Layer::RemoveFromParent() {
266 DCHECK(IsPropertyChangeAllowed());
267 if (parent_)
268 parent_->RemoveChildOrDependent(this);
269 }
270
RemoveChildOrDependent(Layer * child)271 void Layer::RemoveChildOrDependent(Layer* child) {
272 if (mask_layer_.get() == child) {
273 mask_layer_->SetParent(NULL);
274 mask_layer_ = NULL;
275 SetNeedsFullTreeSync();
276 return;
277 }
278 if (replica_layer_.get() == child) {
279 replica_layer_->SetParent(NULL);
280 replica_layer_ = NULL;
281 SetNeedsFullTreeSync();
282 return;
283 }
284
285 for (LayerList::iterator iter = children_.begin();
286 iter != children_.end();
287 ++iter) {
288 if (iter->get() != child)
289 continue;
290
291 child->SetParent(NULL);
292 children_.erase(iter);
293 SetNeedsFullTreeSync();
294 return;
295 }
296 }
297
ReplaceChild(Layer * reference,scoped_refptr<Layer> new_layer)298 void Layer::ReplaceChild(Layer* reference, scoped_refptr<Layer> new_layer) {
299 DCHECK(reference);
300 DCHECK_EQ(reference->parent(), this);
301 DCHECK(IsPropertyChangeAllowed());
302
303 if (reference == new_layer.get())
304 return;
305
306 int reference_index = IndexOfChild(reference);
307 if (reference_index == -1) {
308 NOTREACHED();
309 return;
310 }
311
312 reference->RemoveFromParent();
313
314 if (new_layer.get()) {
315 new_layer->RemoveFromParent();
316 InsertChild(new_layer, reference_index);
317 }
318 }
319
IndexOfChild(const Layer * reference)320 int Layer::IndexOfChild(const Layer* reference) {
321 for (size_t i = 0; i < children_.size(); ++i) {
322 if (children_[i].get() == reference)
323 return i;
324 }
325 return -1;
326 }
327
SetBounds(gfx::Size size)328 void Layer::SetBounds(gfx::Size size) {
329 DCHECK(IsPropertyChangeAllowed());
330 if (bounds() == size)
331 return;
332
333 bounds_ = size;
334 SetNeedsCommit();
335 }
336
RootLayer()337 Layer* Layer::RootLayer() {
338 Layer* layer = this;
339 while (layer->parent())
340 layer = layer->parent();
341 return layer;
342 }
343
RemoveAllChildren()344 void Layer::RemoveAllChildren() {
345 DCHECK(IsPropertyChangeAllowed());
346 while (children_.size()) {
347 Layer* layer = children_[0].get();
348 DCHECK_EQ(this, layer->parent());
349 layer->RemoveFromParent();
350 }
351 }
352
SetChildren(const LayerList & children)353 void Layer::SetChildren(const LayerList& children) {
354 DCHECK(IsPropertyChangeAllowed());
355 if (children == children_)
356 return;
357
358 RemoveAllChildren();
359 for (size_t i = 0; i < children.size(); ++i)
360 AddChild(children[i]);
361 }
362
HasAncestor(const Layer * ancestor) const363 bool Layer::HasAncestor(const Layer* ancestor) const {
364 for (const Layer* layer = parent(); layer; layer = layer->parent()) {
365 if (layer == ancestor)
366 return true;
367 }
368 return false;
369 }
370
RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> request)371 void Layer::RequestCopyOfOutput(
372 scoped_ptr<CopyOutputRequest> request) {
373 DCHECK(IsPropertyChangeAllowed());
374 if (request->IsEmpty())
375 return;
376 copy_requests_.push_back(request.Pass());
377 SetNeedsCommit();
378 }
379
SetAnchorPoint(gfx::PointF anchor_point)380 void Layer::SetAnchorPoint(gfx::PointF anchor_point) {
381 DCHECK(IsPropertyChangeAllowed());
382 if (anchor_point_ == anchor_point)
383 return;
384 anchor_point_ = anchor_point;
385 SetNeedsCommit();
386 }
387
SetAnchorPointZ(float anchor_point_z)388 void Layer::SetAnchorPointZ(float anchor_point_z) {
389 DCHECK(IsPropertyChangeAllowed());
390 if (anchor_point_z_ == anchor_point_z)
391 return;
392 anchor_point_z_ = anchor_point_z;
393 SetNeedsCommit();
394 }
395
SetBackgroundColor(SkColor background_color)396 void Layer::SetBackgroundColor(SkColor background_color) {
397 DCHECK(IsPropertyChangeAllowed());
398 if (background_color_ == background_color)
399 return;
400 background_color_ = background_color;
401 SetNeedsCommit();
402 }
403
SafeOpaqueBackgroundColor() const404 SkColor Layer::SafeOpaqueBackgroundColor() const {
405 SkColor color = background_color();
406 if (SkColorGetA(color) == 255 && !contents_opaque()) {
407 color = SK_ColorTRANSPARENT;
408 } else if (SkColorGetA(color) != 255 && contents_opaque()) {
409 for (const Layer* layer = parent(); layer;
410 layer = layer->parent()) {
411 color = layer->background_color();
412 if (SkColorGetA(color) == 255)
413 break;
414 }
415 if (SkColorGetA(color) != 255)
416 color = layer_tree_host_->background_color();
417 if (SkColorGetA(color) != 255)
418 color = SkColorSetA(color, 255);
419 }
420 return color;
421 }
422
CalculateContentsScale(float ideal_contents_scale,float device_scale_factor,float page_scale_factor,bool animating_transform_to_screen,float * contents_scale_x,float * contents_scale_y,gfx::Size * content_bounds)423 void Layer::CalculateContentsScale(
424 float ideal_contents_scale,
425 float device_scale_factor,
426 float page_scale_factor,
427 bool animating_transform_to_screen,
428 float* contents_scale_x,
429 float* contents_scale_y,
430 gfx::Size* content_bounds) {
431 DCHECK(layer_tree_host_);
432
433 *contents_scale_x = 1;
434 *contents_scale_y = 1;
435 *content_bounds = bounds();
436 }
437
SetMasksToBounds(bool masks_to_bounds)438 void Layer::SetMasksToBounds(bool masks_to_bounds) {
439 DCHECK(IsPropertyChangeAllowed());
440 if (masks_to_bounds_ == masks_to_bounds)
441 return;
442 masks_to_bounds_ = masks_to_bounds;
443 SetNeedsCommit();
444 }
445
SetMaskLayer(Layer * mask_layer)446 void Layer::SetMaskLayer(Layer* mask_layer) {
447 DCHECK(IsPropertyChangeAllowed());
448 if (mask_layer_.get() == mask_layer)
449 return;
450 if (mask_layer_.get()) {
451 DCHECK_EQ(this, mask_layer_->parent());
452 mask_layer_->RemoveFromParent();
453 }
454 mask_layer_ = mask_layer;
455 if (mask_layer_.get()) {
456 DCHECK(!mask_layer_->parent());
457 mask_layer_->RemoveFromParent();
458 mask_layer_->SetParent(this);
459 mask_layer_->SetIsMask(true);
460 }
461 SetNeedsFullTreeSync();
462 }
463
SetReplicaLayer(Layer * layer)464 void Layer::SetReplicaLayer(Layer* layer) {
465 DCHECK(IsPropertyChangeAllowed());
466 if (replica_layer_.get() == layer)
467 return;
468 if (replica_layer_.get()) {
469 DCHECK_EQ(this, replica_layer_->parent());
470 replica_layer_->RemoveFromParent();
471 }
472 replica_layer_ = layer;
473 if (replica_layer_.get()) {
474 DCHECK(!replica_layer_->parent());
475 replica_layer_->RemoveFromParent();
476 replica_layer_->SetParent(this);
477 }
478 SetNeedsFullTreeSync();
479 }
480
SetFilters(const FilterOperations & filters)481 void Layer::SetFilters(const FilterOperations& filters) {
482 DCHECK(IsPropertyChangeAllowed());
483 if (filters_ == filters)
484 return;
485 filters_ = filters;
486 SetNeedsCommit();
487 SetNeedsFilterContextIfNeeded();
488 }
489
FilterIsAnimating() const490 bool Layer::FilterIsAnimating() const {
491 return layer_animation_controller_->IsAnimatingProperty(Animation::Filter);
492 }
493
SetBackgroundFilters(const FilterOperations & filters)494 void Layer::SetBackgroundFilters(const FilterOperations& filters) {
495 DCHECK(IsPropertyChangeAllowed());
496 if (background_filters_ == filters)
497 return;
498 background_filters_ = filters;
499 SetNeedsCommit();
500 SetNeedsFilterContextIfNeeded();
501 }
502
SetOpacity(float opacity)503 void Layer::SetOpacity(float opacity) {
504 DCHECK(IsPropertyChangeAllowed());
505 if (opacity_ == opacity)
506 return;
507 opacity_ = opacity;
508 SetNeedsCommit();
509 }
510
OpacityIsAnimating() const511 bool Layer::OpacityIsAnimating() const {
512 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
513 }
514
OpacityCanAnimateOnImplThread() const515 bool Layer::OpacityCanAnimateOnImplThread() const {
516 return false;
517 }
518
SetBlendMode(SkXfermode::Mode blend_mode)519 void Layer::SetBlendMode(SkXfermode::Mode blend_mode) {
520 DCHECK(IsPropertyChangeAllowed());
521 if (blend_mode_ == blend_mode)
522 return;
523
524 // Allowing only blend modes that are defined in the CSS Compositing standard:
525 // http://dev.w3.org/fxtf/compositing-1/#blending
526 switch (blend_mode) {
527 case SkXfermode::kSrcOver_Mode:
528 case SkXfermode::kScreen_Mode:
529 case SkXfermode::kOverlay_Mode:
530 case SkXfermode::kDarken_Mode:
531 case SkXfermode::kLighten_Mode:
532 case SkXfermode::kColorDodge_Mode:
533 case SkXfermode::kColorBurn_Mode:
534 case SkXfermode::kHardLight_Mode:
535 case SkXfermode::kSoftLight_Mode:
536 case SkXfermode::kDifference_Mode:
537 case SkXfermode::kExclusion_Mode:
538 case SkXfermode::kMultiply_Mode:
539 case SkXfermode::kHue_Mode:
540 case SkXfermode::kSaturation_Mode:
541 case SkXfermode::kColor_Mode:
542 case SkXfermode::kLuminosity_Mode:
543 // supported blend modes
544 break;
545 case SkXfermode::kClear_Mode:
546 case SkXfermode::kSrc_Mode:
547 case SkXfermode::kDst_Mode:
548 case SkXfermode::kDstOver_Mode:
549 case SkXfermode::kSrcIn_Mode:
550 case SkXfermode::kDstIn_Mode:
551 case SkXfermode::kSrcOut_Mode:
552 case SkXfermode::kDstOut_Mode:
553 case SkXfermode::kSrcATop_Mode:
554 case SkXfermode::kDstATop_Mode:
555 case SkXfermode::kXor_Mode:
556 case SkXfermode::kPlus_Mode:
557 case SkXfermode::kModulate_Mode:
558 // Porter Duff Compositing Operators are not yet supported
559 // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators
560 NOTREACHED();
561 return;
562 }
563
564 blend_mode_ = blend_mode;
565 SetNeedsCommit();
566 SetNeedsFilterContextIfNeeded();
567 }
568
SetIsRootForIsolatedGroup(bool root)569 void Layer::SetIsRootForIsolatedGroup(bool root) {
570 DCHECK(IsPropertyChangeAllowed());
571 if (is_root_for_isolated_group_ == root)
572 return;
573 is_root_for_isolated_group_ = root;
574 SetNeedsCommit();
575 }
576
SetContentsOpaque(bool opaque)577 void Layer::SetContentsOpaque(bool opaque) {
578 DCHECK(IsPropertyChangeAllowed());
579 if (contents_opaque_ == opaque)
580 return;
581 contents_opaque_ = opaque;
582 SetNeedsCommit();
583 }
584
SetPosition(gfx::PointF position)585 void Layer::SetPosition(gfx::PointF position) {
586 DCHECK(IsPropertyChangeAllowed());
587 if (position_ == position)
588 return;
589 position_ = position;
590 SetNeedsCommit();
591 }
592
IsContainerForFixedPositionLayers() const593 bool Layer::IsContainerForFixedPositionLayers() const {
594 if (!transform_.IsIdentityOrTranslation())
595 return true;
596 if (parent_ && !parent_->sublayer_transform_.IsIdentityOrTranslation())
597 return true;
598 return is_container_for_fixed_position_layers_;
599 }
600
SetSublayerTransform(const gfx::Transform & sublayer_transform)601 void Layer::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
602 DCHECK(IsPropertyChangeAllowed());
603 if (sublayer_transform_ == sublayer_transform)
604 return;
605 sublayer_transform_ = sublayer_transform;
606 SetNeedsCommit();
607 }
608
SetTransform(const gfx::Transform & transform)609 void Layer::SetTransform(const gfx::Transform& transform) {
610 DCHECK(IsPropertyChangeAllowed());
611 if (transform_ == transform)
612 return;
613 transform_ = transform;
614 SetNeedsCommit();
615 }
616
TransformIsAnimating() const617 bool Layer::TransformIsAnimating() const {
618 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
619 }
620
SetScrollParent(Layer * parent)621 void Layer::SetScrollParent(Layer* parent) {
622 DCHECK(IsPropertyChangeAllowed());
623 if (scroll_parent_ == parent)
624 return;
625
626 if (scroll_parent_)
627 scroll_parent_->RemoveScrollChild(this);
628
629 scroll_parent_ = parent;
630
631 if (scroll_parent_)
632 scroll_parent_->AddScrollChild(this);
633
634 SetNeedsCommit();
635 }
636
AddScrollChild(Layer * child)637 void Layer::AddScrollChild(Layer* child) {
638 if (!scroll_children_)
639 scroll_children_.reset(new std::set<Layer*>);
640 scroll_children_->insert(child);
641 SetNeedsCommit();
642 }
643
RemoveScrollChild(Layer * child)644 void Layer::RemoveScrollChild(Layer* child) {
645 scroll_children_->erase(child);
646 if (scroll_children_->empty())
647 scroll_children_.reset();
648 SetNeedsCommit();
649 }
650
SetClipParent(Layer * ancestor)651 void Layer::SetClipParent(Layer* ancestor) {
652 DCHECK(IsPropertyChangeAllowed());
653 if (clip_parent_ == ancestor)
654 return;
655
656 if (clip_parent_)
657 clip_parent_->RemoveClipChild(this);
658
659 clip_parent_ = ancestor;
660
661 if (clip_parent_)
662 clip_parent_->AddClipChild(this);
663
664 SetNeedsCommit();
665 }
666
AddClipChild(Layer * child)667 void Layer::AddClipChild(Layer* child) {
668 if (!clip_children_)
669 clip_children_.reset(new std::set<Layer*>);
670 clip_children_->insert(child);
671 SetNeedsCommit();
672 }
673
RemoveClipChild(Layer * child)674 void Layer::RemoveClipChild(Layer* child) {
675 clip_children_->erase(child);
676 if (clip_children_->empty())
677 clip_children_.reset();
678 SetNeedsCommit();
679 }
680
SetScrollOffset(gfx::Vector2d scroll_offset)681 void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) {
682 DCHECK(IsPropertyChangeAllowed());
683 if (scroll_offset_ == scroll_offset)
684 return;
685 scroll_offset_ = scroll_offset;
686 SetNeedsCommit();
687 }
688
SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset)689 void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) {
690 DCHECK(IsPropertyChangeAllowed());
691 // This function only gets called during a BeginMainFrame, so there
692 // is no need to call SetNeedsUpdate here.
693 DCHECK(layer_tree_host_ && layer_tree_host_->CommitRequested());
694 if (scroll_offset_ == scroll_offset)
695 return;
696 scroll_offset_ = scroll_offset;
697 SetNeedsPushProperties();
698 if (!did_scroll_callback_.is_null())
699 did_scroll_callback_.Run();
700 // The callback could potentially change the layer structure:
701 // "this" may have been destroyed during the process.
702 }
703
SetMaxScrollOffset(gfx::Vector2d max_scroll_offset)704 void Layer::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
705 DCHECK(IsPropertyChangeAllowed());
706 if (max_scroll_offset_ == max_scroll_offset)
707 return;
708 max_scroll_offset_ = max_scroll_offset;
709 SetNeedsCommit();
710 }
711
SetScrollable(bool scrollable)712 void Layer::SetScrollable(bool scrollable) {
713 DCHECK(IsPropertyChangeAllowed());
714 if (scrollable_ == scrollable)
715 return;
716 scrollable_ = scrollable;
717 SetNeedsCommit();
718 }
719
SetUserScrollable(bool horizontal,bool vertical)720 void Layer::SetUserScrollable(bool horizontal, bool vertical) {
721 DCHECK(IsPropertyChangeAllowed());
722 if (user_scrollable_horizontal_ == horizontal &&
723 user_scrollable_vertical_ == vertical)
724 return;
725 user_scrollable_horizontal_ = horizontal;
726 user_scrollable_vertical_ = vertical;
727 SetNeedsCommit();
728 }
729
SetShouldScrollOnMainThread(bool should_scroll_on_main_thread)730 void Layer::SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) {
731 DCHECK(IsPropertyChangeAllowed());
732 if (should_scroll_on_main_thread_ == should_scroll_on_main_thread)
733 return;
734 should_scroll_on_main_thread_ = should_scroll_on_main_thread;
735 SetNeedsCommit();
736 }
737
SetHaveWheelEventHandlers(bool have_wheel_event_handlers)738 void Layer::SetHaveWheelEventHandlers(bool have_wheel_event_handlers) {
739 DCHECK(IsPropertyChangeAllowed());
740 if (have_wheel_event_handlers_ == have_wheel_event_handlers)
741 return;
742 have_wheel_event_handlers_ = have_wheel_event_handlers;
743 SetNeedsCommit();
744 }
745
SetNonFastScrollableRegion(const Region & region)746 void Layer::SetNonFastScrollableRegion(const Region& region) {
747 DCHECK(IsPropertyChangeAllowed());
748 if (non_fast_scrollable_region_ == region)
749 return;
750 non_fast_scrollable_region_ = region;
751 SetNeedsCommit();
752 }
753
SetTouchEventHandlerRegion(const Region & region)754 void Layer::SetTouchEventHandlerRegion(const Region& region) {
755 DCHECK(IsPropertyChangeAllowed());
756 if (touch_event_handler_region_ == region)
757 return;
758 touch_event_handler_region_ = region;
759 SetNeedsCommit();
760 }
761
SetDrawCheckerboardForMissingTiles(bool checkerboard)762 void Layer::SetDrawCheckerboardForMissingTiles(bool checkerboard) {
763 DCHECK(IsPropertyChangeAllowed());
764 if (draw_checkerboard_for_missing_tiles_ == checkerboard)
765 return;
766 draw_checkerboard_for_missing_tiles_ = checkerboard;
767 SetNeedsCommit();
768 }
769
SetForceRenderSurface(bool force)770 void Layer::SetForceRenderSurface(bool force) {
771 DCHECK(IsPropertyChangeAllowed());
772 if (force_render_surface_ == force)
773 return;
774 force_render_surface_ = force;
775 SetNeedsCommit();
776 }
777
SetDoubleSided(bool double_sided)778 void Layer::SetDoubleSided(bool double_sided) {
779 DCHECK(IsPropertyChangeAllowed());
780 if (double_sided_ == double_sided)
781 return;
782 double_sided_ = double_sided;
783 SetNeedsCommit();
784 }
785
SetIsDrawable(bool is_drawable)786 void Layer::SetIsDrawable(bool is_drawable) {
787 DCHECK(IsPropertyChangeAllowed());
788 if (is_drawable_ == is_drawable)
789 return;
790
791 is_drawable_ = is_drawable;
792 SetNeedsCommit();
793 }
794
SetHideLayerAndSubtree(bool hide)795 void Layer::SetHideLayerAndSubtree(bool hide) {
796 DCHECK(IsPropertyChangeAllowed());
797 if (hide_layer_and_subtree_ == hide)
798 return;
799
800 hide_layer_and_subtree_ = hide;
801 SetNeedsCommit();
802 }
803
SetNeedsDisplayRect(const gfx::RectF & dirty_rect)804 void Layer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
805 if (dirty_rect.IsEmpty())
806 return;
807
808 SetNeedsPushProperties();
809 update_rect_.Union(dirty_rect);
810
811 if (DrawsContent())
812 SetNeedsUpdate();
813 }
814
DescendantIsFixedToContainerLayer() const815 bool Layer::DescendantIsFixedToContainerLayer() const {
816 for (size_t i = 0; i < children_.size(); ++i) {
817 if (children_[i]->position_constraint_.is_fixed_position() ||
818 children_[i]->DescendantIsFixedToContainerLayer())
819 return true;
820 }
821 return false;
822 }
823
SetIsContainerForFixedPositionLayers(bool container)824 void Layer::SetIsContainerForFixedPositionLayers(bool container) {
825 if (is_container_for_fixed_position_layers_ == container)
826 return;
827 is_container_for_fixed_position_layers_ = container;
828
829 if (layer_tree_host_ && layer_tree_host_->CommitRequested())
830 return;
831
832 // Only request a commit if we have a fixed positioned descendant.
833 if (DescendantIsFixedToContainerLayer())
834 SetNeedsCommit();
835 }
836
SetPositionConstraint(const LayerPositionConstraint & constraint)837 void Layer::SetPositionConstraint(const LayerPositionConstraint& constraint) {
838 DCHECK(IsPropertyChangeAllowed());
839 if (position_constraint_ == constraint)
840 return;
841 position_constraint_ = constraint;
842 SetNeedsCommit();
843 }
844
RunCopyCallbackOnMainThread(scoped_ptr<CopyOutputRequest> request,scoped_ptr<CopyOutputResult> result)845 static void RunCopyCallbackOnMainThread(scoped_ptr<CopyOutputRequest> request,
846 scoped_ptr<CopyOutputResult> result) {
847 request->SendResult(result.Pass());
848 }
849
PostCopyCallbackToMainThread(scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,scoped_ptr<CopyOutputRequest> request,scoped_ptr<CopyOutputResult> result)850 static void PostCopyCallbackToMainThread(
851 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
852 scoped_ptr<CopyOutputRequest> request,
853 scoped_ptr<CopyOutputResult> result) {
854 main_thread_task_runner->PostTask(FROM_HERE,
855 base::Bind(&RunCopyCallbackOnMainThread,
856 base::Passed(&request),
857 base::Passed(&result)));
858 }
859
PushPropertiesTo(LayerImpl * layer)860 void Layer::PushPropertiesTo(LayerImpl* layer) {
861 DCHECK(layer_tree_host_);
862
863 // If we did not SavePaintProperties() for the layer this frame, then push the
864 // real property values, not the paint property values.
865 bool use_paint_properties = paint_properties_.source_frame_number ==
866 layer_tree_host_->source_frame_number();
867
868 layer->SetAnchorPoint(anchor_point_);
869 layer->SetAnchorPointZ(anchor_point_z_);
870 layer->SetBackgroundColor(background_color_);
871 layer->SetBounds(use_paint_properties ? paint_properties_.bounds
872 : bounds_);
873 layer->SetContentBounds(content_bounds());
874 layer->SetContentsScale(contents_scale_x(), contents_scale_y());
875
876 bool is_tracing;
877 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
878 &is_tracing);
879 if (is_tracing) {
880 layer->SetDebugName(DebugName());
881 layer->SetDebugInfo(TakeDebugInfo());
882 } else {
883 layer->SetDebugName(std::string());
884 }
885
886 layer->SetCompositingReasons(compositing_reasons_);
887 layer->SetDoubleSided(double_sided_);
888 layer->SetDrawCheckerboardForMissingTiles(
889 draw_checkerboard_for_missing_tiles_);
890 layer->SetForceRenderSurface(force_render_surface_);
891 layer->SetDrawsContent(DrawsContent());
892 layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
893 if (!layer->FilterIsAnimatingOnImplOnly() && !FilterIsAnimating())
894 layer->SetFilters(filters_);
895 DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly()));
896 layer->SetBackgroundFilters(background_filters());
897 layer->SetMasksToBounds(masks_to_bounds_);
898 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
899 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
900 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
901 layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
902 layer->SetContentsOpaque(contents_opaque_);
903 if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating())
904 layer->SetOpacity(opacity_);
905 DCHECK(!(OpacityIsAnimating() && layer->OpacityIsAnimatingOnImplOnly()));
906 layer->SetBlendMode(blend_mode_);
907 layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
908 layer->SetPosition(position_);
909 layer->SetIsContainerForFixedPositionLayers(
910 IsContainerForFixedPositionLayers());
911 layer->SetFixedContainerSizeDelta(gfx::Vector2dF());
912 layer->SetPositionConstraint(position_constraint_);
913 layer->SetPreserves3d(preserves_3d());
914 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
915 layer->SetSublayerTransform(sublayer_transform_);
916 if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating())
917 layer->SetTransform(transform_);
918 DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly()));
919
920 layer->SetScrollable(scrollable_);
921 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
922 layer->set_user_scrollable_vertical(user_scrollable_vertical_);
923 layer->SetMaxScrollOffset(max_scroll_offset_);
924
925 LayerImpl* scroll_parent = NULL;
926 if (scroll_parent_)
927 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
928
929 layer->SetScrollParent(scroll_parent);
930 if (scroll_children_) {
931 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
932 for (std::set<Layer*>::iterator it = scroll_children_->begin();
933 it != scroll_children_->end(); ++it)
934 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
935 layer->SetScrollChildren(scroll_children);
936 }
937
938 LayerImpl* clip_parent = NULL;
939 if (clip_parent_) {
940 clip_parent =
941 layer->layer_tree_impl()->LayerById(clip_parent_->id());
942 }
943
944 layer->SetClipParent(clip_parent);
945 if (clip_children_) {
946 std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
947 for (std::set<Layer*>::iterator it = clip_children_->begin();
948 it != clip_children_->end(); ++it) {
949 LayerImpl* clip_child = layer->layer_tree_impl()->LayerById((*it)->id());
950 DCHECK(clip_child);
951 clip_children->insert(clip_child);
952 }
953 layer->SetClipChildren(clip_children);
954 }
955
956 // Adjust the scroll delta to be just the scrolls that have happened since
957 // the BeginMainFrame was sent. This happens for impl-side painting
958 // in LayerImpl::ApplyScrollDeltasSinceBeginMainFrame in a separate tree walk.
959 if (layer->layer_tree_impl()->settings().impl_side_painting) {
960 layer->SetScrollOffset(scroll_offset_);
961 } else {
962 layer->SetScrollOffsetAndDelta(
963 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta());
964 layer->SetSentScrollDelta(gfx::Vector2d());
965 }
966
967 // Wrap the copy_requests_ in a PostTask to the main thread.
968 ScopedPtrVector<CopyOutputRequest> main_thread_copy_requests;
969 for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
970 it != copy_requests_.end();
971 ++it) {
972 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner =
973 layer_tree_host()->proxy()->MainThreadTaskRunner();
974 scoped_ptr<CopyOutputRequest> original_request = copy_requests_.take(it);
975 const CopyOutputRequest& original_request_ref = *original_request;
976 scoped_ptr<CopyOutputRequest> main_thread_request =
977 CopyOutputRequest::CreateRelayRequest(
978 original_request_ref,
979 base::Bind(&PostCopyCallbackToMainThread,
980 main_thread_task_runner,
981 base::Passed(&original_request)));
982 main_thread_copy_requests.push_back(main_thread_request.Pass());
983 }
984 copy_requests_.clear();
985 layer->PassCopyRequests(&main_thread_copy_requests);
986
987 // If the main thread commits multiple times before the impl thread actually
988 // draws, then damage tracking will become incorrect if we simply clobber the
989 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
990 // union) any update changes that have occurred on the main thread.
991 update_rect_.Union(layer->update_rect());
992 layer->set_update_rect(update_rect_);
993
994 layer->SetStackingOrderChanged(stacking_order_changed_);
995
996 layer_animation_controller_->PushAnimationUpdatesTo(
997 layer->layer_animation_controller());
998
999 // Reset any state that should be cleared for the next update.
1000 stacking_order_changed_ = false;
1001 update_rect_ = gfx::RectF();
1002
1003 needs_push_properties_ = false;
1004 num_dependents_need_push_properties_ = 0;
1005 }
1006
CreateLayerImpl(LayerTreeImpl * tree_impl)1007 scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
1008 return LayerImpl::Create(tree_impl, layer_id_);
1009 }
1010
DrawsContent() const1011 bool Layer::DrawsContent() const {
1012 return is_drawable_;
1013 }
1014
SavePaintProperties()1015 void Layer::SavePaintProperties() {
1016 DCHECK(layer_tree_host_);
1017
1018 // TODO(reveman): Save all layer properties that we depend on not
1019 // changing until PushProperties() has been called. crbug.com/231016
1020 paint_properties_.bounds = bounds_;
1021 paint_properties_.source_frame_number =
1022 layer_tree_host_->source_frame_number();
1023 }
1024
Update(ResourceUpdateQueue * queue,const OcclusionTracker * occlusion)1025 bool Layer::Update(ResourceUpdateQueue* queue,
1026 const OcclusionTracker* occlusion) {
1027 DCHECK(layer_tree_host_);
1028 DCHECK_EQ(layer_tree_host_->source_frame_number(),
1029 paint_properties_.source_frame_number) <<
1030 "SavePaintProperties must be called for any layer that is painted.";
1031 return false;
1032 }
1033
NeedMoreUpdates()1034 bool Layer::NeedMoreUpdates() {
1035 return false;
1036 }
1037
DebugName()1038 std::string Layer::DebugName() {
1039 return client_ ? client_->DebugName() : std::string();
1040 }
1041
TakeDebugInfo()1042 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
1043 if (client_)
1044 return client_->TakeDebugInfo();
1045 else
1046 return NULL;
1047 }
1048
1049
SetCompositingReasons(CompositingReasons reasons)1050 void Layer::SetCompositingReasons(CompositingReasons reasons) {
1051 compositing_reasons_ = reasons;
1052 }
1053
CreateRenderSurface()1054 void Layer::CreateRenderSurface() {
1055 DCHECK(!draw_properties_.render_surface);
1056 draw_properties_.render_surface = make_scoped_ptr(new RenderSurface(this));
1057 draw_properties_.render_target = this;
1058 }
1059
ClearRenderSurface()1060 void Layer::ClearRenderSurface() {
1061 draw_properties_.render_surface.reset();
1062 }
1063
ScrollOffsetForAnimation() const1064 gfx::Vector2dF Layer::ScrollOffsetForAnimation() const {
1065 return TotalScrollOffset();
1066 }
1067
1068 // On<Property>Animated is called due to an ongoing accelerated animation.
1069 // Since this animation is also being run on the compositor thread, there
1070 // is no need to request a commit to push this value over, so the value is
1071 // set directly rather than by calling Set<Property>.
OnFilterAnimated(const FilterOperations & filters)1072 void Layer::OnFilterAnimated(const FilterOperations& filters) {
1073 filters_ = filters;
1074 }
1075
OnOpacityAnimated(float opacity)1076 void Layer::OnOpacityAnimated(float opacity) {
1077 opacity_ = opacity;
1078 }
1079
OnTransformAnimated(const gfx::Transform & transform)1080 void Layer::OnTransformAnimated(const gfx::Transform& transform) {
1081 transform_ = transform;
1082 }
1083
OnScrollOffsetAnimated(gfx::Vector2dF scroll_offset)1084 void Layer::OnScrollOffsetAnimated(gfx::Vector2dF scroll_offset) {
1085 // Do nothing. Scroll deltas will be sent from the compositor thread back
1086 // to the main thread in the same manner as during non-animated
1087 // compositor-driven scrolling.
1088 }
1089
OnAnimationWaitingForDeletion()1090 void Layer::OnAnimationWaitingForDeletion() {
1091 // Animations are only deleted during PushProperties.
1092 SetNeedsPushProperties();
1093 }
1094
IsActive() const1095 bool Layer::IsActive() const {
1096 return true;
1097 }
1098
AddAnimation(scoped_ptr<Animation> animation)1099 bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
1100 if (!layer_animation_controller_->animation_registrar())
1101 return false;
1102
1103 UMA_HISTOGRAM_BOOLEAN("Renderer.AnimationAddedToOrphanLayer",
1104 !layer_tree_host_);
1105 layer_animation_controller_->AddAnimation(animation.Pass());
1106 SetNeedsCommit();
1107 return true;
1108 }
1109
PauseAnimation(int animation_id,double time_offset)1110 void Layer::PauseAnimation(int animation_id, double time_offset) {
1111 layer_animation_controller_->PauseAnimation(animation_id, time_offset);
1112 SetNeedsCommit();
1113 }
1114
RemoveAnimation(int animation_id)1115 void Layer::RemoveAnimation(int animation_id) {
1116 layer_animation_controller_->RemoveAnimation(animation_id);
1117 SetNeedsCommit();
1118 }
1119
SetLayerAnimationControllerForTest(scoped_refptr<LayerAnimationController> controller)1120 void Layer::SetLayerAnimationControllerForTest(
1121 scoped_refptr<LayerAnimationController> controller) {
1122 layer_animation_controller_->RemoveValueObserver(this);
1123 layer_animation_controller_ = controller;
1124 layer_animation_controller_->AddValueObserver(this);
1125 SetNeedsCommit();
1126 }
1127
HasActiveAnimation() const1128 bool Layer::HasActiveAnimation() const {
1129 return layer_animation_controller_->HasActiveAnimation();
1130 }
1131
AddLayerAnimationEventObserver(LayerAnimationEventObserver * animation_observer)1132 void Layer::AddLayerAnimationEventObserver(
1133 LayerAnimationEventObserver* animation_observer) {
1134 layer_animation_controller_->AddEventObserver(animation_observer);
1135 }
1136
RemoveLayerAnimationEventObserver(LayerAnimationEventObserver * animation_observer)1137 void Layer::RemoveLayerAnimationEventObserver(
1138 LayerAnimationEventObserver* animation_observer) {
1139 layer_animation_controller_->RemoveEventObserver(animation_observer);
1140 }
1141
VisibleContentOpaqueRegion() const1142 Region Layer::VisibleContentOpaqueRegion() const {
1143 if (contents_opaque())
1144 return visible_content_rect();
1145 return Region();
1146 }
1147
ToScrollbarLayer()1148 ScrollbarLayerInterface* Layer::ToScrollbarLayer() {
1149 return NULL;
1150 }
1151
rendering_stats_instrumentation() const1152 RenderingStatsInstrumentation* Layer::rendering_stats_instrumentation() const {
1153 return layer_tree_host_->rendering_stats_instrumentation();
1154 }
1155
SupportsLCDText() const1156 bool Layer::SupportsLCDText() const {
1157 return false;
1158 }
1159
RemoveFromScrollTree()1160 void Layer::RemoveFromScrollTree() {
1161 if (scroll_children_.get()) {
1162 for (std::set<Layer*>::iterator it = scroll_children_->begin();
1163 it != scroll_children_->end(); ++it)
1164 (*it)->scroll_parent_ = NULL;
1165 }
1166
1167 if (scroll_parent_)
1168 scroll_parent_->RemoveScrollChild(this);
1169
1170 scroll_parent_ = NULL;
1171 }
1172
RemoveFromClipTree()1173 void Layer::RemoveFromClipTree() {
1174 if (clip_children_.get()) {
1175 for (std::set<Layer*>::iterator it = clip_children_->begin();
1176 it != clip_children_->end(); ++it)
1177 (*it)->clip_parent_ = NULL;
1178 }
1179
1180 if (clip_parent_)
1181 clip_parent_->RemoveClipChild(this);
1182
1183 clip_parent_ = NULL;
1184 }
1185
RunMicroBenchmark(MicroBenchmark * benchmark)1186 void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) {
1187 benchmark->RunOnLayer(this);
1188 }
1189
1190 } // namespace cc
1191