layer_impl.cc revision 3551c9c881056c480085172ff9840cab31610854
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/base/math_util.h" 13#include "cc/debug/debug_colors.h" 14#include "cc/debug/layer_tree_debug_state.h" 15#include "cc/debug/traced_value.h" 16#include "cc/input/layer_scroll_offset_delegate.h" 17#include "cc/layers/painted_scrollbar_layer_impl.h" 18#include "cc/layers/quad_sink.h" 19#include "cc/output/copy_output_request.h" 20#include "cc/quads/debug_border_draw_quad.h" 21#include "cc/trees/layer_tree_impl.h" 22#include "cc/trees/layer_tree_settings.h" 23#include "cc/trees/proxy.h" 24#include "ui/gfx/point_conversions.h" 25#include "ui/gfx/quad_f.h" 26#include "ui/gfx/rect_conversions.h" 27 28namespace cc { 29 30LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) 31 : parent_(NULL), 32 scroll_parent_(NULL), 33 clip_parent_(NULL), 34 mask_layer_id_(-1), 35 replica_layer_id_(-1), 36 layer_id_(id), 37 layer_tree_impl_(tree_impl), 38 anchor_point_(0.5f, 0.5f), 39 anchor_point_z_(0.f), 40 scroll_offset_delegate_(NULL), 41 scrollable_(false), 42 should_scroll_on_main_thread_(false), 43 have_wheel_event_handlers_(false), 44 background_color_(0), 45 stacking_order_changed_(false), 46 double_sided_(true), 47 layer_property_changed_(false), 48 layer_surface_property_changed_(false), 49 masks_to_bounds_(false), 50 contents_opaque_(false), 51 opacity_(1.0), 52 preserves_3d_(false), 53 use_parent_backface_visibility_(false), 54 draw_checkerboard_for_missing_tiles_(false), 55 draws_content_(false), 56 hide_layer_and_subtree_(false), 57 force_render_surface_(false), 58 is_container_for_fixed_position_layers_(false), 59 draw_depth_(0.f), 60 compositing_reasons_(kCompositingReasonUnknown), 61 current_draw_mode_(DRAW_MODE_NONE), 62 horizontal_scrollbar_layer_(NULL), 63 vertical_scrollbar_layer_(NULL) { 64 DCHECK_GT(layer_id_, 0); 65 DCHECK(layer_tree_impl_); 66 layer_tree_impl_->RegisterLayer(this); 67 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); 68 layer_animation_controller_ = 69 registrar->GetAnimationControllerForId(layer_id_); 70 layer_animation_controller_->AddValueObserver(this); 71} 72 73LayerImpl::~LayerImpl() { 74 DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); 75 76 layer_tree_impl_->UnregisterLayer(this); 77 layer_animation_controller_->RemoveValueObserver(this); 78 79 if (scroll_children_) { 80 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); 81 it != scroll_children_->end(); ++it) 82 (*it)->scroll_parent_ = NULL; 83 } 84 85 if (scroll_parent_) 86 scroll_parent_->RemoveScrollChild(this); 87 88 if (clip_children_) { 89 for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); 90 it != clip_children_->end(); ++it) 91 (*it)->clip_parent_ = NULL; 92 } 93 94 if (clip_parent_) 95 clip_parent_->RemoveClipChild(this); 96} 97 98void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { 99 child->set_parent(this); 100 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); 101 children_.push_back(child.Pass()); 102 layer_tree_impl()->set_needs_update_draw_properties(); 103} 104 105scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { 106 for (OwnedLayerImplList::iterator it = children_.begin(); 107 it != children_.end(); 108 ++it) { 109 if (*it == child) { 110 scoped_ptr<LayerImpl> ret = children_.take(it); 111 children_.erase(it); 112 layer_tree_impl()->set_needs_update_draw_properties(); 113 return ret.Pass(); 114 } 115 } 116 return scoped_ptr<LayerImpl>(); 117} 118 119void LayerImpl::ClearChildList() { 120 if (children_.empty()) 121 return; 122 123 children_.clear(); 124 layer_tree_impl()->set_needs_update_draw_properties(); 125} 126 127bool LayerImpl::HasAncestor(const LayerImpl* ancestor) const { 128 if (!ancestor) 129 return false; 130 131 for (const LayerImpl* layer = this; layer; layer = layer->parent()) { 132 if (layer == ancestor) 133 return true; 134 } 135 136 return false; 137} 138 139void LayerImpl::SetScrollParent(LayerImpl* parent) { 140 if (scroll_parent_ == parent) 141 return; 142 143 if (scroll_parent_) 144 scroll_parent_->RemoveScrollChild(this); 145 146 scroll_parent_ = parent; 147} 148 149void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { 150 if (scroll_children_.get() == children) 151 return; 152 scroll_children_.reset(children); 153} 154 155void LayerImpl::RemoveScrollChild(LayerImpl* child) { 156 DCHECK(scroll_children_); 157 scroll_children_->erase(child); 158 if (scroll_children_->empty()) 159 scroll_children_.reset(); 160} 161 162void LayerImpl::SetClipParent(LayerImpl* ancestor) { 163 if (clip_parent_ == ancestor) 164 return; 165 166 if (clip_parent_) 167 clip_parent_->RemoveClipChild(this); 168 169 clip_parent_ = ancestor; 170} 171 172void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { 173 if (clip_children_.get() == children) 174 return; 175 clip_children_.reset(children); 176} 177 178void LayerImpl::RemoveClipChild(LayerImpl* child) { 179 DCHECK(clip_children_); 180 clip_children_->erase(child); 181 if (clip_children_->empty()) 182 clip_children_.reset(); 183} 184 185void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { 186 if (requests->empty()) 187 return; 188 189 bool was_empty = copy_requests_.empty(); 190 copy_requests_.insert_and_take(copy_requests_.end(), *requests); 191 requests->clear(); 192 193 if (was_empty && layer_tree_impl()->IsActiveTree()) 194 layer_tree_impl()->AddLayerWithCopyOutputRequest(this); 195 NoteLayerPropertyChangedForSubtree(); 196} 197 198void LayerImpl::TakeCopyRequestsAndTransformToTarget( 199 ScopedPtrVector<CopyOutputRequest>* requests) { 200 if (copy_requests_.empty()) 201 return; 202 203 size_t first_inserted_request = requests->size(); 204 requests->insert_and_take(requests->end(), copy_requests_); 205 copy_requests_.clear(); 206 207 for (size_t i = first_inserted_request; i < requests->size(); ++i) { 208 CopyOutputRequest* request = requests->at(i); 209 if (!request->has_area()) 210 continue; 211 212 gfx::Rect request_in_layer_space = request->area(); 213 gfx::Rect request_in_content_space = 214 LayerRectToContentRect(request_in_layer_space); 215 request->set_area( 216 MathUtil::MapClippedRect(draw_properties_.target_space_transform, 217 request_in_content_space)); 218 } 219 220 if (layer_tree_impl()->IsActiveTree()) 221 layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); 222} 223 224void LayerImpl::CreateRenderSurface() { 225 DCHECK(!draw_properties_.render_surface); 226 draw_properties_.render_surface = 227 make_scoped_ptr(new RenderSurfaceImpl(this)); 228 draw_properties_.render_target = this; 229} 230 231void LayerImpl::ClearRenderSurface() { 232 draw_properties_.render_surface.reset(); 233} 234 235scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { 236 scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); 237 state->SetAll(draw_properties_.target_space_transform, 238 draw_properties_.content_bounds, 239 draw_properties_.visible_content_rect, 240 draw_properties_.clip_rect, 241 draw_properties_.is_clipped, 242 draw_properties_.opacity); 243 return state.Pass(); 244} 245 246bool LayerImpl::WillDraw(DrawMode draw_mode, 247 ResourceProvider* resource_provider) { 248 // WillDraw/DidDraw must be matched. 249 DCHECK_NE(DRAW_MODE_NONE, draw_mode); 250 DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); 251 current_draw_mode_ = draw_mode; 252 return true; 253} 254 255void LayerImpl::DidDraw(ResourceProvider* resource_provider) { 256 DCHECK_NE(DRAW_MODE_NONE, current_draw_mode_); 257 current_draw_mode_ = DRAW_MODE_NONE; 258} 259 260bool LayerImpl::ShowDebugBorders() const { 261 return layer_tree_impl()->debug_state().show_debug_borders; 262} 263 264void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { 265 if (draws_content_) { 266 *color = DebugColors::ContentLayerBorderColor(); 267 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); 268 return; 269 } 270 271 if (masks_to_bounds_) { 272 *color = DebugColors::MaskingLayerBorderColor(); 273 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl()); 274 return; 275 } 276 277 *color = DebugColors::ContainerLayerBorderColor(); 278 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl()); 279} 280 281void LayerImpl::AppendDebugBorderQuad( 282 QuadSink* quad_sink, 283 const SharedQuadState* shared_quad_state, 284 AppendQuadsData* append_quads_data) const { 285 SkColor color; 286 float width; 287 GetDebugBorderProperties(&color, &width); 288 AppendDebugBorderQuad( 289 quad_sink, shared_quad_state, append_quads_data, color, width); 290} 291 292void LayerImpl::AppendDebugBorderQuad(QuadSink* quad_sink, 293 const SharedQuadState* shared_quad_state, 294 AppendQuadsData* append_quads_data, 295 SkColor color, 296 float width) const { 297 if (!ShowDebugBorders()) 298 return; 299 300 gfx::Rect content_rect(content_bounds()); 301 scoped_ptr<DebugBorderDrawQuad> debug_border_quad = 302 DebugBorderDrawQuad::Create(); 303 debug_border_quad->SetNew(shared_quad_state, content_rect, color, width); 304 quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(), append_quads_data); 305} 306 307bool LayerImpl::HasDelegatedContent() const { 308 return false; 309} 310 311bool LayerImpl::HasContributingDelegatedRenderPasses() const { 312 return false; 313} 314 315RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { 316 return RenderPass::Id(0, 0); 317} 318 319RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) 320 const { 321 return RenderPass::Id(0, 0); 322} 323 324ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { 325 NOTREACHED(); 326 return 0; 327} 328 329void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { 330 // Pending tree never has sent scroll deltas 331 DCHECK(layer_tree_impl()->IsActiveTree()); 332 333 if (sent_scroll_delta_ == sent_scroll_delta) 334 return; 335 336 sent_scroll_delta_ = sent_scroll_delta; 337} 338 339gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { 340 DCHECK(scrollable()); 341 342 gfx::Vector2dF min_delta = -scroll_offset_; 343 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; 344 // Clamp new_delta so that position + delta stays within scroll bounds. 345 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); 346 new_delta.SetToMax(min_delta); 347 new_delta.SetToMin(max_delta); 348 gfx::Vector2dF unscrolled = ScrollDelta() + scroll - new_delta; 349 SetScrollDelta(new_delta); 350 return unscrolled; 351} 352 353void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { 354 // Pending tree never has sent scroll deltas 355 DCHECK(layer_tree_impl()->IsActiveTree()); 356 357 // Apply sent scroll deltas to scroll position / scroll delta as if the 358 // main thread had applied them and then committed those values. 359 // 360 // This function should not change the total scroll offset; it just shifts 361 // some of the scroll delta to the scroll offset. Therefore, adjust these 362 // variables directly rather than calling the scroll offset delegate to 363 // avoid sending it multiple spurious calls. 364 // 365 // Because of the way scroll delta is calculated with a delegate, this will 366 // leave the total scroll offset unchanged on this layer regardless of 367 // whether a delegate is being used. 368 scroll_offset_ += sent_scroll_delta_; 369 scroll_delta_ -= sent_scroll_delta_; 370 sent_scroll_delta_ = gfx::Vector2d(); 371} 372 373void LayerImpl::ApplyScrollDeltasSinceBeginFrame() { 374 // Only the pending tree can have missing scrolls. 375 DCHECK(layer_tree_impl()->IsPendingTree()); 376 if (!scrollable()) 377 return; 378 379 // Pending tree should never have sent scroll deltas. 380 DCHECK(sent_scroll_delta().IsZero()); 381 382 LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id()); 383 if (active_twin) { 384 // Scrolls that happens after begin frame (where the sent scroll delta 385 // comes from) and commit need to be applied to the pending tree 386 // so that it is up to date with the total scroll. 387 SetScrollDelta(active_twin->ScrollDelta() - 388 active_twin->sent_scroll_delta()); 389 } 390} 391 392InputHandler::ScrollStatus LayerImpl::TryScroll( 393 gfx::PointF screen_space_point, 394 InputHandler::ScrollInputType type) const { 395 if (should_scroll_on_main_thread()) { 396 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); 397 return InputHandler::ScrollOnMainThread; 398 } 399 400 if (!screen_space_transform().IsInvertible()) { 401 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); 402 return InputHandler::ScrollIgnored; 403 } 404 405 if (!non_fast_scrollable_region().IsEmpty()) { 406 bool clipped = false; 407 gfx::Transform inverse_screen_space_transform( 408 gfx::Transform::kSkipInitialization); 409 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) { 410 // TODO(shawnsingh): We shouldn't be applying a projection if screen space 411 // transform is uninvertible here. Perhaps we should be returning 412 // ScrollOnMainThread in this case? 413 } 414 415 gfx::PointF hit_test_point_in_content_space = 416 MathUtil::ProjectPoint(inverse_screen_space_transform, 417 screen_space_point, 418 &clipped); 419 gfx::PointF hit_test_point_in_layer_space = 420 gfx::ScalePoint(hit_test_point_in_content_space, 421 1.f / contents_scale_x(), 422 1.f / contents_scale_y()); 423 if (!clipped && 424 non_fast_scrollable_region().Contains( 425 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { 426 TRACE_EVENT0("cc", 427 "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); 428 return InputHandler::ScrollOnMainThread; 429 } 430 } 431 432 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { 433 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); 434 return InputHandler::ScrollOnMainThread; 435 } 436 437 if (!scrollable()) { 438 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 439 return InputHandler::ScrollIgnored; 440 } 441 442 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { 443 TRACE_EVENT0("cc", 444 "LayerImpl::tryScroll: Ignored. Technically scrollable," 445 " but has no affordance in either direction."); 446 return InputHandler::ScrollIgnored; 447 } 448 449 return InputHandler::ScrollStarted; 450} 451 452bool LayerImpl::DrawCheckerboardForMissingTiles() const { 453 return draw_checkerboard_for_missing_tiles_ && 454 !layer_tree_impl()->settings().background_color_instead_of_checkerboard; 455} 456 457gfx::Rect LayerImpl::LayerRectToContentRect( 458 const gfx::RectF& layer_rect) const { 459 gfx::RectF content_rect = 460 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y()); 461 // Intersect with content rect to avoid the extra pixel because for some 462 // values x and y, ceil((x / y) * y) may be x + 1. 463 content_rect.Intersect(gfx::Rect(content_bounds())); 464 return gfx::ToEnclosingRect(content_rect); 465} 466 467skia::RefPtr<SkPicture> LayerImpl::GetPicture() { 468 return skia::RefPtr<SkPicture>(); 469} 470 471bool LayerImpl::CanClipSelf() const { 472 return false; 473} 474 475bool LayerImpl::AreVisibleResourcesReady() const { 476 return true; 477} 478 479scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { 480 return LayerImpl::Create(tree_impl, layer_id_); 481} 482 483void LayerImpl::PushPropertiesTo(LayerImpl* layer) { 484 layer->SetAnchorPoint(anchor_point_); 485 layer->SetAnchorPointZ(anchor_point_z_); 486 layer->SetBackgroundColor(background_color_); 487 layer->SetBounds(bounds_); 488 layer->SetContentBounds(content_bounds()); 489 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); 490 layer->SetDebugName(debug_name_); 491 layer->SetCompositingReasons(compositing_reasons_); 492 layer->SetDoubleSided(double_sided_); 493 layer->SetDrawCheckerboardForMissingTiles( 494 draw_checkerboard_for_missing_tiles_); 495 layer->SetForceRenderSurface(force_render_surface_); 496 layer->SetDrawsContent(DrawsContent()); 497 layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); 498 layer->SetFilters(filters()); 499 layer->SetFilter(filter()); 500 layer->SetBackgroundFilters(background_filters()); 501 layer->SetMasksToBounds(masks_to_bounds_); 502 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); 503 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); 504 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); 505 layer->SetTouchEventHandlerRegion(touch_event_handler_region_); 506 layer->SetContentsOpaque(contents_opaque_); 507 layer->SetOpacity(opacity_); 508 layer->SetPosition(position_); 509 layer->SetIsContainerForFixedPositionLayers( 510 is_container_for_fixed_position_layers_); 511 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); 512 layer->SetPositionConstraint(position_constraint_); 513 layer->SetPreserves3d(preserves_3d()); 514 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); 515 layer->SetSublayerTransform(sublayer_transform_); 516 layer->SetTransform(transform_); 517 518 layer->SetScrollable(scrollable_); 519 layer->SetScrollOffset(scroll_offset_); 520 layer->SetMaxScrollOffset(max_scroll_offset_); 521 522 LayerImpl* scroll_parent = NULL; 523 if (scroll_parent_) 524 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); 525 526 layer->SetScrollParent(scroll_parent); 527 if (scroll_children_) { 528 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; 529 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); 530 it != scroll_children_->end(); ++it) 531 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); 532 layer->SetScrollChildren(scroll_children); 533 } 534 535 LayerImpl* clip_parent = NULL; 536 if (clip_parent_) { 537 clip_parent = layer->layer_tree_impl()->LayerById( 538 clip_parent_->id()); 539 } 540 541 layer->SetClipParent(clip_parent); 542 if (clip_children_) { 543 std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>; 544 for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); 545 it != clip_children_->end(); ++it) 546 clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); 547 layer->SetClipChildren(clip_children); 548 } 549 550 layer->PassCopyRequests(©_requests_); 551 552 // If the main thread commits multiple times before the impl thread actually 553 // draws, then damage tracking will become incorrect if we simply clobber the 554 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. 555 // union) any update changes that have occurred on the main thread. 556 update_rect_.Union(layer->update_rect()); 557 layer->set_update_rect(update_rect_); 558 559 layer->SetScrollDelta(layer->ScrollDelta() - layer->sent_scroll_delta()); 560 layer->SetSentScrollDelta(gfx::Vector2d()); 561 562 layer->SetStackingOrderChanged(stacking_order_changed_); 563 564 // Reset any state that should be cleared for the next update. 565 stacking_order_changed_ = false; 566 update_rect_ = gfx::RectF(); 567} 568 569base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { 570 base::DictionaryValue* result = new base::DictionaryValue; 571 result->SetString("LayerType", LayerTypeAsString()); 572 573 base::ListValue* list = new base::ListValue; 574 list->AppendInteger(bounds().width()); 575 list->AppendInteger(bounds().height()); 576 result->Set("Bounds", list); 577 578 list = new base::ListValue; 579 list->AppendDouble(position_.x()); 580 list->AppendDouble(position_.y()); 581 result->Set("Position", list); 582 583 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform; 584 double transform[16]; 585 gfx_transform.matrix().asColMajord(transform); 586 list = new base::ListValue; 587 for (int i = 0; i < 16; ++i) 588 list->AppendDouble(transform[i]); 589 result->Set("DrawTransform", list); 590 591 result->SetBoolean("DrawsContent", draws_content_); 592 result->SetDouble("Opacity", opacity()); 593 result->SetBoolean("ContentsOpaque", contents_opaque_); 594 595 if (scrollable_) 596 result->SetBoolean("Scrollable", scrollable_); 597 598 list = new base::ListValue; 599 for (size_t i = 0; i < children_.size(); ++i) 600 list->Append(children_[i]->LayerTreeAsJson()); 601 result->Set("Children", list); 602 603 return result; 604} 605 606void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { 607 if (stacking_order_changed) { 608 stacking_order_changed_ = true; 609 NoteLayerPropertyChangedForSubtree(); 610 } 611} 612 613bool LayerImpl::LayerSurfacePropertyChanged() const { 614 if (layer_surface_property_changed_) 615 return true; 616 617 // If this layer's surface property hasn't changed, we want to see if 618 // some layer above us has changed this property. This is done for the 619 // case when such parent layer does not draw content, and therefore will 620 // not be traversed by the damage tracker. We need to make sure that 621 // property change on such layer will be caught by its descendants. 622 LayerImpl* current = this->parent_; 623 while (current && !current->draw_properties_.render_surface) { 624 if (current->layer_surface_property_changed_) 625 return true; 626 current = current->parent_; 627 } 628 629 return false; 630} 631 632void LayerImpl::NoteLayerSurfacePropertyChanged() { 633 layer_surface_property_changed_ = true; 634 layer_tree_impl()->set_needs_update_draw_properties(); 635} 636 637void LayerImpl::NoteLayerPropertyChanged() { 638 layer_property_changed_ = true; 639 layer_tree_impl()->set_needs_update_draw_properties(); 640} 641 642void LayerImpl::NoteLayerPropertyChangedForSubtree() { 643 NoteLayerPropertyChanged(); 644 NoteLayerPropertyChangedForDescendants(); 645} 646 647void LayerImpl::NoteLayerPropertyChangedForDescendants() { 648 layer_tree_impl()->set_needs_update_draw_properties(); 649 for (size_t i = 0; i < children_.size(); ++i) 650 children_[i]->NoteLayerPropertyChangedForSubtree(); 651} 652 653const char* LayerImpl::LayerTypeAsString() const { 654 return "cc::LayerImpl"; 655} 656 657void LayerImpl::ResetAllChangeTrackingForSubtree() { 658 layer_property_changed_ = false; 659 layer_surface_property_changed_ = false; 660 661 update_rect_ = gfx::RectF(); 662 663 if (draw_properties_.render_surface) 664 draw_properties_.render_surface->ResetPropertyChangedFlag(); 665 666 if (mask_layer_) 667 mask_layer_->ResetAllChangeTrackingForSubtree(); 668 669 if (replica_layer_) { 670 // This also resets the replica mask, if it exists. 671 replica_layer_->ResetAllChangeTrackingForSubtree(); 672 } 673 674 for (size_t i = 0; i < children_.size(); ++i) 675 children_[i]->ResetAllChangeTrackingForSubtree(); 676} 677 678bool LayerImpl::LayerIsAlwaysDamaged() const { 679 return false; 680} 681 682void LayerImpl::OnOpacityAnimated(float opacity) { 683 SetOpacity(opacity); 684} 685 686void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { 687 SetTransform(transform); 688} 689 690bool LayerImpl::IsActive() const { 691 return layer_tree_impl_->IsActiveTree(); 692} 693 694void LayerImpl::SetBounds(gfx::Size bounds) { 695 if (bounds_ == bounds) 696 return; 697 698 bounds_ = bounds; 699 700 if (masks_to_bounds()) 701 NoteLayerPropertyChangedForSubtree(); 702 else 703 NoteLayerPropertyChanged(); 704} 705 706void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { 707 int new_layer_id = mask_layer ? mask_layer->id() : -1; 708 709 if (mask_layer) { 710 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl()); 711 DCHECK_NE(new_layer_id, mask_layer_id_); 712 } else if (new_layer_id == mask_layer_id_) { 713 return; 714 } 715 716 mask_layer_ = mask_layer.Pass(); 717 mask_layer_id_ = new_layer_id; 718 if (mask_layer_) 719 mask_layer_->set_parent(this); 720 NoteLayerPropertyChangedForSubtree(); 721} 722 723scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { 724 mask_layer_id_ = -1; 725 return mask_layer_.Pass(); 726} 727 728void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { 729 int new_layer_id = replica_layer ? replica_layer->id() : -1; 730 731 if (replica_layer) { 732 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); 733 DCHECK_NE(new_layer_id, replica_layer_id_); 734 } else if (new_layer_id == replica_layer_id_) { 735 return; 736 } 737 738 replica_layer_ = replica_layer.Pass(); 739 replica_layer_id_ = new_layer_id; 740 if (replica_layer_) 741 replica_layer_->set_parent(this); 742 NoteLayerPropertyChangedForSubtree(); 743} 744 745scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { 746 replica_layer_id_ = -1; 747 return replica_layer_.Pass(); 748} 749 750PaintedScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() { 751 return NULL; 752} 753 754void LayerImpl::SetDrawsContent(bool draws_content) { 755 if (draws_content_ == draws_content) 756 return; 757 758 draws_content_ = draws_content; 759 NoteLayerPropertyChanged(); 760} 761 762void LayerImpl::SetHideLayerAndSubtree(bool hide) { 763 if (hide_layer_and_subtree_ == hide) 764 return; 765 766 hide_layer_and_subtree_ = hide; 767 NoteLayerPropertyChangedForSubtree(); 768} 769 770void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { 771 if (anchor_point_ == anchor_point) 772 return; 773 774 anchor_point_ = anchor_point; 775 NoteLayerPropertyChangedForSubtree(); 776} 777 778void LayerImpl::SetAnchorPointZ(float anchor_point_z) { 779 if (anchor_point_z_ == anchor_point_z) 780 return; 781 782 anchor_point_z_ = anchor_point_z; 783 NoteLayerPropertyChangedForSubtree(); 784} 785 786void LayerImpl::SetBackgroundColor(SkColor background_color) { 787 if (background_color_ == background_color) 788 return; 789 790 background_color_ = background_color; 791 NoteLayerPropertyChanged(); 792} 793 794SkColor LayerImpl::SafeOpaqueBackgroundColor() const { 795 SkColor color = background_color(); 796 if (SkColorGetA(color) == 255 && !contents_opaque()) { 797 color = SK_ColorTRANSPARENT; 798 } else if (SkColorGetA(color) != 255 && contents_opaque()) { 799 for (const LayerImpl* layer = parent(); layer; 800 layer = layer->parent()) { 801 color = layer->background_color(); 802 if (SkColorGetA(color) == 255) 803 break; 804 } 805 if (SkColorGetA(color) != 255) 806 color = layer_tree_impl()->background_color(); 807 if (SkColorGetA(color) != 255) 808 color = SkColorSetA(color, 255); 809 } 810 return color; 811} 812 813void LayerImpl::SetFilters(const FilterOperations& filters) { 814 if (filters_ == filters) 815 return; 816 817 DCHECK(!filter_); 818 filters_ = filters; 819 NoteLayerPropertyChangedForSubtree(); 820} 821 822void LayerImpl::SetBackgroundFilters( 823 const FilterOperations& filters) { 824 if (background_filters_ == filters) 825 return; 826 827 background_filters_ = filters; 828 NoteLayerPropertyChanged(); 829} 830 831void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) { 832 if (filter_.get() == filter.get()) 833 return; 834 835 DCHECK(filters_.IsEmpty()); 836 filter_ = filter; 837 NoteLayerPropertyChangedForSubtree(); 838} 839 840void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { 841 if (masks_to_bounds_ == masks_to_bounds) 842 return; 843 844 masks_to_bounds_ = masks_to_bounds; 845 NoteLayerPropertyChangedForSubtree(); 846} 847 848void LayerImpl::SetContentsOpaque(bool opaque) { 849 if (contents_opaque_ == opaque) 850 return; 851 852 contents_opaque_ = opaque; 853 NoteLayerPropertyChangedForSubtree(); 854} 855 856void LayerImpl::SetOpacity(float opacity) { 857 if (opacity_ == opacity) 858 return; 859 860 opacity_ = opacity; 861 NoteLayerSurfacePropertyChanged(); 862} 863 864bool LayerImpl::OpacityIsAnimating() const { 865 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); 866} 867 868bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { 869 Animation* opacity_animation = 870 layer_animation_controller_->GetAnimation(Animation::Opacity); 871 return opacity_animation && opacity_animation->is_impl_only(); 872} 873 874void LayerImpl::SetPosition(gfx::PointF position) { 875 if (position_ == position) 876 return; 877 878 position_ = position; 879 NoteLayerPropertyChangedForSubtree(); 880} 881 882void LayerImpl::SetPreserves3d(bool preserves3_d) { 883 if (preserves_3d_ == preserves3_d) 884 return; 885 886 preserves_3d_ = preserves3_d; 887 NoteLayerPropertyChangedForSubtree(); 888} 889 890void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { 891 if (sublayer_transform_ == sublayer_transform) 892 return; 893 894 sublayer_transform_ = sublayer_transform; 895 // Sublayer transform does not affect the current layer; it affects only its 896 // children. 897 NoteLayerPropertyChangedForDescendants(); 898} 899 900void LayerImpl::SetTransform(const gfx::Transform& transform) { 901 if (transform_ == transform) 902 return; 903 904 transform_ = transform; 905 NoteLayerSurfacePropertyChanged(); 906} 907 908bool LayerImpl::TransformIsAnimating() const { 909 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); 910} 911 912bool LayerImpl::TransformIsAnimatingOnImplOnly() const { 913 Animation* transform_animation = 914 layer_animation_controller_->GetAnimation(Animation::Transform); 915 return transform_animation && transform_animation->is_impl_only(); 916} 917 918void LayerImpl::SetContentBounds(gfx::Size content_bounds) { 919 if (this->content_bounds() == content_bounds) 920 return; 921 922 draw_properties_.content_bounds = content_bounds; 923 NoteLayerPropertyChanged(); 924} 925 926void LayerImpl::SetContentsScale(float contents_scale_x, 927 float contents_scale_y) { 928 if (this->contents_scale_x() == contents_scale_x && 929 this->contents_scale_y() == contents_scale_y) 930 return; 931 932 draw_properties_.contents_scale_x = contents_scale_x; 933 draw_properties_.contents_scale_y = contents_scale_y; 934 NoteLayerPropertyChanged(); 935} 936 937void LayerImpl::CalculateContentsScale( 938 float ideal_contents_scale, 939 float device_scale_factor, 940 float page_scale_factor, 941 bool animating_transform_to_screen, 942 float* contents_scale_x, 943 float* contents_scale_y, 944 gfx::Size* content_bounds) { 945 // Base LayerImpl has all of its content scales and content bounds pushed 946 // from its Layer during commit and just reuses those values as-is. 947 *contents_scale_x = this->contents_scale_x(); 948 *contents_scale_y = this->contents_scale_y(); 949 *content_bounds = this->content_bounds(); 950} 951 952void LayerImpl::UpdateScrollbarPositions() { 953 gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); 954 955 gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); 956 gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), 957 max_scroll_offset_.y() + bounds_.height()); 958 if (horizontal_scrollbar_layer_) { 959 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); 960 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); 961 horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio( 962 viewport.width() / scrollable_size.width()); 963 } 964 if (vertical_scrollbar_layer_) { 965 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); 966 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); 967 vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio( 968 viewport.height() / scrollable_size.height()); 969 } 970 971 if (current_offset == last_scroll_offset_) 972 return; 973 last_scroll_offset_ = current_offset; 974 975 if (scrollbar_animation_controller_ && 976 !scrollbar_animation_controller_->IsScrollGestureInProgress()) { 977 scrollbar_animation_controller_->DidProgrammaticallyUpdateScroll( 978 layer_tree_impl_->CurrentPhysicalTimeTicks()); 979 } 980 981 // Get the current_offset_.y() value for a sanity-check on scrolling 982 // benchmark metrics. Specifically, we want to make sure 983 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. 984 if (layer_tree_impl()->IsActiveTree()) { 985 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); 986 } 987} 988 989void LayerImpl::SetScrollOffsetDelegate( 990 LayerScrollOffsetDelegate* scroll_offset_delegate) { 991 if (!scroll_offset_delegate && scroll_offset_delegate_) { 992 scroll_delta_ = 993 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 994 } 995 gfx::Vector2dF total_offset = TotalScrollOffset(); 996 scroll_offset_delegate_ = scroll_offset_delegate; 997 if (scroll_offset_delegate_) 998 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); 999} 1000 1001void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { 1002 if (scroll_offset_ == scroll_offset) 1003 return; 1004 1005 scroll_offset_ = scroll_offset; 1006 1007 if (scroll_offset_delegate_) 1008 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); 1009 1010 NoteLayerPropertyChangedForSubtree(); 1011 UpdateScrollbarPositions(); 1012} 1013 1014gfx::Vector2dF LayerImpl::ScrollDelta() const { 1015 if (scroll_offset_delegate_) 1016 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 1017 return scroll_delta_; 1018} 1019 1020void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { 1021 if (ScrollDelta() == scroll_delta) 1022 return; 1023 1024 if (layer_tree_impl()->IsActiveTree()) { 1025 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id()); 1026 if (pending_twin) { 1027 // The pending twin can't mirror the scroll delta of the active 1028 // layer. Although the delta - sent scroll delta difference is 1029 // identical for both twins, the sent scroll delta for the pending 1030 // layer is zero, as anything that has been sent has been baked 1031 // into the layer's position/scroll offset as a part of commit. 1032 DCHECK(pending_twin->sent_scroll_delta().IsZero()); 1033 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); 1034 } 1035 } 1036 1037 if (scroll_offset_delegate_) { 1038 scroll_offset_delegate_->SetTotalScrollOffset( 1039 scroll_offset_ + scroll_delta); 1040 } else { 1041 scroll_delta_ = scroll_delta; 1042 } 1043 1044 NoteLayerPropertyChangedForSubtree(); 1045 UpdateScrollbarPositions(); 1046} 1047 1048gfx::Vector2dF LayerImpl::TotalScrollOffset() const { 1049 return scroll_offset_ + ScrollDelta(); 1050} 1051 1052void LayerImpl::SetDoubleSided(bool double_sided) { 1053 if (double_sided_ == double_sided) 1054 return; 1055 1056 double_sided_ = double_sided; 1057 NoteLayerPropertyChangedForSubtree(); 1058} 1059 1060Region LayerImpl::VisibleContentOpaqueRegion() const { 1061 if (contents_opaque()) 1062 return visible_content_rect(); 1063 return Region(); 1064} 1065 1066void LayerImpl::DidBeginTracing() {} 1067 1068void LayerImpl::DidLoseOutputSurface() {} 1069 1070void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { 1071 if (max_scroll_offset_ == max_scroll_offset) 1072 return; 1073 max_scroll_offset_ = max_scroll_offset; 1074 1075 layer_tree_impl()->set_needs_update_draw_properties(); 1076 UpdateScrollbarPositions(); 1077} 1078 1079void LayerImpl::SetScrollbarOpacity(float opacity) { 1080 if (horizontal_scrollbar_layer_) 1081 horizontal_scrollbar_layer_->SetOpacity(opacity); 1082 if (vertical_scrollbar_layer_) 1083 vertical_scrollbar_layer_->SetOpacity(opacity); 1084} 1085 1086void LayerImpl::DidBecomeActive() { 1087 if (!layer_tree_impl_->settings().use_linear_fade_scrollbar_animator) 1088 return; 1089 1090 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || 1091 vertical_scrollbar_layer_; 1092 if (need_scrollbar_animation_controller) { 1093 if (!scrollbar_animation_controller_) { 1094 base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds( 1095 layer_tree_impl_->settings().scrollbar_linear_fade_delay_ms); 1096 base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds( 1097 layer_tree_impl_->settings().scrollbar_linear_fade_length_ms); 1098 scrollbar_animation_controller_ = 1099 ScrollbarAnimationControllerLinearFade::Create( 1100 this, fadeout_delay, fadeout_length) 1101 .PassAs<ScrollbarAnimationController>(); 1102 } 1103 } else { 1104 scrollbar_animation_controller_.reset(); 1105 } 1106} 1107void LayerImpl::SetHorizontalScrollbarLayer( 1108 PaintedScrollbarLayerImpl* scrollbar_layer) { 1109 horizontal_scrollbar_layer_ = scrollbar_layer; 1110 if (horizontal_scrollbar_layer_) 1111 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); 1112} 1113 1114void LayerImpl::SetVerticalScrollbarLayer( 1115 PaintedScrollbarLayerImpl* scrollbar_layer) { 1116 vertical_scrollbar_layer_ = scrollbar_layer; 1117 if (vertical_scrollbar_layer_) 1118 vertical_scrollbar_layer_->set_scroll_layer_id(id()); 1119} 1120 1121static scoped_ptr<base::Value> 1122CompositingReasonsAsValue(CompositingReasons reasons) { 1123 scoped_ptr<base::ListValue> reason_list(new base::ListValue()); 1124 1125 if (reasons == kCompositingReasonUnknown) { 1126 reason_list->AppendString("No reasons given"); 1127 return reason_list.PassAs<base::Value>(); 1128 } 1129 1130 if (reasons & kCompositingReason3DTransform) 1131 reason_list->AppendString("Has a 3d Transform"); 1132 1133 if (reasons & kCompositingReasonVideo) 1134 reason_list->AppendString("Is accelerated video"); 1135 1136 if (reasons & kCompositingReasonCanvas) 1137 reason_list->AppendString("Is accelerated canvas"); 1138 1139 if (reasons & kCompositingReasonPlugin) 1140 reason_list->AppendString("Is accelerated plugin"); 1141 1142 if (reasons & kCompositingReasonIFrame) 1143 reason_list->AppendString("Is accelerated iframe"); 1144 1145 if (reasons & kCompositingReasonBackfaceVisibilityHidden) 1146 reason_list->AppendString("Has backface-visibility: hidden"); 1147 1148 if (reasons & kCompositingReasonAnimation) 1149 reason_list->AppendString("Has accelerated animation or transition"); 1150 1151 if (reasons & kCompositingReasonFilters) 1152 reason_list->AppendString("Has accelerated filters"); 1153 1154 if (reasons & kCompositingReasonPositionFixed) 1155 reason_list->AppendString("Is fixed position"); 1156 1157 if (reasons & kCompositingReasonPositionSticky) 1158 reason_list->AppendString("Is sticky position"); 1159 1160 if (reasons & kCompositingReasonOverflowScrollingTouch) 1161 reason_list->AppendString("Is a scrollable overflow element"); 1162 1163 if (reasons & kCompositingReasonBlending) 1164 reason_list->AppendString("Has a blend mode"); 1165 1166 if (reasons & kCompositingReasonAssumedOverlap) 1167 reason_list->AppendString("Might overlap a composited animation"); 1168 1169 if (reasons & kCompositingReasonOverlap) 1170 reason_list->AppendString("Overlaps other composited content"); 1171 1172 if (reasons & kCompositingReasonNegativeZIndexChildren) { 1173 reason_list->AppendString("Might overlap negative z-index " 1174 "composited content"); 1175 } 1176 1177 if (reasons & kCompositingReasonTransformWithCompositedDescendants) { 1178 reason_list->AppendString("Has transform needed by a " 1179 "composited descendant"); 1180 } 1181 1182 if (reasons & kCompositingReasonOpacityWithCompositedDescendants) 1183 reason_list->AppendString("Has opacity needed by a composited descendant"); 1184 1185 if (reasons & kCompositingReasonMaskWithCompositedDescendants) 1186 reason_list->AppendString("Has a mask needed by a composited descendant"); 1187 1188 if (reasons & kCompositingReasonReflectionWithCompositedDescendants) 1189 reason_list->AppendString("Has a reflection with a composited descendant"); 1190 1191 if (reasons & kCompositingReasonFilterWithCompositedDescendants) 1192 reason_list->AppendString("Has filter effect with a composited descendant"); 1193 1194 if (reasons & kCompositingReasonBlendingWithCompositedDescendants) 1195 reason_list->AppendString("Has a blend mode with a composited descendant"); 1196 1197 if (reasons & kCompositingReasonClipsCompositingDescendants) 1198 reason_list->AppendString("Clips a composited descendant"); 1199 1200 if (reasons & kCompositingReasonPerspective) { 1201 reason_list->AppendString("Has a perspective transform needed by a " 1202 "composited 3d descendant"); 1203 } 1204 1205 if (reasons & kCompositingReasonPreserve3D) { 1206 reason_list->AppendString("Has preserves-3d style with composited " 1207 "3d descendant"); 1208 } 1209 1210 if (reasons & kCompositingReasonReflectionOfCompositedParent) 1211 reason_list->AppendString("Is the reflection of a composited layer"); 1212 1213 if (reasons & kCompositingReasonRoot) 1214 reason_list->AppendString("Is the root"); 1215 1216 if (reasons & kCompositingReasonLayerForClip) 1217 reason_list->AppendString("Convenience layer, to clip subtree"); 1218 1219 if (reasons & kCompositingReasonLayerForScrollbar) 1220 reason_list->AppendString("Convenience layer for rendering scrollbar"); 1221 1222 if (reasons & kCompositingReasonLayerForScrollingContainer) 1223 reason_list->AppendString("Convenience layer, the scrolling container"); 1224 1225 if (reasons & kCompositingReasonLayerForForeground) { 1226 reason_list->AppendString("Convenience layer, foreground when main layer " 1227 "has negative z-index composited content"); 1228 } 1229 1230 if (reasons & kCompositingReasonLayerForBackground) { 1231 reason_list->AppendString("Convenience layer, background when main layer " 1232 "has a composited background"); 1233 } 1234 1235 if (reasons & kCompositingReasonLayerForMask) 1236 reason_list->AppendString("Is a mask layer"); 1237 1238 if (reasons & kCompositingReasonOverflowScrollingParent) 1239 reason_list->AppendString("Scroll parent is not an ancestor"); 1240 1241 if (reasons & kCompositingReasonOutOfFlowClipping) 1242 reason_list->AppendString("Has clipping ancestor"); 1243 1244 return reason_list.PassAs<base::Value>(); 1245} 1246 1247void LayerImpl::AsValueInto(base::DictionaryValue* state) const { 1248 TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this); 1249 state->SetInteger("layer_id", id()); 1250 state->SetString("layer_name", debug_name()); 1251 state->Set("bounds", MathUtil::AsValue(bounds()).release()); 1252 state->SetInteger("draws_content", DrawsContent()); 1253 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); 1254 state->Set("compositing_reasons", 1255 CompositingReasonsAsValue(compositing_reasons_).release()); 1256 1257 bool clipped; 1258 gfx::QuadF layer_quad = MathUtil::MapQuad( 1259 screen_space_transform(), 1260 gfx::QuadF(gfx::Rect(content_bounds())), 1261 &clipped); 1262 state->Set("layer_quad", MathUtil::AsValue(layer_quad).release()); 1263 1264 1265 scoped_ptr<base::ListValue> children_list(new base::ListValue()); 1266 for (size_t i = 0; i < children_.size(); ++i) 1267 children_list->Append(children_[i]->AsValue().release()); 1268 state->Set("children", children_list.release()); 1269 if (mask_layer_) 1270 state->Set("mask_layer", mask_layer_->AsValue().release()); 1271 if (replica_layer_) 1272 state->Set("replica_layer", replica_layer_->AsValue().release()); 1273 1274 if (scroll_parent_) 1275 state->SetInteger("scroll_parent", scroll_parent_->id()); 1276 1277 if (clip_parent_) 1278 state->SetInteger("clip_parent", clip_parent_->id()); 1279} 1280 1281size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } 1282 1283scoped_ptr<base::Value> LayerImpl::AsValue() const { 1284 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 1285 AsValueInto(state.get()); 1286 return state.PassAs<base::Value>(); 1287} 1288 1289} // namespace cc 1290