layer_impl.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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. 4 5#include "cc/layers/layer_impl.h" 6 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" 28 29namespace cc { 30 31LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) 32 : parent_(NULL), 33 scroll_parent_(NULL), 34 clip_parent_(NULL), 35 mask_layer_id_(-1), 36 replica_layer_id_(-1), 37 layer_id_(id), 38 layer_tree_impl_(tree_impl), 39 anchor_point_(0.5f, 0.5f), 40 anchor_point_z_(0.f), 41 scroll_offset_delegate_(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 background_color_(0), 48 stacking_order_changed_(false), 49 double_sided_(true), 50 layer_property_changed_(false), 51 masks_to_bounds_(false), 52 contents_opaque_(false), 53 opacity_(1.0), 54 preserves_3d_(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), 61 draw_depth_(0.f), 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); 73} 74 75LayerImpl::~LayerImpl() { 76 DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); 77 78 layer_tree_impl_->UnregisterLayer(this); 79 layer_animation_controller_->RemoveValueObserver(this); 80 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; 85 } 86 87 if (scroll_parent_) 88 scroll_parent_->RemoveScrollChild(this); 89 90 if (clip_children_) { 91 for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); 92 it != clip_children_->end(); ++it) 93 (*it)->clip_parent_ = NULL; 94 } 95 96 if (clip_parent_) 97 clip_parent_->RemoveClipChild(this); 98} 99 100void 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(); 105} 106 107scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { 108 for (OwnedLayerImplList::iterator it = children_.begin(); 109 it != children_.end(); 110 ++it) { 111 if (*it == child) { 112 scoped_ptr<LayerImpl> ret = children_.take(it); 113 children_.erase(it); 114 layer_tree_impl()->set_needs_update_draw_properties(); 115 return ret.Pass(); 116 } 117 } 118 return scoped_ptr<LayerImpl>(); 119} 120 121void LayerImpl::ClearChildList() { 122 if (children_.empty()) 123 return; 124 125 children_.clear(); 126 layer_tree_impl()->set_needs_update_draw_properties(); 127} 128 129bool LayerImpl::HasAncestor(const LayerImpl* ancestor) const { 130 if (!ancestor) 131 return false; 132 133 for (const LayerImpl* layer = this; layer; layer = layer->parent()) { 134 if (layer == ancestor) 135 return true; 136 } 137 138 return false; 139} 140 141void LayerImpl::SetScrollParent(LayerImpl* parent) { 142 if (scroll_parent_ == parent) 143 return; 144 145 // Having both a scroll parent and a scroll offset delegate is unsupported. 146 DCHECK(!scroll_offset_delegate_); 147 148 if (scroll_parent_) 149 scroll_parent_->RemoveScrollChild(this); 150 151 scroll_parent_ = parent; 152} 153 154void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { 155 if (scroll_children_.get() == children) 156 return; 157 scroll_children_.reset(children); 158} 159 160void LayerImpl::RemoveScrollChild(LayerImpl* child) { 161 DCHECK(scroll_children_); 162 scroll_children_->erase(child); 163 if (scroll_children_->empty()) 164 scroll_children_.reset(); 165} 166 167void LayerImpl::SetClipParent(LayerImpl* ancestor) { 168 if (clip_parent_ == ancestor) 169 return; 170 171 if (clip_parent_) 172 clip_parent_->RemoveClipChild(this); 173 174 clip_parent_ = ancestor; 175} 176 177void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { 178 if (clip_children_.get() == children) 179 return; 180 clip_children_.reset(children); 181} 182 183void LayerImpl::RemoveClipChild(LayerImpl* child) { 184 DCHECK(clip_children_); 185 clip_children_->erase(child); 186 if (clip_children_->empty()) 187 clip_children_.reset(); 188} 189 190void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { 191 if (requests->empty()) 192 return; 193 194 bool was_empty = copy_requests_.empty(); 195 copy_requests_.insert_and_take(copy_requests_.end(), *requests); 196 requests->clear(); 197 198 if (was_empty && layer_tree_impl()->IsActiveTree()) 199 layer_tree_impl()->AddLayerWithCopyOutputRequest(this); 200 NoteLayerPropertyChangedForSubtree(); 201} 202 203void LayerImpl::TakeCopyRequestsAndTransformToTarget( 204 ScopedPtrVector<CopyOutputRequest>* requests) { 205 if (copy_requests_.empty()) 206 return; 207 208 size_t first_inserted_request = requests->size(); 209 requests->insert_and_take(requests->end(), copy_requests_); 210 copy_requests_.clear(); 211 212 for (size_t i = first_inserted_request; i < requests->size(); ++i) { 213 CopyOutputRequest* request = requests->at(i); 214 if (!request->has_area()) 215 continue; 216 217 gfx::Rect request_in_layer_space = request->area(); 218 gfx::Rect request_in_content_space = 219 LayerRectToContentRect(request_in_layer_space); 220 request->set_area( 221 MathUtil::MapClippedRect(draw_properties_.target_space_transform, 222 request_in_content_space)); 223 } 224 225 if (layer_tree_impl()->IsActiveTree()) 226 layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); 227} 228 229void 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; 234} 235 236void LayerImpl::ClearRenderSurface() { 237 draw_properties_.render_surface.reset(); 238} 239 240scoped_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); 248 return state.Pass(); 249} 250 251bool 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; 257 return true; 258} 259 260void LayerImpl::DidDraw(ResourceProvider* resource_provider) { 261 DCHECK_NE(DRAW_MODE_NONE, current_draw_mode_); 262 current_draw_mode_ = DRAW_MODE_NONE; 263} 264 265bool LayerImpl::ShowDebugBorders() const { 266 return layer_tree_impl()->debug_state().show_debug_borders; 267} 268 269void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { 270 if (draws_content_) { 271 *color = DebugColors::ContentLayerBorderColor(); 272 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); 273 return; 274 } 275 276 if (masks_to_bounds_) { 277 *color = DebugColors::MaskingLayerBorderColor(); 278 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl()); 279 return; 280 } 281 282 *color = DebugColors::ContainerLayerBorderColor(); 283 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl()); 284} 285 286void LayerImpl::AppendDebugBorderQuad( 287 QuadSink* quad_sink, 288 const SharedQuadState* shared_quad_state, 289 AppendQuadsData* append_quads_data) const { 290 SkColor color; 291 float width; 292 GetDebugBorderProperties(&color, &width); 293 AppendDebugBorderQuad( 294 quad_sink, shared_quad_state, append_quads_data, color, width); 295} 296 297void LayerImpl::AppendDebugBorderQuad(QuadSink* quad_sink, 298 const SharedQuadState* shared_quad_state, 299 AppendQuadsData* append_quads_data, 300 SkColor color, 301 float width) const { 302 if (!ShowDebugBorders()) 303 return; 304 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); 310} 311 312bool LayerImpl::HasDelegatedContent() const { 313 return false; 314} 315 316bool LayerImpl::HasContributingDelegatedRenderPasses() const { 317 return false; 318} 319 320RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { 321 return RenderPass::Id(0, 0); 322} 323 324RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) 325 const { 326 return RenderPass::Id(0, 0); 327} 328 329ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { 330 NOTREACHED(); 331 return 0; 332} 333 334void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { 335 // Pending tree never has sent scroll deltas 336 DCHECK(layer_tree_impl()->IsActiveTree()); 337 338 if (sent_scroll_delta_ == sent_scroll_delta) 339 return; 340 341 sent_scroll_delta_ = sent_scroll_delta; 342} 343 344gfx::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()); 349 scroll.set_x(0.f); 350 } 351 if (!user_scrollable_vertical_) { 352 scroll_hidden.set_y(scroll.y()); 353 scroll.set_y(0.f); 354 } 355 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); 365 return unscrolled; 366} 367 368void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { 369 // Pending tree never has sent scroll deltas 370 DCHECK(layer_tree_impl()->IsActiveTree()); 371 372 // Apply sent scroll deltas to scroll position / scroll delta as if the 373 // main thread had applied them and then committed those values. 374 // 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. 379 // 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(); 386} 387 388void LayerImpl::ApplyScrollDeltasSinceBeginFrame() { 389 // Only the pending tree can have missing scrolls. 390 DCHECK(layer_tree_impl()->IsPendingTree()); 391 if (!scrollable()) 392 return; 393 394 // Pending tree should never have sent scroll deltas. 395 DCHECK(sent_scroll_delta().IsZero()); 396 397 LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id()); 398 if (active_twin) { 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()); 404 } 405} 406 407InputHandler::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; 413 } 414 415 if (!screen_space_transform().IsInvertible()) { 416 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); 417 return InputHandler::ScrollIgnored; 418 } 419 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? 428 } 429 430 gfx::PointF hit_test_point_in_content_space = 431 MathUtil::ProjectPoint(inverse_screen_space_transform, 432 screen_space_point, 433 &clipped); 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()); 438 if (!clipped && 439 non_fast_scrollable_region().Contains( 440 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { 441 TRACE_EVENT0("cc", 442 "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); 443 return InputHandler::ScrollOnMainThread; 444 } 445 } 446 447 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { 448 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); 449 return InputHandler::ScrollOnMainThread; 450 } 451 452 if (!scrollable()) { 453 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 454 return InputHandler::ScrollIgnored; 455 } 456 457 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { 458 TRACE_EVENT0("cc", 459 "LayerImpl::tryScroll: Ignored. Technically scrollable," 460 " but has no affordance in either direction."); 461 return InputHandler::ScrollIgnored; 462 } 463 464 if (!user_scrollable_horizontal_ && !user_scrollable_vertical_) { 465 TRACE_EVENT0("cc", 466 "LayerImpl::TryScroll: Ignored. User gesture is not allowed" 467 " to scroll this layer."); 468 return InputHandler::ScrollIgnored; 469 } 470 471 return InputHandler::ScrollStarted; 472} 473 474bool LayerImpl::DrawCheckerboardForMissingTiles() const { 475 return draw_checkerboard_for_missing_tiles_ && 476 !layer_tree_impl()->settings().background_color_instead_of_checkerboard; 477} 478 479gfx::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); 487} 488 489skia::RefPtr<SkPicture> LayerImpl::GetPicture() { 490 return skia::RefPtr<SkPicture>(); 491} 492 493bool LayerImpl::AreVisibleResourcesReady() const { 494 return true; 495} 496 497scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { 498 return LayerImpl::Create(tree_impl, layer_id_); 499} 500 501void 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_); 534 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()); 541 542 layer->SetMaxScrollOffset(max_scroll_offset_); 543 544 LayerImpl* scroll_parent = NULL; 545 if (scroll_parent_) 546 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); 547 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); 555 } 556 557 LayerImpl* clip_parent = NULL; 558 if (clip_parent_) { 559 clip_parent = layer->layer_tree_impl()->LayerById( 560 clip_parent_->id()); 561 } 562 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); 570 } 571 572 layer->PassCopyRequests(©_requests_); 573 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_); 580 581 layer->SetStackingOrderChanged(stacking_order_changed_); 582 583 // Reset any state that should be cleared for the next update. 584 stacking_order_changed_ = false; 585 update_rect_ = gfx::RectF(); 586} 587 588base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { 589 base::DictionaryValue* result = new base::DictionaryValue; 590 result->SetString("LayerType", LayerTypeAsString()); 591 592 base::ListValue* list = new base::ListValue; 593 list->AppendInteger(bounds().width()); 594 list->AppendInteger(bounds().height()); 595 result->Set("Bounds", list); 596 597 list = new base::ListValue; 598 list->AppendDouble(position_.x()); 599 list->AppendDouble(position_.y()); 600 result->Set("Position", list); 601 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); 609 610 result->SetBoolean("DrawsContent", draws_content_); 611 result->SetDouble("Opacity", opacity()); 612 result->SetBoolean("ContentsOpaque", contents_opaque_); 613 614 if (scrollable_) 615 result->SetBoolean("Scrollable", scrollable_); 616 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); 621 622 return result; 623} 624 625void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { 626 if (stacking_order_changed) { 627 stacking_order_changed_ = true; 628 NoteLayerPropertyChangedForSubtree(); 629 } 630} 631 632void LayerImpl::NoteLayerPropertyChanged() { 633 layer_property_changed_ = true; 634 layer_tree_impl()->set_needs_update_draw_properties(); 635} 636 637void LayerImpl::NoteLayerPropertyChangedForSubtree() { 638 NoteLayerPropertyChanged(); 639 NoteLayerPropertyChangedForDescendants(); 640} 641 642void 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(); 646} 647 648const char* LayerImpl::LayerTypeAsString() const { 649 return "cc::LayerImpl"; 650} 651 652void LayerImpl::ResetAllChangeTrackingForSubtree() { 653 layer_property_changed_ = false; 654 655 update_rect_ = gfx::RectF(); 656 657 if (draw_properties_.render_surface) 658 draw_properties_.render_surface->ResetPropertyChangedFlag(); 659 660 if (mask_layer_) 661 mask_layer_->ResetAllChangeTrackingForSubtree(); 662 663 if (replica_layer_) { 664 // This also resets the replica mask, if it exists. 665 replica_layer_->ResetAllChangeTrackingForSubtree(); 666 } 667 668 for (size_t i = 0; i < children_.size(); ++i) 669 children_[i]->ResetAllChangeTrackingForSubtree(); 670} 671 672bool LayerImpl::LayerIsAlwaysDamaged() const { 673 return false; 674} 675 676void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { 677 SetFilters(filters); 678} 679 680void LayerImpl::OnOpacityAnimated(float opacity) { 681 SetOpacity(opacity); 682} 683 684void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { 685 SetTransform(transform); 686} 687 688bool LayerImpl::IsActive() const { 689 return layer_tree_impl_->IsActiveTree(); 690} 691 692void LayerImpl::SetBounds(gfx::Size bounds) { 693 if (bounds_ == bounds) 694 return; 695 696 bounds_ = bounds; 697 698 if (masks_to_bounds()) 699 NoteLayerPropertyChangedForSubtree(); 700 else 701 NoteLayerPropertyChanged(); 702} 703 704void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { 705 int new_layer_id = mask_layer ? mask_layer->id() : -1; 706 707 if (mask_layer) { 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_) { 711 return; 712 } 713 714 mask_layer_ = mask_layer.Pass(); 715 mask_layer_id_ = new_layer_id; 716 if (mask_layer_) 717 mask_layer_->set_parent(this); 718 NoteLayerPropertyChangedForSubtree(); 719} 720 721scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { 722 mask_layer_id_ = -1; 723 return mask_layer_.Pass(); 724} 725 726void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { 727 int new_layer_id = replica_layer ? replica_layer->id() : -1; 728 729 if (replica_layer) { 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_) { 733 return; 734 } 735 736 replica_layer_ = replica_layer.Pass(); 737 replica_layer_id_ = new_layer_id; 738 if (replica_layer_) 739 replica_layer_->set_parent(this); 740 NoteLayerPropertyChangedForSubtree(); 741} 742 743scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { 744 replica_layer_id_ = -1; 745 return replica_layer_.Pass(); 746} 747 748ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() { 749 return NULL; 750} 751 752void LayerImpl::SetDrawsContent(bool draws_content) { 753 if (draws_content_ == draws_content) 754 return; 755 756 draws_content_ = draws_content; 757 NoteLayerPropertyChanged(); 758} 759 760void LayerImpl::SetHideLayerAndSubtree(bool hide) { 761 if (hide_layer_and_subtree_ == hide) 762 return; 763 764 hide_layer_and_subtree_ = hide; 765 NoteLayerPropertyChangedForSubtree(); 766} 767 768void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { 769 if (anchor_point_ == anchor_point) 770 return; 771 772 anchor_point_ = anchor_point; 773 NoteLayerPropertyChangedForSubtree(); 774} 775 776void LayerImpl::SetAnchorPointZ(float anchor_point_z) { 777 if (anchor_point_z_ == anchor_point_z) 778 return; 779 780 anchor_point_z_ = anchor_point_z; 781 NoteLayerPropertyChangedForSubtree(); 782} 783 784void LayerImpl::SetBackgroundColor(SkColor background_color) { 785 if (background_color_ == background_color) 786 return; 787 788 background_color_ = background_color; 789 NoteLayerPropertyChanged(); 790} 791 792SkColor 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) 801 break; 802 } 803 if (SkColorGetA(color) != 255) 804 color = layer_tree_impl()->background_color(); 805 if (SkColorGetA(color) != 255) 806 color = SkColorSetA(color, 255); 807 } 808 return color; 809} 810 811void LayerImpl::SetFilters(const FilterOperations& filters) { 812 if (filters_ == filters) 813 return; 814 815 filters_ = filters; 816 NoteLayerPropertyChangedForSubtree(); 817} 818 819bool LayerImpl::FilterIsAnimating() const { 820 return layer_animation_controller_->IsAnimatingProperty(Animation::Filter); 821} 822 823bool LayerImpl::FilterIsAnimatingOnImplOnly() const { 824 Animation* filter_animation = 825 layer_animation_controller_->GetAnimation(Animation::Filter); 826 return filter_animation && filter_animation->is_impl_only(); 827} 828 829void LayerImpl::SetBackgroundFilters( 830 const FilterOperations& filters) { 831 if (background_filters_ == filters) 832 return; 833 834 background_filters_ = filters; 835 NoteLayerPropertyChanged(); 836} 837 838void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { 839 if (masks_to_bounds_ == masks_to_bounds) 840 return; 841 842 masks_to_bounds_ = masks_to_bounds; 843 NoteLayerPropertyChangedForSubtree(); 844} 845 846void LayerImpl::SetContentsOpaque(bool opaque) { 847 if (contents_opaque_ == opaque) 848 return; 849 850 contents_opaque_ = opaque; 851 NoteLayerPropertyChangedForSubtree(); 852} 853 854void LayerImpl::SetOpacity(float opacity) { 855 if (opacity_ == opacity) 856 return; 857 858 opacity_ = opacity; 859 NoteLayerPropertyChangedForSubtree(); 860} 861 862bool LayerImpl::OpacityIsAnimating() const { 863 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); 864} 865 866bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { 867 Animation* opacity_animation = 868 layer_animation_controller_->GetAnimation(Animation::Opacity); 869 return opacity_animation && opacity_animation->is_impl_only(); 870} 871 872void LayerImpl::SetPosition(gfx::PointF position) { 873 if (position_ == position) 874 return; 875 876 position_ = position; 877 NoteLayerPropertyChangedForSubtree(); 878} 879 880void LayerImpl::SetPreserves3d(bool preserves3_d) { 881 if (preserves_3d_ == preserves3_d) 882 return; 883 884 preserves_3d_ = preserves3_d; 885 NoteLayerPropertyChangedForSubtree(); 886} 887 888void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { 889 if (sublayer_transform_ == sublayer_transform) 890 return; 891 892 sublayer_transform_ = sublayer_transform; 893 // Sublayer transform does not affect the current layer; it affects only its 894 // children. 895 NoteLayerPropertyChangedForDescendants(); 896} 897 898void LayerImpl::SetTransform(const gfx::Transform& transform) { 899 if (transform_ == transform) 900 return; 901 902 transform_ = transform; 903 NoteLayerPropertyChangedForSubtree(); 904} 905 906bool LayerImpl::TransformIsAnimating() const { 907 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); 908} 909 910bool LayerImpl::TransformIsAnimatingOnImplOnly() const { 911 Animation* transform_animation = 912 layer_animation_controller_->GetAnimation(Animation::Transform); 913 return transform_animation && transform_animation->is_impl_only(); 914} 915 916void LayerImpl::SetContentBounds(gfx::Size content_bounds) { 917 if (this->content_bounds() == content_bounds) 918 return; 919 920 draw_properties_.content_bounds = content_bounds; 921 NoteLayerPropertyChanged(); 922} 923 924void 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) 928 return; 929 930 draw_properties_.contents_scale_x = contents_scale_x; 931 draw_properties_.contents_scale_y = contents_scale_y; 932 NoteLayerPropertyChanged(); 933} 934 935void 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(); 948} 949 950void LayerImpl::UpdateScrollbarPositions() { 951 gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); 952 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()); 961 } 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()); 967 } 968 969 if (current_offset == last_scroll_offset_) 970 return; 971 last_scroll_offset_ = current_offset; 972 973 if (scrollbar_animation_controller_) { 974 bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( 975 layer_tree_impl_->CurrentPhysicalTimeTicks()); 976 if (should_animate) 977 layer_tree_impl_->StartScrollbarAnimation(); 978 } 979 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()); 985 } 986} 987 988void 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_) { 993 scroll_delta_ = 994 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 995 } 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); 1001 } 1002} 1003 1004bool LayerImpl::IsExternalFlingActive() const { 1005 return scroll_offset_delegate_ && 1006 scroll_offset_delegate_->IsExternalFlingActive(); 1007} 1008 1009void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { 1010 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); 1011} 1012 1013void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, 1014 gfx::Vector2dF scroll_delta) { 1015 bool changed = false; 1016 1017 if (scroll_offset_ != scroll_offset) { 1018 changed = true; 1019 scroll_offset_ = scroll_offset; 1020 1021 if (scroll_offset_delegate_) 1022 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); 1023 } 1024 1025 if (ScrollDelta() != scroll_delta) { 1026 changed = true; 1027 if (layer_tree_impl()->IsActiveTree()) { 1028 LayerImpl* pending_twin = 1029 layer_tree_impl()->FindPendingTreeLayerById(id()); 1030 if (pending_twin) { 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()); 1038 } 1039 } 1040 1041 if (scroll_offset_delegate_) { 1042 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + 1043 scroll_delta); 1044 } else { 1045 scroll_delta_ = scroll_delta; 1046 } 1047 } 1048 1049 if (changed) { 1050 NoteLayerPropertyChangedForSubtree(); 1051 UpdateScrollbarPositions(); 1052 } 1053} 1054 1055gfx::Vector2dF LayerImpl::ScrollDelta() const { 1056 if (scroll_offset_delegate_) 1057 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 1058 return scroll_delta_; 1059} 1060 1061void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { 1062 SetScrollOffsetAndDelta(scroll_offset_, scroll_delta); 1063} 1064 1065gfx::Vector2dF LayerImpl::TotalScrollOffset() const { 1066 return scroll_offset_ + ScrollDelta(); 1067} 1068 1069void LayerImpl::SetDoubleSided(bool double_sided) { 1070 if (double_sided_ == double_sided) 1071 return; 1072 1073 double_sided_ = double_sided; 1074 NoteLayerPropertyChangedForSubtree(); 1075} 1076 1077Region LayerImpl::VisibleContentOpaqueRegion() const { 1078 if (contents_opaque()) 1079 return visible_content_rect(); 1080 return Region(); 1081} 1082 1083void LayerImpl::DidBeginTracing() {} 1084 1085void LayerImpl::DidLoseOutputSurface() {} 1086 1087void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { 1088 if (max_scroll_offset_ == max_scroll_offset) 1089 return; 1090 max_scroll_offset_ = max_scroll_offset; 1091 1092 if (scroll_offset_delegate_) 1093 scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); 1094 1095 layer_tree_impl()->set_needs_update_draw_properties(); 1096 UpdateScrollbarPositions(); 1097} 1098 1099void LayerImpl::DidBecomeActive() { 1100 if (layer_tree_impl_->settings().scrollbar_animator == 1101 LayerTreeSettings::NoAnimator) { 1102 return; 1103 } 1104 1105 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || 1106 vertical_scrollbar_layer_; 1107 if (!need_scrollbar_animation_controller) { 1108 scrollbar_animation_controller_.reset(); 1109 return; 1110 } 1111 1112 if (scrollbar_animation_controller_) 1113 return; 1114 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); 1121 1122 scrollbar_animation_controller_ = 1123 ScrollbarAnimationControllerLinearFade::Create( 1124 this, fadeout_delay, fadeout_length) 1125 .PassAs<ScrollbarAnimationController>(); 1126 break; 1127 } 1128 case LayerTreeSettings::Thinning: { 1129 scrollbar_animation_controller_ = 1130 ScrollbarAnimationControllerThinning::Create(this) 1131 .PassAs<ScrollbarAnimationController>(); 1132 break; 1133 } 1134 case LayerTreeSettings::NoAnimator: 1135 NOTREACHED(); 1136 break; 1137 } 1138} 1139void 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()); 1144} 1145 1146void 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()); 1151} 1152 1153static scoped_ptr<base::Value> 1154CompositingReasonsAsValue(CompositingReasons reasons) { 1155 scoped_ptr<base::ListValue> reason_list(new base::ListValue()); 1156 1157 if (reasons == kCompositingReasonUnknown) { 1158 reason_list->AppendString("No reasons given"); 1159 return reason_list.PassAs<base::Value>(); 1160 } 1161 1162 if (reasons & kCompositingReason3DTransform) 1163 reason_list->AppendString("Has a 3d Transform"); 1164 1165 if (reasons & kCompositingReasonVideo) 1166 reason_list->AppendString("Is accelerated video"); 1167 1168 if (reasons & kCompositingReasonCanvas) 1169 reason_list->AppendString("Is accelerated canvas"); 1170 1171 if (reasons & kCompositingReasonPlugin) 1172 reason_list->AppendString("Is accelerated plugin"); 1173 1174 if (reasons & kCompositingReasonIFrame) 1175 reason_list->AppendString("Is accelerated iframe"); 1176 1177 if (reasons & kCompositingReasonBackfaceVisibilityHidden) 1178 reason_list->AppendString("Has backface-visibility: hidden"); 1179 1180 if (reasons & kCompositingReasonAnimation) 1181 reason_list->AppendString("Has accelerated animation or transition"); 1182 1183 if (reasons & kCompositingReasonFilters) 1184 reason_list->AppendString("Has accelerated filters"); 1185 1186 if (reasons & kCompositingReasonPositionFixed) 1187 reason_list->AppendString("Is fixed position"); 1188 1189 if (reasons & kCompositingReasonPositionSticky) 1190 reason_list->AppendString("Is sticky position"); 1191 1192 if (reasons & kCompositingReasonOverflowScrollingTouch) 1193 reason_list->AppendString("Is a scrollable overflow element"); 1194 1195 if (reasons & kCompositingReasonAssumedOverlap) 1196 reason_list->AppendString("Might overlap a composited animation"); 1197 1198 if (reasons & kCompositingReasonOverlap) 1199 reason_list->AppendString("Overlaps other composited content"); 1200 1201 if (reasons & kCompositingReasonNegativeZIndexChildren) { 1202 reason_list->AppendString("Might overlap negative z-index " 1203 "composited content"); 1204 } 1205 1206 if (reasons & kCompositingReasonTransformWithCompositedDescendants) { 1207 reason_list->AppendString("Has transform needed by a " 1208 "composited descendant"); 1209 } 1210 1211 if (reasons & kCompositingReasonOpacityWithCompositedDescendants) 1212 reason_list->AppendString("Has opacity needed by a composited descendant"); 1213 1214 if (reasons & kCompositingReasonMaskWithCompositedDescendants) 1215 reason_list->AppendString("Has a mask needed by a composited descendant"); 1216 1217 if (reasons & kCompositingReasonReflectionWithCompositedDescendants) 1218 reason_list->AppendString("Has a reflection with a composited descendant"); 1219 1220 if (reasons & kCompositingReasonFilterWithCompositedDescendants) 1221 reason_list->AppendString("Has filter effect with a composited descendant"); 1222 1223 if (reasons & kCompositingReasonBlendingWithCompositedDescendants) 1224 reason_list->AppendString("Has a blend mode with a composited descendant"); 1225 1226 if (reasons & kCompositingReasonClipsCompositingDescendants) 1227 reason_list->AppendString("Clips a composited descendant"); 1228 1229 if (reasons & kCompositingReasonPerspective) { 1230 reason_list->AppendString("Has a perspective transform needed by a " 1231 "composited 3d descendant"); 1232 } 1233 1234 if (reasons & kCompositingReasonPreserve3D) { 1235 reason_list->AppendString("Has preserves-3d style with composited " 1236 "3d descendant"); 1237 } 1238 1239 if (reasons & kCompositingReasonReflectionOfCompositedParent) 1240 reason_list->AppendString("Is the reflection of a composited layer"); 1241 1242 if (reasons & kCompositingReasonRoot) 1243 reason_list->AppendString("Is the root"); 1244 1245 if (reasons & kCompositingReasonLayerForClip) 1246 reason_list->AppendString("Convenience layer, to clip subtree"); 1247 1248 if (reasons & kCompositingReasonLayerForScrollbar) 1249 reason_list->AppendString("Convenience layer for rendering scrollbar"); 1250 1251 if (reasons & kCompositingReasonLayerForScrollingContainer) 1252 reason_list->AppendString("Convenience layer, the scrolling container"); 1253 1254 if (reasons & kCompositingReasonLayerForForeground) { 1255 reason_list->AppendString("Convenience layer, foreground when main layer " 1256 "has negative z-index composited content"); 1257 } 1258 1259 if (reasons & kCompositingReasonLayerForBackground) { 1260 reason_list->AppendString("Convenience layer, background when main layer " 1261 "has a composited background"); 1262 } 1263 1264 if (reasons & kCompositingReasonLayerForMask) 1265 reason_list->AppendString("Is a mask layer"); 1266 1267 if (reasons & kCompositingReasonOverflowScrollingParent) 1268 reason_list->AppendString("Scroll parent is not an ancestor"); 1269 1270 if (reasons & kCompositingReasonOutOfFlowClipping) 1271 reason_list->AppendString("Has clipping ancestor"); 1272 1273 return reason_list.PassAs<base::Value>(); 1274} 1275 1276void 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()); 1285 1286 bool clipped; 1287 gfx::QuadF layer_quad = MathUtil::MapQuad( 1288 screen_space_transform(), 1289 gfx::QuadF(gfx::Rect(content_bounds())), 1290 &clipped); 1291 state->Set("layer_quad", MathUtil::AsValue(layer_quad).release()); 1292 1293 if (!touch_event_handler_region_.IsEmpty()) { 1294 state->Set("touch_event_handler_region", 1295 touch_event_handler_region_.AsValue().release()); 1296 } 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()); 1302 } 1303 if (!non_fast_scrollable_region_.IsEmpty()) { 1304 state->Set("non_fast_scrollable_region", 1305 non_fast_scrollable_region_.AsValue().release()); 1306 } 1307 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()); 1312 if (mask_layer_) 1313 state->Set("mask_layer", mask_layer_->AsValue().release()); 1314 if (replica_layer_) 1315 state->Set("replica_layer", replica_layer_->AsValue().release()); 1316 1317 if (scroll_parent_) 1318 state->SetInteger("scroll_parent", scroll_parent_->id()); 1319 1320 if (clip_parent_) 1321 state->SetInteger("clip_parent", clip_parent_->id()); 1322 1323 state->SetBoolean("can_use_lcd_text", can_use_lcd_text()); 1324 state->SetBoolean("contents_opaque", contents_opaque()); 1325} 1326 1327size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } 1328 1329scoped_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>(); 1333} 1334 1335} // namespace cc 1336