diff options
Diffstat (limited to 'chromium/cc/layers/layer_impl.cc')
-rw-r--r-- | chromium/cc/layers/layer_impl.cc | 818 |
1 files changed, 454 insertions, 364 deletions
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index 74b69b5572a..fa68275bd73 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -9,25 +9,27 @@ #include "base/strings/stringprintf.h" #include "cc/animation/animation_registrar.h" #include "cc/animation/scrollbar_animation_controller.h" -#include "cc/animation/scrollbar_animation_controller_linear_fade.h" -#include "cc/animation/scrollbar_animation_controller_thinning.h" #include "cc/base/math_util.h" #include "cc/debug/debug_colors.h" #include "cc/debug/layer_tree_debug_state.h" #include "cc/debug/micro_benchmark_impl.h" #include "cc/debug/traced_value.h" #include "cc/input/layer_scroll_offset_delegate.h" +#include "cc/layers/layer_utils.h" #include "cc/layers/painted_scrollbar_layer_impl.h" #include "cc/layers/quad_sink.h" #include "cc/output/copy_output_request.h" #include "cc/quads/debug_border_draw_quad.h" +#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/proxy.h" #include "ui/gfx/box_f.h" +#include "ui/gfx/geometry/vector2d_conversions.h" #include "ui/gfx/point_conversions.h" #include "ui/gfx/quad_f.h" #include "ui/gfx/rect_conversions.h" +#include "ui/gfx/size_conversions.h" namespace cc { LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) @@ -38,35 +40,35 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) replica_layer_id_(-1), layer_id_(id), layer_tree_impl_(tree_impl), - anchor_point_(0.5f, 0.5f), - anchor_point_z_(0.f), scroll_offset_delegate_(NULL), - scrollable_(false), + scroll_clip_layer_(NULL), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), + have_scroll_event_handlers_(false), user_scrollable_horizontal_(true), user_scrollable_vertical_(true), stacking_order_changed_(false), double_sided_(true), + should_flatten_transform_(true), layer_property_changed_(false), masks_to_bounds_(false), contents_opaque_(false), is_root_for_isolated_group_(false), - preserves_3d_(false), use_parent_backface_visibility_(false), draw_checkerboard_for_missing_tiles_(false), draws_content_(false), hide_layer_and_subtree_(false), force_render_surface_(false), + transform_is_invertible_(true), is_container_for_fixed_position_layers_(false), background_color_(0), opacity_(1.0), blend_mode_(SkXfermode::kSrcOver_Mode), draw_depth_(0.f), - compositing_reasons_(kCompositingReasonUnknown), - current_draw_mode_(DRAW_MODE_NONE), - horizontal_scrollbar_layer_(NULL), - vertical_scrollbar_layer_(NULL) { + needs_push_properties_(false), + num_dependents_need_push_properties_(0), + sorting_context_id_(0), + current_draw_mode_(DRAW_MODE_NONE) { DCHECK_GT(layer_id_, 0); DCHECK(layer_tree_impl_); layer_tree_impl_->RegisterLayer(this); @@ -76,6 +78,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) layer_animation_controller_->AddValueObserver(this); if (IsActive()) layer_animation_controller_->set_value_provider(this); + SetNeedsPushProperties(); } LayerImpl::~LayerImpl() { @@ -88,27 +91,12 @@ LayerImpl::~LayerImpl() { layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); layer_tree_impl_->UnregisterLayer(this); - if (scroll_children_) { - for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); - it != scroll_children_->end(); ++it) - (*it)->scroll_parent_ = NULL; - } - - if (scroll_parent_) - scroll_parent_->RemoveScrollChild(this); - - if (clip_children_) { - for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); - it != clip_children_->end(); ++it) - (*it)->clip_parent_ = NULL; - } - - if (clip_parent_) - clip_parent_->RemoveClipChild(this); + TRACE_EVENT_OBJECT_DELETED_WITH_ID( + TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this); } void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { - child->set_parent(this); + child->SetParent(this); DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); children_.push_back(child.Pass()); layer_tree_impl()->set_needs_update_draw_properties(); @@ -128,6 +116,16 @@ scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { return scoped_ptr<LayerImpl>(); } +void LayerImpl::SetParent(LayerImpl* parent) { + if (parent_should_know_need_push_properties()) { + if (parent_) + parent_->RemoveDependentNeedsPushProperties(); + if (parent) + parent->AddDependentNeedsPushProperties(); + } + parent_ = parent; +} + void LayerImpl::ClearChildList() { if (children_.empty()) return; @@ -155,51 +153,39 @@ void LayerImpl::SetScrollParent(LayerImpl* parent) { // Having both a scroll parent and a scroll offset delegate is unsupported. DCHECK(!scroll_offset_delegate_); - if (scroll_parent_) - scroll_parent_->RemoveScrollChild(this); + if (parent) + DCHECK_EQ(layer_tree_impl()->LayerById(parent->id()), parent); scroll_parent_ = parent; + SetNeedsPushProperties(); } void LayerImpl::SetDebugInfo( scoped_refptr<base::debug::ConvertableToTraceFormat> other) { debug_info_ = other; + SetNeedsPushProperties(); } void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { if (scroll_children_.get() == children) return; scroll_children_.reset(children); -} - -void LayerImpl::RemoveScrollChild(LayerImpl* child) { - DCHECK(scroll_children_); - scroll_children_->erase(child); - if (scroll_children_->empty()) - scroll_children_.reset(); + SetNeedsPushProperties(); } void LayerImpl::SetClipParent(LayerImpl* ancestor) { if (clip_parent_ == ancestor) return; - if (clip_parent_) - clip_parent_->RemoveClipChild(this); - clip_parent_ = ancestor; + SetNeedsPushProperties(); } void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { if (clip_children_.get() == children) return; clip_children_.reset(children); -} - -void LayerImpl::RemoveClipChild(LayerImpl* child) { - DCHECK(clip_children_); - clip_children_->erase(child); - if (clip_children_->empty()) - clip_children_.reset(); + SetNeedsPushProperties(); } void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { @@ -217,8 +203,8 @@ void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { void LayerImpl::TakeCopyRequestsAndTransformToTarget( ScopedPtrVector<CopyOutputRequest>* requests) { - if (copy_requests_.empty()) - return; + DCHECK(!copy_requests_.empty()); + DCHECK(layer_tree_impl()->IsActiveTree()); size_t first_inserted_request = requests->size(); requests->insert_and_take(requests->end(), copy_requests_); @@ -232,13 +218,11 @@ void LayerImpl::TakeCopyRequestsAndTransformToTarget( gfx::Rect request_in_layer_space = request->area(); gfx::Rect request_in_content_space = LayerRectToContentRect(request_in_layer_space); - request->set_area( - MathUtil::MapClippedRect(draw_properties_.target_space_transform, - request_in_content_space)); + request->set_area(MathUtil::MapEnclosingClippedRect( + draw_properties_.target_space_transform, request_in_content_space)); } - if (layer_tree_impl()->IsActiveTree()) - layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); + layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); } void LayerImpl::CreateRenderSurface() { @@ -252,16 +236,20 @@ void LayerImpl::ClearRenderSurface() { draw_properties_.render_surface.reset(); } -scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { - scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); +void LayerImpl::ClearRenderSurfaceLayerList() { + if (draw_properties_.render_surface) + draw_properties_.render_surface->layer_list().clear(); +} + +void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const { state->SetAll(draw_properties_.target_space_transform, draw_properties_.content_bounds, draw_properties_.visible_content_rect, draw_properties_.clip_rect, draw_properties_.is_clipped, draw_properties_.opacity, - blend_mode_); - return state.Pass(); + blend_mode_, + sorting_context_id_); } bool LayerImpl::WillDraw(DrawMode draw_mode, @@ -301,16 +289,22 @@ void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { void LayerImpl::AppendDebugBorderQuad( QuadSink* quad_sink, + const gfx::Size& content_bounds, const SharedQuadState* shared_quad_state, AppendQuadsData* append_quads_data) const { SkColor color; float width; GetDebugBorderProperties(&color, &width); - AppendDebugBorderQuad( - quad_sink, shared_quad_state, append_quads_data, color, width); + AppendDebugBorderQuad(quad_sink, + content_bounds, + shared_quad_state, + append_quads_data, + color, + width); } void LayerImpl::AppendDebugBorderQuad(QuadSink* quad_sink, + const gfx::Size& content_bounds, const SharedQuadState* shared_quad_state, AppendQuadsData* append_quads_data, SkColor color, @@ -318,11 +312,13 @@ void LayerImpl::AppendDebugBorderQuad(QuadSink* quad_sink, if (!ShowDebugBorders()) return; - gfx::Rect content_rect(content_bounds()); + gfx::Rect quad_rect(content_bounds); + gfx::Rect visible_quad_rect(quad_rect); scoped_ptr<DebugBorderDrawQuad> debug_border_quad = DebugBorderDrawQuad::Create(); - debug_border_quad->SetNew(shared_quad_state, content_rect, color, width); - quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(), append_quads_data); + debug_border_quad->SetNew( + shared_quad_state, quad_rect, visible_quad_rect, color, width); + quad_sink->Append(debug_border_quad.PassAs<DrawQuad>()); } bool LayerImpl::HasDelegatedContent() const { @@ -347,7 +343,7 @@ ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { return 0; } -void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { +void LayerImpl::SetSentScrollDelta(const gfx::Vector2d& sent_scroll_delta) { // Pending tree never has sent scroll deltas DCHECK(layer_tree_impl()->IsActiveTree()); @@ -357,10 +353,10 @@ void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { sent_scroll_delta_ = sent_scroll_delta; } -gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { +gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { DCHECK(scrollable()); gfx::Vector2dF min_delta = -scroll_offset_; - gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; + gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_; // Clamp new_delta so that position + delta stays within scroll bounds. gfx::Vector2dF new_delta = (ScrollDelta() + scroll); new_delta.SetToMax(min_delta); @@ -368,9 +364,14 @@ gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { gfx::Vector2dF unscrolled = ScrollDelta() + scroll - new_delta; SetScrollDelta(new_delta); + return unscrolled; } +void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { + scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); +} + void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { // Pending tree never has sent scroll deltas DCHECK(layer_tree_impl()->IsActiveTree()); @@ -411,7 +412,7 @@ void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() { } InputHandler::ScrollStatus LayerImpl::TryScroll( - gfx::PointF screen_space_point, + const gfx::PointF& screen_space_point, InputHandler::ScrollInputType type) const { if (should_scroll_on_main_thread()) { TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); @@ -460,7 +461,8 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( return InputHandler::ScrollIgnored; } - if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { + gfx::Vector2d max_scroll_offset = MaxScrollOffset(); + if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollable," " but has no affordance in either direction."); @@ -470,11 +472,6 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( return InputHandler::ScrollStarted; } -bool LayerImpl::DrawCheckerboardForMissingTiles() const { - return draw_checkerboard_for_missing_tiles_ && - !layer_tree_impl()->settings().background_color_instead_of_checkerboard; -} - gfx::Rect LayerImpl::LayerRectToContentRect( const gfx::RectF& layer_rect) const { gfx::RectF content_rect = @@ -489,23 +486,16 @@ skia::RefPtr<SkPicture> LayerImpl::GetPicture() { return skia::RefPtr<SkPicture>(); } -bool LayerImpl::AreVisibleResourcesReady() const { - return true; -} - scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { return LayerImpl::Create(tree_impl, layer_id_); } void LayerImpl::PushPropertiesTo(LayerImpl* layer) { - layer->SetAnchorPoint(anchor_point_); - layer->SetAnchorPointZ(anchor_point_z_); + layer->SetTransformOrigin(transform_origin_); layer->SetBackgroundColor(background_color_); layer->SetBounds(bounds_); layer->SetContentBounds(content_bounds()); layer->SetContentsScale(contents_scale_x(), contents_scale_y()); - layer->SetDebugName(debug_name_); - layer->SetCompositingReasons(compositing_reasons_); layer->SetDoubleSided(double_sided_); layer->SetDrawCheckerboardForMissingTiles( draw_checkerboard_for_missing_tiles_); @@ -517,6 +507,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetMasksToBounds(masks_to_bounds_); layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); + layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); layer->SetTouchEventHandlerRegion(touch_event_handler_region_); layer->SetContentsOpaque(contents_opaque_); @@ -526,39 +517,48 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetPosition(position_); layer->SetIsContainerForFixedPositionLayers( is_container_for_fixed_position_layers_); - layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); layer->SetPositionConstraint(position_constraint_); - layer->SetPreserves3d(preserves_3d()); + layer->SetShouldFlattenTransform(should_flatten_transform_); layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); - layer->SetSublayerTransform(sublayer_transform_); - layer->SetTransform(transform_); + layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); - layer->SetScrollable(scrollable_); + layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() + : Layer::INVALID_ID); layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); layer->set_user_scrollable_vertical(user_scrollable_vertical_); layer->SetScrollOffsetAndDelta( scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); layer->SetSentScrollDelta(gfx::Vector2d()); - - layer->SetMaxScrollOffset(max_scroll_offset_); + layer->Set3dSortingContextId(sorting_context_id_); LayerImpl* scroll_parent = NULL; - if (scroll_parent_) + if (scroll_parent_) { scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); + DCHECK(scroll_parent); + } layer->SetScrollParent(scroll_parent); if (scroll_children_) { std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); - it != scroll_children_->end(); ++it) - scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); + it != scroll_children_->end(); + ++it) { + DCHECK_EQ((*it)->scroll_parent(), this); + LayerImpl* scroll_child = + layer->layer_tree_impl()->LayerById((*it)->id()); + DCHECK(scroll_child); + scroll_children->insert(scroll_child); + } layer->SetScrollChildren(scroll_children); + } else { + layer->SetScrollChildren(NULL); } LayerImpl* clip_parent = NULL; if (clip_parent_) { clip_parent = layer->layer_tree_impl()->LayerById( clip_parent_->id()); + DCHECK(clip_parent); } layer->SetClipParent(clip_parent); @@ -568,6 +568,8 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { it != clip_children_->end(); ++it) clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); layer->SetClipChildren(clip_children); + } else { + layer->SetClipChildren(NULL); } layer->PassCopyRequests(©_requests_); @@ -577,15 +579,40 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. // union) any update changes that have occurred on the main thread. update_rect_.Union(layer->update_rect()); - layer->set_update_rect(update_rect_); + layer->SetUpdateRect(update_rect_); layer->SetStackingOrderChanged(stacking_order_changed_); + layer->SetDebugInfo(debug_info_); // Reset any state that should be cleared for the next update. stacking_order_changed_ = false; update_rect_ = gfx::RectF(); + needs_push_properties_ = false; + num_dependents_need_push_properties_ = 0; +} - layer->SetDebugInfo(debug_info_); +gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const { + if (!scroll_clip_layer_) + return gfx::Vector2dF(); + + float scale_delta = layer_tree_impl()->page_scale_delta(); + float scale = layer_tree_impl()->page_scale_factor(); + + gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->BoundsDelta(); + delta_from_scroll.Scale(1.f / scale); + + // The delta-from-pinch component requires some explanation: A viewport of + // size (w,h) will appear to be size (w/s,h/s) under scale s in the content + // space. If s -> s' on the impl thread, where s' = s * ds, then the apparent + // viewport size change in the content space due to ds is: + // + // (w/s',h/s') - (w/s,h/s) = (w,h)(1/s' - 1/s) = (w,h)(1 - ds)/(s ds) + // + gfx::Vector2dF delta_from_pinch = + gfx::Rect(scroll_clip_layer_->bounds()).bottom_right() - gfx::PointF(); + delta_from_pinch.Scale((1.f - scale_delta) / (scale * scale_delta)); + + return delta_from_scroll + delta_from_pinch; } base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { @@ -611,14 +638,17 @@ base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { result->Set("DrawTransform", list); result->SetBoolean("DrawsContent", draws_content_); + result->SetBoolean("Is3dSorted", Is3dSorted()); result->SetDouble("Opacity", opacity()); result->SetBoolean("ContentsOpaque", contents_opaque_); - if (scrollable_) - result->SetBoolean("Scrollable", scrollable_); + if (scrollable()) + result->SetBoolean("Scrollable", true); if (have_wheel_event_handlers_) result->SetBoolean("WheelHandler", have_wheel_event_handlers_); + if (have_scroll_event_handlers_) + result->SetBoolean("ScrollHandler", have_scroll_event_handlers_); if (!touch_event_handler_region_.IsEmpty()) { scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); result->Set("TouchRegion", region.release()); @@ -642,17 +672,28 @@ void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { void LayerImpl::NoteLayerPropertyChanged() { layer_property_changed_ = true; layer_tree_impl()->set_needs_update_draw_properties(); + SetNeedsPushProperties(); } void LayerImpl::NoteLayerPropertyChangedForSubtree() { - NoteLayerPropertyChanged(); - NoteLayerPropertyChangedForDescendants(); + layer_property_changed_ = true; + layer_tree_impl()->set_needs_update_draw_properties(); + for (size_t i = 0; i < children_.size(); ++i) + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); + SetNeedsPushProperties(); +} + +void LayerImpl::NoteLayerPropertyChangedForDescendantsInternal() { + layer_property_changed_ = true; + for (size_t i = 0; i < children_.size(); ++i) + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); } void LayerImpl::NoteLayerPropertyChangedForDescendants() { layer_tree_impl()->set_needs_update_draw_properties(); for (size_t i = 0; i < children_.size(); ++i) - children_[i]->NoteLayerPropertyChangedForSubtree(); + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); + SetNeedsPushProperties(); } const char* LayerImpl::LayerTypeAsString() const { @@ -663,6 +704,7 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() { layer_property_changed_ = false; update_rect_ = gfx::RectF(); + damage_rect_ = gfx::RectF(); if (draw_properties_.render_surface) draw_properties_.render_surface->ResetPropertyChangedFlag(); @@ -677,10 +719,9 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() { for (size_t i = 0; i < children_.size(); ++i) children_[i]->ResetAllChangeTrackingForSubtree(); -} -bool LayerImpl::LayerIsAlwaysDamaged() const { - return false; + needs_push_properties_ = false; + num_dependents_need_push_properties_ = 0; } gfx::Vector2dF LayerImpl::ScrollOffsetForAnimation() const { @@ -699,7 +740,7 @@ void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { SetTransform(transform); } -void LayerImpl::OnScrollOffsetAnimated(gfx::Vector2dF scroll_offset) { +void LayerImpl::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) { // Only layers in the active tree should need to do anything here, since // layers in the pending tree will find out about these changes as a // result of the call to SetScrollDelta. @@ -717,12 +758,32 @@ bool LayerImpl::IsActive() const { return layer_tree_impl_->IsActiveTree(); } -void LayerImpl::SetBounds(gfx::Size bounds) { +// TODO(wjmaclean) Convert so that bounds returns SizeF. +gfx::Size LayerImpl::bounds() const { + return ToFlooredSize(temporary_impl_bounds_); +} + +void LayerImpl::SetBounds(const gfx::Size& bounds) { if (bounds_ == bounds) return; bounds_ = bounds; + temporary_impl_bounds_ = bounds; + ScrollbarParametersDidChange(); + if (masks_to_bounds()) + NoteLayerPropertyChangedForSubtree(); + else + NoteLayerPropertyChanged(); +} + +void LayerImpl::SetTemporaryImplBounds(const gfx::SizeF& bounds) { + if (temporary_impl_bounds_ == bounds) + return; + + temporary_impl_bounds_ = bounds; + + ScrollbarParametersDidChange(); if (masks_to_bounds()) NoteLayerPropertyChangedForSubtree(); else @@ -742,7 +803,7 @@ void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { mask_layer_ = mask_layer.Pass(); mask_layer_id_ = new_layer_id; if (mask_layer_) - mask_layer_->set_parent(this); + mask_layer_->SetParent(this); NoteLayerPropertyChangedForSubtree(); } @@ -764,7 +825,7 @@ void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { replica_layer_ = replica_layer.Pass(); replica_layer_id_ = new_layer_id; if (replica_layer_) - replica_layer_->set_parent(this); + replica_layer_->SetParent(this); NoteLayerPropertyChangedForSubtree(); } @@ -793,19 +854,10 @@ void LayerImpl::SetHideLayerAndSubtree(bool hide) { NoteLayerPropertyChangedForSubtree(); } -void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { - if (anchor_point_ == anchor_point) +void LayerImpl::SetTransformOrigin(const gfx::Point3F& transform_origin) { + if (transform_origin_ == transform_origin) return; - - anchor_point_ = anchor_point; - NoteLayerPropertyChangedForSubtree(); -} - -void LayerImpl::SetAnchorPointZ(float anchor_point_z) { - if (anchor_point_z_ == anchor_point_z) - return; - - anchor_point_z_ = anchor_point_z; + transform_origin_ = transform_origin; NoteLayerPropertyChangedForSubtree(); } @@ -910,9 +962,10 @@ void LayerImpl::SetIsRootForIsolatedGroup(bool root) { return; is_root_for_isolated_group_ = root; + SetNeedsPushProperties(); } -void LayerImpl::SetPosition(gfx::PointF position) { +void LayerImpl::SetPosition(const gfx::PointF& position) { if (position_ == position) return; @@ -920,22 +973,19 @@ void LayerImpl::SetPosition(gfx::PointF position) { NoteLayerPropertyChangedForSubtree(); } -void LayerImpl::SetPreserves3d(bool preserves3_d) { - if (preserves_3d_ == preserves3_d) +void LayerImpl::SetShouldFlattenTransform(bool flatten) { + if (should_flatten_transform_ == flatten) return; - preserves_3d_ = preserves3_d; + should_flatten_transform_ = flatten; NoteLayerPropertyChangedForSubtree(); } -void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { - if (sublayer_transform_ == sublayer_transform) +void LayerImpl::Set3dSortingContextId(int id) { + if (id == sorting_context_id_) return; - - sublayer_transform_ = sublayer_transform; - // Sublayer transform does not affect the current layer; it affects only its - // children. - NoteLayerPropertyChangedForDescendants(); + sorting_context_id_ = id; + NoteLayerPropertyChangedForSubtree(); } void LayerImpl::SetTransform(const gfx::Transform& transform) { @@ -943,6 +993,19 @@ void LayerImpl::SetTransform(const gfx::Transform& transform) { return; transform_ = transform; + transform_is_invertible_ = transform_.IsInvertible(); + NoteLayerPropertyChangedForSubtree(); +} + +void LayerImpl::SetTransformAndInvertibility(const gfx::Transform& transform, + bool transform_is_invertible) { + if (transform_ == transform) { + DCHECK(transform_is_invertible_ == transform_is_invertible) + << "Can't change invertibility if transform is unchanged"; + return; + } + transform_ = transform; + transform_is_invertible_ = transform_is_invertible; NoteLayerPropertyChangedForSubtree(); } @@ -956,7 +1019,16 @@ bool LayerImpl::TransformIsAnimatingOnImplOnly() const { return transform_animation && transform_animation->is_impl_only(); } -void LayerImpl::SetContentBounds(gfx::Size content_bounds) { +void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) { + update_rect_ = update_rect; + SetNeedsPushProperties(); +} + +void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) { + damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect); +} + +void LayerImpl::SetContentBounds(const gfx::Size& content_bounds) { if (this->content_bounds() == content_bounds) return; @@ -975,61 +1047,8 @@ void LayerImpl::SetContentsScale(float contents_scale_x, NoteLayerPropertyChanged(); } -void LayerImpl::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) { - // Base LayerImpl has all of its content scales and content bounds pushed - // from its Layer during commit and just reuses those values as-is. - *contents_scale_x = this->contents_scale_x(); - *contents_scale_y = this->contents_scale_y(); - *content_bounds = this->content_bounds(); -} - -void LayerImpl::UpdateScrollbarPositions() { - gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); - - gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); - gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), - max_scroll_offset_.y() + bounds_.height()); - if (horizontal_scrollbar_layer_) { - horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); - horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); - horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio( - viewport.width() / scrollable_size.width()); - } - if (vertical_scrollbar_layer_) { - vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); - vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); - vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio( - viewport.height() / scrollable_size.height()); - } - - if (current_offset == last_scroll_offset_) - return; - last_scroll_offset_ = current_offset; - - if (scrollbar_animation_controller_) { - bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( - layer_tree_impl_->CurrentPhysicalTimeTicks()); - if (should_animate) - layer_tree_impl_->StartScrollbarAnimation(); - } - - // Get the current_offset_.y() value for a sanity-check on scrolling - // benchmark metrics. Specifically, we want to make sure - // BasicMouseWheelSmoothScrollGesture has proper scroll curves. - if (layer_tree_impl()->IsActiveTree()) { - TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); - } -} - void LayerImpl::SetScrollOffsetDelegate( - LayerScrollOffsetDelegate* scroll_offset_delegate) { + ScrollOffsetDelegate* scroll_offset_delegate) { // Having both a scroll parent and a scroll offset delegate is unsupported. DCHECK(!scroll_parent_); if (!scroll_offset_delegate && scroll_offset_delegate_) { @@ -1038,10 +1057,8 @@ void LayerImpl::SetScrollOffsetDelegate( } gfx::Vector2dF total_offset = TotalScrollOffset(); scroll_offset_delegate_ = scroll_offset_delegate; - if (scroll_offset_delegate_) { - scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); + if (scroll_offset_delegate_) scroll_offset_delegate_->SetTotalScrollOffset(total_offset); - } } bool LayerImpl::IsExternalFlingActive() const { @@ -1049,14 +1066,16 @@ bool LayerImpl::IsExternalFlingActive() const { scroll_offset_delegate_->IsExternalFlingActive(); } -void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { +void LayerImpl::SetScrollOffset(const gfx::Vector2d& scroll_offset) { SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); } -void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, - gfx::Vector2dF scroll_delta) { +void LayerImpl::SetScrollOffsetAndDelta(const gfx::Vector2d& scroll_offset, + const gfx::Vector2dF& scroll_delta) { bool changed = false; + last_scroll_offset_ = scroll_offset; + if (scroll_offset_ != scroll_offset) { changed = true; scroll_offset_ = scroll_offset; @@ -1091,7 +1110,7 @@ void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, if (changed) { NoteLayerPropertyChangedForSubtree(); - UpdateScrollbarPositions(); + ScrollbarParametersDidChange(); } } @@ -1101,7 +1120,7 @@ gfx::Vector2dF LayerImpl::ScrollDelta() const { return scroll_delta_; } -void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { +void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { SetScrollOffsetAndDelta(scroll_offset_, scroll_delta); } @@ -1125,18 +1144,156 @@ Region LayerImpl::VisibleContentOpaqueRegion() const { void LayerImpl::DidBeginTracing() {} -void LayerImpl::DidLoseOutputSurface() {} +void LayerImpl::ReleaseResources() {} + +gfx::Vector2d LayerImpl::MaxScrollOffset() const { + if (!scroll_clip_layer_ || bounds().IsEmpty()) + return gfx::Vector2d(); + + LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); + DCHECK(this != page_scale_layer); + DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || + IsContainerForFixedPositionLayers()); + + gfx::SizeF scaled_scroll_bounds(bounds()); + + float scale_factor = 1.f; + for (LayerImpl const* current_layer = this; + current_layer != scroll_clip_layer_; + current_layer = current_layer->parent()) { + DCHECK(current_layer); + float current_layer_scale = 1.f; + + const gfx::Transform& layer_transform = current_layer->transform(); + if (current_layer == page_scale_layer) { + DCHECK(layer_transform.IsIdentity()); + current_layer_scale = layer_tree_impl()->total_page_scale_factor(); + } else { + // TODO(wjmaclean) Should we allow for translation too? + DCHECK(layer_transform.IsScale2d()); + gfx::Vector2dF layer_scale = layer_transform.Scale2d(); + // TODO(wjmaclean) Allow for non-isotropic scales. + DCHECK(layer_scale.x() == layer_scale.y()); + current_layer_scale = layer_scale.x(); + } -void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { - if (max_scroll_offset_ == max_scroll_offset) + scale_factor *= current_layer_scale; + } + // TODO(wjmaclean) Once we move to a model where the two-viewport model is + // turned on in all builds, remove the next two lines. For now however, the + // page scale layer may coincide with the clip layer, and so this is + // necessary. + if (page_scale_layer == scroll_clip_layer_) + scale_factor *= layer_tree_impl()->total_page_scale_factor(); + + scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(), + scale_factor * scaled_scroll_bounds.height()); + scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds); + + gfx::Vector2dF max_offset( + scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), + scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); + // We need the final scroll offset to be in CSS coords. + max_offset.Scale(1 / scale_factor); + max_offset.SetToMax(gfx::Vector2dF()); + return gfx::ToFlooredVector2d(max_offset); +} + +gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { + gfx::Vector2dF max_offset = MaxScrollOffset(); + gfx::Vector2dF old_offset = TotalScrollOffset(); + gfx::Vector2dF clamped_offset = old_offset; + + clamped_offset.SetToMin(max_offset); + clamped_offset.SetToMax(gfx::Vector2d()); + gfx::Vector2dF delta = clamped_offset - old_offset; + if (!delta.IsZero()) + ScrollBy(delta); + + return delta; +} + +void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, + LayerImpl* scrollbar_clip_layer) const { + DCHECK(scrollbar_layer); + LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); + + DCHECK(this != page_scale_layer); + DCHECK(scrollbar_clip_layer); + DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || + IsContainerForFixedPositionLayers()); + gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds()); + + // See comment in MaxScrollOffset() regarding the use of the content layer + // bounds here. + gfx::RectF scroll_rect(gfx::PointF(), bounds()); + + if (scroll_rect.size().IsEmpty()) return; - max_scroll_offset_ = max_scroll_offset; - if (scroll_offset_delegate_) - scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); + // TODO(wjmaclean) This computation is nearly identical to the one in + // MaxScrollOffset. Find some way to combine these. + gfx::Vector2dF current_offset; + for (LayerImpl const* current_layer = this; + current_layer != scrollbar_clip_layer; + current_layer = current_layer->parent()) { + DCHECK(current_layer); + const gfx::Transform& layer_transform = current_layer->transform(); + if (current_layer == page_scale_layer) { + DCHECK(layer_transform.IsIdentity()); + float scale_factor = layer_tree_impl()->total_page_scale_factor(); + current_offset.Scale(scale_factor); + scroll_rect.Scale(scale_factor); + } else { + DCHECK(layer_transform.IsScale2d()); + gfx::Vector2dF layer_scale = layer_transform.Scale2d(); + DCHECK(layer_scale.x() == layer_scale.y()); + gfx::Vector2dF new_offset = + current_layer->scroll_offset() + current_layer->ScrollDelta(); + new_offset.Scale(layer_scale.x(), layer_scale.y()); + current_offset += new_offset; + } + } + // TODO(wjmaclean) Once we move to a model where the two-viewport model is + // turned on in all builds, remove the next two lines. For now however, the + // page scale layer may coincide with the clip layer, and so this is + // necessary. + if (page_scale_layer == scrollbar_clip_layer) { + scroll_rect.Scale(layer_tree_impl()->total_page_scale_factor()); + current_offset.Scale(layer_tree_impl()->total_page_scale_factor()); + } + + scrollbar_layer->SetVerticalAdjust( + layer_tree_impl()->VerticalAdjust(scrollbar_clip_layer->id())); + if (scrollbar_layer->orientation() == HORIZONTAL) { + float visible_ratio = clip_rect.width() / scroll_rect.width(); + scrollbar_layer->SetCurrentPos(current_offset.x()); + scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); + scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); + } else { + float visible_ratio = clip_rect.height() / scroll_rect.height(); + scrollbar_layer->SetCurrentPos(current_offset.y()); + scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); + scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); + } layer_tree_impl()->set_needs_update_draw_properties(); - UpdateScrollbarPositions(); + // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should + // activate for every scroll on the main frame, not just the scrolls that move + // the pinch virtual viewport (i.e. trigger from either inner or outer + // viewport). + if (scrollbar_animation_controller_) { + // When both non-overlay and overlay scrollbars are both present, don't + // animate the overlay scrollbars when page scale factor is at the min. + // Non-overlay scrollbars also shouldn't trigger animations. + bool is_animatable_scrollbar = + scrollbar_layer->is_overlay_scrollbar() && + ((layer_tree_impl()->total_page_scale_factor() > + layer_tree_impl()->min_page_scale_factor()) || + !layer_tree_impl()->settings().use_pinch_zoom_scrollbars); + if (is_animatable_scrollbar) + scrollbar_animation_controller_->DidScrollUpdate(); + } } void LayerImpl::DidBecomeActive() { @@ -1145,8 +1302,7 @@ void LayerImpl::DidBecomeActive() { return; } - bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || - vertical_scrollbar_layer_; + bool need_scrollbar_animation_controller = scrollable() && scrollbars_; if (!need_scrollbar_animation_controller) { scrollbar_animation_controller_.reset(); return; @@ -1155,179 +1311,99 @@ void LayerImpl::DidBecomeActive() { if (scrollbar_animation_controller_) return; - switch (layer_tree_impl_->settings().scrollbar_animator) { - case LayerTreeSettings::LinearFade: { - base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds( - layer_tree_impl_->settings().scrollbar_linear_fade_delay_ms); - base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds( - layer_tree_impl_->settings().scrollbar_linear_fade_length_ms); - - scrollbar_animation_controller_ = - ScrollbarAnimationControllerLinearFade::Create( - this, fadeout_delay, fadeout_length) - .PassAs<ScrollbarAnimationController>(); - break; - } - case LayerTreeSettings::Thinning: { - scrollbar_animation_controller_ = - ScrollbarAnimationControllerThinning::Create(this) - .PassAs<ScrollbarAnimationController>(); - break; - } - case LayerTreeSettings::NoAnimator: - NOTREACHED(); - break; - } -} -void LayerImpl::SetHorizontalScrollbarLayer( - ScrollbarLayerImplBase* scrollbar_layer) { - horizontal_scrollbar_layer_ = scrollbar_layer; - if (horizontal_scrollbar_layer_) - horizontal_scrollbar_layer_->set_scroll_layer_id(id()); -} - -void LayerImpl::SetVerticalScrollbarLayer( - ScrollbarLayerImplBase* scrollbar_layer) { - vertical_scrollbar_layer_ = scrollbar_layer; - if (vertical_scrollbar_layer_) - vertical_scrollbar_layer_->set_scroll_layer_id(id()); + scrollbar_animation_controller_ = + layer_tree_impl_->CreateScrollbarAnimationController(this); } -static scoped_ptr<base::Value> -CompositingReasonsAsValue(CompositingReasons reasons) { - scoped_ptr<base::ListValue> reason_list(new base::ListValue()); - - if (reasons == kCompositingReasonUnknown) { - reason_list->AppendString("No reasons given"); - return reason_list.PassAs<base::Value>(); - } - - if (reasons & kCompositingReason3DTransform) - reason_list->AppendString("Has a 3d Transform"); - - if (reasons & kCompositingReasonVideo) - reason_list->AppendString("Is accelerated video"); - - if (reasons & kCompositingReasonCanvas) - reason_list->AppendString("Is accelerated canvas"); - - if (reasons & kCompositingReasonPlugin) - reason_list->AppendString("Is accelerated plugin"); - - if (reasons & kCompositingReasonIFrame) - reason_list->AppendString("Is accelerated iframe"); - - if (reasons & kCompositingReasonBackfaceVisibilityHidden) - reason_list->AppendString("Has backface-visibility: hidden"); - - if (reasons & kCompositingReasonAnimation) - reason_list->AppendString("Has accelerated animation or transition"); - - if (reasons & kCompositingReasonFilters) - reason_list->AppendString("Has accelerated filters"); - - if (reasons & kCompositingReasonPositionFixed) - reason_list->AppendString("Is fixed position"); - - if (reasons & kCompositingReasonPositionSticky) - reason_list->AppendString("Is sticky position"); - - if (reasons & kCompositingReasonOverflowScrollingTouch) - reason_list->AppendString("Is a scrollable overflow element"); - - if (reasons & kCompositingReasonAssumedOverlap) - reason_list->AppendString("Might overlap a composited animation"); - - if (reasons & kCompositingReasonOverlap) - reason_list->AppendString("Overlaps other composited content"); - - if (reasons & kCompositingReasonNegativeZIndexChildren) { - reason_list->AppendString("Might overlap negative z-index " - "composited content"); - } - - if (reasons & kCompositingReasonTransformWithCompositedDescendants) { - reason_list->AppendString("Has transform needed by a " - "composited descendant"); - } - - if (reasons & kCompositingReasonOpacityWithCompositedDescendants) - reason_list->AppendString("Has opacity needed by a composited descendant"); - - if (reasons & kCompositingReasonMaskWithCompositedDescendants) - reason_list->AppendString("Has a mask needed by a composited descendant"); - - if (reasons & kCompositingReasonReflectionWithCompositedDescendants) - reason_list->AppendString("Has a reflection with a composited descendant"); +void LayerImpl::ClearScrollbars() { + if (!scrollbars_) + return; - if (reasons & kCompositingReasonFilterWithCompositedDescendants) - reason_list->AppendString("Has filter effect with a composited descendant"); + scrollbars_.reset(NULL); +} - if (reasons & kCompositingReasonBlendingWithCompositedDescendants) - reason_list->AppendString("Has a blend mode with a composited descendant"); +void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { + DCHECK(layer); + DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end()); + if (!scrollbars_) + scrollbars_.reset(new ScrollbarSet()); - if (reasons & kCompositingReasonClipsCompositingDescendants) - reason_list->AppendString("Clips a composited descendant"); + scrollbars_->insert(layer); +} - if (reasons & kCompositingReasonPerspective) { - reason_list->AppendString("Has a perspective transform needed by a " - "composited 3d descendant"); - } +void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { + DCHECK(scrollbars_); + DCHECK(layer); + DCHECK(scrollbars_->find(layer) != scrollbars_->end()); - if (reasons & kCompositingReasonPreserve3D) { - reason_list->AppendString("Has preserves-3d style with composited " - "3d descendant"); - } - - if (reasons & kCompositingReasonReflectionOfCompositedParent) - reason_list->AppendString("Is the reflection of a composited layer"); + scrollbars_->erase(layer); + if (scrollbars_->empty()) + scrollbars_.reset(); +} - if (reasons & kCompositingReasonRoot) - reason_list->AppendString("Is the root"); +bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { + if (!scrollbars_) + return false; - if (reasons & kCompositingReasonLayerForClip) - reason_list->AppendString("Convenience layer, to clip subtree"); + for (ScrollbarSet::iterator it = scrollbars_->begin(); + it != scrollbars_->end(); + ++it) + if ((*it)->orientation() == orientation) + return true; - if (reasons & kCompositingReasonLayerForScrollbar) - reason_list->AppendString("Convenience layer for rendering scrollbar"); + return false; +} - if (reasons & kCompositingReasonLayerForScrollingContainer) - reason_list->AppendString("Convenience layer, the scrolling container"); +void LayerImpl::ScrollbarParametersDidChange() { + if (!scrollbars_) + return; - if (reasons & kCompositingReasonLayerForForeground) { - reason_list->AppendString("Convenience layer, foreground when main layer " - "has negative z-index composited content"); - } + for (ScrollbarSet::iterator it = scrollbars_->begin(); + it != scrollbars_->end(); + ++it) + (*it)->ScrollbarParametersDidChange(); +} - if (reasons & kCompositingReasonLayerForBackground) { - reason_list->AppendString("Convenience layer, background when main layer " - "has a composited background"); - } +void LayerImpl::SetNeedsPushProperties() { + if (needs_push_properties_) + return; + if (!parent_should_know_need_push_properties() && parent_) + parent_->AddDependentNeedsPushProperties(); + needs_push_properties_ = true; +} - if (reasons & kCompositingReasonLayerForMask) - reason_list->AppendString("Is a mask layer"); +void LayerImpl::AddDependentNeedsPushProperties() { + DCHECK_GE(num_dependents_need_push_properties_, 0); - if (reasons & kCompositingReasonOverflowScrollingParent) - reason_list->AppendString("Scroll parent is not an ancestor"); + if (!parent_should_know_need_push_properties() && parent_) + parent_->AddDependentNeedsPushProperties(); - if (reasons & kCompositingReasonOutOfFlowClipping) - reason_list->AppendString("Has clipping ancestor"); + num_dependents_need_push_properties_++; +} - if (reasons & kCompositingReasonIsolateCompositedDescendants) - reason_list->AppendString("Should isolate composited descendants"); +void LayerImpl::RemoveDependentNeedsPushProperties() { + num_dependents_need_push_properties_--; + DCHECK_GE(num_dependents_need_push_properties_, 0); - return reason_list.PassAs<base::Value>(); + if (!parent_should_know_need_push_properties() && parent_) + parent_->RemoveDependentNeedsPushProperties(); } void LayerImpl::AsValueInto(base::DictionaryValue* state) const { - TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this); + TracedValue::MakeDictIntoImplicitSnapshotWithCategory( + TRACE_DISABLED_BY_DEFAULT("cc.debug"), + state, + "cc::LayerImpl", + LayerTypeAsString(), + this); state->SetInteger("layer_id", id()); - state->SetString("layer_name", debug_name()); - state->Set("bounds", MathUtil::AsValue(bounds()).release()); + state->Set("bounds", MathUtil::AsValue(bounds_).release()); + state->Set("position", MathUtil::AsValue(position_).release()); state->SetInteger("draws_content", DrawsContent()); state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); - state->Set("compositing_reasons", - CompositingReasonsAsValue(compositing_reasons_).release()); + state->Set("scroll_offset", MathUtil::AsValue(scroll_offset_).release()); + state->Set("transform_origin", + MathUtil::AsValue(transform_origin_).release()); bool clipped; gfx::QuadF layer_quad = MathUtil::MapQuad( @@ -1346,6 +1422,12 @@ void LayerImpl::AsValueInto(base::DictionaryValue* state) const { state->Set("wheel_event_handler_region", wheel_region.AsValue().release()); } + if (have_scroll_event_handlers_) { + gfx::Rect scroll_rect(content_bounds()); + Region scroll_region(scroll_rect); + state->Set("scroll_event_handler_region", + scroll_region.AsValue().release()); + } if (!non_fast_scrollable_region_.IsEmpty()) { state->Set("non_fast_scrollable_region", non_fast_scrollable_region_.AsValue().release()); @@ -1369,28 +1451,37 @@ void LayerImpl::AsValueInto(base::DictionaryValue* state) const { state->SetBoolean("can_use_lcd_text", can_use_lcd_text()); state->SetBoolean("contents_opaque", contents_opaque()); - if (layer_animation_controller_->IsAnimatingProperty(Animation::Transform) || - layer_animation_controller_->IsAnimatingProperty(Animation::Filter)) { - gfx::BoxF box(bounds().width(), bounds().height(), 0.f); - gfx::BoxF inflated; - if (layer_animation_controller_->AnimatedBoundsForBox(box, &inflated)) - state->Set("animated_bounds", MathUtil::AsValue(inflated).release()); - } + state->SetBoolean( + "has_animation_bounds", + layer_animation_controller()->HasAnimationThatInflatesBounds()); + + gfx::BoxF box; + if (LayerUtils::GetAnimationBounds(*this, &box)) + state->Set("animation_bounds", MathUtil::AsValue(box).release()); if (debug_info_.get()) { std::string str; debug_info_->AppendAsTraceFormat(&str); base::JSONReader json_reader; - // Parsing the JSON and re-encoding it is not very efficient, - // but it's the simplest way to achieve the desired effect, which - // is to output: - // {..., layout_rects: [{geometry_rect: ...}, ...], ...} - // rather than: - // {layout_rects: "[{geometry_rect: ...}, ...]", ...} - state->Set("layout_rects", json_reader.ReadToValue(str)); + scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str)); + + if (debug_info_value->IsType(base::Value::TYPE_DICTIONARY)) { + base::DictionaryValue* dictionary_value = NULL; + bool converted_to_dictionary = + debug_info_value->GetAsDictionary(&dictionary_value); + DCHECK(converted_to_dictionary); + state->MergeDictionary(dictionary_value); + } else { + NOTREACHED(); + } } } +bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const { + return draw_properties_.last_drawn_render_surface_layer_list_id == + layer_tree_impl_->current_render_surface_list_id(); +} + size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } scoped_ptr<base::Value> LayerImpl::AsValue() const { @@ -1402,5 +1493,4 @@ scoped_ptr<base::Value> LayerImpl::AsValue() const { void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { benchmark->RunOnLayer(this); } - } // namespace cc |