layer_impl.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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/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/quad_sink.h" 18#include "cc/layers/scrollbar_layer_impl.h" 19#include "cc/quads/debug_border_draw_quad.h" 20#include "cc/trees/layer_tree_impl.h" 21#include "cc/trees/layer_tree_settings.h" 22#include "cc/trees/proxy.h" 23#include "ui/gfx/point_conversions.h" 24#include "ui/gfx/quad_f.h" 25#include "ui/gfx/rect_conversions.h" 26 27namespace cc { 28 29LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) 30 : parent_(NULL), 31 mask_layer_id_(-1), 32 replica_layer_id_(-1), 33 layer_id_(id), 34 layer_tree_impl_(tree_impl), 35 anchor_point_(0.5f, 0.5f), 36 anchor_point_z_(0.f), 37 scroll_offset_delegate_(NULL), 38 scrollable_(false), 39 should_scroll_on_main_thread_(false), 40 have_wheel_event_handlers_(false), 41 background_color_(0), 42 stacking_order_changed_(false), 43 double_sided_(true), 44 layer_property_changed_(false), 45 layer_surface_property_changed_(false), 46 masks_to_bounds_(false), 47 contents_opaque_(false), 48 opacity_(1.0), 49 preserves_3d_(false), 50 use_parent_backface_visibility_(false), 51 draw_checkerboard_for_missing_tiles_(false), 52 draws_content_(false), 53 force_render_surface_(false), 54 is_container_for_fixed_position_layers_(false), 55 draw_depth_(0.f), 56#ifndef NDEBUG 57 between_will_draw_and_did_draw_(false), 58#endif 59 horizontal_scrollbar_layer_(NULL), 60 vertical_scrollbar_layer_(NULL) { 61 DCHECK_GT(layer_id_, 0); 62 DCHECK(layer_tree_impl_); 63 layer_tree_impl_->RegisterLayer(this); 64 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); 65 layer_animation_controller_ = 66 registrar->GetAnimationControllerForId(layer_id_); 67 layer_animation_controller_->AddValueObserver(this); 68} 69 70LayerImpl::~LayerImpl() { 71#ifndef NDEBUG 72 DCHECK(!between_will_draw_and_did_draw_); 73#endif 74 75 for (size_t i = 0; i < request_copy_callbacks_.size(); ++i) 76 request_copy_callbacks_[i].Run(scoped_ptr<SkBitmap>()); 77 78 layer_tree_impl_->UnregisterLayer(this); 79 layer_animation_controller_->RemoveValueObserver(this); 80} 81 82void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { 83 child->set_parent(this); 84 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); 85 children_.push_back(child.Pass()); 86 layer_tree_impl()->set_needs_update_draw_properties(); 87} 88 89scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { 90 for (OwnedLayerImplList::iterator it = children_.begin(); 91 it != children_.end(); 92 ++it) { 93 if (*it == child) { 94 scoped_ptr<LayerImpl> ret = children_.take(it); 95 children_.erase(it); 96 layer_tree_impl()->set_needs_update_draw_properties(); 97 return ret.Pass(); 98 } 99 } 100 return scoped_ptr<LayerImpl>(); 101} 102 103void LayerImpl::ClearChildList() { 104 if (children_.empty()) 105 return; 106 107 children_.clear(); 108 layer_tree_impl()->set_needs_update_draw_properties(); 109} 110 111void LayerImpl::PassRequestCopyCallbacks( 112 std::vector<RenderPass::RequestCopyAsBitmapCallback>* callbacks) { 113 if (callbacks->empty()) 114 return; 115 116 request_copy_callbacks_.insert(request_copy_callbacks_.end(), 117 callbacks->begin(), 118 callbacks->end()); 119 callbacks->clear(); 120 121 NoteLayerPropertyChangedForSubtree(); 122} 123 124void LayerImpl::TakeRequestCopyCallbacks( 125 std::vector<RenderPass::RequestCopyAsBitmapCallback>* callbacks) { 126 if (request_copy_callbacks_.empty()) 127 return; 128 129 callbacks->insert(callbacks->end(), 130 request_copy_callbacks_.begin(), 131 request_copy_callbacks_.end()); 132 request_copy_callbacks_.clear(); 133} 134 135void LayerImpl::CreateRenderSurface() { 136 DCHECK(!draw_properties_.render_surface); 137 draw_properties_.render_surface = 138 make_scoped_ptr(new RenderSurfaceImpl(this)); 139 draw_properties_.render_target = this; 140} 141 142void LayerImpl::ClearRenderSurface() { 143 draw_properties_.render_surface.reset(); 144} 145 146scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { 147 scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); 148 state->SetAll(draw_properties_.target_space_transform, 149 draw_properties_.content_bounds, 150 draw_properties_.visible_content_rect, 151 draw_properties_.clip_rect, 152 draw_properties_.is_clipped, 153 draw_properties_.opacity); 154 return state.Pass(); 155} 156 157void LayerImpl::WillDraw(ResourceProvider* resource_provider) { 158#ifndef NDEBUG 159 // WillDraw/DidDraw must be matched. 160 DCHECK(!between_will_draw_and_did_draw_); 161 between_will_draw_and_did_draw_ = true; 162#endif 163} 164 165void LayerImpl::DidDraw(ResourceProvider* resource_provider) { 166#ifndef NDEBUG 167 DCHECK(between_will_draw_and_did_draw_); 168 between_will_draw_and_did_draw_ = false; 169#endif 170} 171 172bool LayerImpl::ShowDebugBorders() const { 173 return layer_tree_impl()->debug_state().show_debug_borders; 174} 175 176void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { 177 if (draws_content_) { 178 *color = DebugColors::ContentLayerBorderColor(); 179 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); 180 return; 181 } 182 183 if (masks_to_bounds_) { 184 *color = DebugColors::MaskingLayerBorderColor(); 185 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl()); 186 return; 187 } 188 189 *color = DebugColors::ContainerLayerBorderColor(); 190 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl()); 191} 192 193void LayerImpl::AppendDebugBorderQuad( 194 QuadSink* quad_sink, 195 const SharedQuadState* shared_quad_state, 196 AppendQuadsData* append_quads_data) const { 197 if (!ShowDebugBorders()) 198 return; 199 200 SkColor color; 201 float width; 202 GetDebugBorderProperties(&color, &width); 203 204 gfx::Rect content_rect(content_bounds()); 205 scoped_ptr<DebugBorderDrawQuad> debug_border_quad = 206 DebugBorderDrawQuad::Create(); 207 debug_border_quad->SetNew(shared_quad_state, content_rect, color, width); 208 quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(), append_quads_data); 209} 210 211bool LayerImpl::HasDelegatedContent() const { 212 return false; 213} 214 215bool LayerImpl::HasContributingDelegatedRenderPasses() const { 216 return false; 217} 218 219RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { 220 return RenderPass::Id(0, 0); 221} 222 223RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) 224 const { 225 return RenderPass::Id(0, 0); 226} 227 228ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { 229 NOTREACHED(); 230 return 0; 231} 232 233void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { 234 // Pending tree never has sent scroll deltas 235 DCHECK(layer_tree_impl()->IsActiveTree()); 236 237 if (sent_scroll_delta_ == sent_scroll_delta) 238 return; 239 240 sent_scroll_delta_ = sent_scroll_delta; 241} 242 243gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { 244 gfx::Vector2dF min_delta = -scroll_offset_; 245 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; 246 // Clamp new_delta so that position + delta stays within scroll bounds. 247 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); 248 new_delta.ClampToMin(min_delta); 249 new_delta.ClampToMax(max_delta); 250 gfx::Vector2dF unscrolled = ScrollDelta() + scroll - new_delta; 251 252 SetScrollDelta(new_delta); 253 return unscrolled; 254} 255 256InputHandler::ScrollStatus LayerImpl::TryScroll( 257 gfx::PointF screen_space_point, 258 InputHandler::ScrollInputType type) const { 259 if (should_scroll_on_main_thread()) { 260 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); 261 return InputHandler::ScrollOnMainThread; 262 } 263 264 if (!screen_space_transform().IsInvertible()) { 265 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); 266 return InputHandler::ScrollIgnored; 267 } 268 269 if (!non_fast_scrollable_region().IsEmpty()) { 270 bool clipped = false; 271 gfx::Transform inverse_screen_space_transform( 272 gfx::Transform::kSkipInitialization); 273 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) { 274 // TODO(shawnsingh): We shouldn't be applying a projection if screen space 275 // transform is uninvertible here. Perhaps we should be returning 276 // ScrollOnMainThread in this case? 277 } 278 279 gfx::PointF hit_test_point_in_content_space = 280 MathUtil::ProjectPoint(inverse_screen_space_transform, 281 screen_space_point, 282 &clipped); 283 gfx::PointF hit_test_point_in_layer_space = 284 gfx::ScalePoint(hit_test_point_in_content_space, 285 1.f / contents_scale_x(), 286 1.f / contents_scale_y()); 287 if (!clipped && 288 non_fast_scrollable_region().Contains( 289 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { 290 TRACE_EVENT0("cc", 291 "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); 292 return InputHandler::ScrollOnMainThread; 293 } 294 } 295 296 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { 297 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); 298 return InputHandler::ScrollOnMainThread; 299 } 300 301 if (!scrollable()) { 302 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 303 return InputHandler::ScrollIgnored; 304 } 305 306 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { 307 TRACE_EVENT0("cc", 308 "LayerImpl::tryScroll: Ignored. Technically scrollable," 309 " but has no affordance in either direction."); 310 return InputHandler::ScrollIgnored; 311 } 312 313 return InputHandler::ScrollStarted; 314} 315 316bool LayerImpl::DrawCheckerboardForMissingTiles() const { 317 return draw_checkerboard_for_missing_tiles_ && 318 !layer_tree_impl()->settings().background_color_instead_of_checkerboard; 319} 320 321gfx::Rect LayerImpl::LayerRectToContentRect( 322 const gfx::RectF& layer_rect) const { 323 gfx::RectF content_rect = 324 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y()); 325 // Intersect with content rect to avoid the extra pixel because for some 326 // values x and y, ceil((x / y) * y) may be x + 1. 327 content_rect.Intersect(gfx::Rect(content_bounds())); 328 return gfx::ToEnclosingRect(content_rect); 329} 330 331skia::RefPtr<SkPicture> LayerImpl::GetPicture() { 332 return skia::RefPtr<SkPicture>(); 333} 334 335bool LayerImpl::CanClipSelf() const { 336 return false; 337} 338 339bool LayerImpl::AreVisibleResourcesReady() const { 340 return true; 341} 342 343scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { 344 return LayerImpl::Create(tree_impl, layer_id_); 345} 346 347void LayerImpl::PushPropertiesTo(LayerImpl* layer) { 348 layer->SetAnchorPoint(anchor_point_); 349 layer->SetAnchorPointZ(anchor_point_z_); 350 layer->SetBackgroundColor(background_color_); 351 layer->SetBounds(bounds_); 352 layer->SetContentBounds(content_bounds()); 353 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); 354 layer->SetDebugName(debug_name_); 355 layer->SetDoubleSided(double_sided_); 356 layer->SetDrawCheckerboardForMissingTiles( 357 draw_checkerboard_for_missing_tiles_); 358 layer->SetForceRenderSurface(force_render_surface_); 359 layer->SetDrawsContent(DrawsContent()); 360 layer->SetFilters(filters()); 361 layer->SetFilter(filter()); 362 layer->SetBackgroundFilters(background_filters()); 363 layer->SetMasksToBounds(masks_to_bounds_); 364 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); 365 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); 366 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); 367 layer->SetTouchEventHandlerRegion(touch_event_handler_region_); 368 layer->SetContentsOpaque(contents_opaque_); 369 layer->SetOpacity(opacity_); 370 layer->SetPosition(position_); 371 layer->SetIsContainerForFixedPositionLayers( 372 is_container_for_fixed_position_layers_); 373 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); 374 layer->SetPositionConstraint(position_constraint_); 375 layer->SetPreserves3d(preserves_3d()); 376 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); 377 layer->SetSublayerTransform(sublayer_transform_); 378 layer->SetTransform(transform_); 379 380 layer->SetScrollable(scrollable_); 381 layer->SetScrollOffset(scroll_offset_); 382 layer->SetMaxScrollOffset(max_scroll_offset_); 383 384 layer->PassRequestCopyCallbacks(&request_copy_callbacks_); 385 386 // If the main thread commits multiple times before the impl thread actually 387 // draws, then damage tracking will become incorrect if we simply clobber the 388 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. 389 // union) any update changes that have occurred on the main thread. 390 update_rect_.Union(layer->update_rect()); 391 layer->set_update_rect(update_rect_); 392 393 layer->SetScrollDelta(layer->ScrollDelta() - layer->sent_scroll_delta()); 394 layer->SetSentScrollDelta(gfx::Vector2d()); 395 396 layer->SetStackingOrderChanged(stacking_order_changed_); 397 398 // Reset any state that should be cleared for the next update. 399 stacking_order_changed_ = false; 400 update_rect_ = gfx::RectF(); 401} 402 403std::string LayerImpl::IndentString(int indent) { 404 std::string str; 405 for (int i = 0; i != indent; ++i) 406 str.append(" "); 407 return str; 408} 409 410void LayerImpl::DumpLayerProperties(std::string* str, int indent) const { 411 std::string indent_str = IndentString(indent); 412 str->append(indent_str); 413 base::StringAppendF(str, "layer ID: %d\n", layer_id_); 414 415 str->append(indent_str); 416 base::StringAppendF( 417 str, "bounds: %d, %d\n", bounds().width(), bounds().height()); 418 419 if (draw_properties_.render_target) { 420 str->append(indent_str); 421 base::StringAppendF( 422 str, "renderTarget: %d\n", draw_properties_.render_target->layer_id_); 423 } 424 425 str->append(indent_str); 426 base::StringAppendF(str, "position: %f, %f\n", position_.x(), position_.y()); 427 428 str->append(indent_str); 429 base::StringAppendF(str, "contentsOpaque: %d\n", contents_opaque_); 430 431 str->append(indent_str); 432 const gfx::Transform& transform = draw_properties_.target_space_transform; 433 base::StringAppendF(str, 434 "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f" 435 " // %f, %f, %f, %f // %f, %f, %f, %f\n", 436 transform.matrix().getDouble(0, 0), 437 transform.matrix().getDouble(0, 1), 438 transform.matrix().getDouble(0, 2), 439 transform.matrix().getDouble(0, 3), 440 transform.matrix().getDouble(1, 0), 441 transform.matrix().getDouble(1, 1), 442 transform.matrix().getDouble(1, 2), 443 transform.matrix().getDouble(1, 3), 444 transform.matrix().getDouble(2, 0), 445 transform.matrix().getDouble(2, 1), 446 transform.matrix().getDouble(2, 2), 447 transform.matrix().getDouble(2, 3), 448 transform.matrix().getDouble(3, 0), 449 transform.matrix().getDouble(3, 1), 450 transform.matrix().getDouble(3, 2), 451 transform.matrix().getDouble(3, 3)); 452 453 str->append(indent_str); 454 base::StringAppendF( 455 str, "draws_content: %s\n", draws_content_ ? "yes" : "no"); 456} 457 458std::string LayerImpl::LayerTreeAsText() const { 459 std::string str; 460 DumpLayer(&str, 0); 461 return str; 462} 463 464void LayerImpl::DumpLayer(std::string* str, int indent) const { 465 str->append(IndentString(indent)); 466 base::StringAppendF(str, "%s(%s)\n", LayerTypeAsString(), debug_name_.data()); 467 DumpLayerProperties(str, indent+2); 468 if (replica_layer_) { 469 str->append(IndentString(indent+2)); 470 str->append("Replica:\n"); 471 replica_layer_->DumpLayer(str, indent+3); 472 } 473 if (mask_layer_) { 474 str->append(IndentString(indent+2)); 475 str->append("Mask:\n"); 476 mask_layer_->DumpLayer(str, indent+3); 477 } 478 for (size_t i = 0; i < children_.size(); ++i) 479 children_[i]->DumpLayer(str, indent+1); 480} 481 482base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { 483 base::ListValue* list; 484 base::DictionaryValue* result = new base::DictionaryValue; 485 result->SetString("LayerType", LayerTypeAsString()); 486 487 list = new base::ListValue; 488 list->AppendInteger(bounds().width()); 489 list->AppendInteger(bounds().height()); 490 result->Set("Bounds", list); 491 492 list = new base::ListValue; 493 list->AppendDouble(position_.x()); 494 list->AppendDouble(position_.y()); 495 result->Set("Position", list); 496 497 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform; 498 double transform[16]; 499 gfx_transform.matrix().asColMajord(transform); 500 list = new base::ListValue; 501 for (int i = 0; i < 16; ++i) 502 list->AppendDouble(transform[i]); 503 result->Set("DrawTransform", list); 504 505 result->SetBoolean("DrawsContent", draws_content_); 506 result->SetDouble("Opacity", opacity()); 507 508 list = new base::ListValue; 509 for (size_t i = 0; i < children_.size(); ++i) 510 list->Append(children_[i]->LayerTreeAsJson()); 511 result->Set("Children", list); 512 513 return result; 514} 515 516void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { 517 if (stacking_order_changed) { 518 stacking_order_changed_ = true; 519 NoteLayerPropertyChangedForSubtree(); 520 } 521} 522 523bool LayerImpl::LayerSurfacePropertyChanged() const { 524 if (layer_surface_property_changed_) 525 return true; 526 527 // If this layer's surface property hasn't changed, we want to see if 528 // some layer above us has changed this property. This is done for the 529 // case when such parent layer does not draw content, and therefore will 530 // not be traversed by the damage tracker. We need to make sure that 531 // property change on such layer will be caught by its descendants. 532 LayerImpl* current = this->parent_; 533 while (current && !current->draw_properties_.render_surface) { 534 if (current->layer_surface_property_changed_) 535 return true; 536 current = current->parent_; 537 } 538 539 return false; 540} 541 542void LayerImpl::NoteLayerSurfacePropertyChanged() { 543 layer_surface_property_changed_ = true; 544 layer_tree_impl()->set_needs_update_draw_properties(); 545} 546 547void LayerImpl::NoteLayerPropertyChanged() { 548 layer_property_changed_ = true; 549 layer_tree_impl()->set_needs_update_draw_properties(); 550} 551 552void LayerImpl::NoteLayerPropertyChangedForSubtree() { 553 NoteLayerPropertyChanged(); 554 NoteLayerPropertyChangedForDescendants(); 555} 556 557void LayerImpl::NoteLayerPropertyChangedForDescendants() { 558 layer_tree_impl()->set_needs_update_draw_properties(); 559 for (size_t i = 0; i < children_.size(); ++i) 560 children_[i]->NoteLayerPropertyChangedForSubtree(); 561} 562 563const char* LayerImpl::LayerTypeAsString() const { 564 return "Layer"; 565} 566 567void LayerImpl::ResetAllChangeTrackingForSubtree() { 568 layer_property_changed_ = false; 569 layer_surface_property_changed_ = false; 570 571 update_rect_ = gfx::RectF(); 572 573 if (draw_properties_.render_surface) 574 draw_properties_.render_surface->ResetPropertyChangedFlag(); 575 576 if (mask_layer_) 577 mask_layer_->ResetAllChangeTrackingForSubtree(); 578 579 if (replica_layer_) { 580 // This also resets the replica mask, if it exists. 581 replica_layer_->ResetAllChangeTrackingForSubtree(); 582 } 583 584 for (size_t i = 0; i < children_.size(); ++i) 585 children_[i]->ResetAllChangeTrackingForSubtree(); 586} 587 588bool LayerImpl::LayerIsAlwaysDamaged() const { 589 return false; 590} 591 592void LayerImpl::OnOpacityAnimated(float opacity) { 593 SetOpacity(opacity); 594} 595 596void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { 597 SetTransform(transform); 598} 599 600bool LayerImpl::IsActive() const { 601 return layer_tree_impl_->IsActiveTree(); 602} 603 604void LayerImpl::SetBounds(gfx::Size bounds) { 605 if (bounds_ == bounds) 606 return; 607 608 bounds_ = bounds; 609 610 if (masks_to_bounds()) 611 NoteLayerPropertyChangedForSubtree(); 612 else 613 NoteLayerPropertyChanged(); 614} 615 616void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { 617 int new_layer_id = mask_layer ? mask_layer->id() : -1; 618 619 if (mask_layer) { 620 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl()); 621 DCHECK_NE(new_layer_id, mask_layer_id_); 622 } else if (new_layer_id == mask_layer_id_) { 623 return; 624 } 625 626 mask_layer_ = mask_layer.Pass(); 627 mask_layer_id_ = new_layer_id; 628 if (mask_layer_) 629 mask_layer_->set_parent(this); 630 NoteLayerPropertyChangedForSubtree(); 631} 632 633scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { 634 mask_layer_id_ = -1; 635 return mask_layer_.Pass(); 636} 637 638void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { 639 int new_layer_id = replica_layer ? replica_layer->id() : -1; 640 641 if (replica_layer) { 642 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); 643 DCHECK_NE(new_layer_id, replica_layer_id_); 644 } else if (new_layer_id == replica_layer_id_) { 645 return; 646 } 647 648 replica_layer_ = replica_layer.Pass(); 649 replica_layer_id_ = new_layer_id; 650 if (replica_layer_) 651 replica_layer_->set_parent(this); 652 NoteLayerPropertyChangedForSubtree(); 653} 654 655scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { 656 replica_layer_id_ = -1; 657 return replica_layer_.Pass(); 658} 659 660ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() { 661 return NULL; 662} 663 664void LayerImpl::SetDrawsContent(bool draws_content) { 665 if (draws_content_ == draws_content) 666 return; 667 668 draws_content_ = draws_content; 669 NoteLayerPropertyChanged(); 670} 671 672void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { 673 if (anchor_point_ == anchor_point) 674 return; 675 676 anchor_point_ = anchor_point; 677 NoteLayerPropertyChangedForSubtree(); 678} 679 680void LayerImpl::SetAnchorPointZ(float anchor_point_z) { 681 if (anchor_point_z_ == anchor_point_z) 682 return; 683 684 anchor_point_z_ = anchor_point_z; 685 NoteLayerPropertyChangedForSubtree(); 686} 687 688void LayerImpl::SetBackgroundColor(SkColor background_color) { 689 if (background_color_ == background_color) 690 return; 691 692 background_color_ = background_color; 693 NoteLayerPropertyChanged(); 694} 695 696void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) { 697 if (filters_ == filters) 698 return; 699 700 DCHECK(!filter_); 701 filters_ = filters; 702 NoteLayerPropertyChangedForSubtree(); 703} 704 705void LayerImpl::SetBackgroundFilters( 706 const WebKit::WebFilterOperations& filters) { 707 if (background_filters_ == filters) 708 return; 709 710 background_filters_ = filters; 711 NoteLayerPropertyChanged(); 712} 713 714void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) { 715 if (filter_.get() == filter.get()) 716 return; 717 718 DCHECK(filters_.isEmpty()); 719 filter_ = filter; 720 NoteLayerPropertyChangedForSubtree(); 721} 722 723void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { 724 if (masks_to_bounds_ == masks_to_bounds) 725 return; 726 727 masks_to_bounds_ = masks_to_bounds; 728 NoteLayerPropertyChangedForSubtree(); 729} 730 731void LayerImpl::SetContentsOpaque(bool opaque) { 732 if (contents_opaque_ == opaque) 733 return; 734 735 contents_opaque_ = opaque; 736 NoteLayerPropertyChangedForSubtree(); 737} 738 739void LayerImpl::SetOpacity(float opacity) { 740 if (opacity_ == opacity) 741 return; 742 743 opacity_ = opacity; 744 NoteLayerSurfacePropertyChanged(); 745} 746 747bool LayerImpl::OpacityIsAnimating() const { 748 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); 749} 750 751bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { 752 Animation* opacity_animation = 753 layer_animation_controller_->GetAnimation(Animation::Opacity); 754 return opacity_animation && opacity_animation->is_impl_only(); 755} 756 757void LayerImpl::SetPosition(gfx::PointF position) { 758 if (position_ == position) 759 return; 760 761 position_ = position; 762 NoteLayerPropertyChangedForSubtree(); 763} 764 765void LayerImpl::SetPreserves3d(bool preserves3_d) { 766 if (preserves_3d_ == preserves3_d) 767 return; 768 769 preserves_3d_ = preserves3_d; 770 NoteLayerPropertyChangedForSubtree(); 771} 772 773void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { 774 if (sublayer_transform_ == sublayer_transform) 775 return; 776 777 sublayer_transform_ = sublayer_transform; 778 // Sublayer transform does not affect the current layer; it affects only its 779 // children. 780 NoteLayerPropertyChangedForDescendants(); 781} 782 783void LayerImpl::SetTransform(const gfx::Transform& transform) { 784 if (transform_ == transform) 785 return; 786 787 transform_ = transform; 788 NoteLayerSurfacePropertyChanged(); 789} 790 791bool LayerImpl::TransformIsAnimating() const { 792 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); 793} 794 795bool LayerImpl::TransformIsAnimatingOnImplOnly() const { 796 Animation* transform_animation = 797 layer_animation_controller_->GetAnimation(Animation::Transform); 798 return transform_animation && transform_animation->is_impl_only(); 799} 800 801void LayerImpl::SetContentBounds(gfx::Size content_bounds) { 802 if (this->content_bounds() == content_bounds) 803 return; 804 805 draw_properties_.content_bounds = content_bounds; 806 NoteLayerPropertyChanged(); 807} 808 809void LayerImpl::SetContentsScale(float contents_scale_x, 810 float contents_scale_y) { 811 if (this->contents_scale_x() == contents_scale_x && 812 this->contents_scale_y() == contents_scale_y) 813 return; 814 815 draw_properties_.contents_scale_x = contents_scale_x; 816 draw_properties_.contents_scale_y = contents_scale_y; 817 NoteLayerPropertyChanged(); 818} 819 820void LayerImpl::CalculateContentsScale( 821 float ideal_contents_scale, 822 float device_scale_factor, 823 float page_scale_factor, 824 bool animating_transform_to_screen, 825 float* contents_scale_x, 826 float* contents_scale_y, 827 gfx::Size* content_bounds) { 828 // Base LayerImpl has all of its content scales and content bounds pushed 829 // from its Layer during commit and just reuses those values as-is. 830 *contents_scale_x = this->contents_scale_x(); 831 *contents_scale_y = this->contents_scale_y(); 832 *content_bounds = this->content_bounds(); 833} 834 835void LayerImpl::UpdateScrollbarPositions() { 836 gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); 837 838 gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); 839 gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), 840 max_scroll_offset_.y() + bounds_.height()); 841 if (horizontal_scrollbar_layer_) { 842 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); 843 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width()); 844 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); 845 horizontal_scrollbar_layer_->SetViewportWithinScrollableArea( 846 viewport, scrollable_size); 847 } 848 if (vertical_scrollbar_layer_) { 849 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); 850 vertical_scrollbar_layer_->SetTotalSize(bounds_.height()); 851 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); 852 vertical_scrollbar_layer_->SetViewportWithinScrollableArea( 853 viewport, scrollable_size); 854 } 855 856 if (current_offset == last_scroll_offset_) 857 return; 858 last_scroll_offset_ = current_offset; 859 860 if (scrollbar_animation_controller_ && 861 !scrollbar_animation_controller_->IsScrollGestureInProgress()) { 862 scrollbar_animation_controller_->DidProgrammaticallyUpdateScroll( 863 layer_tree_impl()->CurrentFrameTimeTicks()); 864 } 865 866 // Get the current_offset_.y() value for a sanity-check on scrolling 867 // benchmark metrics. Specifically, we want to make sure 868 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. 869 if (layer_tree_impl()->IsActiveTree()) { 870 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); 871 } 872} 873 874void LayerImpl::SetScrollOffsetDelegate( 875 LayerScrollOffsetDelegate* scroll_offset_delegate) { 876 if (!scroll_offset_delegate && scroll_offset_delegate_) { 877 scroll_delta_ = 878 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 879 } 880 gfx::Vector2dF total_offset = TotalScrollOffset(); 881 scroll_offset_delegate_ = scroll_offset_delegate; 882 if (scroll_offset_delegate_) 883 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); 884} 885 886void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { 887 if (scroll_offset_ == scroll_offset) 888 return; 889 890 scroll_offset_ = scroll_offset; 891 892 if (scroll_offset_delegate_) 893 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); 894 895 NoteLayerPropertyChangedForSubtree(); 896 UpdateScrollbarPositions(); 897} 898 899gfx::Vector2dF LayerImpl::ScrollDelta() const { 900 if (scroll_offset_delegate_) 901 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 902 return scroll_delta_; 903} 904 905void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { 906 if (ScrollDelta() == scroll_delta) 907 return; 908 909 if (layer_tree_impl()->IsActiveTree()) { 910 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id()); 911 if (pending_twin) { 912 // The pending twin can't mirror the scroll delta of the active 913 // layer. Although the delta - sent scroll delta difference is 914 // identical for both twins, the sent scroll delta for the pending 915 // layer is zero, as anything that has been sent has been baked 916 // into the layer's position/scroll offset as a part of commit. 917 DCHECK(pending_twin->sent_scroll_delta().IsZero()); 918 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); 919 } 920 } 921 922 if (scroll_offset_delegate_) { 923 scroll_offset_delegate_->SetTotalScrollOffset( 924 scroll_offset_ + scroll_delta); 925 } else { 926 scroll_delta_ = scroll_delta; 927 } 928 NoteLayerPropertyChangedForSubtree(); 929 930 UpdateScrollbarPositions(); 931} 932 933gfx::Vector2dF LayerImpl::TotalScrollOffset() const { 934 return scroll_offset_ + ScrollDelta(); 935} 936 937void LayerImpl::SetDoubleSided(bool double_sided) { 938 if (double_sided_ == double_sided) 939 return; 940 941 double_sided_ = double_sided; 942 NoteLayerPropertyChangedForSubtree(); 943} 944 945Region LayerImpl::VisibleContentOpaqueRegion() const { 946 if (contents_opaque()) 947 return visible_content_rect(); 948 return Region(); 949} 950 951void LayerImpl::DidLoseOutputSurface() {} 952 953void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { 954 if (max_scroll_offset_ == max_scroll_offset) 955 return; 956 max_scroll_offset_ = max_scroll_offset; 957 958 layer_tree_impl()->set_needs_update_draw_properties(); 959 UpdateScrollbarPositions(); 960} 961 962void LayerImpl::SetScrollbarOpacity(float opacity) { 963 if (horizontal_scrollbar_layer_) 964 horizontal_scrollbar_layer_->SetOpacity(opacity); 965 if (vertical_scrollbar_layer_) 966 vertical_scrollbar_layer_->SetOpacity(opacity); 967} 968 969inline scoped_ptr<ScrollbarAnimationController> 970CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) { 971 base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(300); 972 base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(300); 973 return ScrollbarAnimationControllerLinearFade::Create( 974 layer, fadeout_delay, fadeout_length) 975 .PassAs<ScrollbarAnimationController>(); 976} 977 978void LayerImpl::DidBecomeActive() { 979 if (!layer_tree_impl_->settings().use_linear_fade_scrollbar_animator) 980 return; 981 982 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || 983 vertical_scrollbar_layer_; 984 if (need_scrollbar_animation_controller) { 985 if (!scrollbar_animation_controller_) { 986 scrollbar_animation_controller_ = 987 CreateScrollbarAnimationControllerWithFade(this); 988 } 989 } else { 990 scrollbar_animation_controller_.reset(); 991 } 992} 993void LayerImpl::SetHorizontalScrollbarLayer( 994 ScrollbarLayerImpl* scrollbar_layer) { 995 horizontal_scrollbar_layer_ = scrollbar_layer; 996 if (horizontal_scrollbar_layer_) 997 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); 998} 999 1000void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) { 1001 vertical_scrollbar_layer_ = scrollbar_layer; 1002 if (vertical_scrollbar_layer_) 1003 vertical_scrollbar_layer_->set_scroll_layer_id(id()); 1004} 1005 1006void LayerImpl::AsValueInto(base::DictionaryValue* state) const { 1007 TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerImpl", this); 1008 state->SetInteger("layer_id", id()); 1009 state->Set("bounds", MathUtil::AsValue(bounds()).release()); 1010 state->SetInteger("draws_content", DrawsContent()); 1011 1012 bool clipped; 1013 gfx::QuadF layer_quad = MathUtil::MapQuad( 1014 screen_space_transform(), 1015 gfx::QuadF(gfx::Rect(content_bounds())), 1016 &clipped); 1017 state->Set("layer_quad", MathUtil::AsValue(layer_quad).release()); 1018 1019 1020 scoped_ptr<base::ListValue> children_list(new base::ListValue()); 1021 for (size_t i = 0; i < children_.size(); ++i) 1022 children_list->Append(children_[i]->AsValue().release()); 1023 state->Set("children", children_list.release()); 1024 if (mask_layer_) 1025 state->Set("mask_layer", mask_layer_->AsValue().release()); 1026 if (replica_layer_) 1027 state->Set("replica_layer", replica_layer_->AsValue().release()); 1028} 1029 1030scoped_ptr<base::Value> LayerImpl::AsValue() const { 1031 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 1032 AsValueInto(state.get()); 1033 return state.PassAs<base::Value>(); 1034} 1035 1036} // namespace cc 1037