1 // Copyright 2011 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.
5 #include "cc/layers/layer_impl.h"
7 #include "base/debug/trace_event.h"
8 #include "base/strings/stringprintf.h"
9 #include "cc/animation/animation_registrar.h"
10 #include "cc/animation/scrollbar_animation_controller.h"
11 #include "cc/animation/scrollbar_animation_controller_linear_fade.h"
12 #include "cc/animation/scrollbar_animation_controller_thinning.h"
13 #include "cc/base/math_util.h"
14 #include "cc/debug/debug_colors.h"
15 #include "cc/debug/layer_tree_debug_state.h"
16 #include "cc/debug/traced_value.h"
17 #include "cc/input/layer_scroll_offset_delegate.h"
18 #include "cc/layers/painted_scrollbar_layer_impl.h"
19 #include "cc/layers/quad_sink.h"
20 #include "cc/output/copy_output_request.h"
21 #include "cc/quads/debug_border_draw_quad.h"
22 #include "cc/trees/layer_tree_impl.h"
23 #include "cc/trees/layer_tree_settings.h"
24 #include "cc/trees/proxy.h"
25 #include "ui/gfx/point_conversions.h"
26 #include "ui/gfx/quad_f.h"
27 #include "ui/gfx/rect_conversions.h"
31 LayerImpl::LayerImpl(LayerTreeImpl
* tree_impl
, int id
)
36 replica_layer_id_(-1),
38 layer_tree_impl_(tree_impl
),
39 anchor_point_(0.5f
, 0.5f
),
41 scroll_offset_delegate_(NULL
),
43 should_scroll_on_main_thread_(false),
44 have_wheel_event_handlers_(false),
45 user_scrollable_horizontal_(true),
46 user_scrollable_vertical_(true),
48 stacking_order_changed_(false),
50 layer_property_changed_(false),
51 masks_to_bounds_(false),
52 contents_opaque_(false),
55 use_parent_backface_visibility_(false),
56 draw_checkerboard_for_missing_tiles_(false),
57 draws_content_(false),
58 hide_layer_and_subtree_(false),
59 force_render_surface_(false),
60 is_container_for_fixed_position_layers_(false),
62 compositing_reasons_(kCompositingReasonUnknown
),
63 current_draw_mode_(DRAW_MODE_NONE
),
64 horizontal_scrollbar_layer_(NULL
),
65 vertical_scrollbar_layer_(NULL
) {
66 DCHECK_GT(layer_id_
, 0);
67 DCHECK(layer_tree_impl_
);
68 layer_tree_impl_
->RegisterLayer(this);
69 AnimationRegistrar
* registrar
= layer_tree_impl_
->animationRegistrar();
70 layer_animation_controller_
=
71 registrar
->GetAnimationControllerForId(layer_id_
);
72 layer_animation_controller_
->AddValueObserver(this);
75 LayerImpl::~LayerImpl() {
76 DCHECK_EQ(DRAW_MODE_NONE
, current_draw_mode_
);
78 layer_tree_impl_
->UnregisterLayer(this);
79 layer_animation_controller_
->RemoveValueObserver(this);
81 if (scroll_children_
) {
82 for (std::set
<LayerImpl
*>::iterator it
= scroll_children_
->begin();
83 it
!= scroll_children_
->end(); ++it
)
84 (*it
)->scroll_parent_
= NULL
;
88 scroll_parent_
->RemoveScrollChild(this);
91 for (std::set
<LayerImpl
*>::iterator it
= clip_children_
->begin();
92 it
!= clip_children_
->end(); ++it
)
93 (*it
)->clip_parent_
= NULL
;
97 clip_parent_
->RemoveClipChild(this);
100 void LayerImpl::AddChild(scoped_ptr
<LayerImpl
> child
) {
101 child
->set_parent(this);
102 DCHECK_EQ(layer_tree_impl(), child
->layer_tree_impl());
103 children_
.push_back(child
.Pass());
104 layer_tree_impl()->set_needs_update_draw_properties();
107 scoped_ptr
<LayerImpl
> LayerImpl::RemoveChild(LayerImpl
* child
) {
108 for (OwnedLayerImplList::iterator it
= children_
.begin();
109 it
!= children_
.end();
112 scoped_ptr
<LayerImpl
> ret
= children_
.take(it
);
114 layer_tree_impl()->set_needs_update_draw_properties();
118 return scoped_ptr
<LayerImpl
>();
121 void LayerImpl::ClearChildList() {
122 if (children_
.empty())
126 layer_tree_impl()->set_needs_update_draw_properties();
129 bool LayerImpl::HasAncestor(const LayerImpl
* ancestor
) const {
133 for (const LayerImpl
* layer
= this; layer
; layer
= layer
->parent()) {
134 if (layer
== ancestor
)
141 void LayerImpl::SetScrollParent(LayerImpl
* parent
) {
142 if (scroll_parent_
== parent
)
145 // Having both a scroll parent and a scroll offset delegate is unsupported.
146 DCHECK(!scroll_offset_delegate_
);
149 scroll_parent_
->RemoveScrollChild(this);
151 scroll_parent_
= parent
;
154 void LayerImpl::SetScrollChildren(std::set
<LayerImpl
*>* children
) {
155 if (scroll_children_
.get() == children
)
157 scroll_children_
.reset(children
);
160 void LayerImpl::RemoveScrollChild(LayerImpl
* child
) {
161 DCHECK(scroll_children_
);
162 scroll_children_
->erase(child
);
163 if (scroll_children_
->empty())
164 scroll_children_
.reset();
167 void LayerImpl::SetClipParent(LayerImpl
* ancestor
) {
168 if (clip_parent_
== ancestor
)
172 clip_parent_
->RemoveClipChild(this);
174 clip_parent_
= ancestor
;
177 void LayerImpl::SetClipChildren(std::set
<LayerImpl
*>* children
) {
178 if (clip_children_
.get() == children
)
180 clip_children_
.reset(children
);
183 void LayerImpl::RemoveClipChild(LayerImpl
* child
) {
184 DCHECK(clip_children_
);
185 clip_children_
->erase(child
);
186 if (clip_children_
->empty())
187 clip_children_
.reset();
190 void LayerImpl::PassCopyRequests(ScopedPtrVector
<CopyOutputRequest
>* requests
) {
191 if (requests
->empty())
194 bool was_empty
= copy_requests_
.empty();
195 copy_requests_
.insert_and_take(copy_requests_
.end(), *requests
);
198 if (was_empty
&& layer_tree_impl()->IsActiveTree())
199 layer_tree_impl()->AddLayerWithCopyOutputRequest(this);
200 NoteLayerPropertyChangedForSubtree();
203 void LayerImpl::TakeCopyRequestsAndTransformToTarget(
204 ScopedPtrVector
<CopyOutputRequest
>* requests
) {
205 if (copy_requests_
.empty())
208 size_t first_inserted_request
= requests
->size();
209 requests
->insert_and_take(requests
->end(), copy_requests_
);
210 copy_requests_
.clear();
212 for (size_t i
= first_inserted_request
; i
< requests
->size(); ++i
) {
213 CopyOutputRequest
* request
= requests
->at(i
);
214 if (!request
->has_area())
217 gfx::Rect request_in_layer_space
= request
->area();
218 gfx::Rect request_in_content_space
=
219 LayerRectToContentRect(request_in_layer_space
);
221 MathUtil::MapClippedRect(draw_properties_
.target_space_transform
,
222 request_in_content_space
));
225 if (layer_tree_impl()->IsActiveTree())
226 layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
229 void LayerImpl::CreateRenderSurface() {
230 DCHECK(!draw_properties_
.render_surface
);
231 draw_properties_
.render_surface
=
232 make_scoped_ptr(new RenderSurfaceImpl(this));
233 draw_properties_
.render_target
= this;
236 void LayerImpl::ClearRenderSurface() {
237 draw_properties_
.render_surface
.reset();
240 scoped_ptr
<SharedQuadState
> LayerImpl::CreateSharedQuadState() const {
241 scoped_ptr
<SharedQuadState
> state
= SharedQuadState::Create();
242 state
->SetAll(draw_properties_
.target_space_transform
,
243 draw_properties_
.content_bounds
,
244 draw_properties_
.visible_content_rect
,
245 draw_properties_
.clip_rect
,
246 draw_properties_
.is_clipped
,
247 draw_properties_
.opacity
);
251 bool LayerImpl::WillDraw(DrawMode draw_mode
,
252 ResourceProvider
* resource_provider
) {
253 // WillDraw/DidDraw must be matched.
254 DCHECK_NE(DRAW_MODE_NONE
, draw_mode
);
255 DCHECK_EQ(DRAW_MODE_NONE
, current_draw_mode_
);
256 current_draw_mode_
= draw_mode
;
260 void LayerImpl::DidDraw(ResourceProvider
* resource_provider
) {
261 DCHECK_NE(DRAW_MODE_NONE
, current_draw_mode_
);
262 current_draw_mode_
= DRAW_MODE_NONE
;
265 bool LayerImpl::ShowDebugBorders() const {
266 return layer_tree_impl()->debug_state().show_debug_borders
;
269 void LayerImpl::GetDebugBorderProperties(SkColor
* color
, float* width
) const {
270 if (draws_content_
) {
271 *color
= DebugColors::ContentLayerBorderColor();
272 *width
= DebugColors::ContentLayerBorderWidth(layer_tree_impl());
276 if (masks_to_bounds_
) {
277 *color
= DebugColors::MaskingLayerBorderColor();
278 *width
= DebugColors::MaskingLayerBorderWidth(layer_tree_impl());
282 *color
= DebugColors::ContainerLayerBorderColor();
283 *width
= DebugColors::ContainerLayerBorderWidth(layer_tree_impl());
286 void LayerImpl::AppendDebugBorderQuad(
288 const SharedQuadState
* shared_quad_state
,
289 AppendQuadsData
* append_quads_data
) const {
292 GetDebugBorderProperties(&color
, &width
);
293 AppendDebugBorderQuad(
294 quad_sink
, shared_quad_state
, append_quads_data
, color
, width
);
297 void LayerImpl::AppendDebugBorderQuad(QuadSink
* quad_sink
,
298 const SharedQuadState
* shared_quad_state
,
299 AppendQuadsData
* append_quads_data
,
302 if (!ShowDebugBorders())
305 gfx::Rect
content_rect(content_bounds());
306 scoped_ptr
<DebugBorderDrawQuad
> debug_border_quad
=
307 DebugBorderDrawQuad::Create();
308 debug_border_quad
->SetNew(shared_quad_state
, content_rect
, color
, width
);
309 quad_sink
->Append(debug_border_quad
.PassAs
<DrawQuad
>(), append_quads_data
);
312 bool LayerImpl::HasDelegatedContent() const {
316 bool LayerImpl::HasContributingDelegatedRenderPasses() const {
320 RenderPass::Id
LayerImpl::FirstContributingRenderPassId() const {
321 return RenderPass::Id(0, 0);
324 RenderPass::Id
LayerImpl::NextContributingRenderPassId(RenderPass::Id id
)
326 return RenderPass::Id(0, 0);
329 ResourceProvider::ResourceId
LayerImpl::ContentsResourceId() const {
334 void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta
) {
335 // Pending tree never has sent scroll deltas
336 DCHECK(layer_tree_impl()->IsActiveTree());
338 if (sent_scroll_delta_
== sent_scroll_delta
)
341 sent_scroll_delta_
= sent_scroll_delta
;
344 gfx::Vector2dF
LayerImpl::ScrollBy(gfx::Vector2dF scroll
) {
345 DCHECK(scrollable());
346 gfx::Vector2dF scroll_hidden
;
347 if (!user_scrollable_horizontal_
) {
348 scroll_hidden
.set_x(scroll
.x());
351 if (!user_scrollable_vertical_
) {
352 scroll_hidden
.set_y(scroll
.y());
356 gfx::Vector2dF min_delta
= -scroll_offset_
;
357 gfx::Vector2dF max_delta
= max_scroll_offset_
- scroll_offset_
;
358 // Clamp new_delta so that position + delta stays within scroll bounds.
359 gfx::Vector2dF new_delta
= (ScrollDelta() + scroll
);
360 new_delta
.SetToMax(min_delta
);
361 new_delta
.SetToMin(max_delta
);
362 gfx::Vector2dF unscrolled
=
363 ScrollDelta() + scroll
+ scroll_hidden
- new_delta
;
364 SetScrollDelta(new_delta
);
368 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() {
369 // Pending tree never has sent scroll deltas
370 DCHECK(layer_tree_impl()->IsActiveTree());
372 // Apply sent scroll deltas to scroll position / scroll delta as if the
373 // main thread had applied them and then committed those values.
375 // This function should not change the total scroll offset; it just shifts
376 // some of the scroll delta to the scroll offset. Therefore, adjust these
377 // variables directly rather than calling the scroll offset delegate to
378 // avoid sending it multiple spurious calls.
380 // Because of the way scroll delta is calculated with a delegate, this will
381 // leave the total scroll offset unchanged on this layer regardless of
382 // whether a delegate is being used.
383 scroll_offset_
+= sent_scroll_delta_
;
384 scroll_delta_
-= sent_scroll_delta_
;
385 sent_scroll_delta_
= gfx::Vector2d();
388 void LayerImpl::ApplyScrollDeltasSinceBeginFrame() {
389 // Only the pending tree can have missing scrolls.
390 DCHECK(layer_tree_impl()->IsPendingTree());
394 // Pending tree should never have sent scroll deltas.
395 DCHECK(sent_scroll_delta().IsZero());
397 LayerImpl
* active_twin
= layer_tree_impl()->FindActiveTreeLayerById(id());
399 // Scrolls that happens after begin frame (where the sent scroll delta
400 // comes from) and commit need to be applied to the pending tree
401 // so that it is up to date with the total scroll.
402 SetScrollDelta(active_twin
->ScrollDelta() -
403 active_twin
->sent_scroll_delta());
407 InputHandler::ScrollStatus
LayerImpl::TryScroll(
408 gfx::PointF screen_space_point
,
409 InputHandler::ScrollInputType type
) const {
410 if (should_scroll_on_main_thread()) {
411 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread");
412 return InputHandler::ScrollOnMainThread
;
415 if (!screen_space_transform().IsInvertible()) {
416 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform");
417 return InputHandler::ScrollIgnored
;
420 if (!non_fast_scrollable_region().IsEmpty()) {
421 bool clipped
= false;
422 gfx::Transform
inverse_screen_space_transform(
423 gfx::Transform::kSkipInitialization
);
424 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform
)) {
425 // TODO(shawnsingh): We shouldn't be applying a projection if screen space
426 // transform is uninvertible here. Perhaps we should be returning
427 // ScrollOnMainThread in this case?
430 gfx::PointF hit_test_point_in_content_space
=
431 MathUtil::ProjectPoint(inverse_screen_space_transform
,
434 gfx::PointF hit_test_point_in_layer_space
=
435 gfx::ScalePoint(hit_test_point_in_content_space
,
436 1.f
/ contents_scale_x(),
437 1.f
/ contents_scale_y());
439 non_fast_scrollable_region().Contains(
440 gfx::ToRoundedPoint(hit_test_point_in_layer_space
))) {
442 "LayerImpl::tryScroll: Failed NonFastScrollableRegion");
443 return InputHandler::ScrollOnMainThread
;
447 if (type
== InputHandler::Wheel
&& have_wheel_event_handlers()) {
448 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers");
449 return InputHandler::ScrollOnMainThread
;
453 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
454 return InputHandler::ScrollIgnored
;
457 if (max_scroll_offset_
.x() <= 0 && max_scroll_offset_
.y() <= 0) {
459 "LayerImpl::tryScroll: Ignored. Technically scrollable,"
460 " but has no affordance in either direction.");
461 return InputHandler::ScrollIgnored
;
464 if (!user_scrollable_horizontal_
&& !user_scrollable_vertical_
) {
466 "LayerImpl::TryScroll: Ignored. User gesture is not allowed"
467 " to scroll this layer.");
468 return InputHandler::ScrollIgnored
;
471 return InputHandler::ScrollStarted
;
474 bool LayerImpl::DrawCheckerboardForMissingTiles() const {
475 return draw_checkerboard_for_missing_tiles_
&&
476 !layer_tree_impl()->settings().background_color_instead_of_checkerboard
;
479 gfx::Rect
LayerImpl::LayerRectToContentRect(
480 const gfx::RectF
& layer_rect
) const {
481 gfx::RectF content_rect
=
482 gfx::ScaleRect(layer_rect
, contents_scale_x(), contents_scale_y());
483 // Intersect with content rect to avoid the extra pixel because for some
484 // values x and y, ceil((x / y) * y) may be x + 1.
485 content_rect
.Intersect(gfx::Rect(content_bounds()));
486 return gfx::ToEnclosingRect(content_rect
);
489 skia::RefPtr
<SkPicture
> LayerImpl::GetPicture() {
490 return skia::RefPtr
<SkPicture
>();
493 bool LayerImpl::AreVisibleResourcesReady() const {
497 scoped_ptr
<LayerImpl
> LayerImpl::CreateLayerImpl(LayerTreeImpl
* tree_impl
) {
498 return LayerImpl::Create(tree_impl
, layer_id_
);
501 void LayerImpl::PushPropertiesTo(LayerImpl
* layer
) {
502 layer
->SetAnchorPoint(anchor_point_
);
503 layer
->SetAnchorPointZ(anchor_point_z_
);
504 layer
->SetBackgroundColor(background_color_
);
505 layer
->SetBounds(bounds_
);
506 layer
->SetContentBounds(content_bounds());
507 layer
->SetContentsScale(contents_scale_x(), contents_scale_y());
508 layer
->SetDebugName(debug_name_
);
509 layer
->SetCompositingReasons(compositing_reasons_
);
510 layer
->SetDoubleSided(double_sided_
);
511 layer
->SetDrawCheckerboardForMissingTiles(
512 draw_checkerboard_for_missing_tiles_
);
513 layer
->SetForceRenderSurface(force_render_surface_
);
514 layer
->SetDrawsContent(DrawsContent());
515 layer
->SetHideLayerAndSubtree(hide_layer_and_subtree_
);
516 layer
->SetFilters(filters());
517 layer
->SetBackgroundFilters(background_filters());
518 layer
->SetMasksToBounds(masks_to_bounds_
);
519 layer
->SetShouldScrollOnMainThread(should_scroll_on_main_thread_
);
520 layer
->SetHaveWheelEventHandlers(have_wheel_event_handlers_
);
521 layer
->SetNonFastScrollableRegion(non_fast_scrollable_region_
);
522 layer
->SetTouchEventHandlerRegion(touch_event_handler_region_
);
523 layer
->SetContentsOpaque(contents_opaque_
);
524 layer
->SetOpacity(opacity_
);
525 layer
->SetPosition(position_
);
526 layer
->SetIsContainerForFixedPositionLayers(
527 is_container_for_fixed_position_layers_
);
528 layer
->SetFixedContainerSizeDelta(fixed_container_size_delta_
);
529 layer
->SetPositionConstraint(position_constraint_
);
530 layer
->SetPreserves3d(preserves_3d());
531 layer
->SetUseParentBackfaceVisibility(use_parent_backface_visibility_
);
532 layer
->SetSublayerTransform(sublayer_transform_
);
533 layer
->SetTransform(transform_
);
535 layer
->SetScrollable(scrollable_
);
536 layer
->set_user_scrollable_horizontal(user_scrollable_horizontal_
);
537 layer
->set_user_scrollable_vertical(user_scrollable_vertical_
);
538 layer
->SetScrollOffsetAndDelta(
539 scroll_offset_
, layer
->ScrollDelta() - layer
->sent_scroll_delta());
540 layer
->SetSentScrollDelta(gfx::Vector2d());
542 layer
->SetMaxScrollOffset(max_scroll_offset_
);
544 LayerImpl
* scroll_parent
= NULL
;
546 scroll_parent
= layer
->layer_tree_impl()->LayerById(scroll_parent_
->id());
548 layer
->SetScrollParent(scroll_parent
);
549 if (scroll_children_
) {
550 std::set
<LayerImpl
*>* scroll_children
= new std::set
<LayerImpl
*>;
551 for (std::set
<LayerImpl
*>::iterator it
= scroll_children_
->begin();
552 it
!= scroll_children_
->end(); ++it
)
553 scroll_children
->insert(layer
->layer_tree_impl()->LayerById((*it
)->id()));
554 layer
->SetScrollChildren(scroll_children
);
557 LayerImpl
* clip_parent
= NULL
;
559 clip_parent
= layer
->layer_tree_impl()->LayerById(
563 layer
->SetClipParent(clip_parent
);
564 if (clip_children_
) {
565 std::set
<LayerImpl
*>* clip_children
= new std::set
<LayerImpl
*>;
566 for (std::set
<LayerImpl
*>::iterator it
= clip_children_
->begin();
567 it
!= clip_children_
->end(); ++it
)
568 clip_children
->insert(layer
->layer_tree_impl()->LayerById((*it
)->id()));
569 layer
->SetClipChildren(clip_children
);
572 layer
->PassCopyRequests(©_requests_
);
574 // If the main thread commits multiple times before the impl thread actually
575 // draws, then damage tracking will become incorrect if we simply clobber the
576 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
577 // union) any update changes that have occurred on the main thread.
578 update_rect_
.Union(layer
->update_rect());
579 layer
->set_update_rect(update_rect_
);
581 layer
->SetStackingOrderChanged(stacking_order_changed_
);
583 // Reset any state that should be cleared for the next update.
584 stacking_order_changed_
= false;
585 update_rect_
= gfx::RectF();
588 base::DictionaryValue
* LayerImpl::LayerTreeAsJson() const {
589 base::DictionaryValue
* result
= new base::DictionaryValue
;
590 result
->SetString("LayerType", LayerTypeAsString());
592 base::ListValue
* list
= new base::ListValue
;
593 list
->AppendInteger(bounds().width());
594 list
->AppendInteger(bounds().height());
595 result
->Set("Bounds", list
);
597 list
= new base::ListValue
;
598 list
->AppendDouble(position_
.x());
599 list
->AppendDouble(position_
.y());
600 result
->Set("Position", list
);
602 const gfx::Transform
& gfx_transform
= draw_properties_
.target_space_transform
;
603 double transform
[16];
604 gfx_transform
.matrix().asColMajord(transform
);
605 list
= new base::ListValue
;
606 for (int i
= 0; i
< 16; ++i
)
607 list
->AppendDouble(transform
[i
]);
608 result
->Set("DrawTransform", list
);
610 result
->SetBoolean("DrawsContent", draws_content_
);
611 result
->SetDouble("Opacity", opacity());
612 result
->SetBoolean("ContentsOpaque", contents_opaque_
);
615 result
->SetBoolean("Scrollable", scrollable_
);
617 list
= new base::ListValue
;
618 for (size_t i
= 0; i
< children_
.size(); ++i
)
619 list
->Append(children_
[i
]->LayerTreeAsJson());
620 result
->Set("Children", list
);
625 void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed
) {
626 if (stacking_order_changed
) {
627 stacking_order_changed_
= true;
628 NoteLayerPropertyChangedForSubtree();
632 void LayerImpl::NoteLayerPropertyChanged() {
633 layer_property_changed_
= true;
634 layer_tree_impl()->set_needs_update_draw_properties();
637 void LayerImpl::NoteLayerPropertyChangedForSubtree() {
638 NoteLayerPropertyChanged();
639 NoteLayerPropertyChangedForDescendants();
642 void LayerImpl::NoteLayerPropertyChangedForDescendants() {
643 layer_tree_impl()->set_needs_update_draw_properties();
644 for (size_t i
= 0; i
< children_
.size(); ++i
)
645 children_
[i
]->NoteLayerPropertyChangedForSubtree();
648 const char* LayerImpl::LayerTypeAsString() const {
649 return "cc::LayerImpl";
652 void LayerImpl::ResetAllChangeTrackingForSubtree() {
653 layer_property_changed_
= false;
655 update_rect_
= gfx::RectF();
657 if (draw_properties_
.render_surface
)
658 draw_properties_
.render_surface
->ResetPropertyChangedFlag();
661 mask_layer_
->ResetAllChangeTrackingForSubtree();
663 if (replica_layer_
) {
664 // This also resets the replica mask, if it exists.
665 replica_layer_
->ResetAllChangeTrackingForSubtree();
668 for (size_t i
= 0; i
< children_
.size(); ++i
)
669 children_
[i
]->ResetAllChangeTrackingForSubtree();
672 bool LayerImpl::LayerIsAlwaysDamaged() const {
676 void LayerImpl::OnFilterAnimated(const FilterOperations
& filters
) {
680 void LayerImpl::OnOpacityAnimated(float opacity
) {
684 void LayerImpl::OnTransformAnimated(const gfx::Transform
& transform
) {
685 SetTransform(transform
);
688 bool LayerImpl::IsActive() const {
689 return layer_tree_impl_
->IsActiveTree();
692 void LayerImpl::SetBounds(gfx::Size bounds
) {
693 if (bounds_
== bounds
)
698 if (masks_to_bounds())
699 NoteLayerPropertyChangedForSubtree();
701 NoteLayerPropertyChanged();
704 void LayerImpl::SetMaskLayer(scoped_ptr
<LayerImpl
> mask_layer
) {
705 int new_layer_id
= mask_layer
? mask_layer
->id() : -1;
708 DCHECK_EQ(layer_tree_impl(), mask_layer
->layer_tree_impl());
709 DCHECK_NE(new_layer_id
, mask_layer_id_
);
710 } else if (new_layer_id
== mask_layer_id_
) {
714 mask_layer_
= mask_layer
.Pass();
715 mask_layer_id_
= new_layer_id
;
717 mask_layer_
->set_parent(this);
718 NoteLayerPropertyChangedForSubtree();
721 scoped_ptr
<LayerImpl
> LayerImpl::TakeMaskLayer() {
723 return mask_layer_
.Pass();
726 void LayerImpl::SetReplicaLayer(scoped_ptr
<LayerImpl
> replica_layer
) {
727 int new_layer_id
= replica_layer
? replica_layer
->id() : -1;
730 DCHECK_EQ(layer_tree_impl(), replica_layer
->layer_tree_impl());
731 DCHECK_NE(new_layer_id
, replica_layer_id_
);
732 } else if (new_layer_id
== replica_layer_id_
) {
736 replica_layer_
= replica_layer
.Pass();
737 replica_layer_id_
= new_layer_id
;
739 replica_layer_
->set_parent(this);
740 NoteLayerPropertyChangedForSubtree();
743 scoped_ptr
<LayerImpl
> LayerImpl::TakeReplicaLayer() {
744 replica_layer_id_
= -1;
745 return replica_layer_
.Pass();
748 ScrollbarLayerImplBase
* LayerImpl::ToScrollbarLayer() {
752 void LayerImpl::SetDrawsContent(bool draws_content
) {
753 if (draws_content_
== draws_content
)
756 draws_content_
= draws_content
;
757 NoteLayerPropertyChanged();
760 void LayerImpl::SetHideLayerAndSubtree(bool hide
) {
761 if (hide_layer_and_subtree_
== hide
)
764 hide_layer_and_subtree_
= hide
;
765 NoteLayerPropertyChangedForSubtree();
768 void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point
) {
769 if (anchor_point_
== anchor_point
)
772 anchor_point_
= anchor_point
;
773 NoteLayerPropertyChangedForSubtree();
776 void LayerImpl::SetAnchorPointZ(float anchor_point_z
) {
777 if (anchor_point_z_
== anchor_point_z
)
780 anchor_point_z_
= anchor_point_z
;
781 NoteLayerPropertyChangedForSubtree();
784 void LayerImpl::SetBackgroundColor(SkColor background_color
) {
785 if (background_color_
== background_color
)
788 background_color_
= background_color
;
789 NoteLayerPropertyChanged();
792 SkColor
LayerImpl::SafeOpaqueBackgroundColor() const {
793 SkColor color
= background_color();
794 if (SkColorGetA(color
) == 255 && !contents_opaque()) {
795 color
= SK_ColorTRANSPARENT
;
796 } else if (SkColorGetA(color
) != 255 && contents_opaque()) {
797 for (const LayerImpl
* layer
= parent(); layer
;
798 layer
= layer
->parent()) {
799 color
= layer
->background_color();
800 if (SkColorGetA(color
) == 255)
803 if (SkColorGetA(color
) != 255)
804 color
= layer_tree_impl()->background_color();
805 if (SkColorGetA(color
) != 255)
806 color
= SkColorSetA(color
, 255);
811 void LayerImpl::SetFilters(const FilterOperations
& filters
) {
812 if (filters_
== filters
)
816 NoteLayerPropertyChangedForSubtree();
819 bool LayerImpl::FilterIsAnimating() const {
820 return layer_animation_controller_
->IsAnimatingProperty(Animation::Filter
);
823 bool LayerImpl::FilterIsAnimatingOnImplOnly() const {
824 Animation
* filter_animation
=
825 layer_animation_controller_
->GetAnimation(Animation::Filter
);
826 return filter_animation
&& filter_animation
->is_impl_only();
829 void LayerImpl::SetBackgroundFilters(
830 const FilterOperations
& filters
) {
831 if (background_filters_
== filters
)
834 background_filters_
= filters
;
835 NoteLayerPropertyChanged();
838 void LayerImpl::SetMasksToBounds(bool masks_to_bounds
) {
839 if (masks_to_bounds_
== masks_to_bounds
)
842 masks_to_bounds_
= masks_to_bounds
;
843 NoteLayerPropertyChangedForSubtree();
846 void LayerImpl::SetContentsOpaque(bool opaque
) {
847 if (contents_opaque_
== opaque
)
850 contents_opaque_
= opaque
;
851 NoteLayerPropertyChangedForSubtree();
854 void LayerImpl::SetOpacity(float opacity
) {
855 if (opacity_
== opacity
)
859 NoteLayerPropertyChangedForSubtree();
862 bool LayerImpl::OpacityIsAnimating() const {
863 return layer_animation_controller_
->IsAnimatingProperty(Animation::Opacity
);
866 bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
867 Animation
* opacity_animation
=
868 layer_animation_controller_
->GetAnimation(Animation::Opacity
);
869 return opacity_animation
&& opacity_animation
->is_impl_only();
872 void LayerImpl::SetPosition(gfx::PointF position
) {
873 if (position_
== position
)
876 position_
= position
;
877 NoteLayerPropertyChangedForSubtree();
880 void LayerImpl::SetPreserves3d(bool preserves3_d
) {
881 if (preserves_3d_
== preserves3_d
)
884 preserves_3d_
= preserves3_d
;
885 NoteLayerPropertyChangedForSubtree();
888 void LayerImpl::SetSublayerTransform(const gfx::Transform
& sublayer_transform
) {
889 if (sublayer_transform_
== sublayer_transform
)
892 sublayer_transform_
= sublayer_transform
;
893 // Sublayer transform does not affect the current layer; it affects only its
895 NoteLayerPropertyChangedForDescendants();
898 void LayerImpl::SetTransform(const gfx::Transform
& transform
) {
899 if (transform_
== transform
)
902 transform_
= transform
;
903 NoteLayerPropertyChangedForSubtree();
906 bool LayerImpl::TransformIsAnimating() const {
907 return layer_animation_controller_
->IsAnimatingProperty(Animation::Transform
);
910 bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
911 Animation
* transform_animation
=
912 layer_animation_controller_
->GetAnimation(Animation::Transform
);
913 return transform_animation
&& transform_animation
->is_impl_only();
916 void LayerImpl::SetContentBounds(gfx::Size content_bounds
) {
917 if (this->content_bounds() == content_bounds
)
920 draw_properties_
.content_bounds
= content_bounds
;
921 NoteLayerPropertyChanged();
924 void LayerImpl::SetContentsScale(float contents_scale_x
,
925 float contents_scale_y
) {
926 if (this->contents_scale_x() == contents_scale_x
&&
927 this->contents_scale_y() == contents_scale_y
)
930 draw_properties_
.contents_scale_x
= contents_scale_x
;
931 draw_properties_
.contents_scale_y
= contents_scale_y
;
932 NoteLayerPropertyChanged();
935 void LayerImpl::CalculateContentsScale(
936 float ideal_contents_scale
,
937 float device_scale_factor
,
938 float page_scale_factor
,
939 bool animating_transform_to_screen
,
940 float* contents_scale_x
,
941 float* contents_scale_y
,
942 gfx::Size
* content_bounds
) {
943 // Base LayerImpl has all of its content scales and content bounds pushed
944 // from its Layer during commit and just reuses those values as-is.
945 *contents_scale_x
= this->contents_scale_x();
946 *contents_scale_y
= this->contents_scale_y();
947 *content_bounds
= this->content_bounds();
950 void LayerImpl::UpdateScrollbarPositions() {
951 gfx::Vector2dF current_offset
= scroll_offset_
+ ScrollDelta();
953 gfx::RectF
viewport(PointAtOffsetFromOrigin(current_offset
), bounds_
);
954 gfx::SizeF
scrollable_size(max_scroll_offset_
.x() + bounds_
.width(),
955 max_scroll_offset_
.y() + bounds_
.height());
956 if (horizontal_scrollbar_layer_
) {
957 horizontal_scrollbar_layer_
->SetCurrentPos(current_offset
.x());
958 horizontal_scrollbar_layer_
->SetMaximum(max_scroll_offset_
.x());
959 horizontal_scrollbar_layer_
->SetVisibleToTotalLengthRatio(
960 viewport
.width() / scrollable_size
.width());
962 if (vertical_scrollbar_layer_
) {
963 vertical_scrollbar_layer_
->SetCurrentPos(current_offset
.y());
964 vertical_scrollbar_layer_
->SetMaximum(max_scroll_offset_
.y());
965 vertical_scrollbar_layer_
->SetVisibleToTotalLengthRatio(
966 viewport
.height() / scrollable_size
.height());
969 if (current_offset
== last_scroll_offset_
)
971 last_scroll_offset_
= current_offset
;
973 if (scrollbar_animation_controller_
) {
974 bool should_animate
= scrollbar_animation_controller_
->DidScrollUpdate(
975 layer_tree_impl_
->CurrentPhysicalTimeTicks());
977 layer_tree_impl_
->StartScrollbarAnimation();
980 // Get the current_offset_.y() value for a sanity-check on scrolling
981 // benchmark metrics. Specifically, we want to make sure
982 // BasicMouseWheelSmoothScrollGesture has proper scroll curves.
983 if (layer_tree_impl()->IsActiveTree()) {
984 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset
.y());
988 void LayerImpl::SetScrollOffsetDelegate(
989 LayerScrollOffsetDelegate
* scroll_offset_delegate
) {
990 // Having both a scroll parent and a scroll offset delegate is unsupported.
991 DCHECK(!scroll_parent_
);
992 if (!scroll_offset_delegate
&& scroll_offset_delegate_
) {
994 scroll_offset_delegate_
->GetTotalScrollOffset() - scroll_offset_
;
996 gfx::Vector2dF total_offset
= TotalScrollOffset();
997 scroll_offset_delegate_
= scroll_offset_delegate
;
998 if (scroll_offset_delegate_
) {
999 scroll_offset_delegate_
->SetMaxScrollOffset(max_scroll_offset_
);
1000 scroll_offset_delegate_
->SetTotalScrollOffset(total_offset
);
1004 bool LayerImpl::IsExternalFlingActive() const {
1005 return scroll_offset_delegate_
&&
1006 scroll_offset_delegate_
->IsExternalFlingActive();
1009 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset
) {
1010 SetScrollOffsetAndDelta(scroll_offset
, ScrollDelta());
1013 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset
,
1014 gfx::Vector2dF scroll_delta
) {
1015 bool changed
= false;
1017 if (scroll_offset_
!= scroll_offset
) {
1019 scroll_offset_
= scroll_offset
;
1021 if (scroll_offset_delegate_
)
1022 scroll_offset_delegate_
->SetTotalScrollOffset(TotalScrollOffset());
1025 if (ScrollDelta() != scroll_delta
) {
1027 if (layer_tree_impl()->IsActiveTree()) {
1028 LayerImpl
* pending_twin
=
1029 layer_tree_impl()->FindPendingTreeLayerById(id());
1031 // The pending twin can't mirror the scroll delta of the active
1032 // layer. Although the delta - sent scroll delta difference is
1033 // identical for both twins, the sent scroll delta for the pending
1034 // layer is zero, as anything that has been sent has been baked
1035 // into the layer's position/scroll offset as a part of commit.
1036 DCHECK(pending_twin
->sent_scroll_delta().IsZero());
1037 pending_twin
->SetScrollDelta(scroll_delta
- sent_scroll_delta());
1041 if (scroll_offset_delegate_
) {
1042 scroll_offset_delegate_
->SetTotalScrollOffset(scroll_offset_
+
1045 scroll_delta_
= scroll_delta
;
1050 NoteLayerPropertyChangedForSubtree();
1051 UpdateScrollbarPositions();
1055 gfx::Vector2dF
LayerImpl::ScrollDelta() const {
1056 if (scroll_offset_delegate_
)
1057 return scroll_offset_delegate_
->GetTotalScrollOffset() - scroll_offset_
;
1058 return scroll_delta_
;
1061 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta
) {
1062 SetScrollOffsetAndDelta(scroll_offset_
, scroll_delta
);
1065 gfx::Vector2dF
LayerImpl::TotalScrollOffset() const {
1066 return scroll_offset_
+ ScrollDelta();
1069 void LayerImpl::SetDoubleSided(bool double_sided
) {
1070 if (double_sided_
== double_sided
)
1073 double_sided_
= double_sided
;
1074 NoteLayerPropertyChangedForSubtree();
1077 Region
LayerImpl::VisibleContentOpaqueRegion() const {
1078 if (contents_opaque())
1079 return visible_content_rect();
1083 void LayerImpl::DidBeginTracing() {}
1085 void LayerImpl::DidLoseOutputSurface() {}
1087 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset
) {
1088 if (max_scroll_offset_
== max_scroll_offset
)
1090 max_scroll_offset_
= max_scroll_offset
;
1092 if (scroll_offset_delegate_
)
1093 scroll_offset_delegate_
->SetMaxScrollOffset(max_scroll_offset_
);
1095 layer_tree_impl()->set_needs_update_draw_properties();
1096 UpdateScrollbarPositions();
1099 void LayerImpl::DidBecomeActive() {
1100 if (layer_tree_impl_
->settings().scrollbar_animator
==
1101 LayerTreeSettings::NoAnimator
) {
1105 bool need_scrollbar_animation_controller
= horizontal_scrollbar_layer_
||
1106 vertical_scrollbar_layer_
;
1107 if (!need_scrollbar_animation_controller
) {
1108 scrollbar_animation_controller_
.reset();
1112 if (scrollbar_animation_controller_
)
1115 switch (layer_tree_impl_
->settings().scrollbar_animator
) {
1116 case LayerTreeSettings::LinearFade
: {
1117 base::TimeDelta fadeout_delay
= base::TimeDelta::FromMilliseconds(
1118 layer_tree_impl_
->settings().scrollbar_linear_fade_delay_ms
);
1119 base::TimeDelta fadeout_length
= base::TimeDelta::FromMilliseconds(
1120 layer_tree_impl_
->settings().scrollbar_linear_fade_length_ms
);
1122 scrollbar_animation_controller_
=
1123 ScrollbarAnimationControllerLinearFade::Create(
1124 this, fadeout_delay
, fadeout_length
)
1125 .PassAs
<ScrollbarAnimationController
>();
1128 case LayerTreeSettings::Thinning
: {
1129 scrollbar_animation_controller_
=
1130 ScrollbarAnimationControllerThinning::Create(this)
1131 .PassAs
<ScrollbarAnimationController
>();
1134 case LayerTreeSettings::NoAnimator
:
1139 void LayerImpl::SetHorizontalScrollbarLayer(
1140 ScrollbarLayerImplBase
* scrollbar_layer
) {
1141 horizontal_scrollbar_layer_
= scrollbar_layer
;
1142 if (horizontal_scrollbar_layer_
)
1143 horizontal_scrollbar_layer_
->set_scroll_layer_id(id());
1146 void LayerImpl::SetVerticalScrollbarLayer(
1147 ScrollbarLayerImplBase
* scrollbar_layer
) {
1148 vertical_scrollbar_layer_
= scrollbar_layer
;
1149 if (vertical_scrollbar_layer_
)
1150 vertical_scrollbar_layer_
->set_scroll_layer_id(id());
1153 static scoped_ptr
<base::Value
>
1154 CompositingReasonsAsValue(CompositingReasons reasons
) {
1155 scoped_ptr
<base::ListValue
> reason_list(new base::ListValue());
1157 if (reasons
== kCompositingReasonUnknown
) {
1158 reason_list
->AppendString("No reasons given");
1159 return reason_list
.PassAs
<base::Value
>();
1162 if (reasons
& kCompositingReason3DTransform
)
1163 reason_list
->AppendString("Has a 3d Transform");
1165 if (reasons
& kCompositingReasonVideo
)
1166 reason_list
->AppendString("Is accelerated video");
1168 if (reasons
& kCompositingReasonCanvas
)
1169 reason_list
->AppendString("Is accelerated canvas");
1171 if (reasons
& kCompositingReasonPlugin
)
1172 reason_list
->AppendString("Is accelerated plugin");
1174 if (reasons
& kCompositingReasonIFrame
)
1175 reason_list
->AppendString("Is accelerated iframe");
1177 if (reasons
& kCompositingReasonBackfaceVisibilityHidden
)
1178 reason_list
->AppendString("Has backface-visibility: hidden");
1180 if (reasons
& kCompositingReasonAnimation
)
1181 reason_list
->AppendString("Has accelerated animation or transition");
1183 if (reasons
& kCompositingReasonFilters
)
1184 reason_list
->AppendString("Has accelerated filters");
1186 if (reasons
& kCompositingReasonPositionFixed
)
1187 reason_list
->AppendString("Is fixed position");
1189 if (reasons
& kCompositingReasonPositionSticky
)
1190 reason_list
->AppendString("Is sticky position");
1192 if (reasons
& kCompositingReasonOverflowScrollingTouch
)
1193 reason_list
->AppendString("Is a scrollable overflow element");
1195 if (reasons
& kCompositingReasonAssumedOverlap
)
1196 reason_list
->AppendString("Might overlap a composited animation");
1198 if (reasons
& kCompositingReasonOverlap
)
1199 reason_list
->AppendString("Overlaps other composited content");
1201 if (reasons
& kCompositingReasonNegativeZIndexChildren
) {
1202 reason_list
->AppendString("Might overlap negative z-index "
1203 "composited content");
1206 if (reasons
& kCompositingReasonTransformWithCompositedDescendants
) {
1207 reason_list
->AppendString("Has transform needed by a "
1208 "composited descendant");
1211 if (reasons
& kCompositingReasonOpacityWithCompositedDescendants
)
1212 reason_list
->AppendString("Has opacity needed by a composited descendant");
1214 if (reasons
& kCompositingReasonMaskWithCompositedDescendants
)
1215 reason_list
->AppendString("Has a mask needed by a composited descendant");
1217 if (reasons
& kCompositingReasonReflectionWithCompositedDescendants
)
1218 reason_list
->AppendString("Has a reflection with a composited descendant");
1220 if (reasons
& kCompositingReasonFilterWithCompositedDescendants
)
1221 reason_list
->AppendString("Has filter effect with a composited descendant");
1223 if (reasons
& kCompositingReasonBlendingWithCompositedDescendants
)
1224 reason_list
->AppendString("Has a blend mode with a composited descendant");
1226 if (reasons
& kCompositingReasonClipsCompositingDescendants
)
1227 reason_list
->AppendString("Clips a composited descendant");
1229 if (reasons
& kCompositingReasonPerspective
) {
1230 reason_list
->AppendString("Has a perspective transform needed by a "
1231 "composited 3d descendant");
1234 if (reasons
& kCompositingReasonPreserve3D
) {
1235 reason_list
->AppendString("Has preserves-3d style with composited "
1239 if (reasons
& kCompositingReasonReflectionOfCompositedParent
)
1240 reason_list
->AppendString("Is the reflection of a composited layer");
1242 if (reasons
& kCompositingReasonRoot
)
1243 reason_list
->AppendString("Is the root");
1245 if (reasons
& kCompositingReasonLayerForClip
)
1246 reason_list
->AppendString("Convenience layer, to clip subtree");
1248 if (reasons
& kCompositingReasonLayerForScrollbar
)
1249 reason_list
->AppendString("Convenience layer for rendering scrollbar");
1251 if (reasons
& kCompositingReasonLayerForScrollingContainer
)
1252 reason_list
->AppendString("Convenience layer, the scrolling container");
1254 if (reasons
& kCompositingReasonLayerForForeground
) {
1255 reason_list
->AppendString("Convenience layer, foreground when main layer "
1256 "has negative z-index composited content");
1259 if (reasons
& kCompositingReasonLayerForBackground
) {
1260 reason_list
->AppendString("Convenience layer, background when main layer "
1261 "has a composited background");
1264 if (reasons
& kCompositingReasonLayerForMask
)
1265 reason_list
->AppendString("Is a mask layer");
1267 if (reasons
& kCompositingReasonOverflowScrollingParent
)
1268 reason_list
->AppendString("Scroll parent is not an ancestor");
1270 if (reasons
& kCompositingReasonOutOfFlowClipping
)
1271 reason_list
->AppendString("Has clipping ancestor");
1273 return reason_list
.PassAs
<base::Value
>();
1276 void LayerImpl::AsValueInto(base::DictionaryValue
* state
) const {
1277 TracedValue::MakeDictIntoImplicitSnapshot(state
, LayerTypeAsString(), this);
1278 state
->SetInteger("layer_id", id());
1279 state
->SetString("layer_name", debug_name());
1280 state
->Set("bounds", MathUtil::AsValue(bounds()).release());
1281 state
->SetInteger("draws_content", DrawsContent());
1282 state
->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
1283 state
->Set("compositing_reasons",
1284 CompositingReasonsAsValue(compositing_reasons_
).release());
1287 gfx::QuadF layer_quad
= MathUtil::MapQuad(
1288 screen_space_transform(),
1289 gfx::QuadF(gfx::Rect(content_bounds())),
1291 state
->Set("layer_quad", MathUtil::AsValue(layer_quad
).release());
1293 if (!touch_event_handler_region_
.IsEmpty()) {
1294 state
->Set("touch_event_handler_region",
1295 touch_event_handler_region_
.AsValue().release());
1297 if (have_wheel_event_handlers_
) {
1298 gfx::Rect
wheel_rect(content_bounds());
1299 Region
wheel_region(wheel_rect
);
1300 state
->Set("wheel_event_handler_region",
1301 wheel_region
.AsValue().release());
1303 if (!non_fast_scrollable_region_
.IsEmpty()) {
1304 state
->Set("non_fast_scrollable_region",
1305 non_fast_scrollable_region_
.AsValue().release());
1308 scoped_ptr
<base::ListValue
> children_list(new base::ListValue());
1309 for (size_t i
= 0; i
< children_
.size(); ++i
)
1310 children_list
->Append(children_
[i
]->AsValue().release());
1311 state
->Set("children", children_list
.release());
1313 state
->Set("mask_layer", mask_layer_
->AsValue().release());
1315 state
->Set("replica_layer", replica_layer_
->AsValue().release());
1318 state
->SetInteger("scroll_parent", scroll_parent_
->id());
1321 state
->SetInteger("clip_parent", clip_parent_
->id());
1323 state
->SetBoolean("can_use_lcd_text", can_use_lcd_text());
1324 state
->SetBoolean("contents_opaque", contents_opaque());
1327 size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
1329 scoped_ptr
<base::Value
> LayerImpl::AsValue() const {
1330 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue());
1331 AsValueInto(state
.get());
1332 return state
.PassAs
<base::Value
>();