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/trees/layer_tree_host_impl.h" 6 7 #include <algorithm> 8 9 #include "base/basictypes.h" 10 #include "base/containers/hash_tables.h" 11 #include "base/json/json_writer.h" 12 #include "base/metrics/histogram.h" 13 #include "base/stl_util.h" 14 #include "base/strings/stringprintf.h" 15 #include "cc/animation/scrollbar_animation_controller.h" 16 #include "cc/animation/timing_function.h" 17 #include "cc/base/math_util.h" 18 #include "cc/base/util.h" 19 #include "cc/debug/debug_rect_history.h" 20 #include "cc/debug/frame_rate_counter.h" 21 #include "cc/debug/overdraw_metrics.h" 22 #include "cc/debug/paint_time_counter.h" 23 #include "cc/debug/rendering_stats_instrumentation.h" 24 #include "cc/debug/traced_value.h" 25 #include "cc/input/page_scale_animation.h" 26 #include "cc/input/top_controls_manager.h" 27 #include "cc/layers/append_quads_data.h" 28 #include "cc/layers/heads_up_display_layer_impl.h" 29 #include "cc/layers/layer_impl.h" 30 #include "cc/layers/layer_iterator.h" 31 #include "cc/layers/render_surface_impl.h" 32 #include "cc/layers/scrollbar_layer_impl.h" 33 #include "cc/output/compositor_frame_metadata.h" 34 #include "cc/output/copy_output_request.h" 35 #include "cc/output/delegating_renderer.h" 36 #include "cc/output/gl_renderer.h" 37 #include "cc/output/software_renderer.h" 38 #include "cc/quads/render_pass_draw_quad.h" 39 #include "cc/quads/shared_quad_state.h" 40 #include "cc/quads/solid_color_draw_quad.h" 41 #include "cc/resources/memory_history.h" 42 #include "cc/resources/picture_layer_tiling.h" 43 #include "cc/resources/prioritized_resource_manager.h" 44 #include "cc/resources/ui_resource_bitmap.h" 45 #include "cc/scheduler/delay_based_time_source.h" 46 #include "cc/scheduler/texture_uploader.h" 47 #include "cc/trees/damage_tracker.h" 48 #include "cc/trees/layer_tree_host.h" 49 #include "cc/trees/layer_tree_host_common.h" 50 #include "cc/trees/layer_tree_impl.h" 51 #include "cc/trees/quad_culler.h" 52 #include "cc/trees/single_thread_proxy.h" 53 #include "cc/trees/tree_synchronizer.h" 54 #include "ui/gfx/size_conversions.h" 55 #include "ui/gfx/vector2d_conversions.h" 56 57 namespace { 58 59 void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) { 60 if (visible) { 61 TRACE_EVENT_ASYNC_BEGIN1("webkit", 62 "LayerTreeHostImpl::SetVisible", 63 id, 64 "LayerTreeHostImpl", 65 id); 66 return; 67 } 68 69 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id); 70 } 71 72 } // namespace 73 74 namespace cc { 75 76 class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { 77 public: 78 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create( 79 LayerTreeHostImpl* layer_tree_host_impl, 80 scoped_refptr<DelayBasedTimeSource> time_source) { 81 return make_scoped_ptr( 82 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl, 83 time_source)); 84 } 85 virtual ~LayerTreeHostImplTimeSourceAdapter() { 86 time_source_->SetClient(NULL); 87 time_source_->SetActive(false); 88 } 89 90 virtual void OnTimerTick() OVERRIDE { 91 // In single threaded mode we attempt to simulate changing the current 92 // thread by maintaining a fake thread id. When we switch from one 93 // thread to another, we construct DebugScopedSetXXXThread objects that 94 // update the thread id. This lets DCHECKS that ensure we're on the 95 // right thread to work correctly in single threaded mode. The problem 96 // here is that the timer tasks are run via the message loop, and when 97 // they run, we've had no chance to construct a DebugScopedSetXXXThread 98 // object. The result is that we report that we're running on the main 99 // thread. In multi-threaded mode, this timer is run on the compositor 100 // thread, so to keep this consistent in single-threaded mode, we'll 101 // construct a DebugScopedSetImplThread object. There is no need to do 102 // this in multi-threaded mode since the real thread id's will be 103 // correct. In fact, setting fake thread id's interferes with the real 104 // thread id's and causes breakage. 105 scoped_ptr<DebugScopedSetImplThread> set_impl_thread; 106 if (!layer_tree_host_impl_->proxy()->HasImplThread()) { 107 set_impl_thread.reset( 108 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy())); 109 } 110 111 // TODO(enne): This should probably happen post-animate. 112 if (layer_tree_host_impl_->pending_tree()) { 113 layer_tree_host_impl_->ActivatePendingTreeIfNeeded(); 114 115 if (layer_tree_host_impl_->pending_tree()) { 116 layer_tree_host_impl_->pending_tree()->UpdateDrawProperties(); 117 layer_tree_host_impl_->ManageTiles(); 118 } 119 } 120 121 layer_tree_host_impl_->Animate( 122 layer_tree_host_impl_->CurrentFrameTimeTicks(), 123 layer_tree_host_impl_->CurrentFrameTime()); 124 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true); 125 bool start_ready_animations = true; 126 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 127 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); 128 } 129 130 void SetActive(bool active) { 131 if (active != time_source_->Active()) 132 time_source_->SetActive(active); 133 } 134 135 private: 136 LayerTreeHostImplTimeSourceAdapter( 137 LayerTreeHostImpl* layer_tree_host_impl, 138 scoped_refptr<DelayBasedTimeSource> time_source) 139 : layer_tree_host_impl_(layer_tree_host_impl), 140 time_source_(time_source) { 141 time_source_->SetClient(this); 142 } 143 144 LayerTreeHostImpl* layer_tree_host_impl_; 145 scoped_refptr<DelayBasedTimeSource> time_source_; 146 147 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter); 148 }; 149 150 LayerTreeHostImpl::FrameData::FrameData() 151 : contains_incomplete_tile(false), has_no_damage(false) {} 152 153 LayerTreeHostImpl::FrameData::~FrameData() {} 154 155 scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( 156 const LayerTreeSettings& settings, 157 LayerTreeHostImplClient* client, 158 Proxy* proxy, 159 RenderingStatsInstrumentation* rendering_stats_instrumentation) { 160 return make_scoped_ptr( 161 new LayerTreeHostImpl(settings, 162 client, 163 proxy, 164 rendering_stats_instrumentation)); 165 } 166 167 LayerTreeHostImpl::LayerTreeHostImpl( 168 const LayerTreeSettings& settings, 169 LayerTreeHostImplClient* client, 170 Proxy* proxy, 171 RenderingStatsInstrumentation* rendering_stats_instrumentation) 172 : client_(client), 173 proxy_(proxy), 174 input_handler_client_(NULL), 175 did_lock_scrolling_layer_(false), 176 should_bubble_scrolls_(false), 177 wheel_scrolling_(false), 178 manage_tiles_needed_(false), 179 root_layer_scroll_offset_delegate_(NULL), 180 settings_(settings), 181 visible_(true), 182 cached_managed_memory_policy_( 183 PrioritizedResourceManager::DefaultMemoryAllocationLimit(), 184 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, 185 0, 186 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING, 187 ManagedMemoryPolicy::kDefaultNumResourcesLimit), 188 pinch_gesture_active_(false), 189 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())), 190 paint_time_counter_(PaintTimeCounter::Create()), 191 memory_history_(MemoryHistory::Create()), 192 debug_rect_history_(DebugRectHistory::Create()), 193 max_memory_needed_bytes_(0), 194 last_sent_memory_visible_bytes_(0), 195 last_sent_memory_visible_and_nearby_bytes_(0), 196 last_sent_memory_use_bytes_(0), 197 zero_budget_(false), 198 device_scale_factor_(1.f), 199 overdraw_bottom_height_(0.f), 200 device_viewport_valid_for_tile_management_(true), 201 external_stencil_test_enabled_(false), 202 animation_registrar_(AnimationRegistrar::Create()), 203 rendering_stats_instrumentation_(rendering_stats_instrumentation), 204 need_to_update_visible_tiles_before_draw_(false) { 205 DCHECK(proxy_->IsImplThread()); 206 DidVisibilityChange(this, visible_); 207 208 SetDebugState(settings.initial_debug_state); 209 210 if (settings.calculate_top_controls_position) { 211 top_controls_manager_ = 212 TopControlsManager::Create(this, 213 settings.top_controls_height, 214 settings.top_controls_show_threshold, 215 settings.top_controls_hide_threshold); 216 } 217 218 SetDebugState(settings.initial_debug_state); 219 220 // LTHI always has an active tree. 221 active_tree_ = LayerTreeImpl::create(this); 222 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 223 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", this); 224 } 225 226 LayerTreeHostImpl::~LayerTreeHostImpl() { 227 DCHECK(proxy_->IsImplThread()); 228 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); 229 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 230 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", this); 231 232 if (input_handler_client_) { 233 input_handler_client_->WillShutdown(); 234 input_handler_client_ = NULL; 235 } 236 237 // The layer trees must be destroyed before the layer tree host. We've 238 // made a contract with our animation controllers that the registrar 239 // will outlive them, and we must make good. 240 recycle_tree_.reset(); 241 pending_tree_.reset(); 242 active_tree_.reset(); 243 } 244 245 void LayerTreeHostImpl::BeginCommit() {} 246 247 void LayerTreeHostImpl::CommitComplete() { 248 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete"); 249 250 // Impl-side painting needs an update immediately post-commit to have the 251 // opportunity to create tilings. Other paths can call UpdateDrawProperties 252 // more lazily when needed prior to drawing. 253 if (settings_.impl_side_painting) { 254 pending_tree_->set_needs_update_draw_properties(); 255 pending_tree_->UpdateDrawProperties(); 256 // Start working on newly created tiles immediately if needed. 257 ManageTiles(); 258 } else { 259 active_tree_->set_needs_update_draw_properties(); 260 } 261 262 client_->SendManagedMemoryStats(); 263 } 264 265 bool LayerTreeHostImpl::CanDraw() const { 266 // Note: If you are changing this function or any other function that might 267 // affect the result of CanDraw, make sure to call 268 // client_->OnCanDrawStateChanged in the proper places and update the 269 // NotifyIfCanDrawChanged test. 270 271 if (!renderer_) { 272 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer", 273 TRACE_EVENT_SCOPE_THREAD); 274 return false; 275 } 276 277 // Must have an OutputSurface if |renderer_| is not NULL. 278 DCHECK(output_surface_); 279 280 // TODO(boliu): Make draws without root_layer work and move this below 281 // draw_and_swap_full_viewport_every_frame check. Tracked in crbug.com/264967. 282 if (!active_tree_->root_layer()) { 283 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer", 284 TRACE_EVENT_SCOPE_THREAD); 285 return false; 286 } 287 288 if (output_surface_->capabilities().draw_and_swap_full_viewport_every_frame) 289 return true; 290 291 if (DeviceViewport().IsEmpty()) { 292 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport", 293 TRACE_EVENT_SCOPE_THREAD); 294 return false; 295 } 296 if (active_tree_->ViewportSizeInvalid()) { 297 TRACE_EVENT_INSTANT0( 298 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed", 299 TRACE_EVENT_SCOPE_THREAD); 300 return false; 301 } 302 if (active_tree_->ContentsTexturesPurged()) { 303 TRACE_EVENT_INSTANT0( 304 "cc", "LayerTreeHostImpl::CanDraw contents textures purged", 305 TRACE_EVENT_SCOPE_THREAD); 306 return false; 307 } 308 return true; 309 } 310 311 void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time, 312 base::Time wall_clock_time) { 313 if (input_handler_client_) 314 input_handler_client_->Animate(monotonic_time); 315 AnimatePageScale(monotonic_time); 316 AnimateLayers(monotonic_time, wall_clock_time); 317 AnimateScrollbars(monotonic_time); 318 AnimateTopControls(monotonic_time); 319 } 320 321 void LayerTreeHostImpl::ManageTiles() { 322 if (!tile_manager_) 323 return; 324 if (!manage_tiles_needed_) 325 return; 326 manage_tiles_needed_ = false; 327 tile_manager_->ManageTiles(); 328 329 size_t memory_required_bytes; 330 size_t memory_nice_to_have_bytes; 331 size_t memory_used_bytes; 332 tile_manager_->GetMemoryStats(&memory_required_bytes, 333 &memory_nice_to_have_bytes, 334 &memory_used_bytes); 335 SendManagedMemoryStats(memory_required_bytes, 336 memory_nice_to_have_bytes, 337 memory_used_bytes); 338 } 339 340 void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset, 341 bool anchor_point, 342 float page_scale, 343 base::TimeTicks start_time, 344 base::TimeDelta duration) { 345 if (!RootScrollLayer()) 346 return; 347 348 gfx::Vector2dF scroll_total = 349 RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta(); 350 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize(); 351 gfx::SizeF viewport_size = UnscaledScrollableViewportSize(); 352 353 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF(); 354 355 // Easing constants experimentally determined. 356 scoped_ptr<TimingFunction> timing_function = 357 CubicBezierTimingFunction::Create(.8, 0, .3, .9).PassAs<TimingFunction>(); 358 359 page_scale_animation_ = 360 PageScaleAnimation::Create(scroll_total, 361 active_tree_->total_page_scale_factor(), 362 viewport_size, 363 scaled_scrollable_size, 364 start_time_seconds, 365 timing_function.Pass()); 366 367 if (anchor_point) { 368 gfx::Vector2dF anchor(target_offset); 369 page_scale_animation_->ZoomWithAnchor(anchor, 370 page_scale, 371 duration.InSecondsF()); 372 } else { 373 gfx::Vector2dF scaled_target_offset = target_offset; 374 page_scale_animation_->ZoomTo(scaled_target_offset, 375 page_scale, 376 duration.InSecondsF()); 377 } 378 379 client_->SetNeedsRedrawOnImplThread(); 380 client_->SetNeedsCommitOnImplThread(); 381 client_->RenewTreePriority(); 382 } 383 384 void LayerTreeHostImpl::ScheduleAnimation() { 385 client_->SetNeedsRedrawOnImplThread(); 386 } 387 388 bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) { 389 if (!settings_.touch_hit_testing) 390 return true; 391 if (!EnsureRenderSurfaceLayerList()) 392 return false; 393 394 gfx::PointF device_viewport_point = 395 gfx::ScalePoint(viewport_point, device_scale_factor_); 396 397 // First find out which layer was hit from the saved list of visible layers 398 // in the most recent frame. 399 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 400 device_viewport_point, 401 active_tree_->RenderSurfaceLayerList()); 402 403 // Walk up the hierarchy and look for a layer with a touch event handler 404 // region that the given point hits. 405 for (; layer_impl; layer_impl = layer_impl->parent()) { 406 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point, 407 layer_impl)) 408 return true; 409 } 410 411 return false; 412 } 413 414 void LayerTreeHostImpl::SetLatencyInfoForInputEvent( 415 const ui::LatencyInfo& latency_info) { 416 active_tree()->SetLatencyInfo(latency_info); 417 } 418 419 void LayerTreeHostImpl::TrackDamageForAllSurfaces( 420 LayerImpl* root_draw_layer, 421 const LayerImplList& render_surface_layer_list) { 422 // For now, we use damage tracking to compute a global scissor. To do this, we 423 // must compute all damage tracking before drawing anything, so that we know 424 // the root damage rect. The root damage rect is then used to scissor each 425 // surface. 426 427 for (int surface_index = render_surface_layer_list.size() - 1; 428 surface_index >= 0; 429 --surface_index) { 430 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; 431 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); 432 DCHECK(render_surface); 433 render_surface->damage_tracker()->UpdateDamageTrackingState( 434 render_surface->layer_list(), 435 render_surface_layer->id(), 436 render_surface->SurfacePropertyChangedOnlyFromDescendant(), 437 render_surface->content_rect(), 438 render_surface_layer->mask_layer(), 439 render_surface_layer->filters(), 440 render_surface_layer->filter().get()); 441 } 442 } 443 444 scoped_ptr<base::Value> LayerTreeHostImpl::FrameData::AsValue() const { 445 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 446 value->SetBoolean("contains_incomplete_tile", contains_incomplete_tile); 447 value->SetBoolean("has_no_damage", has_no_damage); 448 449 // Quad data can be quite large, so only dump render passes if we select 450 // cc.debug.quads. 451 bool quads_enabled; 452 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 453 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), &quads_enabled); 454 if (quads_enabled) { 455 scoped_ptr<base::ListValue> render_pass_list(new base::ListValue()); 456 for (size_t i = 0; i < render_passes.size(); ++i) 457 render_pass_list->Append(render_passes[i]->AsValue().release()); 458 value->Set("render_passes", render_pass_list.release()); 459 } 460 return value.PassAs<base::Value>(); 461 } 462 463 void LayerTreeHostImpl::FrameData::AppendRenderPass( 464 scoped_ptr<RenderPass> render_pass) { 465 render_passes_by_id[render_pass->id] = render_pass.get(); 466 render_passes.push_back(render_pass.Pass()); 467 } 468 469 static DrawMode GetDrawMode(OutputSurface* output_surface) { 470 if (output_surface->ForcedDrawToSoftwareDevice()) { 471 return DRAW_MODE_RESOURCELESS_SOFTWARE; 472 } else if (output_surface->context3d()) { 473 return DRAW_MODE_HARDWARE; 474 } else { 475 DCHECK(output_surface->software_device()); 476 return DRAW_MODE_SOFTWARE; 477 } 478 } 479 480 static void AppendQuadsForLayer(RenderPass* target_render_pass, 481 LayerImpl* layer, 482 const OcclusionTrackerImpl& occlusion_tracker, 483 AppendQuadsData* append_quads_data) { 484 bool for_surface = false; 485 QuadCuller quad_culler(&target_render_pass->quad_list, 486 &target_render_pass->shared_quad_state_list, 487 layer, 488 occlusion_tracker, 489 layer->ShowDebugBorders(), 490 for_surface); 491 layer->AppendQuads(&quad_culler, append_quads_data); 492 } 493 494 static void AppendQuadsForRenderSurfaceLayer( 495 RenderPass* target_render_pass, 496 LayerImpl* layer, 497 const RenderPass* contributing_render_pass, 498 const OcclusionTrackerImpl& occlusion_tracker, 499 AppendQuadsData* append_quads_data) { 500 bool for_surface = true; 501 QuadCuller quad_culler(&target_render_pass->quad_list, 502 &target_render_pass->shared_quad_state_list, 503 layer, 504 occlusion_tracker, 505 layer->ShowDebugBorders(), 506 for_surface); 507 508 bool is_replica = false; 509 layer->render_surface()->AppendQuads(&quad_culler, 510 append_quads_data, 511 is_replica, 512 contributing_render_pass->id); 513 514 // Add replica after the surface so that it appears below the surface. 515 if (layer->has_replica()) { 516 is_replica = true; 517 layer->render_surface()->AppendQuads(&quad_culler, 518 append_quads_data, 519 is_replica, 520 contributing_render_pass->id); 521 } 522 } 523 524 static void AppendQuadsToFillScreen( 525 RenderPass* target_render_pass, 526 LayerImpl* root_layer, 527 SkColor screen_background_color, 528 const OcclusionTrackerImpl& occlusion_tracker) { 529 if (!root_layer || !SkColorGetA(screen_background_color)) 530 return; 531 532 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen(); 533 if (fill_region.IsEmpty()) 534 return; 535 536 bool for_surface = false; 537 QuadCuller quad_culler(&target_render_pass->quad_list, 538 &target_render_pass->shared_quad_state_list, 539 root_layer, 540 occlusion_tracker, 541 root_layer->ShowDebugBorders(), 542 for_surface); 543 544 // Manually create the quad state for the gutter quads, as the root layer 545 // doesn't have any bounds and so can't generate this itself. 546 // TODO(danakj): Make the gutter quads generated by the solid color layer 547 // (make it smarter about generating quads to fill unoccluded areas). 548 549 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect(); 550 float opacity = 1.f; 551 SharedQuadState* shared_quad_state = 552 quad_culler.UseSharedQuadState(SharedQuadState::Create()); 553 shared_quad_state->SetAll(root_layer->draw_transform(), 554 root_target_rect.size(), 555 root_target_rect, 556 root_target_rect, 557 false, 558 opacity); 559 560 AppendQuadsData append_quads_data; 561 562 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization); 563 bool did_invert = root_layer->screen_space_transform().GetInverse( 564 &transform_to_layer_space); 565 DCHECK(did_invert); 566 for (Region::Iterator fill_rects(fill_region); 567 fill_rects.has_rect(); 568 fill_rects.next()) { 569 // The root layer transform is composed of translations and scales only, 570 // no perspective, so mapping is sufficient (as opposed to projecting). 571 gfx::Rect layer_rect = 572 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect()); 573 // Skip the quad culler and just append the quads directly to avoid 574 // occlusion checks. 575 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); 576 quad->SetNew(shared_quad_state, layer_rect, screen_background_color, false); 577 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data); 578 } 579 } 580 581 bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { 582 DCHECK(frame->render_passes.empty()); 583 584 if (!CanDraw() || !active_tree_->root_layer()) 585 return false; 586 587 TrackDamageForAllSurfaces(active_tree_->root_layer(), 588 *frame->render_surface_layer_list); 589 590 // If the root render surface has no visible damage, then don't generate a 591 // frame at all. 592 RenderSurfaceImpl* root_surface = 593 active_tree_->root_layer()->render_surface(); 594 bool root_surface_has_no_visible_damage = 595 !root_surface->damage_tracker()->current_damage_rect().Intersects( 596 root_surface->content_rect()); 597 bool root_surface_has_contributing_layers = 598 !root_surface->layer_list().empty(); 599 if (root_surface_has_contributing_layers && 600 root_surface_has_no_visible_damage) { 601 TRACE_EVENT0("cc", 602 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); 603 frame->has_no_damage = true; 604 // A copy request should cause damage, so we should not have any copy 605 // requests in this case. 606 DCHECK_EQ(0u, active_tree_->LayersWithCopyOutputRequest().size()); 607 DCHECK(!output_surface_->capabilities() 608 .draw_and_swap_full_viewport_every_frame); 609 return true; 610 } 611 612 TRACE_EVENT1("cc", 613 "LayerTreeHostImpl::CalculateRenderPasses", 614 "render_surface_layer_list.size()", 615 static_cast<uint64>(frame->render_surface_layer_list->size())); 616 617 // Create the render passes in dependency order. 618 for (int surface_index = frame->render_surface_layer_list->size() - 1; 619 surface_index >= 0; 620 --surface_index) { 621 LayerImpl* render_surface_layer = 622 (*frame->render_surface_layer_list)[surface_index]; 623 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); 624 625 bool should_draw_into_render_pass = 626 render_surface_layer->parent() == NULL || 627 render_surface->contributes_to_drawn_surface() || 628 render_surface_layer->HasCopyRequest(); 629 if (should_draw_into_render_pass) 630 render_surface_layer->render_surface()->AppendRenderPasses(frame); 631 } 632 633 bool record_metrics_for_frame = 634 settings_.show_overdraw_in_tracing && 635 base::debug::TraceLog::GetInstance() && 636 base::debug::TraceLog::GetInstance()->IsEnabled(); 637 OcclusionTrackerImpl occlusion_tracker( 638 active_tree_->root_layer()->render_surface()->content_rect(), 639 record_metrics_for_frame); 640 occlusion_tracker.set_minimum_tracking_size( 641 settings_.minimum_occlusion_tracking_size); 642 643 if (debug_state_.show_occluding_rects) { 644 occlusion_tracker.set_occluding_screen_space_rects_container( 645 &frame->occluding_screen_space_rects); 646 } 647 if (debug_state_.show_non_occluding_rects) { 648 occlusion_tracker.set_non_occluding_screen_space_rects_container( 649 &frame->non_occluding_screen_space_rects); 650 } 651 652 // Add quads to the Render passes in FrontToBack order to allow for testing 653 // occlusion and performing culling during the tree walk. 654 typedef LayerIterator<LayerImpl, 655 LayerImplList, 656 RenderSurfaceImpl, 657 LayerIteratorActions::FrontToBack> LayerIteratorType; 658 659 // Typically when we are missing a texture and use a checkerboard quad, we 660 // still draw the frame. However when the layer being checkerboarded is moving 661 // due to an impl-animation, we drop the frame to avoid flashing due to the 662 // texture suddenly appearing in the future. 663 bool draw_frame = true; 664 // When we have a copy request for a layer, we need to draw no matter 665 // what, as the layer may disappear after this frame. 666 bool have_copy_request = false; 667 668 int layers_drawn = 0; 669 670 const DrawMode draw_mode = GetDrawMode(output_surface_.get()); 671 672 LayerIteratorType end = 673 LayerIteratorType::End(frame->render_surface_layer_list); 674 for (LayerIteratorType it = 675 LayerIteratorType::Begin(frame->render_surface_layer_list); 676 it != end; 677 ++it) { 678 RenderPass::Id target_render_pass_id = 679 it.target_render_surface_layer()->render_surface()->RenderPassId(); 680 RenderPass* target_render_pass = 681 frame->render_passes_by_id[target_render_pass_id]; 682 683 bool prevent_occlusion = it.target_render_surface_layer()->HasCopyRequest(); 684 occlusion_tracker.EnterLayer(it, prevent_occlusion); 685 686 AppendQuadsData append_quads_data(target_render_pass_id); 687 688 if (it.represents_target_render_surface()) { 689 if (it->HasCopyRequest()) { 690 have_copy_request = true; 691 it->TakeCopyRequestsAndTransformToTarget( 692 &target_render_pass->copy_requests); 693 } 694 } else if (it.represents_contributing_render_surface() && 695 it->render_surface()->contributes_to_drawn_surface()) { 696 RenderPass::Id contributing_render_pass_id = 697 it->render_surface()->RenderPassId(); 698 RenderPass* contributing_render_pass = 699 frame->render_passes_by_id[contributing_render_pass_id]; 700 AppendQuadsForRenderSurfaceLayer(target_render_pass, 701 *it, 702 contributing_render_pass, 703 occlusion_tracker, 704 &append_quads_data); 705 } else if (it.represents_itself() && 706 !it->visible_content_rect().IsEmpty()) { 707 bool has_occlusion_from_outside_target_surface; 708 bool impl_draw_transform_is_unknown = false; 709 if (occlusion_tracker.Occluded( 710 it->render_target(), 711 it->visible_content_rect(), 712 it->draw_transform(), 713 impl_draw_transform_is_unknown, 714 it->is_clipped(), 715 it->clip_rect(), 716 &has_occlusion_from_outside_target_surface)) { 717 append_quads_data.had_occlusion_from_outside_target_surface |= 718 has_occlusion_from_outside_target_surface; 719 } else if (it->WillDraw(draw_mode, resource_provider_.get())) { 720 DCHECK_EQ(active_tree_, it->layer_tree_impl()); 721 722 frame->will_draw_layers.push_back(*it); 723 724 if (it->HasContributingDelegatedRenderPasses()) { 725 RenderPass::Id contributing_render_pass_id = 726 it->FirstContributingRenderPassId(); 727 while (frame->render_passes_by_id.find(contributing_render_pass_id) != 728 frame->render_passes_by_id.end()) { 729 RenderPass* render_pass = 730 frame->render_passes_by_id[contributing_render_pass_id]; 731 732 AppendQuadsData append_quads_data(render_pass->id); 733 AppendQuadsForLayer(render_pass, 734 *it, 735 occlusion_tracker, 736 &append_quads_data); 737 738 contributing_render_pass_id = 739 it->NextContributingRenderPassId(contributing_render_pass_id); 740 } 741 } 742 743 AppendQuadsForLayer(target_render_pass, 744 *it, 745 occlusion_tracker, 746 &append_quads_data); 747 } 748 749 ++layers_drawn; 750 } 751 752 if (append_quads_data.had_occlusion_from_outside_target_surface) 753 target_render_pass->has_occlusion_from_outside_target_surface = true; 754 755 if (append_quads_data.num_missing_tiles) { 756 rendering_stats_instrumentation_->AddMissingTiles( 757 append_quads_data.num_missing_tiles); 758 bool layer_has_animating_transform = 759 it->screen_space_transform_is_animating() || 760 it->draw_transform_is_animating(); 761 if (layer_has_animating_transform) 762 draw_frame = false; 763 } 764 765 if (append_quads_data.had_incomplete_tile) 766 frame->contains_incomplete_tile = true; 767 768 occlusion_tracker.LeaveLayer(it); 769 } 770 771 if (have_copy_request || 772 output_surface_->capabilities().draw_and_swap_full_viewport_every_frame) 773 draw_frame = true; 774 775 rendering_stats_instrumentation_->AddLayersDrawn(layers_drawn); 776 777 #ifndef NDEBUG 778 for (size_t i = 0; i < frame->render_passes.size(); ++i) { 779 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j) 780 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state); 781 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id) 782 != frame->render_passes_by_id.end()); 783 } 784 #endif 785 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin()); 786 787 if (!active_tree_->has_transparent_background()) { 788 frame->render_passes.back()->has_transparent_background = false; 789 AppendQuadsToFillScreen(frame->render_passes.back(), 790 active_tree_->root_layer(), 791 active_tree_->background_color(), 792 occlusion_tracker); 793 } 794 795 if (draw_frame) 796 occlusion_tracker.overdraw_metrics()->RecordMetrics(this); 797 else 798 DCHECK(!have_copy_request); 799 800 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); 801 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); 802 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()), 803 frame); 804 805 // Any copy requests left in the tree are not going to get serviced, and 806 // should be aborted. 807 ScopedPtrVector<CopyOutputRequest> requests_to_abort; 808 while (!active_tree_->LayersWithCopyOutputRequest().empty()) { 809 LayerImpl* layer = active_tree_->LayersWithCopyOutputRequest().back(); 810 layer->TakeCopyRequestsAndTransformToTarget(&requests_to_abort); 811 } 812 for (size_t i = 0; i < requests_to_abort.size(); ++i) 813 requests_to_abort[i]->SendEmptyResult(); 814 815 // If we're making a frame to draw, it better have at least one render pass. 816 DCHECK(!frame->render_passes.empty()); 817 818 // Should only have one render pass in resourceless software mode. 819 if (output_surface_->ForcedDrawToSoftwareDevice()) 820 DCHECK_EQ(1u, frame->render_passes.size()); 821 822 return draw_frame; 823 } 824 825 void LayerTreeHostImpl::MainThreadHasStoppedFlinging() { 826 if (input_handler_client_) 827 input_handler_client_->MainThreadHasStoppedFlinging(); 828 } 829 830 void LayerTreeHostImpl::UpdateBackgroundAnimateTicking( 831 bool should_background_tick) { 832 DCHECK(proxy_->IsImplThread()); 833 834 bool enabled = should_background_tick && 835 !animation_registrar_->active_animation_controllers().empty(); 836 837 // Lazily create the time_source adapter so that we can vary the interval for 838 // testing. 839 if (!time_source_client_adapter_) { 840 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create( 841 this, 842 DelayBasedTimeSource::Create( 843 LowFrequencyAnimationInterval(), 844 proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner() 845 : proxy_->MainThreadTaskRunner())); 846 } 847 848 time_source_client_adapter_->SetActive(enabled); 849 } 850 851 void LayerTreeHostImpl::SetViewportDamage(gfx::Rect damage_rect) { 852 viewport_damage_rect_.Union(damage_rect); 853 } 854 855 static inline RenderPass* FindRenderPassById( 856 RenderPass::Id render_pass_id, 857 const LayerTreeHostImpl::FrameData& frame) { 858 RenderPassIdHashMap::const_iterator it = 859 frame.render_passes_by_id.find(render_pass_id); 860 return it != frame.render_passes_by_id.end() ? it->second : NULL; 861 } 862 863 static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, 864 LayerTreeHostImpl::FrameData* frame) { 865 RenderPass* remove_render_pass = 866 FindRenderPassById(remove_render_pass_id, *frame); 867 // The pass was already removed by another quad - probably the original, and 868 // we are the replica. 869 if (!remove_render_pass) 870 return; 871 RenderPassList& render_passes = frame->render_passes; 872 RenderPassList::iterator to_remove = std::find(render_passes.begin(), 873 render_passes.end(), 874 remove_render_pass); 875 876 DCHECK(to_remove != render_passes.end()); 877 878 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove); 879 frame->render_passes.erase(to_remove); 880 frame->render_passes_by_id.erase(remove_render_pass_id); 881 882 // Now follow up for all RenderPass quads and remove their RenderPasses 883 // recursively. 884 const QuadList& quad_list = removed_pass->quad_list; 885 QuadList::ConstBackToFrontIterator quad_list_iterator = 886 quad_list.BackToFrontBegin(); 887 for (; quad_list_iterator != quad_list.BackToFrontEnd(); 888 ++quad_list_iterator) { 889 DrawQuad* current_quad = (*quad_list_iterator); 890 if (current_quad->material != DrawQuad::RENDER_PASS) 891 continue; 892 893 RenderPass::Id next_remove_render_pass_id = 894 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id; 895 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame); 896 } 897 } 898 899 bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures:: 900 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, 901 const FrameData& frame) const { 902 DCHECK(renderer_); 903 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty(); 904 bool quad_has_cached_resource = 905 renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id); 906 if (quad_has_damage) { 907 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage"); 908 return false; 909 } else if (!quad_has_cached_resource) { 910 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture"); 911 return false; 912 } 913 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!"); 914 return true; 915 } 916 917 bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( 918 const RenderPassDrawQuad& quad, const FrameData& frame) const { 919 const RenderPass* render_pass = 920 FindRenderPassById(quad.render_pass_id, frame); 921 if (!render_pass) 922 return false; 923 924 // If any quad or RenderPass draws into this RenderPass, then keep it. 925 const QuadList& quad_list = render_pass->quad_list; 926 for (QuadList::ConstBackToFrontIterator quad_list_iterator = 927 quad_list.BackToFrontBegin(); 928 quad_list_iterator != quad_list.BackToFrontEnd(); 929 ++quad_list_iterator) { 930 DrawQuad* current_quad = *quad_list_iterator; 931 932 if (current_quad->material != DrawQuad::RENDER_PASS) 933 return false; 934 935 const RenderPass* contributing_pass = FindRenderPassById( 936 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame); 937 if (contributing_pass) 938 return false; 939 } 940 return true; 941 } 942 943 // Defined for linking tests. 944 template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< 945 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>( 946 CullRenderPassesWithCachedTextures culler, FrameData* frame); 947 template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< 948 LayerTreeHostImpl::CullRenderPassesWithNoQuads>( 949 CullRenderPassesWithNoQuads culler, FrameData*); 950 951 // static 952 template <typename RenderPassCuller> 953 void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler, 954 FrameData* frame) { 955 for (size_t it = culler.RenderPassListBegin(frame->render_passes); 956 it != culler.RenderPassListEnd(frame->render_passes); 957 it = culler.RenderPassListNext(it)) { 958 const RenderPass* current_pass = frame->render_passes[it]; 959 const QuadList& quad_list = current_pass->quad_list; 960 QuadList::ConstBackToFrontIterator quad_list_iterator = 961 quad_list.BackToFrontBegin(); 962 963 for (; quad_list_iterator != quad_list.BackToFrontEnd(); 964 ++quad_list_iterator) { 965 DrawQuad* current_quad = *quad_list_iterator; 966 967 if (current_quad->material != DrawQuad::RENDER_PASS) 968 continue; 969 970 const RenderPassDrawQuad* render_pass_quad = 971 RenderPassDrawQuad::MaterialCast(current_quad); 972 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame)) 973 continue; 974 975 // We are changing the vector in the middle of iteration. Because we 976 // delete render passes that draw into the current pass, we are 977 // guaranteed that any data from the iterator to the end will not 978 // change. So, capture the iterator position from the end of the 979 // list, and restore it after the change. 980 size_t position_from_end = frame->render_passes.size() - it; 981 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame); 982 it = frame->render_passes.size() - position_from_end; 983 DCHECK_GE(frame->render_passes.size(), position_from_end); 984 } 985 } 986 } 987 988 bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame, 989 gfx::Rect device_viewport_damage_rect) { 990 TRACE_EVENT1("cc", 991 "LayerTreeHostImpl::PrepareToDraw", 992 "SourceFrameNumber", 993 active_tree_->source_frame_number()); 994 995 if (need_to_update_visible_tiles_before_draw_) { 996 DCHECK(tile_manager_); 997 if (tile_manager_->UpdateVisibleTiles()) 998 DidInitializeVisibleTile(); 999 } 1000 1001 active_tree_->UpdateDrawProperties(); 1002 1003 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList(); 1004 frame->render_passes.clear(); 1005 frame->render_passes_by_id.clear(); 1006 frame->will_draw_layers.clear(); 1007 frame->contains_incomplete_tile = false; 1008 frame->has_no_damage = false; 1009 1010 if (active_tree_->root_layer()) { 1011 device_viewport_damage_rect.Union(viewport_damage_rect_); 1012 viewport_damage_rect_ = gfx::Rect(); 1013 1014 active_tree_->root_layer()->render_surface()->damage_tracker()-> 1015 AddDamageNextUpdate(device_viewport_damage_rect); 1016 } 1017 1018 if (!CalculateRenderPasses(frame)) { 1019 DCHECK(!output_surface_->capabilities() 1020 .draw_and_swap_full_viewport_every_frame); 1021 return false; 1022 } 1023 1024 // If we return true, then we expect DrawLayers() to be called before this 1025 // function is called again. 1026 return true; 1027 } 1028 1029 void LayerTreeHostImpl::EvictTexturesForTesting() { 1030 EnforceManagedMemoryPolicy(ManagedMemoryPolicy(0)); 1031 } 1032 1033 void LayerTreeHostImpl::EnforceManagedMemoryPolicy( 1034 const ManagedMemoryPolicy& policy) { 1035 1036 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread( 1037 visible_ ? policy.bytes_limit_when_visible 1038 : policy.bytes_limit_when_not_visible, 1039 ManagedMemoryPolicy::PriorityCutoffToValue( 1040 visible_ ? policy.priority_cutoff_when_visible 1041 : policy.priority_cutoff_when_not_visible)); 1042 if (evicted_resources) { 1043 active_tree_->SetContentsTexturesPurged(); 1044 if (pending_tree_) 1045 pending_tree_->SetContentsTexturesPurged(); 1046 client_->SetNeedsCommitOnImplThread(); 1047 client_->OnCanDrawStateChanged(CanDraw()); 1048 client_->RenewTreePriority(); 1049 } 1050 client_->SendManagedMemoryStats(); 1051 1052 UpdateTileManagerMemoryPolicy(policy); 1053 } 1054 1055 void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( 1056 const ManagedMemoryPolicy& policy) { 1057 if (!tile_manager_) 1058 return; 1059 1060 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState()); 1061 new_state.memory_limit_in_bytes = visible_ ? 1062 policy.bytes_limit_when_visible : 1063 policy.bytes_limit_when_not_visible; 1064 // TODO(reveman): We should avoid keeping around unused resources if 1065 // possible. crbug.com/224475 1066 new_state.unused_memory_limit_in_bytes = static_cast<size_t>( 1067 (static_cast<int64>(new_state.memory_limit_in_bytes) * 1068 settings_.max_unused_resource_memory_percentage) / 100); 1069 new_state.memory_limit_policy = 1070 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy( 1071 visible_ ? 1072 policy.priority_cutoff_when_visible : 1073 policy.priority_cutoff_when_not_visible); 1074 new_state.num_resources_limit = policy.num_resources_limit; 1075 tile_manager_->SetGlobalState(new_state); 1076 manage_tiles_needed_ = true; 1077 } 1078 1079 bool LayerTreeHostImpl::HasImplThread() const { 1080 return proxy_->HasImplThread(); 1081 } 1082 1083 void LayerTreeHostImpl::DidInitializeVisibleTile() { 1084 // TODO(reveman): Determine tiles that changed and only damage 1085 // what's necessary. 1086 SetFullRootLayerDamage(); 1087 if (client_) 1088 client_->DidInitializeVisibleTileOnImplThread(); 1089 } 1090 1091 void LayerTreeHostImpl::NotifyReadyToActivate() { 1092 if (pending_tree_) { 1093 need_to_update_visible_tiles_before_draw_ = true; 1094 ActivatePendingTree(); 1095 } 1096 } 1097 1098 bool LayerTreeHostImpl::ShouldClearRootRenderPass() const { 1099 return settings_.should_clear_root_render_pass; 1100 } 1101 1102 void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { 1103 SetManagedMemoryPolicy(policy, zero_budget_); 1104 } 1105 1106 void LayerTreeHostImpl::SetDiscardBackBufferWhenNotVisible(bool discard) { 1107 DCHECK(renderer_); 1108 renderer_->SetDiscardBackBufferWhenNotVisible(discard); 1109 } 1110 1111 void LayerTreeHostImpl::SetTreeActivationCallback( 1112 const base::Closure& callback) { 1113 DCHECK(proxy_->IsImplThread()); 1114 DCHECK(settings_.impl_side_painting || callback.is_null()); 1115 tree_activation_callback_ = callback; 1116 } 1117 1118 void LayerTreeHostImpl::SetManagedMemoryPolicy( 1119 const ManagedMemoryPolicy& policy, bool zero_budget) { 1120 if (cached_managed_memory_policy_ == policy && zero_budget_ == zero_budget) 1121 return; 1122 1123 ManagedMemoryPolicy old_policy = ActualManagedMemoryPolicy(); 1124 1125 cached_managed_memory_policy_ = policy; 1126 zero_budget_ = zero_budget; 1127 ManagedMemoryPolicy actual_policy = ActualManagedMemoryPolicy(); 1128 1129 if (old_policy == actual_policy) 1130 return; 1131 1132 if (!proxy_->HasImplThread()) { 1133 // In single-thread mode, this can be called on the main thread by 1134 // GLRenderer::OnMemoryAllocationChanged. 1135 DebugScopedSetImplThread impl_thread(proxy_); 1136 EnforceManagedMemoryPolicy(actual_policy); 1137 } else { 1138 DCHECK(proxy_->IsImplThread()); 1139 EnforceManagedMemoryPolicy(actual_policy); 1140 } 1141 1142 // If there is already enough memory to draw everything imaginable and the 1143 // new memory limit does not change this, then do not re-commit. Don't bother 1144 // skipping commits if this is not visible (commits don't happen when not 1145 // visible, there will almost always be a commit when this becomes visible). 1146 bool needs_commit = true; 1147 if (visible() && 1148 actual_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && 1149 old_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && 1150 actual_policy.priority_cutoff_when_visible == 1151 old_policy.priority_cutoff_when_visible) { 1152 needs_commit = false; 1153 } 1154 1155 if (needs_commit) 1156 client_->SetNeedsCommitOnImplThread(); 1157 } 1158 1159 void LayerTreeHostImpl::SetExternalDrawConstraints( 1160 const gfx::Transform& transform, 1161 gfx::Rect viewport, 1162 gfx::Rect clip, 1163 bool valid_for_tile_management) { 1164 external_transform_ = transform; 1165 external_viewport_ = viewport; 1166 external_clip_ = clip; 1167 device_viewport_valid_for_tile_management_ = valid_for_tile_management; 1168 } 1169 1170 void LayerTreeHostImpl::SetExternalStencilTest(bool enabled) { 1171 external_stencil_test_enabled_ = enabled; 1172 } 1173 1174 void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) { 1175 client_->SetNeedsRedrawRectOnImplThread(damage_rect); 1176 } 1177 1178 void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) { 1179 client_->BeginFrameOnImplThread(args); 1180 } 1181 1182 void LayerTreeHostImpl::OnSwapBuffersComplete( 1183 const CompositorFrameAck* ack) { 1184 // TODO(piman): We may need to do some validation on this ack before 1185 // processing it. 1186 if (ack && renderer_) 1187 renderer_->ReceiveSwapBuffersAck(*ack); 1188 1189 client_->OnSwapBuffersCompleteOnImplThread(); 1190 } 1191 1192 void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { 1193 client_->OnCanDrawStateChanged(CanDraw()); 1194 } 1195 1196 CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { 1197 CompositorFrameMetadata metadata; 1198 metadata.device_scale_factor = device_scale_factor_; 1199 metadata.page_scale_factor = active_tree_->total_page_scale_factor(); 1200 metadata.viewport_size = active_tree_->ScrollableViewportSize(); 1201 metadata.root_layer_size = active_tree_->ScrollableSize(); 1202 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor(); 1203 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); 1204 metadata.latency_info = active_tree_->GetLatencyInfo(); 1205 if (top_controls_manager_) { 1206 metadata.location_bar_offset = 1207 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset()); 1208 metadata.location_bar_content_translation = 1209 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset()); 1210 metadata.overdraw_bottom_height = overdraw_bottom_height_; 1211 } 1212 1213 if (!RootScrollLayer()) 1214 return metadata; 1215 1216 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset(); 1217 1218 return metadata; 1219 } 1220 1221 bool LayerTreeHostImpl::AllowPartialSwap() const { 1222 // We don't track damage on the HUD layer (it interacts with damage tracking 1223 // visualizations), so disable partial swaps to make the HUD layer display 1224 // properly. 1225 return !debug_state_.ShowHudRects(); 1226 } 1227 1228 bool LayerTreeHostImpl::ExternalStencilTestEnabled() const { 1229 return external_stencil_test_enabled_; 1230 } 1231 1232 static void LayerTreeHostImplDidBeginTracingCallback(LayerImpl* layer) { 1233 layer->DidBeginTracing(); 1234 } 1235 1236 void LayerTreeHostImpl::DrawLayers(FrameData* frame, 1237 base::TimeTicks frame_begin_time) { 1238 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); 1239 DCHECK(CanDraw()); 1240 1241 if (frame->has_no_damage) { 1242 TRACE_EVENT0("cc", "EarlyOut_NoDamage"); 1243 DCHECK(!output_surface_->capabilities() 1244 .draw_and_swap_full_viewport_every_frame); 1245 return; 1246 } 1247 1248 DCHECK(!frame->render_passes.empty()); 1249 1250 fps_counter_->SaveTimeStamp(frame_begin_time); 1251 1252 rendering_stats_instrumentation_->SetScreenFrameCount( 1253 fps_counter_->current_frame_number()); 1254 rendering_stats_instrumentation_->SetDroppedFrameCount( 1255 fps_counter_->dropped_frame_count()); 1256 1257 if (tile_manager_) { 1258 memory_history_->SaveEntry( 1259 tile_manager_->memory_stats_from_last_assign()); 1260 } 1261 1262 if (debug_state_.ShowHudRects()) { 1263 debug_rect_history_->SaveDebugRectsForCurrentFrame( 1264 active_tree_->root_layer(), 1265 *frame->render_surface_layer_list, 1266 frame->occluding_screen_space_rects, 1267 frame->non_occluding_screen_space_rects, 1268 debug_state_); 1269 } 1270 1271 if (!settings_.impl_side_painting && debug_state_.continuous_painting) { 1272 const RenderingStats& stats = 1273 rendering_stats_instrumentation_->GetRenderingStats(); 1274 paint_time_counter_->SavePaintTime(stats.total_paint_time); 1275 } 1276 1277 bool is_new_trace; 1278 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); 1279 if (is_new_trace) { 1280 if (pending_tree_) { 1281 LayerTreeHostCommon::CallFunctionForSubtree( 1282 pending_tree_->root_layer(), 1283 base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); 1284 } 1285 LayerTreeHostCommon::CallFunctionForSubtree( 1286 active_tree_->root_layer(), 1287 base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); 1288 } 1289 1290 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 1291 TRACE_DISABLED_BY_DEFAULT("cc.debug") "," 1292 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), "cc::LayerTreeHostImpl", 1293 this, TracedValue::FromValue(AsValueWithFrame(frame).release())); 1294 1295 // Because the contents of the HUD depend on everything else in the frame, the 1296 // contents of its texture are updated as the last thing before the frame is 1297 // drawn. 1298 if (active_tree_->hud_layer()) { 1299 active_tree_->hud_layer()->UpdateHudTexture( 1300 GetDrawMode(output_surface_.get()), resource_provider_.get()); 1301 } 1302 1303 if (output_surface_->ForcedDrawToSoftwareDevice()) { 1304 bool disable_picture_quad_image_filtering = 1305 IsCurrentlyScrolling() || needs_animate_layers(); 1306 1307 scoped_ptr<SoftwareRenderer> temp_software_renderer = 1308 SoftwareRenderer::Create(this, output_surface_.get(), NULL); 1309 temp_software_renderer->DrawFrame(&frame->render_passes, disable_picture_quad_image_filtering); 1310 } else { 1311 renderer_->DrawFrame(&frame->render_passes, false); 1312 } 1313 // The render passes should be consumed by the renderer. 1314 DCHECK(frame->render_passes.empty()); 1315 frame->render_passes_by_id.clear(); 1316 1317 // The next frame should start by assuming nothing has changed, and changes 1318 // are noted as they occur. 1319 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) { 1320 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()-> 1321 DidDrawDamagedArea(); 1322 } 1323 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree(); 1324 } 1325 1326 void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) { 1327 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i) 1328 frame.will_draw_layers[i]->DidDraw(resource_provider_.get()); 1329 1330 // Once all layers have been drawn, pending texture uploads should no 1331 // longer block future uploads. 1332 resource_provider_->MarkPendingUploadsAsNonBlocking(); 1333 } 1334 1335 void LayerTreeHostImpl::FinishAllRendering() { 1336 if (renderer_) 1337 renderer_->Finish(); 1338 } 1339 1340 bool LayerTreeHostImpl::IsContextLost() { 1341 DCHECK(proxy_->IsImplThread()); 1342 return renderer_ && renderer_->IsContextLost(); 1343 } 1344 1345 const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const { 1346 return renderer_->Capabilities(); 1347 } 1348 1349 bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { 1350 if (frame.has_no_damage) 1351 return false; 1352 renderer_->SwapBuffers(); 1353 active_tree_->ClearLatencyInfo(); 1354 return true; 1355 } 1356 1357 void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) { 1358 if (output_surface_) 1359 output_surface_->SetNeedsBeginFrame(enable); 1360 } 1361 1362 float LayerTreeHostImpl::DeviceScaleFactor() const { 1363 return device_scale_factor_; 1364 } 1365 1366 gfx::SizeF LayerTreeHostImpl::UnscaledScrollableViewportSize() const { 1367 // The container layer bounds should be used if non-overlay scrollbars may 1368 // exist since it adjusts for them. 1369 LayerImpl* container_layer = active_tree_->RootContainerLayer(); 1370 if (!Settings().solid_color_scrollbars && container_layer) { 1371 DCHECK(!top_controls_manager_); 1372 DCHECK_EQ(0, overdraw_bottom_height_); 1373 return container_layer->bounds(); 1374 } 1375 1376 gfx::SizeF dip_size = 1377 gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor()); 1378 1379 float top_offset = 1380 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f; 1381 return gfx::SizeF(dip_size.width(), 1382 dip_size.height() - top_offset - overdraw_bottom_height_); 1383 } 1384 1385 const LayerTreeSettings& LayerTreeHostImpl::Settings() const { 1386 return settings(); 1387 } 1388 1389 void LayerTreeHostImpl::DidLoseOutputSurface() { 1390 // TODO(jamesr): The renderer_ check is needed to make some of the 1391 // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or 1392 // important) in production. We should adjust the test to not need this. 1393 if (renderer_) 1394 client_->DidLoseOutputSurfaceOnImplThread(); 1395 } 1396 1397 void LayerTreeHostImpl::Readback(void* pixels, 1398 gfx::Rect rect_in_device_viewport) { 1399 DCHECK(renderer_); 1400 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport); 1401 } 1402 1403 bool LayerTreeHostImpl::HaveRootScrollLayer() const { 1404 return !!RootScrollLayer(); 1405 } 1406 1407 LayerImpl* LayerTreeHostImpl::RootLayer() const { 1408 return active_tree_->root_layer(); 1409 } 1410 1411 LayerImpl* LayerTreeHostImpl::RootScrollLayer() const { 1412 return active_tree_->RootScrollLayer(); 1413 } 1414 1415 LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { 1416 return active_tree_->CurrentlyScrollingLayer(); 1417 } 1418 1419 bool LayerTreeHostImpl::IsCurrentlyScrolling() const { 1420 return CurrentlyScrollingLayer() || 1421 (RootScrollLayer() && RootScrollLayer()->IsExternalFlingActive()); 1422 } 1423 1424 // Content layers can be either directly scrollable or contained in an outer 1425 // scrolling layer which applies the scroll transform. Given a content layer, 1426 // this function returns the associated scroll layer if any. 1427 static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) { 1428 if (!layer_impl) 1429 return 0; 1430 1431 if (layer_impl->scrollable()) 1432 return layer_impl; 1433 1434 if (layer_impl->DrawsContent() && 1435 layer_impl->parent() && 1436 layer_impl->parent()->scrollable()) 1437 return layer_impl->parent(); 1438 1439 return 0; 1440 } 1441 1442 void LayerTreeHostImpl::CreatePendingTree() { 1443 CHECK(!pending_tree_); 1444 if (recycle_tree_) 1445 recycle_tree_.swap(pending_tree_); 1446 else 1447 pending_tree_ = LayerTreeImpl::create(this); 1448 client_->OnCanDrawStateChanged(CanDraw()); 1449 client_->OnHasPendingTreeStateChanged(pending_tree_); 1450 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get()); 1451 TRACE_EVENT_ASYNC_STEP0("cc", 1452 "PendingTree", pending_tree_.get(), "waiting"); 1453 } 1454 1455 void LayerTreeHostImpl::UpdateVisibleTiles() { 1456 DCHECK(!client_->IsInsideDraw()) << 1457 "Updating visible tiles within a draw may trigger " 1458 "spurious redraws."; 1459 if (tile_manager_ && tile_manager_->UpdateVisibleTiles()) 1460 DidInitializeVisibleTile(); 1461 1462 need_to_update_visible_tiles_before_draw_ = false; 1463 } 1464 1465 void LayerTreeHostImpl::ActivatePendingTreeIfNeeded() { 1466 DCHECK(pending_tree_); 1467 CHECK(settings_.impl_side_painting); 1468 1469 if (!pending_tree_) 1470 return; 1471 1472 // The tile manager is usually responsible for notifying activation. 1473 // If there is no tile manager, then we need to manually activate. 1474 if (!tile_manager_ || tile_manager_->AreTilesRequiredForActivationReady()) { 1475 ActivatePendingTree(); 1476 return; 1477 } 1478 1479 // Manage tiles in case state affecting tile priority has changed. 1480 ManageTiles(); 1481 1482 TRACE_EVENT_ASYNC_STEP1( 1483 "cc", 1484 "PendingTree", pending_tree_.get(), "activate", 1485 "state", TracedValue::FromValue(ActivationStateAsValue().release())); 1486 } 1487 1488 void LayerTreeHostImpl::ActivatePendingTree() { 1489 CHECK(pending_tree_); 1490 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get()); 1491 1492 active_tree_->SetRootLayerScrollOffsetDelegate(NULL); 1493 active_tree_->PushPersistedState(pending_tree_.get()); 1494 if (pending_tree_->needs_full_tree_sync()) { 1495 active_tree_->SetRootLayer( 1496 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(), 1497 active_tree_->DetachLayerTree(), 1498 active_tree_.get())); 1499 } 1500 TreeSynchronizer::PushProperties(pending_tree_->root_layer(), 1501 active_tree_->root_layer()); 1502 DCHECK(!recycle_tree_); 1503 1504 // Process any requests in the UI resource queue. The request queue is given 1505 // in LayerTreeHost::FinishCommitOnImplThread. This must take place before 1506 // the swap. 1507 pending_tree_->ProcessUIResourceRequestQueue(); 1508 1509 pending_tree_->PushPropertiesTo(active_tree_.get()); 1510 1511 // Now that we've synced everything from the pending tree to the active 1512 // tree, rename the pending tree the recycle tree so we can reuse it on the 1513 // next sync. 1514 pending_tree_.swap(recycle_tree_); 1515 1516 active_tree_->DidBecomeActive(); 1517 active_tree_->SetRootLayerScrollOffsetDelegate( 1518 root_layer_scroll_offset_delegate_); 1519 1520 // Reduce wasted memory now that unlinked resources are guaranteed not 1521 // to be used. 1522 client_->ReduceWastedContentsTextureMemoryOnImplThread(); 1523 1524 client_->OnCanDrawStateChanged(CanDraw()); 1525 client_->OnHasPendingTreeStateChanged(pending_tree_); 1526 client_->SetNeedsRedrawOnImplThread(); 1527 client_->RenewTreePriority(); 1528 1529 if (debug_state_.continuous_painting) { 1530 const RenderingStats& stats = 1531 rendering_stats_instrumentation_->GetRenderingStats(); 1532 paint_time_counter_->SavePaintTime( 1533 stats.total_paint_time + stats.total_record_time + 1534 stats.total_rasterize_time_for_now_bins_on_pending_tree); 1535 } 1536 1537 client_->DidActivatePendingTree(); 1538 if (!tree_activation_callback_.is_null()) 1539 tree_activation_callback_.Run(); 1540 } 1541 1542 void LayerTreeHostImpl::SetVisible(bool visible) { 1543 DCHECK(proxy_->IsImplThread()); 1544 1545 if (visible_ == visible) 1546 return; 1547 visible_ = visible; 1548 DidVisibilityChange(this, visible_); 1549 EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy()); 1550 1551 // Evict tiles immediately if invisible since this tab may never get another 1552 // draw or timer tick. 1553 if (!visible_) 1554 ManageTiles(); 1555 1556 if (!renderer_) 1557 return; 1558 1559 renderer_->SetVisible(visible); 1560 } 1561 1562 ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const { 1563 ManagedMemoryPolicy actual = cached_managed_memory_policy_; 1564 if (debug_state_.rasterize_only_visible_content) { 1565 actual.priority_cutoff_when_not_visible = 1566 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; 1567 actual.priority_cutoff_when_visible = 1568 ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY; 1569 } 1570 1571 if (zero_budget_) { 1572 actual.bytes_limit_when_visible = 0; 1573 actual.bytes_limit_when_not_visible = 0; 1574 } 1575 1576 return actual; 1577 } 1578 1579 size_t LayerTreeHostImpl::memory_allocation_limit_bytes() const { 1580 return ActualManagedMemoryPolicy().bytes_limit_when_visible; 1581 } 1582 1583 void LayerTreeHostImpl::ReleaseTreeResources() { 1584 if (active_tree_->root_layer()) 1585 SendReleaseResourcesRecursive(active_tree_->root_layer()); 1586 if (pending_tree_ && pending_tree_->root_layer()) 1587 SendReleaseResourcesRecursive(pending_tree_->root_layer()); 1588 if (recycle_tree_ && recycle_tree_->root_layer()) 1589 SendReleaseResourcesRecursive(recycle_tree_->root_layer()); 1590 1591 // Remove all existing maps from UIResourceId to ResourceId. 1592 ui_resource_map_.clear(); 1593 } 1594 1595 void LayerTreeHostImpl::CreateAndSetRenderer( 1596 OutputSurface* output_surface, 1597 ResourceProvider* resource_provider, 1598 bool skip_gl_renderer) { 1599 DCHECK(!renderer_); 1600 if (output_surface->capabilities().delegated_rendering) { 1601 renderer_ = 1602 DelegatingRenderer::Create(this, output_surface, resource_provider); 1603 } else if (output_surface->context3d() && !skip_gl_renderer) { 1604 renderer_ = GLRenderer::Create(this, 1605 output_surface, 1606 resource_provider, 1607 settings_.highp_threshold_min, 1608 settings_.force_direct_layer_drawing); 1609 } else if (output_surface->software_device()) { 1610 renderer_ = 1611 SoftwareRenderer::Create(this, output_surface, resource_provider); 1612 } 1613 1614 if (renderer_) { 1615 renderer_->SetVisible(visible_); 1616 SetFullRootLayerDamage(); 1617 1618 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs to be 1619 // initialized to get max texture size. Also, after releasing resources, 1620 // trees need another update to generate new ones. 1621 active_tree_->set_needs_update_draw_properties(); 1622 if (pending_tree_) 1623 pending_tree_->set_needs_update_draw_properties(); 1624 } 1625 } 1626 1627 void LayerTreeHostImpl::CreateAndSetTileManager( 1628 ResourceProvider* resource_provider, 1629 bool using_map_image) { 1630 DCHECK(settings_.impl_side_painting); 1631 DCHECK(resource_provider); 1632 tile_manager_ = TileManager::Create(this, 1633 resource_provider, 1634 settings_.num_raster_threads, 1635 rendering_stats_instrumentation_, 1636 using_map_image); 1637 UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); 1638 need_to_update_visible_tiles_before_draw_ = false; 1639 } 1640 1641 void LayerTreeHostImpl::EnforceZeroBudget(bool zero_budget) { 1642 SetManagedMemoryPolicy(cached_managed_memory_policy_, zero_budget); 1643 } 1644 1645 bool LayerTreeHostImpl::InitializeRenderer( 1646 scoped_ptr<OutputSurface> output_surface) { 1647 // Since we will create a new resource provider, we cannot continue to use 1648 // the old resources (i.e. render_surfaces and texture IDs). Clear them 1649 // before we destroy the old resource provider. 1650 ReleaseTreeResources(); 1651 if (resource_provider_) 1652 resource_provider_->DidLoseOutputSurface(); 1653 1654 // Note: order is important here. 1655 renderer_.reset(); 1656 tile_manager_.reset(); 1657 resource_provider_.reset(); 1658 output_surface_.reset(); 1659 1660 if (!output_surface->BindToClient(this)) 1661 return false; 1662 1663 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( 1664 output_surface.get(), settings_.highp_threshold_min); 1665 if (!resource_provider) 1666 return false; 1667 1668 if (output_surface->capabilities().deferred_gl_initialization) 1669 EnforceZeroBudget(true); 1670 1671 bool skip_gl_renderer = false; 1672 CreateAndSetRenderer( 1673 output_surface.get(), resource_provider.get(), skip_gl_renderer); 1674 1675 if (!renderer_) 1676 return false; 1677 1678 if (settings_.impl_side_painting) { 1679 CreateAndSetTileManager(resource_provider.get(), 1680 GetRendererCapabilities().using_map_image); 1681 } 1682 1683 // Setup BeginFrameEmulation if it's not supported natively 1684 if (!settings_.begin_frame_scheduling_enabled) { 1685 const base::TimeDelta display_refresh_interval = 1686 base::TimeDelta::FromMicroseconds( 1687 base::Time::kMicrosecondsPerSecond / 1688 settings_.refresh_rate); 1689 1690 output_surface->InitializeBeginFrameEmulation( 1691 proxy_->ImplThreadTaskRunner(), 1692 settings_.throttle_frame_production, 1693 display_refresh_interval); 1694 } 1695 1696 int max_frames_pending = 1697 output_surface->capabilities().max_frames_pending; 1698 if (max_frames_pending <= 0) 1699 max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING; 1700 output_surface->SetMaxFramesPending(max_frames_pending); 1701 1702 resource_provider_ = resource_provider.Pass(); 1703 output_surface_ = output_surface.Pass(); 1704 1705 client_->OnCanDrawStateChanged(CanDraw()); 1706 1707 return true; 1708 } 1709 1710 bool LayerTreeHostImpl::DeferredInitialize( 1711 scoped_refptr<ContextProvider> offscreen_context_provider) { 1712 DCHECK(output_surface_->capabilities().deferred_gl_initialization); 1713 DCHECK(settings_.impl_side_painting); 1714 DCHECK(settings_.solid_color_scrollbars); 1715 DCHECK(output_surface_->context3d()); 1716 1717 ReleaseTreeResources(); 1718 renderer_.reset(); 1719 resource_provider_->InitializeGL(); 1720 bool skip_gl_renderer = false; 1721 CreateAndSetRenderer( 1722 output_surface_.get(), resource_provider_.get(), skip_gl_renderer); 1723 1724 bool success = !!renderer_.get(); 1725 client_->DidTryInitializeRendererOnImplThread(success, 1726 offscreen_context_provider); 1727 if (success) { 1728 EnforceZeroBudget(false); 1729 client_->SetNeedsCommitOnImplThread(); 1730 } 1731 return success; 1732 } 1733 1734 void LayerTreeHostImpl::ReleaseGL() { 1735 DCHECK(output_surface_->capabilities().deferred_gl_initialization); 1736 DCHECK(settings_.impl_side_painting); 1737 DCHECK(settings_.solid_color_scrollbars); 1738 DCHECK(output_surface_->context3d()); 1739 1740 ReleaseTreeResources(); 1741 renderer_.reset(); 1742 tile_manager_.reset(); 1743 resource_provider_->InitializeSoftware(); 1744 1745 bool skip_gl_renderer = true; 1746 CreateAndSetRenderer( 1747 output_surface_.get(), resource_provider_.get(), skip_gl_renderer); 1748 DCHECK(renderer_); 1749 1750 EnforceZeroBudget(true); 1751 CreateAndSetTileManager(resource_provider_.get(), 1752 GetRendererCapabilities().using_map_image); 1753 DCHECK(tile_manager_); 1754 1755 bool success = true; 1756 client_->DidTryInitializeRendererOnImplThread( 1757 success, scoped_refptr<ContextProvider>()); 1758 client_->SetNeedsCommitOnImplThread(); 1759 } 1760 1761 void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) { 1762 if (device_viewport_size == device_viewport_size_) 1763 return; 1764 1765 if (pending_tree_ && device_viewport_size_ != device_viewport_size) 1766 active_tree_->SetViewportSizeInvalid(); 1767 1768 device_viewport_size_ = device_viewport_size; 1769 1770 UpdateMaxScrollOffset(); 1771 1772 if (renderer_) 1773 renderer_->ViewportChanged(); 1774 1775 client_->OnCanDrawStateChanged(CanDraw()); 1776 SetFullRootLayerDamage(); 1777 } 1778 1779 void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) { 1780 if (overdraw_bottom_height == overdraw_bottom_height_) 1781 return; 1782 overdraw_bottom_height_ = overdraw_bottom_height; 1783 1784 UpdateMaxScrollOffset(); 1785 SetFullRootLayerDamage(); 1786 } 1787 1788 void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { 1789 if (device_scale_factor == device_scale_factor_) 1790 return; 1791 device_scale_factor_ = device_scale_factor; 1792 1793 if (renderer_) 1794 renderer_->ViewportChanged(); 1795 1796 UpdateMaxScrollOffset(); 1797 SetFullRootLayerDamage(); 1798 } 1799 1800 gfx::Rect LayerTreeHostImpl::DeviceViewport() const { 1801 if (external_viewport_.IsEmpty()) 1802 return gfx::Rect(device_viewport_size_); 1803 1804 return external_viewport_; 1805 } 1806 1807 gfx::Rect LayerTreeHostImpl::DeviceClip() const { 1808 return external_clip_; 1809 } 1810 1811 const gfx::Transform& LayerTreeHostImpl::DeviceTransform() const { 1812 return external_transform_; 1813 } 1814 1815 void LayerTreeHostImpl::UpdateMaxScrollOffset() { 1816 active_tree_->UpdateMaxScrollOffset(); 1817 } 1818 1819 void LayerTreeHostImpl::DidChangeTopControlsPosition() { 1820 client_->SetNeedsRedrawOnImplThread(); 1821 active_tree_->set_needs_update_draw_properties(); 1822 SetFullRootLayerDamage(); 1823 } 1824 1825 bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() { 1826 active_tree_->UpdateDrawProperties(); 1827 return !active_tree_->RenderSurfaceLayerList().empty(); 1828 } 1829 1830 void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { 1831 DCHECK(input_handler_client_ == NULL); 1832 input_handler_client_ = client; 1833 } 1834 1835 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( 1836 gfx::Point viewport_point, InputHandler::ScrollInputType type) { 1837 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); 1838 1839 if (top_controls_manager_) 1840 top_controls_manager_->ScrollBegin(); 1841 1842 DCHECK(!CurrentlyScrollingLayer()); 1843 ClearCurrentlyScrollingLayer(); 1844 1845 if (!EnsureRenderSurfaceLayerList()) 1846 return ScrollIgnored; 1847 1848 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, 1849 device_scale_factor_); 1850 1851 // First find out which layer was hit from the saved list of visible layers 1852 // in the most recent frame. 1853 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 1854 device_viewport_point, active_tree_->RenderSurfaceLayerList()); 1855 1856 // Walk up the hierarchy and look for a scrollable layer. 1857 LayerImpl* potentially_scrolling_layer_impl = 0; 1858 for (; layer_impl; layer_impl = layer_impl->parent()) { 1859 // The content layer can also block attempts to scroll outside the main 1860 // thread. 1861 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); 1862 if (status == ScrollOnMainThread) { 1863 rendering_stats_instrumentation_->IncrementMainThreadScrolls(); 1864 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); 1865 return ScrollOnMainThread; 1866 } 1867 1868 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl); 1869 if (!scroll_layer_impl) 1870 continue; 1871 1872 status = scroll_layer_impl->TryScroll(device_viewport_point, type); 1873 1874 // If any layer wants to divert the scroll event to the main thread, abort. 1875 if (status == ScrollOnMainThread) { 1876 rendering_stats_instrumentation_->IncrementMainThreadScrolls(); 1877 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); 1878 return ScrollOnMainThread; 1879 } 1880 1881 if (status == ScrollStarted && !potentially_scrolling_layer_impl) 1882 potentially_scrolling_layer_impl = scroll_layer_impl; 1883 } 1884 1885 // When hiding top controls is enabled and the controls are hidden or 1886 // overlaying the content, force scrolls to be enabled on the root layer to 1887 // allow bringing the top controls back into view. 1888 if (!potentially_scrolling_layer_impl && top_controls_manager_ && 1889 top_controls_manager_->content_top_offset() != 1890 settings_.top_controls_height) { 1891 potentially_scrolling_layer_impl = RootScrollLayer(); 1892 } 1893 1894 // If we want to send a DidOverscroll for this scroll it can't be ignored. 1895 if (!potentially_scrolling_layer_impl && settings_.always_overscroll) 1896 potentially_scrolling_layer_impl = RootScrollLayer(); 1897 1898 if (potentially_scrolling_layer_impl) { 1899 active_tree_->SetCurrentlyScrollingLayer( 1900 potentially_scrolling_layer_impl); 1901 should_bubble_scrolls_ = (type != NonBubblingGesture); 1902 wheel_scrolling_ = (type == Wheel); 1903 rendering_stats_instrumentation_->IncrementImplThreadScrolls(); 1904 client_->RenewTreePriority(); 1905 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); 1906 return ScrollStarted; 1907 } 1908 return ScrollIgnored; 1909 } 1910 1911 gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta( 1912 LayerImpl* layer_impl, 1913 float scale_from_viewport_to_screen_space, 1914 gfx::PointF viewport_point, 1915 gfx::Vector2dF viewport_delta) { 1916 // Layers with non-invertible screen space transforms should not have passed 1917 // the scroll hit test in the first place. 1918 DCHECK(layer_impl->screen_space_transform().IsInvertible()); 1919 gfx::Transform inverse_screen_space_transform( 1920 gfx::Transform::kSkipInitialization); 1921 bool did_invert = layer_impl->screen_space_transform().GetInverse( 1922 &inverse_screen_space_transform); 1923 // TODO(shawnsingh): With the advent of impl-side crolling for non-root 1924 // layers, we may need to explicitly handle uninvertible transforms here. 1925 DCHECK(did_invert); 1926 1927 gfx::PointF screen_space_point = 1928 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space); 1929 1930 gfx::Vector2dF screen_space_delta = viewport_delta; 1931 screen_space_delta.Scale(scale_from_viewport_to_screen_space); 1932 1933 // First project the scroll start and end points to local layer space to find 1934 // the scroll delta in layer coordinates. 1935 bool start_clipped, end_clipped; 1936 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta; 1937 gfx::PointF local_start_point = 1938 MathUtil::ProjectPoint(inverse_screen_space_transform, 1939 screen_space_point, 1940 &start_clipped); 1941 gfx::PointF local_end_point = 1942 MathUtil::ProjectPoint(inverse_screen_space_transform, 1943 screen_space_end_point, 1944 &end_clipped); 1945 1946 // In general scroll point coordinates should not get clipped. 1947 DCHECK(!start_clipped); 1948 DCHECK(!end_clipped); 1949 if (start_clipped || end_clipped) 1950 return gfx::Vector2dF(); 1951 1952 // local_start_point and local_end_point are in content space but we want to 1953 // move them to layer space for scrolling. 1954 float width_scale = 1.f / layer_impl->contents_scale_x(); 1955 float height_scale = 1.f / layer_impl->contents_scale_y(); 1956 local_start_point.Scale(width_scale, height_scale); 1957 local_end_point.Scale(width_scale, height_scale); 1958 1959 // Apply the scroll delta. 1960 gfx::Vector2dF previous_delta = layer_impl->ScrollDelta(); 1961 layer_impl->ScrollBy(local_end_point - local_start_point); 1962 1963 // Get the end point in the layer's content space so we can apply its 1964 // ScreenSpaceTransform. 1965 gfx::PointF actual_local_end_point = local_start_point + 1966 layer_impl->ScrollDelta() - 1967 previous_delta; 1968 gfx::PointF actual_local_content_end_point = 1969 gfx::ScalePoint(actual_local_end_point, 1970 1.f / width_scale, 1971 1.f / height_scale); 1972 1973 // Calculate the applied scroll delta in viewport space coordinates. 1974 gfx::PointF actual_screen_space_end_point = 1975 MathUtil::MapPoint(layer_impl->screen_space_transform(), 1976 actual_local_content_end_point, 1977 &end_clipped); 1978 DCHECK(!end_clipped); 1979 if (end_clipped) 1980 return gfx::Vector2dF(); 1981 gfx::PointF actual_viewport_end_point = 1982 gfx::ScalePoint(actual_screen_space_end_point, 1983 1.f / scale_from_viewport_to_screen_space); 1984 return actual_viewport_end_point - viewport_point; 1985 } 1986 1987 static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, 1988 gfx::Vector2dF local_delta) { 1989 gfx::Vector2dF previous_delta(layer_impl->ScrollDelta()); 1990 layer_impl->ScrollBy(local_delta); 1991 return layer_impl->ScrollDelta() - previous_delta; 1992 } 1993 1994 bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, 1995 gfx::Vector2dF scroll_delta) { 1996 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); 1997 if (!CurrentlyScrollingLayer()) 1998 return false; 1999 2000 gfx::Vector2dF pending_delta = scroll_delta; 2001 gfx::Vector2dF unused_root_delta; 2002 bool did_scroll_x = false; 2003 bool did_scroll_y = false; 2004 bool consume_by_top_controls = top_controls_manager_ && 2005 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0); 2006 2007 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); 2008 layer_impl; 2009 layer_impl = layer_impl->parent()) { 2010 if (!layer_impl->scrollable()) 2011 continue; 2012 2013 if (layer_impl == RootScrollLayer()) { 2014 // Only allow bubble scrolling when the scroll is in the direction to make 2015 // the top controls visible. 2016 if (consume_by_top_controls && layer_impl == RootScrollLayer()) { 2017 pending_delta = top_controls_manager_->ScrollBy(pending_delta); 2018 UpdateMaxScrollOffset(); 2019 } 2020 // Track root layer deltas for reporting overscroll. 2021 unused_root_delta = pending_delta; 2022 } 2023 2024 gfx::Vector2dF applied_delta; 2025 // Gesture events need to be transformed from viewport coordinates to local 2026 // layer coordinates so that the scrolling contents exactly follow the 2027 // user's finger. In contrast, wheel events represent a fixed amount of 2028 // scrolling so we can just apply them directly. 2029 if (!wheel_scrolling_) { 2030 float scale_from_viewport_to_screen_space = device_scale_factor_; 2031 applied_delta = 2032 ScrollLayerWithViewportSpaceDelta(layer_impl, 2033 scale_from_viewport_to_screen_space, 2034 viewport_point, pending_delta); 2035 } else { 2036 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta); 2037 } 2038 2039 // If the layer wasn't able to move, try the next one in the hierarchy. 2040 float move_threshold = 0.1f; 2041 bool did_move_layer_x = std::abs(applied_delta.x()) > move_threshold; 2042 bool did_move_layer_y = std::abs(applied_delta.y()) > move_threshold; 2043 did_scroll_x |= did_move_layer_x; 2044 did_scroll_y |= did_move_layer_y; 2045 if (!did_move_layer_x && !did_move_layer_y) { 2046 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_) 2047 continue; 2048 else 2049 break; 2050 } 2051 2052 if (layer_impl == RootScrollLayer()) 2053 unused_root_delta.Subtract(applied_delta); 2054 2055 did_lock_scrolling_layer_ = true; 2056 if (!should_bubble_scrolls_) { 2057 active_tree_->SetCurrentlyScrollingLayer(layer_impl); 2058 break; 2059 } 2060 2061 // If the applied delta is within 45 degrees of the input delta, bail out to 2062 // make it easier to scroll just one layer in one direction without 2063 // affecting any of its parents. 2064 float angle_threshold = 45; 2065 if (MathUtil::SmallestAngleBetweenVectors( 2066 applied_delta, pending_delta) < angle_threshold) { 2067 pending_delta = gfx::Vector2d(); 2068 break; 2069 } 2070 2071 // Allow further movement only on an axis perpendicular to the direction in 2072 // which the layer moved. 2073 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x()); 2074 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis); 2075 2076 if (gfx::ToRoundedVector2d(pending_delta).IsZero()) 2077 break; 2078 } 2079 2080 bool did_scroll = did_scroll_x || did_scroll_y; 2081 if (did_scroll) { 2082 client_->SetNeedsCommitOnImplThread(); 2083 client_->SetNeedsRedrawOnImplThread(); 2084 client_->RenewTreePriority(); 2085 } 2086 2087 // Scrolling along an axis resets accumulated root overscroll for that axis. 2088 if (did_scroll_x) 2089 accumulated_root_overscroll_.set_x(0); 2090 if (did_scroll_y) 2091 accumulated_root_overscroll_.set_y(0); 2092 2093 accumulated_root_overscroll_ += unused_root_delta; 2094 bool did_overscroll = !gfx::ToRoundedVector2d(unused_root_delta).IsZero(); 2095 if (did_overscroll && input_handler_client_) { 2096 DidOverscrollParams params; 2097 params.accumulated_overscroll = accumulated_root_overscroll_; 2098 params.latest_overscroll_delta = unused_root_delta; 2099 params.current_fling_velocity = current_fling_velocity_; 2100 input_handler_client_->DidOverscroll(params); 2101 } 2102 2103 return did_scroll; 2104 } 2105 2106 // This implements scrolling by page as described here: 2107 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel 2108 // for events with WHEEL_PAGESCROLL set. 2109 bool LayerTreeHostImpl::ScrollVerticallyByPage(gfx::Point viewport_point, 2110 ScrollDirection direction) { 2111 DCHECK(wheel_scrolling_); 2112 2113 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); 2114 layer_impl; 2115 layer_impl = layer_impl->parent()) { 2116 if (!layer_impl->scrollable()) 2117 continue; 2118 2119 if (!layer_impl->vertical_scrollbar_layer()) 2120 continue; 2121 2122 float height = layer_impl->vertical_scrollbar_layer()->bounds().height(); 2123 2124 // These magical values match WebKit and are designed to scroll nearly the 2125 // entire visible content height but leave a bit of overlap. 2126 float page = std::max(height * 0.875f, 1.f); 2127 if (direction == SCROLL_BACKWARD) 2128 page = -page; 2129 2130 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page); 2131 2132 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta); 2133 2134 if (!applied_delta.IsZero()) { 2135 client_->SetNeedsCommitOnImplThread(); 2136 client_->SetNeedsRedrawOnImplThread(); 2137 client_->RenewTreePriority(); 2138 return true; 2139 } 2140 2141 active_tree_->SetCurrentlyScrollingLayer(layer_impl); 2142 } 2143 2144 return false; 2145 } 2146 2147 void LayerTreeHostImpl::SetRootLayerScrollOffsetDelegate( 2148 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) { 2149 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate; 2150 active_tree_->SetRootLayerScrollOffsetDelegate( 2151 root_layer_scroll_offset_delegate_); 2152 } 2153 2154 void LayerTreeHostImpl::OnRootLayerDelegatedScrollOffsetChanged() { 2155 DCHECK(root_layer_scroll_offset_delegate_ != NULL); 2156 client_->SetNeedsCommitOnImplThread(); 2157 } 2158 2159 void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { 2160 active_tree_->ClearCurrentlyScrollingLayer(); 2161 did_lock_scrolling_layer_ = false; 2162 accumulated_root_overscroll_ = gfx::Vector2dF(); 2163 current_fling_velocity_ = gfx::Vector2dF(); 2164 } 2165 2166 void LayerTreeHostImpl::ScrollEnd() { 2167 if (top_controls_manager_) 2168 top_controls_manager_->ScrollEnd(); 2169 ClearCurrentlyScrollingLayer(); 2170 StartScrollbarAnimation(); 2171 } 2172 2173 InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { 2174 if (!active_tree_->CurrentlyScrollingLayer()) 2175 return ScrollIgnored; 2176 2177 if (settings_.ignore_root_layer_flings && 2178 active_tree_->CurrentlyScrollingLayer() == 2179 active_tree_->RootScrollLayer()) { 2180 ClearCurrentlyScrollingLayer(); 2181 return ScrollIgnored; 2182 } 2183 2184 return ScrollStarted; 2185 } 2186 2187 void LayerTreeHostImpl::NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) { 2188 current_fling_velocity_ = velocity; 2189 } 2190 2191 void LayerTreeHostImpl::PinchGestureBegin() { 2192 pinch_gesture_active_ = true; 2193 previous_pinch_anchor_ = gfx::Point(); 2194 client_->RenewTreePriority(); 2195 active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer()); 2196 } 2197 2198 void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, 2199 gfx::Point anchor) { 2200 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate"); 2201 2202 if (!RootScrollLayer()) 2203 return; 2204 2205 // Keep the center-of-pinch anchor specified by (x, y) in a stable 2206 // position over the course of the magnify. 2207 float page_scale_delta = active_tree_->page_scale_delta(); 2208 gfx::PointF previous_scale_anchor = 2209 gfx::ScalePoint(anchor, 1.f / page_scale_delta); 2210 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta); 2211 page_scale_delta = active_tree_->page_scale_delta(); 2212 gfx::PointF new_scale_anchor = 2213 gfx::ScalePoint(anchor, 1.f / page_scale_delta); 2214 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor; 2215 2216 previous_pinch_anchor_ = anchor; 2217 2218 move.Scale(1 / active_tree_->page_scale_factor()); 2219 2220 RootScrollLayer()->ScrollBy(move); 2221 2222 client_->SetNeedsCommitOnImplThread(); 2223 client_->SetNeedsRedrawOnImplThread(); 2224 client_->RenewTreePriority(); 2225 } 2226 2227 void LayerTreeHostImpl::PinchGestureEnd() { 2228 pinch_gesture_active_ = false; 2229 client_->SetNeedsCommitOnImplThread(); 2230 } 2231 2232 static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, 2233 LayerImpl* layer_impl) { 2234 if (!layer_impl) 2235 return; 2236 2237 gfx::Vector2d scroll_delta = 2238 gfx::ToFlooredVector2d(layer_impl->ScrollDelta()); 2239 if (!scroll_delta.IsZero()) { 2240 LayerTreeHostCommon::ScrollUpdateInfo scroll; 2241 scroll.layer_id = layer_impl->id(); 2242 scroll.scroll_delta = scroll_delta; 2243 scroll_info->scrolls.push_back(scroll); 2244 layer_impl->SetSentScrollDelta(scroll_delta); 2245 } 2246 2247 for (size_t i = 0; i < layer_impl->children().size(); ++i) 2248 CollectScrollDeltas(scroll_info, layer_impl->children()[i]); 2249 } 2250 2251 scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { 2252 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); 2253 2254 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); 2255 scroll_info->page_scale_delta = active_tree_->page_scale_delta(); 2256 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta); 2257 2258 return scroll_info.Pass(); 2259 } 2260 2261 void LayerTreeHostImpl::SetFullRootLayerDamage() { 2262 SetViewportDamage(gfx::Rect(DeviceViewport().size())); 2263 } 2264 2265 void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { 2266 if (!page_scale_animation_ || !RootScrollLayer()) 2267 return; 2268 2269 double monotonic_time = (time - base::TimeTicks()).InSecondsF(); 2270 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() + 2271 RootScrollLayer()->ScrollDelta(); 2272 2273 active_tree_->SetPageScaleDelta( 2274 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) / 2275 active_tree_->page_scale_factor()); 2276 gfx::Vector2dF next_scroll = 2277 page_scale_animation_->ScrollOffsetAtTime(monotonic_time); 2278 2279 RootScrollLayer()->ScrollBy(next_scroll - scroll_total); 2280 client_->SetNeedsRedrawOnImplThread(); 2281 2282 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { 2283 page_scale_animation_.reset(); 2284 client_->SetNeedsCommitOnImplThread(); 2285 client_->RenewTreePriority(); 2286 } 2287 } 2288 2289 void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { 2290 if (!top_controls_manager_ || !RootScrollLayer()) 2291 return; 2292 gfx::Vector2dF scroll = top_controls_manager_->Animate(time); 2293 UpdateMaxScrollOffset(); 2294 if (RootScrollLayer()->TotalScrollOffset().y() == 0.f) 2295 return; 2296 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d( 2297 scroll, 1.f / active_tree_->total_page_scale_factor())); 2298 } 2299 2300 void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, 2301 base::Time wall_clock_time) { 2302 if (!settings_.accelerated_animation_enabled || 2303 animation_registrar_->active_animation_controllers().empty() || 2304 !active_tree_->root_layer()) 2305 return; 2306 2307 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers"); 2308 2309 last_animation_time_ = wall_clock_time; 2310 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF(); 2311 2312 AnimationRegistrar::AnimationControllerMap copy = 2313 animation_registrar_->active_animation_controllers(); 2314 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 2315 iter != copy.end(); 2316 ++iter) 2317 (*iter).second->Animate(monotonic_seconds); 2318 2319 client_->SetNeedsRedrawOnImplThread(); 2320 } 2321 2322 void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { 2323 if (!settings_.accelerated_animation_enabled || 2324 animation_registrar_->active_animation_controllers().empty() || 2325 !active_tree_->root_layer()) 2326 return; 2327 2328 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState"); 2329 scoped_ptr<AnimationEventsVector> events = 2330 make_scoped_ptr(new AnimationEventsVector); 2331 AnimationRegistrar::AnimationControllerMap copy = 2332 animation_registrar_->active_animation_controllers(); 2333 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 2334 iter != copy.end(); 2335 ++iter) 2336 (*iter).second->UpdateState(start_ready_animations, events.get()); 2337 2338 if (!events->empty()) { 2339 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(), 2340 last_animation_time_); 2341 } 2342 } 2343 2344 base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const { 2345 return base::TimeDelta::FromSeconds(1); 2346 } 2347 2348 void LayerTreeHostImpl::SendReleaseResourcesRecursive(LayerImpl* current) { 2349 DCHECK(current); 2350 // TODO(boliu): Rename DidLoseOutputSurface to ReleaseResources. 2351 current->DidLoseOutputSurface(); 2352 if (current->mask_layer()) 2353 SendReleaseResourcesRecursive(current->mask_layer()); 2354 if (current->replica_layer()) 2355 SendReleaseResourcesRecursive(current->replica_layer()); 2356 for (size_t i = 0; i < current->children().size(); ++i) 2357 SendReleaseResourcesRecursive(current->children()[i]); 2358 } 2359 2360 std::string LayerTreeHostImpl::LayerTreeAsJson() const { 2361 std::string str; 2362 if (active_tree_->root_layer()) { 2363 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson()); 2364 base::JSONWriter::WriteWithOptions( 2365 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str); 2366 } 2367 return str; 2368 } 2369 2370 int LayerTreeHostImpl::SourceAnimationFrameNumber() const { 2371 return fps_counter_->current_frame_number(); 2372 } 2373 2374 void LayerTreeHostImpl::SendManagedMemoryStats( 2375 size_t memory_visible_bytes, 2376 size_t memory_visible_and_nearby_bytes, 2377 size_t memory_use_bytes) { 2378 if (!renderer_) 2379 return; 2380 2381 // Round the numbers being sent up to the next 8MB, to throttle the rate 2382 // at which we spam the GPU process. 2383 static const size_t rounding_step = 8 * 1024 * 1024; 2384 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step); 2385 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes, 2386 rounding_step); 2387 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step); 2388 if (last_sent_memory_visible_bytes_ == memory_visible_bytes && 2389 last_sent_memory_visible_and_nearby_bytes_ == 2390 memory_visible_and_nearby_bytes && 2391 last_sent_memory_use_bytes_ == memory_use_bytes) { 2392 return; 2393 } 2394 last_sent_memory_visible_bytes_ = memory_visible_bytes; 2395 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes; 2396 last_sent_memory_use_bytes_ = memory_use_bytes; 2397 2398 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_, 2399 last_sent_memory_visible_and_nearby_bytes_, 2400 last_sent_memory_use_bytes_); 2401 } 2402 2403 void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) { 2404 AnimateScrollbarsRecursive(active_tree_->root_layer(), time); 2405 } 2406 2407 void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer, 2408 base::TimeTicks time) { 2409 if (!layer) 2410 return; 2411 2412 ScrollbarAnimationController* scrollbar_controller = 2413 layer->scrollbar_animation_controller(); 2414 if (scrollbar_controller && scrollbar_controller->Animate(time)) { 2415 TRACE_EVENT_INSTANT0( 2416 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars", 2417 TRACE_EVENT_SCOPE_THREAD); 2418 client_->SetNeedsRedrawOnImplThread(); 2419 } 2420 2421 for (size_t i = 0; i < layer->children().size(); ++i) 2422 AnimateScrollbarsRecursive(layer->children()[i], time); 2423 } 2424 2425 void LayerTreeHostImpl::StartScrollbarAnimation() { 2426 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation"); 2427 StartScrollbarAnimationRecursive(RootLayer(), CurrentPhysicalTimeTicks()); 2428 } 2429 2430 void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer, 2431 base::TimeTicks time) { 2432 if (!layer) 2433 return; 2434 2435 ScrollbarAnimationController* scrollbar_controller = 2436 layer->scrollbar_animation_controller(); 2437 if (scrollbar_controller && scrollbar_controller->IsAnimating()) { 2438 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time); 2439 if (delay > base::TimeDelta()) 2440 client_->RequestScrollbarAnimationOnImplThread(delay); 2441 else if (scrollbar_controller->Animate(time)) 2442 client_->SetNeedsRedrawOnImplThread(); 2443 } 2444 2445 for (size_t i = 0; i < layer->children().size(); ++i) 2446 StartScrollbarAnimationRecursive(layer->children()[i], time); 2447 } 2448 2449 void LayerTreeHostImpl::SetTreePriority(TreePriority priority) { 2450 if (!tile_manager_) 2451 return; 2452 2453 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState()); 2454 if (new_state.tree_priority == priority) 2455 return; 2456 2457 new_state.tree_priority = priority; 2458 tile_manager_->SetGlobalState(new_state); 2459 manage_tiles_needed_ = true; 2460 } 2461 2462 void LayerTreeHostImpl::ResetCurrentFrameTimeForNextFrame() { 2463 current_frame_timeticks_ = base::TimeTicks(); 2464 current_frame_time_ = base::Time(); 2465 } 2466 2467 void LayerTreeHostImpl::UpdateCurrentFrameTime(base::TimeTicks* ticks, 2468 base::Time* now) const { 2469 if (ticks->is_null()) { 2470 DCHECK(now->is_null()); 2471 *ticks = CurrentPhysicalTimeTicks(); 2472 *now = base::Time::Now(); 2473 } 2474 } 2475 2476 base::TimeTicks LayerTreeHostImpl::CurrentFrameTimeTicks() { 2477 UpdateCurrentFrameTime(¤t_frame_timeticks_, ¤t_frame_time_); 2478 return current_frame_timeticks_; 2479 } 2480 2481 base::Time LayerTreeHostImpl::CurrentFrameTime() { 2482 UpdateCurrentFrameTime(¤t_frame_timeticks_, ¤t_frame_time_); 2483 return current_frame_time_; 2484 } 2485 2486 base::TimeTicks LayerTreeHostImpl::CurrentPhysicalTimeTicks() const { 2487 return base::TimeTicks::Now(); 2488 } 2489 2490 scoped_ptr<base::Value> LayerTreeHostImpl::AsValueWithFrame( 2491 FrameData* frame) const { 2492 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 2493 if (this->pending_tree_) 2494 state->Set("activation_state", ActivationStateAsValue().release()); 2495 state->Set("device_viewport_size", 2496 MathUtil::AsValue(device_viewport_size_).release()); 2497 if (tile_manager_) 2498 state->Set("tiles", tile_manager_->AllTilesAsValue().release()); 2499 state->Set("active_tree", active_tree_->AsValue().release()); 2500 if (pending_tree_) 2501 state->Set("pending_tree", pending_tree_->AsValue().release()); 2502 if (frame) 2503 state->Set("frame", frame->AsValue().release()); 2504 return state.PassAs<base::Value>(); 2505 } 2506 2507 scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const { 2508 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 2509 state->Set("lthi", TracedValue::CreateIDRef(this).release()); 2510 if (tile_manager_) 2511 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release()); 2512 return state.PassAs<base::Value>(); 2513 } 2514 2515 void LayerTreeHostImpl::SetDebugState( 2516 const LayerTreeDebugState& new_debug_state) { 2517 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state)) 2518 return; 2519 if (debug_state_.continuous_painting != new_debug_state.continuous_painting) 2520 paint_time_counter_->ClearHistory(); 2521 2522 debug_state_ = new_debug_state; 2523 SetFullRootLayerDamage(); 2524 } 2525 2526 void LayerTreeHostImpl::CreateUIResource( 2527 UIResourceId uid, 2528 scoped_refptr<UIResourceBitmap> bitmap) { 2529 DCHECK_GT(uid, 0); 2530 DCHECK_EQ(bitmap->GetFormat(), UIResourceBitmap::RGBA8); 2531 2532 // Allow for multiple creation requests with the same UIResourceId. The 2533 // previous resource is simply deleted. 2534 ResourceProvider::ResourceId id = ResourceIdForUIResource(uid); 2535 if (id) 2536 DeleteUIResource(uid); 2537 id = resource_provider_->CreateResource( 2538 bitmap->GetSize(), GL_RGBA, ResourceProvider::TextureUsageAny); 2539 2540 ui_resource_map_[uid] = id; 2541 resource_provider_->SetPixels(id, 2542 reinterpret_cast<uint8_t*>(bitmap->GetPixels()), 2543 gfx::Rect(bitmap->GetSize()), 2544 gfx::Rect(bitmap->GetSize()), 2545 gfx::Vector2d(0, 0)); 2546 } 2547 2548 void LayerTreeHostImpl::DeleteUIResource(UIResourceId uid) { 2549 ResourceProvider::ResourceId id = ResourceIdForUIResource(uid); 2550 if (id) { 2551 resource_provider_->DeleteResource(id); 2552 ui_resource_map_.erase(uid); 2553 } 2554 } 2555 2556 ResourceProvider::ResourceId LayerTreeHostImpl::ResourceIdForUIResource( 2557 UIResourceId uid) const { 2558 UIResourceMap::const_iterator iter = ui_resource_map_.find(uid); 2559 if (iter != ui_resource_map_.end()) 2560 return iter->second; 2561 return 0; 2562 } 2563 2564 } // namespace cc 2565