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 #include <limits> 9 10 #include "base/basictypes.h" 11 #include "base/containers/hash_tables.h" 12 #include "base/debug/trace_event_argument.h" 13 #include "base/json/json_writer.h" 14 #include "base/metrics/histogram.h" 15 #include "base/stl_util.h" 16 #include "base/strings/stringprintf.h" 17 #include "cc/animation/animation_id_provider.h" 18 #include "cc/animation/scroll_offset_animation_curve.h" 19 #include "cc/animation/scrollbar_animation_controller.h" 20 #include "cc/animation/timing_function.h" 21 #include "cc/base/latency_info_swap_promise_monitor.h" 22 #include "cc/base/math_util.h" 23 #include "cc/base/util.h" 24 #include "cc/debug/benchmark_instrumentation.h" 25 #include "cc/debug/debug_rect_history.h" 26 #include "cc/debug/devtools_instrumentation.h" 27 #include "cc/debug/frame_rate_counter.h" 28 #include "cc/debug/paint_time_counter.h" 29 #include "cc/debug/rendering_stats_instrumentation.h" 30 #include "cc/debug/traced_value.h" 31 #include "cc/input/page_scale_animation.h" 32 #include "cc/input/top_controls_manager.h" 33 #include "cc/layers/append_quads_data.h" 34 #include "cc/layers/heads_up_display_layer_impl.h" 35 #include "cc/layers/layer_impl.h" 36 #include "cc/layers/layer_iterator.h" 37 #include "cc/layers/painted_scrollbar_layer_impl.h" 38 #include "cc/layers/render_surface_impl.h" 39 #include "cc/layers/scrollbar_layer_impl_base.h" 40 #include "cc/output/compositor_frame_metadata.h" 41 #include "cc/output/copy_output_request.h" 42 #include "cc/output/delegating_renderer.h" 43 #include "cc/output/gl_renderer.h" 44 #include "cc/output/software_renderer.h" 45 #include "cc/quads/render_pass_draw_quad.h" 46 #include "cc/quads/shared_quad_state.h" 47 #include "cc/quads/solid_color_draw_quad.h" 48 #include "cc/quads/texture_draw_quad.h" 49 #include "cc/resources/bitmap_raster_worker_pool.h" 50 #include "cc/resources/eviction_tile_priority_queue.h" 51 #include "cc/resources/gpu_raster_worker_pool.h" 52 #include "cc/resources/memory_history.h" 53 #include "cc/resources/one_copy_raster_worker_pool.h" 54 #include "cc/resources/picture_layer_tiling.h" 55 #include "cc/resources/pixel_buffer_raster_worker_pool.h" 56 #include "cc/resources/prioritized_resource_manager.h" 57 #include "cc/resources/raster_tile_priority_queue.h" 58 #include "cc/resources/raster_worker_pool.h" 59 #include "cc/resources/resource_pool.h" 60 #include "cc/resources/texture_mailbox_deleter.h" 61 #include "cc/resources/ui_resource_bitmap.h" 62 #include "cc/resources/zero_copy_raster_worker_pool.h" 63 #include "cc/scheduler/delay_based_time_source.h" 64 #include "cc/trees/damage_tracker.h" 65 #include "cc/trees/layer_tree_host.h" 66 #include "cc/trees/layer_tree_host_common.h" 67 #include "cc/trees/layer_tree_impl.h" 68 #include "cc/trees/occlusion_tracker.h" 69 #include "cc/trees/single_thread_proxy.h" 70 #include "cc/trees/tree_synchronizer.h" 71 #include "gpu/command_buffer/client/gles2_interface.h" 72 #include "gpu/GLES2/gl2extchromium.h" 73 #include "ui/gfx/frame_time.h" 74 #include "ui/gfx/geometry/rect_conversions.h" 75 #include "ui/gfx/size_conversions.h" 76 #include "ui/gfx/vector2d_conversions.h" 77 78 namespace cc { 79 namespace { 80 81 void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { 82 if (visible) { 83 TRACE_EVENT_ASYNC_BEGIN1("webkit", 84 "LayerTreeHostImpl::SetVisible", 85 id, 86 "LayerTreeHostImpl", 87 id); 88 return; 89 } 90 91 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id); 92 } 93 94 size_t GetMaxTransferBufferUsageBytes( 95 const ContextProvider::Capabilities& context_capabilities, 96 double refresh_rate) { 97 // We want to make sure the default transfer buffer size is equal to the 98 // amount of data that can be uploaded by the compositor to avoid stalling 99 // the pipeline. 100 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. 101 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; 102 103 // We need to upload at least enough work to keep the GPU process busy until 104 // the next time it can handle a request to start more uploads from the 105 // compositor. We assume that it will pick up any sent upload requests within 106 // the time of a vsync, since the browser will want to swap a frame within 107 // that time interval, and then uploads should have a chance to be processed. 108 size_t ms_per_frame = std::floor(1000.0 / refresh_rate); 109 size_t max_transfer_buffer_usage_bytes = 110 ms_per_frame * kMaxBytesUploadedPerMs; 111 112 // The context may request a lower limit based on the device capabilities. 113 return std::min(context_capabilities.max_transfer_buffer_usage_bytes, 114 max_transfer_buffer_usage_bytes); 115 } 116 117 unsigned GetMapImageTextureTarget( 118 const ContextProvider::Capabilities& context_capabilities) { 119 if (context_capabilities.gpu.egl_image_external) 120 return GL_TEXTURE_EXTERNAL_OES; 121 if (context_capabilities.gpu.texture_rectangle) 122 return GL_TEXTURE_RECTANGLE_ARB; 123 124 return GL_TEXTURE_2D; 125 } 126 127 size_t GetMaxStagingResourceCount() { 128 // Upper bound for number of staging resource to allow. 129 return 32; 130 } 131 132 } // namespace 133 134 class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { 135 public: 136 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create( 137 LayerTreeHostImpl* layer_tree_host_impl, 138 scoped_refptr<DelayBasedTimeSource> time_source) { 139 return make_scoped_ptr( 140 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl, 141 time_source)); 142 } 143 virtual ~LayerTreeHostImplTimeSourceAdapter() { 144 time_source_->SetClient(NULL); 145 time_source_->SetActive(false); 146 } 147 148 virtual void OnTimerTick() OVERRIDE { 149 // In single threaded mode we attempt to simulate changing the current 150 // thread by maintaining a fake thread id. When we switch from one 151 // thread to another, we construct DebugScopedSetXXXThread objects that 152 // update the thread id. This lets DCHECKS that ensure we're on the 153 // right thread to work correctly in single threaded mode. The problem 154 // here is that the timer tasks are run via the message loop, and when 155 // they run, we've had no chance to construct a DebugScopedSetXXXThread 156 // object. The result is that we report that we're running on the main 157 // thread. In multi-threaded mode, this timer is run on the compositor 158 // thread, so to keep this consistent in single-threaded mode, we'll 159 // construct a DebugScopedSetImplThread object. There is no need to do 160 // this in multi-threaded mode since the real thread id's will be 161 // correct. In fact, setting fake thread id's interferes with the real 162 // thread id's and causes breakage. 163 scoped_ptr<DebugScopedSetImplThread> set_impl_thread; 164 if (!layer_tree_host_impl_->proxy()->HasImplThread()) { 165 set_impl_thread.reset( 166 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy())); 167 } 168 169 layer_tree_host_impl_->Animate( 170 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); 171 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true); 172 bool start_ready_animations = true; 173 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 174 175 if (layer_tree_host_impl_->pending_tree()) { 176 layer_tree_host_impl_->pending_tree()->UpdateDrawProperties(); 177 layer_tree_host_impl_->ManageTiles(); 178 } 179 180 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); 181 } 182 183 void SetActive(bool active) { 184 if (active != time_source_->Active()) 185 time_source_->SetActive(active); 186 } 187 188 bool Active() const { return time_source_->Active(); } 189 190 private: 191 LayerTreeHostImplTimeSourceAdapter( 192 LayerTreeHostImpl* layer_tree_host_impl, 193 scoped_refptr<DelayBasedTimeSource> time_source) 194 : layer_tree_host_impl_(layer_tree_host_impl), 195 time_source_(time_source) { 196 time_source_->SetClient(this); 197 } 198 199 LayerTreeHostImpl* layer_tree_host_impl_; 200 scoped_refptr<DelayBasedTimeSource> time_source_; 201 202 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter); 203 }; 204 205 LayerTreeHostImpl::FrameData::FrameData() 206 : contains_incomplete_tile(false), has_no_damage(false) {} 207 208 LayerTreeHostImpl::FrameData::~FrameData() {} 209 210 scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( 211 const LayerTreeSettings& settings, 212 LayerTreeHostImplClient* client, 213 Proxy* proxy, 214 RenderingStatsInstrumentation* rendering_stats_instrumentation, 215 SharedBitmapManager* manager, 216 int id) { 217 return make_scoped_ptr(new LayerTreeHostImpl( 218 settings, client, proxy, rendering_stats_instrumentation, manager, id)); 219 } 220 221 LayerTreeHostImpl::LayerTreeHostImpl( 222 const LayerTreeSettings& settings, 223 LayerTreeHostImplClient* client, 224 Proxy* proxy, 225 RenderingStatsInstrumentation* rendering_stats_instrumentation, 226 SharedBitmapManager* manager, 227 int id) 228 : client_(client), 229 proxy_(proxy), 230 use_gpu_rasterization_(false), 231 input_handler_client_(NULL), 232 did_lock_scrolling_layer_(false), 233 should_bubble_scrolls_(false), 234 wheel_scrolling_(false), 235 scroll_affects_scroll_handler_(false), 236 scroll_layer_id_when_mouse_over_scrollbar_(0), 237 tile_priorities_dirty_(false), 238 root_layer_scroll_offset_delegate_(NULL), 239 settings_(settings), 240 visible_(true), 241 cached_managed_memory_policy_( 242 PrioritizedResourceManager::DefaultMemoryAllocationLimit(), 243 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 244 ManagedMemoryPolicy::kDefaultNumResourcesLimit), 245 pinch_gesture_active_(false), 246 pinch_gesture_end_should_clear_scrolling_layer_(false), 247 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())), 248 paint_time_counter_(PaintTimeCounter::Create()), 249 memory_history_(MemoryHistory::Create()), 250 debug_rect_history_(DebugRectHistory::Create()), 251 texture_mailbox_deleter_(new TextureMailboxDeleter( 252 proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner() 253 : proxy_->MainThreadTaskRunner())), 254 max_memory_needed_bytes_(0), 255 zero_budget_(false), 256 device_scale_factor_(1.f), 257 overhang_ui_resource_id_(0), 258 resourceless_software_draw_(false), 259 begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()), 260 animation_registrar_(AnimationRegistrar::Create()), 261 rendering_stats_instrumentation_(rendering_stats_instrumentation), 262 micro_benchmark_controller_(this), 263 need_to_update_visible_tiles_before_draw_(false), 264 shared_bitmap_manager_(manager), 265 id_(id) { 266 DCHECK(proxy_->IsImplThread()); 267 DidVisibilityChange(this, visible_); 268 animation_registrar_->set_supports_scroll_animations( 269 proxy_->SupportsImplScrolling()); 270 271 SetDebugState(settings.initial_debug_state); 272 273 // LTHI always has an active tree. 274 active_tree_ = LayerTreeImpl::create(this); 275 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 276 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); 277 278 if (settings.calculate_top_controls_position) { 279 top_controls_manager_ = 280 TopControlsManager::Create(this, 281 settings.top_controls_height, 282 settings.top_controls_show_threshold, 283 settings.top_controls_hide_threshold); 284 285 // TODO(bokan): This is a quick fix. The browser should lock the top 286 // controls to shown on creation but this appears not to work. Tracked 287 // in crbug.com/417680. 288 // Initialize with top controls showing. 289 SetControlsTopOffset(0.f); 290 } 291 } 292 293 LayerTreeHostImpl::~LayerTreeHostImpl() { 294 DCHECK(proxy_->IsImplThread()); 295 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); 296 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 297 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); 298 299 if (input_handler_client_) { 300 input_handler_client_->WillShutdown(); 301 input_handler_client_ = NULL; 302 } 303 304 // The layer trees must be destroyed before the layer tree host. We've 305 // made a contract with our animation controllers that the registrar 306 // will outlive them, and we must make good. 307 if (recycle_tree_) 308 recycle_tree_->Shutdown(); 309 if (pending_tree_) 310 pending_tree_->Shutdown(); 311 active_tree_->Shutdown(); 312 recycle_tree_.reset(); 313 pending_tree_.reset(); 314 active_tree_.reset(); 315 DestroyTileManager(); 316 } 317 318 void LayerTreeHostImpl::BeginMainFrameAborted(bool did_handle) { 319 // If the begin frame data was handled, then scroll and scale set was applied 320 // by the main thread, so the active tree needs to be updated as if these sent 321 // values were applied and committed. 322 if (did_handle) { 323 active_tree_->ApplySentScrollAndScaleDeltasFromAbortedCommit(); 324 active_tree_->ResetContentsTexturesPurged(); 325 } 326 } 327 328 void LayerTreeHostImpl::BeginCommit() { 329 TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit"); 330 331 if (UsePendingTreeForSync()) 332 CreatePendingTree(); 333 } 334 335 void LayerTreeHostImpl::CommitComplete() { 336 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete"); 337 338 if (pending_tree_) 339 pending_tree_->ApplyScrollDeltasSinceBeginMainFrame(); 340 sync_tree()->set_needs_update_draw_properties(); 341 342 if (settings_.impl_side_painting) { 343 // Impl-side painting needs an update immediately post-commit to have the 344 // opportunity to create tilings. Other paths can call UpdateDrawProperties 345 // more lazily when needed prior to drawing. 346 sync_tree()->UpdateDrawProperties(); 347 // Start working on newly created tiles immediately if needed. 348 if (tile_manager_ && tile_priorities_dirty_) 349 ManageTiles(); 350 else 351 NotifyReadyToActivate(); 352 } else { 353 // If we're not in impl-side painting, the tree is immediately considered 354 // active. 355 ActivateSyncTree(); 356 } 357 358 micro_benchmark_controller_.DidCompleteCommit(); 359 } 360 361 bool LayerTreeHostImpl::CanDraw() const { 362 // Note: If you are changing this function or any other function that might 363 // affect the result of CanDraw, make sure to call 364 // client_->OnCanDrawStateChanged in the proper places and update the 365 // NotifyIfCanDrawChanged test. 366 367 if (!renderer_) { 368 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer", 369 TRACE_EVENT_SCOPE_THREAD); 370 return false; 371 } 372 373 // Must have an OutputSurface if |renderer_| is not NULL. 374 DCHECK(output_surface_); 375 376 // TODO(boliu): Make draws without root_layer work and move this below 377 // draw_and_swap_full_viewport_every_frame check. Tracked in crbug.com/264967. 378 if (!active_tree_->root_layer()) { 379 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer", 380 TRACE_EVENT_SCOPE_THREAD); 381 return false; 382 } 383 384 if (output_surface_->capabilities().draw_and_swap_full_viewport_every_frame) 385 return true; 386 387 if (DrawViewportSize().IsEmpty()) { 388 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport", 389 TRACE_EVENT_SCOPE_THREAD); 390 return false; 391 } 392 if (active_tree_->ViewportSizeInvalid()) { 393 TRACE_EVENT_INSTANT0( 394 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed", 395 TRACE_EVENT_SCOPE_THREAD); 396 return false; 397 } 398 if (active_tree_->ContentsTexturesPurged()) { 399 TRACE_EVENT_INSTANT0( 400 "cc", "LayerTreeHostImpl::CanDraw contents textures purged", 401 TRACE_EVENT_SCOPE_THREAD); 402 return false; 403 } 404 if (EvictedUIResourcesExist()) { 405 TRACE_EVENT_INSTANT0( 406 "cc", "LayerTreeHostImpl::CanDraw UI resources evicted not recreated", 407 TRACE_EVENT_SCOPE_THREAD); 408 return false; 409 } 410 return true; 411 } 412 413 void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time) { 414 if (input_handler_client_) 415 input_handler_client_->Animate(monotonic_time); 416 AnimatePageScale(monotonic_time); 417 AnimateLayers(monotonic_time); 418 AnimateScrollbars(monotonic_time); 419 AnimateTopControls(monotonic_time); 420 } 421 422 void LayerTreeHostImpl::ManageTiles() { 423 if (!tile_manager_) 424 return; 425 if (!tile_priorities_dirty_) 426 return; 427 428 tile_priorities_dirty_ = false; 429 tile_manager_->ManageTiles(global_tile_state_); 430 431 client_->DidManageTiles(); 432 } 433 434 bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( 435 const gfx::Point& viewport_point, 436 InputHandler::ScrollInputType type) { 437 if (!CurrentlyScrollingLayer()) 438 return false; 439 440 gfx::PointF device_viewport_point = 441 gfx::ScalePoint(viewport_point, device_scale_factor_); 442 443 LayerImpl* layer_impl = 444 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); 445 446 bool scroll_on_main_thread = false; 447 LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( 448 device_viewport_point, type, layer_impl, &scroll_on_main_thread, NULL); 449 return CurrentlyScrollingLayer() == scrolling_layer_impl; 450 } 451 452 bool LayerTreeHostImpl::HaveTouchEventHandlersAt( 453 const gfx::Point& viewport_point) { 454 455 gfx::PointF device_viewport_point = 456 gfx::ScalePoint(viewport_point, device_scale_factor_); 457 458 LayerImpl* layer_impl = 459 active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( 460 device_viewport_point); 461 462 return layer_impl != NULL; 463 } 464 465 scoped_ptr<SwapPromiseMonitor> 466 LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor( 467 ui::LatencyInfo* latency) { 468 return scoped_ptr<SwapPromiseMonitor>( 469 new LatencyInfoSwapPromiseMonitor(latency, NULL, this)); 470 } 471 472 void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate( 473 scoped_ptr<SwapPromise> swap_promise) { 474 swap_promises_for_main_thread_scroll_update_.push_back(swap_promise.Pass()); 475 } 476 477 void LayerTreeHostImpl::TrackDamageForAllSurfaces( 478 LayerImpl* root_draw_layer, 479 const LayerImplList& render_surface_layer_list) { 480 // For now, we use damage tracking to compute a global scissor. To do this, we 481 // must compute all damage tracking before drawing anything, so that we know 482 // the root damage rect. The root damage rect is then used to scissor each 483 // surface. 484 485 for (int surface_index = render_surface_layer_list.size() - 1; 486 surface_index >= 0; 487 --surface_index) { 488 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; 489 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); 490 DCHECK(render_surface); 491 render_surface->damage_tracker()->UpdateDamageTrackingState( 492 render_surface->layer_list(), 493 render_surface_layer->id(), 494 render_surface->SurfacePropertyChangedOnlyFromDescendant(), 495 render_surface->content_rect(), 496 render_surface_layer->mask_layer(), 497 render_surface_layer->filters()); 498 } 499 } 500 501 void LayerTreeHostImpl::FrameData::AsValueInto( 502 base::debug::TracedValue* value) const { 503 value->SetBoolean("contains_incomplete_tile", contains_incomplete_tile); 504 value->SetBoolean("has_no_damage", has_no_damage); 505 506 // Quad data can be quite large, so only dump render passes if we select 507 // cc.debug.quads. 508 bool quads_enabled; 509 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 510 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), &quads_enabled); 511 if (quads_enabled) { 512 value->BeginArray("render_passes"); 513 for (size_t i = 0; i < render_passes.size(); ++i) { 514 value->BeginDictionary(); 515 render_passes[i]->AsValueInto(value); 516 value->EndDictionary(); 517 } 518 value->EndArray(); 519 } 520 } 521 522 void LayerTreeHostImpl::FrameData::AppendRenderPass( 523 scoped_ptr<RenderPass> render_pass) { 524 render_passes_by_id[render_pass->id] = render_pass.get(); 525 render_passes.push_back(render_pass.Pass()); 526 } 527 528 DrawMode LayerTreeHostImpl::GetDrawMode() const { 529 if (resourceless_software_draw_) { 530 return DRAW_MODE_RESOURCELESS_SOFTWARE; 531 } else if (output_surface_->context_provider()) { 532 return DRAW_MODE_HARDWARE; 533 } else { 534 DCHECK_EQ(!output_surface_->software_device(), 535 output_surface_->capabilities().delegated_rendering && 536 !output_surface_->capabilities().deferred_gl_initialization) 537 << output_surface_->capabilities().delegated_rendering << " " 538 << output_surface_->capabilities().deferred_gl_initialization; 539 return DRAW_MODE_SOFTWARE; 540 } 541 } 542 543 static void AppendQuadsForLayer( 544 RenderPass* target_render_pass, 545 LayerImpl* layer, 546 const OcclusionTracker<LayerImpl>& occlusion_tracker, 547 AppendQuadsData* append_quads_data) { 548 layer->AppendQuads(target_render_pass, occlusion_tracker, append_quads_data); 549 } 550 551 static void AppendQuadsForRenderSurfaceLayer( 552 RenderPass* target_render_pass, 553 LayerImpl* layer, 554 const RenderPass* contributing_render_pass, 555 const OcclusionTracker<LayerImpl>& occlusion_tracker, 556 AppendQuadsData* append_quads_data) { 557 bool is_replica = false; 558 layer->render_surface()->AppendQuads(target_render_pass, 559 occlusion_tracker, 560 append_quads_data, 561 is_replica, 562 contributing_render_pass->id); 563 564 // Add replica after the surface so that it appears below the surface. 565 if (layer->has_replica()) { 566 is_replica = true; 567 layer->render_surface()->AppendQuads(target_render_pass, 568 occlusion_tracker, 569 append_quads_data, 570 is_replica, 571 contributing_render_pass->id); 572 } 573 } 574 575 static void AppendQuadsToFillScreen( 576 ResourceProvider::ResourceId overhang_resource_id, 577 const gfx::SizeF& overhang_resource_scaled_size, 578 const gfx::Rect& root_scroll_layer_rect, 579 RenderPass* target_render_pass, 580 LayerImpl* root_layer, 581 SkColor screen_background_color, 582 const OcclusionTracker<LayerImpl>& occlusion_tracker) { 583 if (!root_layer || !SkColorGetA(screen_background_color)) 584 return; 585 586 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen(); 587 if (fill_region.IsEmpty()) 588 return; 589 590 // Divide the fill region into the part to be filled with the overhang 591 // resource and the part to be filled with the background color. 592 Region screen_background_color_region = fill_region; 593 Region overhang_region; 594 if (overhang_resource_id) { 595 overhang_region = fill_region; 596 overhang_region.Subtract(root_scroll_layer_rect); 597 screen_background_color_region.Intersect(root_scroll_layer_rect); 598 } 599 600 // Manually create the quad state for the gutter quads, as the root layer 601 // doesn't have any bounds and so can't generate this itself. 602 // TODO(danakj): Make the gutter quads generated by the solid color layer 603 // (make it smarter about generating quads to fill unoccluded areas). 604 605 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect(); 606 float opacity = 1.f; 607 int sorting_context_id = 0; 608 SharedQuadState* shared_quad_state = 609 target_render_pass->CreateAndAppendSharedQuadState(); 610 shared_quad_state->SetAll(gfx::Transform(), 611 root_target_rect.size(), 612 root_target_rect, 613 root_target_rect, 614 false, 615 opacity, 616 SkXfermode::kSrcOver_Mode, 617 sorting_context_id); 618 619 for (Region::Iterator fill_rects(screen_background_color_region); 620 fill_rects.has_rect(); 621 fill_rects.next()) { 622 gfx::Rect screen_space_rect = fill_rects.rect(); 623 gfx::Rect visible_screen_space_rect = screen_space_rect; 624 // Skip the quad culler and just append the quads directly to avoid 625 // occlusion checks. 626 SolidColorDrawQuad* quad = 627 target_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 628 quad->SetNew(shared_quad_state, 629 screen_space_rect, 630 visible_screen_space_rect, 631 screen_background_color, 632 false); 633 } 634 for (Region::Iterator fill_rects(overhang_region); 635 fill_rects.has_rect(); 636 fill_rects.next()) { 637 DCHECK(overhang_resource_id); 638 gfx::Rect screen_space_rect = fill_rects.rect(); 639 gfx::Rect opaque_screen_space_rect = screen_space_rect; 640 gfx::Rect visible_screen_space_rect = screen_space_rect; 641 TextureDrawQuad* tex_quad = 642 target_render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); 643 const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; 644 tex_quad->SetNew( 645 shared_quad_state, 646 screen_space_rect, 647 opaque_screen_space_rect, 648 visible_screen_space_rect, 649 overhang_resource_id, 650 false, 651 gfx::PointF( 652 screen_space_rect.x() / overhang_resource_scaled_size.width(), 653 screen_space_rect.y() / overhang_resource_scaled_size.height()), 654 gfx::PointF( 655 screen_space_rect.right() / overhang_resource_scaled_size.width(), 656 screen_space_rect.bottom() / 657 overhang_resource_scaled_size.height()), 658 screen_background_color, 659 vertex_opacity, 660 false); 661 } 662 } 663 664 DrawResult LayerTreeHostImpl::CalculateRenderPasses( 665 FrameData* frame) { 666 DCHECK(frame->render_passes.empty()); 667 DCHECK(CanDraw()); 668 DCHECK(active_tree_->root_layer()); 669 670 TrackDamageForAllSurfaces(active_tree_->root_layer(), 671 *frame->render_surface_layer_list); 672 673 // If the root render surface has no visible damage, then don't generate a 674 // frame at all. 675 RenderSurfaceImpl* root_surface = 676 active_tree_->root_layer()->render_surface(); 677 bool root_surface_has_no_visible_damage = 678 !root_surface->damage_tracker()->current_damage_rect().Intersects( 679 root_surface->content_rect()); 680 bool root_surface_has_contributing_layers = 681 !root_surface->layer_list().empty(); 682 bool hud_wants_to_draw_ = active_tree_->hud_layer() && 683 active_tree_->hud_layer()->IsAnimatingHUDContents(); 684 if (root_surface_has_contributing_layers && 685 root_surface_has_no_visible_damage && 686 active_tree_->LayersWithCopyOutputRequest().empty() && 687 !hud_wants_to_draw_) { 688 TRACE_EVENT0("cc", 689 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); 690 frame->has_no_damage = true; 691 DCHECK(!output_surface_->capabilities() 692 .draw_and_swap_full_viewport_every_frame); 693 return DRAW_SUCCESS; 694 } 695 696 TRACE_EVENT1("cc", 697 "LayerTreeHostImpl::CalculateRenderPasses", 698 "render_surface_layer_list.size()", 699 static_cast<uint64>(frame->render_surface_layer_list->size())); 700 701 // Create the render passes in dependency order. 702 for (int surface_index = frame->render_surface_layer_list->size() - 1; 703 surface_index >= 0; 704 --surface_index) { 705 LayerImpl* render_surface_layer = 706 (*frame->render_surface_layer_list)[surface_index]; 707 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); 708 709 bool should_draw_into_render_pass = 710 render_surface_layer->parent() == NULL || 711 render_surface->contributes_to_drawn_surface() || 712 render_surface_layer->HasCopyRequest(); 713 if (should_draw_into_render_pass) 714 render_surface_layer->render_surface()->AppendRenderPasses(frame); 715 } 716 717 // When we are displaying the HUD, change the root damage rect to cover the 718 // entire root surface. This will disable partial-swap/scissor optimizations 719 // that would prevent the HUD from updating, since the HUD does not cause 720 // damage itself, to prevent it from messing with damage visualizations. Since 721 // damage visualizations are done off the LayerImpls and RenderSurfaceImpls, 722 // changing the RenderPass does not affect them. 723 if (active_tree_->hud_layer()) { 724 RenderPass* root_pass = frame->render_passes.back(); 725 root_pass->damage_rect = root_pass->output_rect; 726 } 727 728 OcclusionTracker<LayerImpl> occlusion_tracker( 729 active_tree_->root_layer()->render_surface()->content_rect()); 730 occlusion_tracker.set_minimum_tracking_size( 731 settings_.minimum_occlusion_tracking_size); 732 733 if (debug_state_.show_occluding_rects) { 734 occlusion_tracker.set_occluding_screen_space_rects_container( 735 &frame->occluding_screen_space_rects); 736 } 737 if (debug_state_.show_non_occluding_rects) { 738 occlusion_tracker.set_non_occluding_screen_space_rects_container( 739 &frame->non_occluding_screen_space_rects); 740 } 741 742 // Add quads to the Render passes in front-to-back order to allow for testing 743 // occlusion and performing culling during the tree walk. 744 typedef LayerIterator<LayerImpl> LayerIteratorType; 745 746 // Typically when we are missing a texture and use a checkerboard quad, we 747 // still draw the frame. However when the layer being checkerboarded is moving 748 // due to an impl-animation, we drop the frame to avoid flashing due to the 749 // texture suddenly appearing in the future. 750 DrawResult draw_result = DRAW_SUCCESS; 751 // When we have a copy request for a layer, we need to draw no matter 752 // what, as the layer may disappear after this frame. 753 bool have_copy_request = false; 754 755 int layers_drawn = 0; 756 757 const DrawMode draw_mode = GetDrawMode(); 758 759 int num_missing_tiles = 0; 760 int num_incomplete_tiles = 0; 761 762 LayerIteratorType end = 763 LayerIteratorType::End(frame->render_surface_layer_list); 764 for (LayerIteratorType it = 765 LayerIteratorType::Begin(frame->render_surface_layer_list); 766 it != end; 767 ++it) { 768 RenderPassId target_render_pass_id = 769 it.target_render_surface_layer()->render_surface()->GetRenderPassId(); 770 RenderPass* target_render_pass = 771 frame->render_passes_by_id[target_render_pass_id]; 772 773 occlusion_tracker.EnterLayer(it); 774 775 AppendQuadsData append_quads_data(target_render_pass_id); 776 777 if (it.represents_target_render_surface()) { 778 if (it->HasCopyRequest()) { 779 have_copy_request = true; 780 it->TakeCopyRequestsAndTransformToTarget( 781 &target_render_pass->copy_requests); 782 } 783 } else if (it.represents_contributing_render_surface() && 784 it->render_surface()->contributes_to_drawn_surface()) { 785 RenderPassId contributing_render_pass_id = 786 it->render_surface()->GetRenderPassId(); 787 RenderPass* contributing_render_pass = 788 frame->render_passes_by_id[contributing_render_pass_id]; 789 AppendQuadsForRenderSurfaceLayer(target_render_pass, 790 *it, 791 contributing_render_pass, 792 occlusion_tracker, 793 &append_quads_data); 794 } else if (it.represents_itself() && 795 !it->visible_content_rect().IsEmpty()) { 796 bool occluded = 797 occlusion_tracker.GetCurrentOcclusionForLayer(it->draw_transform()) 798 .IsOccluded(it->visible_content_rect()); 799 if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) { 800 DCHECK_EQ(active_tree_, it->layer_tree_impl()); 801 802 frame->will_draw_layers.push_back(*it); 803 804 if (it->HasContributingDelegatedRenderPasses()) { 805 RenderPassId contributing_render_pass_id = 806 it->FirstContributingRenderPassId(); 807 while (frame->render_passes_by_id.find(contributing_render_pass_id) != 808 frame->render_passes_by_id.end()) { 809 RenderPass* render_pass = 810 frame->render_passes_by_id[contributing_render_pass_id]; 811 812 AppendQuadsData append_quads_data(render_pass->id); 813 AppendQuadsForLayer(render_pass, 814 *it, 815 occlusion_tracker, 816 &append_quads_data); 817 818 contributing_render_pass_id = 819 it->NextContributingRenderPassId(contributing_render_pass_id); 820 } 821 } 822 823 AppendQuadsForLayer(target_render_pass, 824 *it, 825 occlusion_tracker, 826 &append_quads_data); 827 } 828 829 ++layers_drawn; 830 } 831 832 rendering_stats_instrumentation_->AddVisibleContentArea( 833 append_quads_data.visible_content_area); 834 rendering_stats_instrumentation_->AddApproximatedVisibleContentArea( 835 append_quads_data.approximated_visible_content_area); 836 837 num_missing_tiles += append_quads_data.num_missing_tiles; 838 num_incomplete_tiles += append_quads_data.num_incomplete_tiles; 839 840 if (append_quads_data.num_missing_tiles) { 841 bool layer_has_animating_transform = 842 it->screen_space_transform_is_animating() || 843 it->draw_transform_is_animating(); 844 if (layer_has_animating_transform) 845 draw_result = DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 846 } 847 848 if (append_quads_data.num_incomplete_tiles || 849 append_quads_data.num_missing_tiles) { 850 frame->contains_incomplete_tile = true; 851 if (active_tree()->RequiresHighResToDraw()) 852 draw_result = DRAW_ABORTED_MISSING_HIGH_RES_CONTENT; 853 } 854 855 occlusion_tracker.LeaveLayer(it); 856 } 857 858 if (have_copy_request || 859 output_surface_->capabilities().draw_and_swap_full_viewport_every_frame) 860 draw_result = DRAW_SUCCESS; 861 862 #if DCHECK_IS_ON 863 for (size_t i = 0; i < frame->render_passes.size(); ++i) { 864 for (QuadList::Iterator iter = frame->render_passes[i]->quad_list.begin(); 865 iter != frame->render_passes[i]->quad_list.end(); 866 ++iter) 867 DCHECK(iter->shared_quad_state); 868 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id) 869 != frame->render_passes_by_id.end()); 870 } 871 #endif 872 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin()); 873 874 if (!active_tree_->has_transparent_background()) { 875 frame->render_passes.back()->has_transparent_background = false; 876 AppendQuadsToFillScreen( 877 ResourceIdForUIResource(overhang_ui_resource_id_), 878 gfx::ScaleSize(overhang_ui_resource_size_, device_scale_factor_), 879 active_tree_->RootScrollLayerDeviceViewportBounds(), 880 frame->render_passes.back(), 881 active_tree_->root_layer(), 882 active_tree_->background_color(), 883 occlusion_tracker); 884 } 885 886 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); 887 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); 888 889 // Any copy requests left in the tree are not going to get serviced, and 890 // should be aborted. 891 ScopedPtrVector<CopyOutputRequest> requests_to_abort; 892 while (!active_tree_->LayersWithCopyOutputRequest().empty()) { 893 LayerImpl* layer = active_tree_->LayersWithCopyOutputRequest().back(); 894 layer->TakeCopyRequestsAndTransformToTarget(&requests_to_abort); 895 } 896 for (size_t i = 0; i < requests_to_abort.size(); ++i) 897 requests_to_abort[i]->SendEmptyResult(); 898 899 // If we're making a frame to draw, it better have at least one render pass. 900 DCHECK(!frame->render_passes.empty()); 901 902 if (active_tree_->has_ever_been_drawn()) { 903 UMA_HISTOGRAM_COUNTS_100( 904 "Compositing.RenderPass.AppendQuadData.NumMissingTiles", 905 num_missing_tiles); 906 UMA_HISTOGRAM_COUNTS_100( 907 "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles", 908 num_incomplete_tiles); 909 } 910 911 // Should only have one render pass in resourceless software mode. 912 DCHECK(draw_mode != DRAW_MODE_RESOURCELESS_SOFTWARE || 913 frame->render_passes.size() == 1u) 914 << frame->render_passes.size(); 915 916 return draw_result; 917 } 918 919 void LayerTreeHostImpl::MainThreadHasStoppedFlinging() { 920 if (input_handler_client_) 921 input_handler_client_->MainThreadHasStoppedFlinging(); 922 } 923 924 void LayerTreeHostImpl::UpdateBackgroundAnimateTicking( 925 bool should_background_tick) { 926 DCHECK(proxy_->IsImplThread()); 927 if (should_background_tick) 928 DCHECK(active_tree_->root_layer()); 929 930 bool enabled = should_background_tick && needs_animate_layers(); 931 932 // Lazily create the time_source adapter so that we can vary the interval for 933 // testing. 934 if (!time_source_client_adapter_) { 935 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create( 936 this, 937 DelayBasedTimeSource::Create( 938 LowFrequencyAnimationInterval(), 939 proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner() 940 : proxy_->MainThreadTaskRunner())); 941 } 942 943 time_source_client_adapter_->SetActive(enabled); 944 } 945 946 void LayerTreeHostImpl::DidAnimateScrollOffset() { 947 client_->SetNeedsCommitOnImplThread(); 948 client_->RenewTreePriority(); 949 } 950 951 void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) { 952 viewport_damage_rect_.Union(damage_rect); 953 } 954 955 static inline RenderPass* FindRenderPassById( 956 RenderPassId render_pass_id, 957 const LayerTreeHostImpl::FrameData& frame) { 958 RenderPassIdHashMap::const_iterator it = 959 frame.render_passes_by_id.find(render_pass_id); 960 return it != frame.render_passes_by_id.end() ? it->second : NULL; 961 } 962 963 static void RemoveRenderPassesRecursive(RenderPassId remove_render_pass_id, 964 LayerTreeHostImpl::FrameData* frame) { 965 RenderPass* remove_render_pass = 966 FindRenderPassById(remove_render_pass_id, *frame); 967 // The pass was already removed by another quad - probably the original, and 968 // we are the replica. 969 if (!remove_render_pass) 970 return; 971 RenderPassList& render_passes = frame->render_passes; 972 RenderPassList::iterator to_remove = std::find(render_passes.begin(), 973 render_passes.end(), 974 remove_render_pass); 975 976 DCHECK(to_remove != render_passes.end()); 977 978 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove); 979 frame->render_passes.erase(to_remove); 980 frame->render_passes_by_id.erase(remove_render_pass_id); 981 982 // Now follow up for all RenderPass quads and remove their RenderPasses 983 // recursively. 984 const QuadList& quad_list = removed_pass->quad_list; 985 QuadList::ConstBackToFrontIterator quad_list_iterator = 986 quad_list.BackToFrontBegin(); 987 for (; quad_list_iterator != quad_list.BackToFrontEnd(); 988 ++quad_list_iterator) { 989 const DrawQuad* current_quad = &*quad_list_iterator; 990 if (current_quad->material != DrawQuad::RENDER_PASS) 991 continue; 992 993 RenderPassId next_remove_render_pass_id = 994 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id; 995 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame); 996 } 997 } 998 999 bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( 1000 const RenderPassDrawQuad& quad, const FrameData& frame) const { 1001 const RenderPass* render_pass = 1002 FindRenderPassById(quad.render_pass_id, frame); 1003 if (!render_pass) 1004 return false; 1005 1006 // If any quad or RenderPass draws into this RenderPass, then keep it. 1007 const QuadList& quad_list = render_pass->quad_list; 1008 for (QuadList::ConstBackToFrontIterator quad_list_iterator = 1009 quad_list.BackToFrontBegin(); 1010 quad_list_iterator != quad_list.BackToFrontEnd(); 1011 ++quad_list_iterator) { 1012 const DrawQuad* current_quad = &*quad_list_iterator; 1013 1014 if (current_quad->material != DrawQuad::RENDER_PASS) 1015 return false; 1016 1017 const RenderPass* contributing_pass = FindRenderPassById( 1018 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame); 1019 if (contributing_pass) 1020 return false; 1021 } 1022 return true; 1023 } 1024 1025 // Defined for linking tests. 1026 template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< 1027 LayerTreeHostImpl::CullRenderPassesWithNoQuads>( 1028 CullRenderPassesWithNoQuads culler, FrameData*); 1029 1030 // static 1031 template <typename RenderPassCuller> 1032 void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler, 1033 FrameData* frame) { 1034 for (size_t it = culler.RenderPassListBegin(frame->render_passes); 1035 it != culler.RenderPassListEnd(frame->render_passes); 1036 it = culler.RenderPassListNext(it)) { 1037 const RenderPass* current_pass = frame->render_passes[it]; 1038 const QuadList& quad_list = current_pass->quad_list; 1039 QuadList::ConstBackToFrontIterator quad_list_iterator = 1040 quad_list.BackToFrontBegin(); 1041 1042 for (; quad_list_iterator != quad_list.BackToFrontEnd(); 1043 ++quad_list_iterator) { 1044 const DrawQuad* current_quad = &*quad_list_iterator; 1045 1046 if (current_quad->material != DrawQuad::RENDER_PASS) 1047 continue; 1048 1049 const RenderPassDrawQuad* render_pass_quad = 1050 RenderPassDrawQuad::MaterialCast(current_quad); 1051 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame)) 1052 continue; 1053 1054 // We are changing the vector in the middle of iteration. Because we 1055 // delete render passes that draw into the current pass, we are 1056 // guaranteed that any data from the iterator to the end will not 1057 // change. So, capture the iterator position from the end of the 1058 // list, and restore it after the change. 1059 size_t position_from_end = frame->render_passes.size() - it; 1060 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame); 1061 it = frame->render_passes.size() - position_from_end; 1062 DCHECK_GE(frame->render_passes.size(), position_from_end); 1063 } 1064 } 1065 } 1066 1067 DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { 1068 TRACE_EVENT1("cc", 1069 "LayerTreeHostImpl::PrepareToDraw", 1070 "SourceFrameNumber", 1071 active_tree_->source_frame_number()); 1072 1073 if (need_to_update_visible_tiles_before_draw_ && 1074 tile_manager_ && tile_manager_->UpdateVisibleTiles()) { 1075 DidInitializeVisibleTile(); 1076 } 1077 need_to_update_visible_tiles_before_draw_ = true; 1078 1079 UMA_HISTOGRAM_CUSTOM_COUNTS( 1080 "Compositing.NumActiveLayers", active_tree_->NumLayers(), 1, 400, 20); 1081 1082 bool ok = active_tree_->UpdateDrawProperties(); 1083 DCHECK(ok) << "UpdateDrawProperties failed during draw"; 1084 1085 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList(); 1086 frame->render_passes.clear(); 1087 frame->render_passes_by_id.clear(); 1088 frame->will_draw_layers.clear(); 1089 frame->contains_incomplete_tile = false; 1090 frame->has_no_damage = false; 1091 1092 if (active_tree_->root_layer()) { 1093 gfx::Rect device_viewport_damage_rect = viewport_damage_rect_; 1094 viewport_damage_rect_ = gfx::Rect(); 1095 1096 active_tree_->root_layer()->render_surface()->damage_tracker()-> 1097 AddDamageNextUpdate(device_viewport_damage_rect); 1098 } 1099 1100 DrawResult draw_result = CalculateRenderPasses(frame); 1101 if (draw_result != DRAW_SUCCESS) { 1102 DCHECK(!output_surface_->capabilities() 1103 .draw_and_swap_full_viewport_every_frame); 1104 return draw_result; 1105 } 1106 1107 // If we return DRAW_SUCCESS, then we expect DrawLayers() to be called before 1108 // this function is called again. 1109 return draw_result; 1110 } 1111 1112 void LayerTreeHostImpl::EvictTexturesForTesting() { 1113 EnforceManagedMemoryPolicy(ManagedMemoryPolicy(0)); 1114 } 1115 1116 void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) { 1117 NOTREACHED(); 1118 } 1119 1120 void LayerTreeHostImpl::DidInitializeVisibleTileForTesting() { 1121 // Add arbitrary damage, to trigger prepare-to-draws. 1122 // Here, setting damage as viewport size, used only for testing. 1123 SetFullRootLayerDamage(); 1124 DidInitializeVisibleTile(); 1125 } 1126 1127 void LayerTreeHostImpl::ResetTreesForTesting() { 1128 if (active_tree_) 1129 active_tree_->DetachLayerTree(); 1130 active_tree_ = LayerTreeImpl::create(this); 1131 if (pending_tree_) 1132 pending_tree_->DetachLayerTree(); 1133 pending_tree_.reset(); 1134 if (recycle_tree_) 1135 recycle_tree_->DetachLayerTree(); 1136 recycle_tree_.reset(); 1137 } 1138 1139 void LayerTreeHostImpl::ResetRecycleTreeForTesting() { 1140 if (recycle_tree_) 1141 recycle_tree_->DetachLayerTree(); 1142 recycle_tree_.reset(); 1143 } 1144 1145 void LayerTreeHostImpl::EnforceManagedMemoryPolicy( 1146 const ManagedMemoryPolicy& policy) { 1147 1148 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread( 1149 visible_ ? policy.bytes_limit_when_visible : 0, 1150 ManagedMemoryPolicy::PriorityCutoffToValue( 1151 visible_ ? policy.priority_cutoff_when_visible 1152 : gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING)); 1153 if (evicted_resources) { 1154 active_tree_->SetContentsTexturesPurged(); 1155 if (pending_tree_) 1156 pending_tree_->SetContentsTexturesPurged(); 1157 client_->SetNeedsCommitOnImplThread(); 1158 client_->OnCanDrawStateChanged(CanDraw()); 1159 client_->RenewTreePriority(); 1160 } 1161 1162 UpdateTileManagerMemoryPolicy(policy); 1163 } 1164 1165 void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( 1166 const ManagedMemoryPolicy& policy) { 1167 if (!tile_manager_) 1168 return; 1169 1170 global_tile_state_.hard_memory_limit_in_bytes = 0; 1171 global_tile_state_.soft_memory_limit_in_bytes = 0; 1172 if (visible_ && policy.bytes_limit_when_visible > 0) { 1173 global_tile_state_.hard_memory_limit_in_bytes = 1174 policy.bytes_limit_when_visible; 1175 global_tile_state_.soft_memory_limit_in_bytes = 1176 (static_cast<int64>(global_tile_state_.hard_memory_limit_in_bytes) * 1177 settings_.max_memory_for_prepaint_percentage) / 1178 100; 1179 } 1180 global_tile_state_.memory_limit_policy = 1181 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy( 1182 visible_ ? 1183 policy.priority_cutoff_when_visible : 1184 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING); 1185 global_tile_state_.num_resources_limit = policy.num_resources_limit; 1186 1187 // TODO(reveman): We should avoid keeping around unused resources if 1188 // possible. crbug.com/224475 1189 // Unused limit is calculated from soft-limit, as hard-limit may 1190 // be very high and shouldn't typically be exceeded. 1191 size_t unused_memory_limit_in_bytes = static_cast<size_t>( 1192 (static_cast<int64>(global_tile_state_.soft_memory_limit_in_bytes) * 1193 settings_.max_unused_resource_memory_percentage) / 1194 100); 1195 1196 DCHECK(resource_pool_); 1197 resource_pool_->CheckBusyResources(); 1198 // Soft limit is used for resource pool such that memory returns to soft 1199 // limit after going over. 1200 resource_pool_->SetResourceUsageLimits( 1201 global_tile_state_.soft_memory_limit_in_bytes, 1202 unused_memory_limit_in_bytes, 1203 global_tile_state_.num_resources_limit); 1204 1205 // Release all staging resources when invisible. 1206 if (staging_resource_pool_) { 1207 staging_resource_pool_->CheckBusyResources(); 1208 staging_resource_pool_->SetResourceUsageLimits( 1209 std::numeric_limits<size_t>::max(), 1210 std::numeric_limits<size_t>::max(), 1211 visible_ ? GetMaxStagingResourceCount() : 0); 1212 } 1213 1214 DidModifyTilePriorities(); 1215 } 1216 1217 void LayerTreeHostImpl::DidModifyTilePriorities() { 1218 DCHECK(settings_.impl_side_painting); 1219 // Mark priorities as dirty and schedule a ManageTiles(). 1220 tile_priorities_dirty_ = true; 1221 client_->SetNeedsManageTilesOnImplThread(); 1222 } 1223 1224 void LayerTreeHostImpl::DidInitializeVisibleTile() { 1225 if (client_ && !client_->IsInsideDraw()) 1226 client_->DidInitializeVisibleTileOnImplThread(); 1227 } 1228 1229 void LayerTreeHostImpl::GetPictureLayerImplPairs( 1230 std::vector<PictureLayerImpl::Pair>* layer_pairs) const { 1231 DCHECK(layer_pairs->empty()); 1232 for (std::vector<PictureLayerImpl*>::const_iterator it = 1233 picture_layers_.begin(); 1234 it != picture_layers_.end(); 1235 ++it) { 1236 PictureLayerImpl* layer = *it; 1237 1238 // TODO(vmpstr): Iterators and should handle this instead. crbug.com/381704 1239 if (!layer->HasValidTilePriorities()) 1240 continue; 1241 1242 PictureLayerImpl* twin_layer = layer->GetTwinLayer(); 1243 1244 // Ignore the twin layer when tile priorities are invalid. 1245 // TODO(vmpstr): Iterators should handle this instead. crbug.com/381704 1246 if (twin_layer && !twin_layer->HasValidTilePriorities()) 1247 twin_layer = NULL; 1248 1249 // If the current tree is ACTIVE_TREE, then always generate a layer_pair. 1250 // If current tree is PENDING_TREE, then only generate a layer_pair if 1251 // there is no twin layer. 1252 if (layer->GetTree() == ACTIVE_TREE) { 1253 DCHECK(!twin_layer || twin_layer->GetTree() == PENDING_TREE); 1254 layer_pairs->push_back(PictureLayerImpl::Pair(layer, twin_layer)); 1255 } else if (!twin_layer) { 1256 layer_pairs->push_back(PictureLayerImpl::Pair(NULL, layer)); 1257 } 1258 } 1259 } 1260 1261 void LayerTreeHostImpl::BuildRasterQueue(RasterTilePriorityQueue* queue, 1262 TreePriority tree_priority) { 1263 picture_layer_pairs_.clear(); 1264 GetPictureLayerImplPairs(&picture_layer_pairs_); 1265 queue->Build(picture_layer_pairs_, tree_priority); 1266 } 1267 1268 void LayerTreeHostImpl::BuildEvictionQueue(EvictionTilePriorityQueue* queue, 1269 TreePriority tree_priority) { 1270 picture_layer_pairs_.clear(); 1271 GetPictureLayerImplPairs(&picture_layer_pairs_); 1272 queue->Build(picture_layer_pairs_, tree_priority); 1273 } 1274 1275 const std::vector<PictureLayerImpl*>& LayerTreeHostImpl::GetPictureLayers() 1276 const { 1277 return picture_layers_; 1278 } 1279 1280 void LayerTreeHostImpl::NotifyReadyToActivate() { 1281 client_->NotifyReadyToActivate(); 1282 } 1283 1284 void LayerTreeHostImpl::NotifyTileStateChanged(const Tile* tile) { 1285 TRACE_EVENT0("cc", "LayerTreeHostImpl::NotifyTileStateChanged"); 1286 1287 if (active_tree_) { 1288 LayerImpl* layer_impl = 1289 active_tree_->FindActiveTreeLayerById(tile->layer_id()); 1290 if (layer_impl) 1291 layer_impl->NotifyTileStateChanged(tile); 1292 } 1293 1294 if (pending_tree_) { 1295 LayerImpl* layer_impl = 1296 pending_tree_->FindPendingTreeLayerById(tile->layer_id()); 1297 if (layer_impl) 1298 layer_impl->NotifyTileStateChanged(tile); 1299 } 1300 } 1301 1302 void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { 1303 SetManagedMemoryPolicy(policy, zero_budget_); 1304 } 1305 1306 void LayerTreeHostImpl::SetTreeActivationCallback( 1307 const base::Closure& callback) { 1308 DCHECK(proxy_->IsImplThread()); 1309 DCHECK(settings_.impl_side_painting || callback.is_null()); 1310 tree_activation_callback_ = callback; 1311 } 1312 1313 void LayerTreeHostImpl::SetManagedMemoryPolicy( 1314 const ManagedMemoryPolicy& policy, bool zero_budget) { 1315 if (cached_managed_memory_policy_ == policy && zero_budget_ == zero_budget) 1316 return; 1317 1318 ManagedMemoryPolicy old_policy = ActualManagedMemoryPolicy(); 1319 1320 cached_managed_memory_policy_ = policy; 1321 zero_budget_ = zero_budget; 1322 ManagedMemoryPolicy actual_policy = ActualManagedMemoryPolicy(); 1323 1324 if (old_policy == actual_policy) 1325 return; 1326 1327 if (!proxy_->HasImplThread()) { 1328 // In single-thread mode, this can be called on the main thread by 1329 // GLRenderer::OnMemoryAllocationChanged. 1330 DebugScopedSetImplThread impl_thread(proxy_); 1331 EnforceManagedMemoryPolicy(actual_policy); 1332 } else { 1333 DCHECK(proxy_->IsImplThread()); 1334 EnforceManagedMemoryPolicy(actual_policy); 1335 } 1336 1337 // If there is already enough memory to draw everything imaginable and the 1338 // new memory limit does not change this, then do not re-commit. Don't bother 1339 // skipping commits if this is not visible (commits don't happen when not 1340 // visible, there will almost always be a commit when this becomes visible). 1341 bool needs_commit = true; 1342 if (visible() && 1343 actual_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && 1344 old_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && 1345 actual_policy.priority_cutoff_when_visible == 1346 old_policy.priority_cutoff_when_visible) { 1347 needs_commit = false; 1348 } 1349 1350 if (needs_commit) 1351 client_->SetNeedsCommitOnImplThread(); 1352 } 1353 1354 void LayerTreeHostImpl::SetExternalDrawConstraints( 1355 const gfx::Transform& transform, 1356 const gfx::Rect& viewport, 1357 const gfx::Rect& clip, 1358 const gfx::Rect& viewport_rect_for_tile_priority, 1359 const gfx::Transform& transform_for_tile_priority, 1360 bool resourceless_software_draw) { 1361 gfx::Rect viewport_rect_for_tile_priority_in_view_space; 1362 if (!resourceless_software_draw) { 1363 gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); 1364 if (transform_for_tile_priority.GetInverse(&screen_to_view)) { 1365 // Convert from screen space to view space. 1366 viewport_rect_for_tile_priority_in_view_space = 1367 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( 1368 screen_to_view, viewport_rect_for_tile_priority)); 1369 } 1370 } 1371 1372 if (external_transform_ != transform || external_viewport_ != viewport || 1373 resourceless_software_draw_ != resourceless_software_draw || 1374 viewport_rect_for_tile_priority_ != 1375 viewport_rect_for_tile_priority_in_view_space) { 1376 active_tree_->set_needs_update_draw_properties(); 1377 } 1378 1379 external_transform_ = transform; 1380 external_viewport_ = viewport; 1381 external_clip_ = clip; 1382 viewport_rect_for_tile_priority_ = 1383 viewport_rect_for_tile_priority_in_view_space; 1384 resourceless_software_draw_ = resourceless_software_draw; 1385 } 1386 1387 void LayerTreeHostImpl::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { 1388 if (damage_rect.IsEmpty()) 1389 return; 1390 NotifySwapPromiseMonitorsOfSetNeedsRedraw(); 1391 client_->SetNeedsRedrawRectOnImplThread(damage_rect); 1392 } 1393 1394 void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) { 1395 client_->BeginFrame(args); 1396 } 1397 1398 void LayerTreeHostImpl::DidSwapBuffers() { 1399 client_->DidSwapBuffersOnImplThread(); 1400 } 1401 1402 void LayerTreeHostImpl::DidSwapBuffersComplete() { 1403 client_->DidSwapBuffersCompleteOnImplThread(); 1404 } 1405 1406 void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) { 1407 // TODO(piman): We may need to do some validation on this ack before 1408 // processing it. 1409 if (renderer_) 1410 renderer_->ReceiveSwapBuffersAck(*ack); 1411 1412 // In OOM, we now might be able to release more resources that were held 1413 // because they were exported. 1414 if (tile_manager_) { 1415 DCHECK(resource_pool_); 1416 1417 resource_pool_->CheckBusyResources(); 1418 resource_pool_->ReduceResourceUsage(); 1419 } 1420 // If we're not visible, we likely released resources, so we want to 1421 // aggressively flush here to make sure those DeleteTextures make it to the 1422 // GPU process to free up the memory. 1423 if (output_surface_->context_provider() && !visible_) { 1424 output_surface_->context_provider()->ContextGL()->ShallowFlushCHROMIUM(); 1425 } 1426 } 1427 1428 void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { 1429 client_->OnCanDrawStateChanged(CanDraw()); 1430 } 1431 1432 CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { 1433 CompositorFrameMetadata metadata; 1434 metadata.device_scale_factor = device_scale_factor_; 1435 metadata.page_scale_factor = active_tree_->total_page_scale_factor(); 1436 metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize(); 1437 metadata.root_layer_size = active_tree_->ScrollableSize(); 1438 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor(); 1439 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); 1440 if (top_controls_manager_) { 1441 metadata.location_bar_offset = 1442 gfx::Vector2dF(0.f, top_controls_manager_->ControlsTopOffset()); 1443 metadata.location_bar_content_translation = 1444 gfx::Vector2dF(0.f, top_controls_manager_->ContentTopOffset()); 1445 } 1446 1447 active_tree_->GetViewportSelection(&metadata.selection_start, 1448 &metadata.selection_end); 1449 1450 if (!InnerViewportScrollLayer()) 1451 return metadata; 1452 1453 metadata.root_scroll_offset = active_tree_->TotalScrollOffset(); 1454 1455 return metadata; 1456 } 1457 1458 static void LayerTreeHostImplDidBeginTracingCallback(LayerImpl* layer) { 1459 layer->DidBeginTracing(); 1460 } 1461 1462 void LayerTreeHostImpl::DrawLayers(FrameData* frame, 1463 base::TimeTicks frame_begin_time) { 1464 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); 1465 DCHECK(CanDraw()); 1466 1467 if (frame->has_no_damage) { 1468 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); 1469 DCHECK(!output_surface_->capabilities() 1470 .draw_and_swap_full_viewport_every_frame); 1471 return; 1472 } 1473 1474 DCHECK(!frame->render_passes.empty()); 1475 1476 fps_counter_->SaveTimeStamp(frame_begin_time, 1477 !output_surface_->context_provider()); 1478 bool on_main_thread = false; 1479 rendering_stats_instrumentation_->IncrementFrameCount( 1480 1, on_main_thread); 1481 1482 if (tile_manager_) { 1483 memory_history_->SaveEntry( 1484 tile_manager_->memory_stats_from_last_assign()); 1485 } 1486 1487 if (debug_state_.ShowHudRects()) { 1488 debug_rect_history_->SaveDebugRectsForCurrentFrame( 1489 active_tree_->root_layer(), 1490 active_tree_->hud_layer(), 1491 *frame->render_surface_layer_list, 1492 frame->occluding_screen_space_rects, 1493 frame->non_occluding_screen_space_rects, 1494 debug_state_); 1495 } 1496 1497 if (!settings_.impl_side_painting && debug_state_.continuous_painting) { 1498 const RenderingStats& stats = 1499 rendering_stats_instrumentation_->GetRenderingStats(); 1500 paint_time_counter_->SavePaintTime(stats.main_stats.paint_time); 1501 } 1502 1503 bool is_new_trace; 1504 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); 1505 if (is_new_trace) { 1506 if (pending_tree_) { 1507 LayerTreeHostCommon::CallFunctionForSubtree( 1508 pending_tree_->root_layer(), 1509 base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); 1510 } 1511 LayerTreeHostCommon::CallFunctionForSubtree( 1512 active_tree_->root_layer(), 1513 base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); 1514 } 1515 1516 { 1517 TRACE_EVENT0("cc", "DrawLayers.FrameViewerTracing"); 1518 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 1519 TRACE_DISABLED_BY_DEFAULT("cc.debug") "," 1520 TRACE_DISABLED_BY_DEFAULT("cc.debug.quads") "," 1521 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers"), 1522 "cc::LayerTreeHostImpl", 1523 id_, 1524 AsValueWithFrame(frame)); 1525 } 1526 1527 const DrawMode draw_mode = GetDrawMode(); 1528 1529 // Because the contents of the HUD depend on everything else in the frame, the 1530 // contents of its texture are updated as the last thing before the frame is 1531 // drawn. 1532 if (active_tree_->hud_layer()) { 1533 TRACE_EVENT0("cc", "DrawLayers.UpdateHudTexture"); 1534 active_tree_->hud_layer()->UpdateHudTexture(draw_mode, 1535 resource_provider_.get()); 1536 } 1537 1538 if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) { 1539 bool disable_picture_quad_image_filtering = 1540 IsActivelyScrolling() || needs_animate_layers(); 1541 1542 scoped_ptr<SoftwareRenderer> temp_software_renderer = 1543 SoftwareRenderer::Create(this, &settings_, output_surface_.get(), NULL); 1544 temp_software_renderer->DrawFrame(&frame->render_passes, 1545 device_scale_factor_, 1546 DeviceViewport(), 1547 DeviceClip(), 1548 disable_picture_quad_image_filtering); 1549 } else { 1550 renderer_->DrawFrame(&frame->render_passes, 1551 device_scale_factor_, 1552 DeviceViewport(), 1553 DeviceClip(), 1554 false); 1555 } 1556 // The render passes should be consumed by the renderer. 1557 DCHECK(frame->render_passes.empty()); 1558 frame->render_passes_by_id.clear(); 1559 1560 // The next frame should start by assuming nothing has changed, and changes 1561 // are noted as they occur. 1562 // TODO(boliu): If we did a temporary software renderer frame, propogate the 1563 // damage forward to the next frame. 1564 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) { 1565 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()-> 1566 DidDrawDamagedArea(); 1567 } 1568 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree(); 1569 1570 active_tree_->set_has_ever_been_drawn(true); 1571 devtools_instrumentation::DidDrawFrame(id_); 1572 benchmark_instrumentation::IssueImplThreadRenderingStatsEvent( 1573 rendering_stats_instrumentation_->impl_thread_rendering_stats()); 1574 rendering_stats_instrumentation_->AccumulateAndClearImplThreadStats(); 1575 } 1576 1577 void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) { 1578 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i) 1579 frame.will_draw_layers[i]->DidDraw(resource_provider_.get()); 1580 1581 // Once all layers have been drawn, pending texture uploads should no 1582 // longer block future uploads. 1583 resource_provider_->MarkPendingUploadsAsNonBlocking(); 1584 } 1585 1586 void LayerTreeHostImpl::FinishAllRendering() { 1587 if (renderer_) 1588 renderer_->Finish(); 1589 } 1590 1591 void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { 1592 if (use_gpu == use_gpu_rasterization_) 1593 return; 1594 1595 use_gpu_rasterization_ = use_gpu; 1596 ReleaseTreeResources(); 1597 1598 // Replace existing tile manager with another one that uses appropriate 1599 // rasterizer. 1600 if (tile_manager_) { 1601 DestroyTileManager(); 1602 CreateAndSetTileManager(); 1603 } 1604 1605 // We have released tilings for both active and pending tree. 1606 // We would not have any content to draw until the pending tree is activated. 1607 // Prevent the active tree from drawing until activation. 1608 active_tree_->SetRequiresHighResToDraw(); 1609 } 1610 1611 const RendererCapabilitiesImpl& 1612 LayerTreeHostImpl::GetRendererCapabilities() const { 1613 return renderer_->Capabilities(); 1614 } 1615 1616 bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { 1617 active_tree()->ResetRequiresHighResToDraw(); 1618 if (frame.has_no_damage) { 1619 active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS); 1620 return false; 1621 } 1622 CompositorFrameMetadata metadata = MakeCompositorFrameMetadata(); 1623 active_tree()->FinishSwapPromises(&metadata); 1624 for (size_t i = 0; i < metadata.latency_info.size(); i++) { 1625 TRACE_EVENT_FLOW_STEP0( 1626 "input", 1627 "LatencyInfo.Flow", 1628 TRACE_ID_DONT_MANGLE(metadata.latency_info[i].trace_id), 1629 "SwapBuffers"); 1630 } 1631 renderer_->SwapBuffers(metadata); 1632 return true; 1633 } 1634 1635 void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) { 1636 if (output_surface_) 1637 output_surface_->SetNeedsBeginFrame(enable); 1638 else 1639 DCHECK(!enable); 1640 } 1641 1642 void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { 1643 // Sample the frame time now. This time will be used for updating animations 1644 // when we draw. 1645 UpdateCurrentBeginFrameArgs(args); 1646 // Cache the begin impl frame interval 1647 begin_impl_frame_interval_ = args.interval; 1648 } 1649 1650 void LayerTreeHostImpl::UpdateInnerViewportContainerSize() { 1651 LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer(); 1652 if (!container_layer) 1653 return; 1654 1655 if (top_controls_manager_) { 1656 container_layer->SetBoundsDelta( 1657 gfx::Vector2dF(0, active_tree_->top_controls_layout_height() - 1658 active_tree_->total_top_controls_content_offset())); 1659 } 1660 } 1661 1662 void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) { 1663 if (active_tree_->top_controls_layout_height() == height) 1664 return; 1665 1666 active_tree_->set_top_controls_layout_height(height); 1667 UpdateInnerViewportContainerSize(); 1668 SetFullRootLayerDamage(); 1669 } 1670 1671 void LayerTreeHostImpl::DidLoseOutputSurface() { 1672 if (resource_provider_) 1673 resource_provider_->DidLoseOutputSurface(); 1674 client_->DidLoseOutputSurfaceOnImplThread(); 1675 } 1676 1677 bool LayerTreeHostImpl::HaveRootScrollLayer() const { 1678 return !!InnerViewportScrollLayer(); 1679 } 1680 1681 LayerImpl* LayerTreeHostImpl::RootLayer() const { 1682 return active_tree_->root_layer(); 1683 } 1684 1685 LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { 1686 return active_tree_->InnerViewportScrollLayer(); 1687 } 1688 1689 LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { 1690 return active_tree_->OuterViewportScrollLayer(); 1691 } 1692 1693 LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { 1694 return active_tree_->CurrentlyScrollingLayer(); 1695 } 1696 1697 bool LayerTreeHostImpl::IsActivelyScrolling() const { 1698 return (did_lock_scrolling_layer_ && CurrentlyScrollingLayer()) || 1699 (InnerViewportScrollLayer() && 1700 InnerViewportScrollLayer()->IsExternalFlingActive()) || 1701 (OuterViewportScrollLayer() && 1702 OuterViewportScrollLayer()->IsExternalFlingActive()); 1703 } 1704 1705 // Content layers can be either directly scrollable or contained in an outer 1706 // scrolling layer which applies the scroll transform. Given a content layer, 1707 // this function returns the associated scroll layer if any. 1708 static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) { 1709 if (!layer_impl) 1710 return NULL; 1711 1712 if (layer_impl->scrollable()) 1713 return layer_impl; 1714 1715 if (layer_impl->DrawsContent() && 1716 layer_impl->parent() && 1717 layer_impl->parent()->scrollable()) 1718 return layer_impl->parent(); 1719 1720 return NULL; 1721 } 1722 1723 void LayerTreeHostImpl::CreatePendingTree() { 1724 CHECK(!pending_tree_); 1725 if (recycle_tree_) 1726 recycle_tree_.swap(pending_tree_); 1727 else 1728 pending_tree_ = LayerTreeImpl::create(this); 1729 1730 // Update the delta from the active tree, which may have 1731 // adjusted its delta prior to the pending tree being created. 1732 DCHECK_EQ(1.f, pending_tree_->sent_page_scale_delta()); 1733 DCHECK_EQ(0.f, pending_tree_->sent_top_controls_delta()); 1734 pending_tree_->SetPageScaleDelta(active_tree_->page_scale_delta() / 1735 active_tree_->sent_page_scale_delta()); 1736 pending_tree_->set_top_controls_delta( 1737 active_tree_->top_controls_delta() - 1738 active_tree_->sent_top_controls_delta()); 1739 1740 client_->OnCanDrawStateChanged(CanDraw()); 1741 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree:waiting", pending_tree_.get()); 1742 } 1743 1744 void LayerTreeHostImpl::UpdateVisibleTiles() { 1745 if (tile_manager_ && tile_manager_->UpdateVisibleTiles()) 1746 DidInitializeVisibleTile(); 1747 need_to_update_visible_tiles_before_draw_ = false; 1748 } 1749 1750 void LayerTreeHostImpl::ActivateSyncTree() { 1751 need_to_update_visible_tiles_before_draw_ = true; 1752 1753 if (pending_tree_) { 1754 TRACE_EVENT_ASYNC_END0("cc", "PendingTree:waiting", pending_tree_.get()); 1755 1756 active_tree_->SetRootLayerScrollOffsetDelegate(NULL); 1757 active_tree_->PushPersistedState(pending_tree_.get()); 1758 // Process any requests in the UI resource queue. The request queue is 1759 // given in LayerTreeHost::FinishCommitOnImplThread. This must take place 1760 // before the swap. 1761 pending_tree_->ProcessUIResourceRequestQueue(); 1762 1763 if (pending_tree_->needs_full_tree_sync()) { 1764 active_tree_->SetRootLayer( 1765 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(), 1766 active_tree_->DetachLayerTree(), 1767 active_tree_.get())); 1768 } 1769 TreeSynchronizer::PushProperties(pending_tree_->root_layer(), 1770 active_tree_->root_layer()); 1771 pending_tree_->PushPropertiesTo(active_tree_.get()); 1772 1773 // Now that we've synced everything from the pending tree to the active 1774 // tree, rename the pending tree the recycle tree so we can reuse it on the 1775 // next sync. 1776 DCHECK(!recycle_tree_); 1777 pending_tree_.swap(recycle_tree_); 1778 1779 active_tree_->SetRootLayerScrollOffsetDelegate( 1780 root_layer_scroll_offset_delegate_); 1781 1782 if (top_controls_manager_) { 1783 top_controls_manager_->SetControlsTopOffset( 1784 active_tree_->total_top_controls_content_offset() - 1785 top_controls_manager_->top_controls_height()); 1786 } 1787 1788 UpdateInnerViewportContainerSize(); 1789 } else { 1790 active_tree_->ProcessUIResourceRequestQueue(); 1791 } 1792 1793 active_tree_->DidBecomeActive(); 1794 ActivateAnimations(); 1795 if (settings_.impl_side_painting) 1796 client_->RenewTreePriority(); 1797 1798 client_->OnCanDrawStateChanged(CanDraw()); 1799 client_->DidActivateSyncTree(); 1800 if (!tree_activation_callback_.is_null()) 1801 tree_activation_callback_.Run(); 1802 1803 if (debug_state_.continuous_painting) { 1804 const RenderingStats& stats = 1805 rendering_stats_instrumentation_->GetRenderingStats(); 1806 paint_time_counter_->SavePaintTime(stats.main_stats.paint_time + 1807 stats.main_stats.record_time + 1808 stats.impl_stats.rasterize_time); 1809 } 1810 1811 if (time_source_client_adapter_ && time_source_client_adapter_->Active()) 1812 DCHECK(active_tree_->root_layer()); 1813 1814 scoped_ptr<PageScaleAnimation> page_scale_animation = 1815 active_tree_->TakePageScaleAnimation(); 1816 if (page_scale_animation) { 1817 page_scale_animation_ = page_scale_animation.Pass(); 1818 SetNeedsAnimate(); 1819 client_->SetNeedsCommitOnImplThread(); 1820 client_->RenewTreePriority(); 1821 } 1822 } 1823 1824 void LayerTreeHostImpl::SetVisible(bool visible) { 1825 DCHECK(proxy_->IsImplThread()); 1826 1827 if (visible_ == visible) 1828 return; 1829 visible_ = visible; 1830 DidVisibilityChange(this, visible_); 1831 EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy()); 1832 1833 // If we just became visible, we have to ensure that we draw high res tiles, 1834 // to prevent checkerboard/low res flashes. 1835 if (visible_) 1836 active_tree()->SetRequiresHighResToDraw(); 1837 else 1838 EvictAllUIResources(); 1839 1840 // Evict tiles immediately if invisible since this tab may never get another 1841 // draw or timer tick. 1842 if (!visible_) 1843 ManageTiles(); 1844 1845 if (!renderer_) 1846 return; 1847 1848 renderer_->SetVisible(visible); 1849 } 1850 1851 void LayerTreeHostImpl::SetNeedsAnimate() { 1852 NotifySwapPromiseMonitorsOfSetNeedsRedraw(); 1853 client_->SetNeedsAnimateOnImplThread(); 1854 } 1855 1856 void LayerTreeHostImpl::SetNeedsRedraw() { 1857 NotifySwapPromiseMonitorsOfSetNeedsRedraw(); 1858 client_->SetNeedsRedrawOnImplThread(); 1859 } 1860 1861 ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const { 1862 ManagedMemoryPolicy actual = cached_managed_memory_policy_; 1863 if (debug_state_.rasterize_only_visible_content) { 1864 actual.priority_cutoff_when_visible = 1865 gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY; 1866 } else if (use_gpu_rasterization()) { 1867 actual.priority_cutoff_when_visible = 1868 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; 1869 } 1870 1871 if (zero_budget_) { 1872 actual.bytes_limit_when_visible = 0; 1873 } 1874 1875 return actual; 1876 } 1877 1878 size_t LayerTreeHostImpl::memory_allocation_limit_bytes() const { 1879 return ActualManagedMemoryPolicy().bytes_limit_when_visible; 1880 } 1881 1882 int LayerTreeHostImpl::memory_allocation_priority_cutoff() const { 1883 return ManagedMemoryPolicy::PriorityCutoffToValue( 1884 ActualManagedMemoryPolicy().priority_cutoff_when_visible); 1885 } 1886 1887 void LayerTreeHostImpl::ReleaseTreeResources() { 1888 active_tree_->ReleaseResources(); 1889 if (pending_tree_) 1890 pending_tree_->ReleaseResources(); 1891 if (recycle_tree_) 1892 recycle_tree_->ReleaseResources(); 1893 1894 EvictAllUIResources(); 1895 } 1896 1897 void LayerTreeHostImpl::CreateAndSetRenderer() { 1898 DCHECK(!renderer_); 1899 DCHECK(output_surface_); 1900 DCHECK(resource_provider_); 1901 1902 if (output_surface_->capabilities().delegated_rendering) { 1903 renderer_ = DelegatingRenderer::Create( 1904 this, &settings_, output_surface_.get(), resource_provider_.get()); 1905 } else if (output_surface_->context_provider()) { 1906 renderer_ = GLRenderer::Create(this, 1907 &settings_, 1908 output_surface_.get(), 1909 resource_provider_.get(), 1910 texture_mailbox_deleter_.get(), 1911 settings_.highp_threshold_min); 1912 } else if (output_surface_->software_device()) { 1913 renderer_ = SoftwareRenderer::Create( 1914 this, &settings_, output_surface_.get(), resource_provider_.get()); 1915 } 1916 DCHECK(renderer_); 1917 1918 renderer_->SetVisible(visible_); 1919 SetFullRootLayerDamage(); 1920 1921 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs to be 1922 // initialized to get max texture size. Also, after releasing resources, 1923 // trees need another update to generate new ones. 1924 active_tree_->set_needs_update_draw_properties(); 1925 if (pending_tree_) 1926 pending_tree_->set_needs_update_draw_properties(); 1927 client_->UpdateRendererCapabilitiesOnImplThread(); 1928 } 1929 1930 void LayerTreeHostImpl::CreateAndSetTileManager() { 1931 DCHECK(!tile_manager_); 1932 DCHECK(settings_.impl_side_painting); 1933 DCHECK(output_surface_); 1934 DCHECK(resource_provider_); 1935 DCHECK(proxy_->ImplThreadTaskRunner()); 1936 1937 ContextProvider* context_provider = output_surface_->context_provider(); 1938 if (!context_provider) { 1939 resource_pool_ = 1940 ResourcePool::Create(resource_provider_.get(), 1941 GL_TEXTURE_2D, 1942 resource_provider_->best_texture_format()); 1943 1944 raster_worker_pool_ = 1945 BitmapRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), 1946 RasterWorkerPool::GetTaskGraphRunner(), 1947 resource_provider_.get()); 1948 } else if (use_gpu_rasterization_) { 1949 resource_pool_ = 1950 ResourcePool::Create(resource_provider_.get(), 1951 GL_TEXTURE_2D, 1952 resource_provider_->best_texture_format()); 1953 1954 raster_worker_pool_ = 1955 GpuRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), 1956 context_provider, 1957 resource_provider_.get()); 1958 } else if (UseZeroCopyRasterizer()) { 1959 resource_pool_ = ResourcePool::Create( 1960 resource_provider_.get(), 1961 GetMapImageTextureTarget(context_provider->ContextCapabilities()), 1962 resource_provider_->best_texture_format()); 1963 1964 raster_worker_pool_ = 1965 ZeroCopyRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), 1966 RasterWorkerPool::GetTaskGraphRunner(), 1967 resource_provider_.get()); 1968 } else if (UseOneCopyRasterizer()) { 1969 // We need to create a staging resource pool when using copy rasterizer. 1970 staging_resource_pool_ = ResourcePool::Create( 1971 resource_provider_.get(), 1972 GetMapImageTextureTarget(context_provider->ContextCapabilities()), 1973 resource_provider_->best_texture_format()); 1974 resource_pool_ = 1975 ResourcePool::Create(resource_provider_.get(), 1976 GL_TEXTURE_2D, 1977 resource_provider_->best_texture_format()); 1978 1979 raster_worker_pool_ = 1980 OneCopyRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), 1981 RasterWorkerPool::GetTaskGraphRunner(), 1982 context_provider, 1983 resource_provider_.get(), 1984 staging_resource_pool_.get()); 1985 } else { 1986 resource_pool_ = ResourcePool::Create( 1987 resource_provider_.get(), 1988 GL_TEXTURE_2D, 1989 resource_provider_->memory_efficient_texture_format()); 1990 1991 raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( 1992 proxy_->ImplThreadTaskRunner(), 1993 RasterWorkerPool::GetTaskGraphRunner(), 1994 context_provider, 1995 resource_provider_.get(), 1996 GetMaxTransferBufferUsageBytes(context_provider->ContextCapabilities(), 1997 settings_.refresh_rate)); 1998 } 1999 2000 tile_manager_ = 2001 TileManager::Create(this, 2002 proxy_->ImplThreadTaskRunner(), 2003 resource_pool_.get(), 2004 raster_worker_pool_->AsRasterizer(), 2005 rendering_stats_instrumentation_); 2006 2007 UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); 2008 need_to_update_visible_tiles_before_draw_ = false; 2009 } 2010 2011 void LayerTreeHostImpl::DestroyTileManager() { 2012 tile_manager_.reset(); 2013 resource_pool_.reset(); 2014 staging_resource_pool_.reset(); 2015 raster_worker_pool_.reset(); 2016 } 2017 2018 bool LayerTreeHostImpl::UsePendingTreeForSync() const { 2019 // In impl-side painting, synchronize to the pending tree so that it has 2020 // time to raster before being displayed. 2021 return settings_.impl_side_painting; 2022 } 2023 2024 bool LayerTreeHostImpl::UseZeroCopyRasterizer() const { 2025 return settings_.use_zero_copy && GetRendererCapabilities().using_map_image; 2026 } 2027 2028 bool LayerTreeHostImpl::UseOneCopyRasterizer() const { 2029 // Sync query support is required by one-copy rasterizer. 2030 return settings_.use_one_copy && GetRendererCapabilities().using_map_image && 2031 resource_provider_->use_sync_query(); 2032 } 2033 2034 void LayerTreeHostImpl::EnforceZeroBudget(bool zero_budget) { 2035 SetManagedMemoryPolicy(cached_managed_memory_policy_, zero_budget); 2036 } 2037 2038 bool LayerTreeHostImpl::InitializeRenderer( 2039 scoped_ptr<OutputSurface> output_surface) { 2040 TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer"); 2041 2042 // Since we will create a new resource provider, we cannot continue to use 2043 // the old resources (i.e. render_surfaces and texture IDs). Clear them 2044 // before we destroy the old resource provider. 2045 ReleaseTreeResources(); 2046 2047 // Note: order is important here. 2048 renderer_.reset(); 2049 DestroyTileManager(); 2050 resource_provider_.reset(); 2051 output_surface_.reset(); 2052 2053 if (!output_surface->BindToClient(this)) 2054 return false; 2055 2056 output_surface_ = output_surface.Pass(); 2057 resource_provider_ = 2058 ResourceProvider::Create(output_surface_.get(), 2059 shared_bitmap_manager_, 2060 proxy_->blocking_main_thread_task_runner(), 2061 settings_.highp_threshold_min, 2062 settings_.use_rgba_4444_textures, 2063 settings_.texture_id_allocation_chunk_size, 2064 settings_.use_distance_field_text); 2065 2066 if (output_surface_->capabilities().deferred_gl_initialization) 2067 EnforceZeroBudget(true); 2068 2069 CreateAndSetRenderer(); 2070 2071 if (settings_.impl_side_painting) 2072 CreateAndSetTileManager(); 2073 2074 // Initialize vsync parameters to sane values. 2075 const base::TimeDelta display_refresh_interval = 2076 base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / 2077 settings_.refresh_rate); 2078 CommitVSyncParameters(base::TimeTicks(), display_refresh_interval); 2079 2080 // TODO(brianderson): Don't use a hard-coded parent draw time. 2081 base::TimeDelta parent_draw_time = 2082 (!settings_.begin_frame_scheduling_enabled && 2083 output_surface_->capabilities().adjust_deadline_for_parent) 2084 ? BeginFrameArgs::DefaultEstimatedParentDrawTime() 2085 : base::TimeDelta(); 2086 client_->SetEstimatedParentDrawTime(parent_draw_time); 2087 2088 int max_frames_pending = output_surface_->capabilities().max_frames_pending; 2089 if (max_frames_pending <= 0) 2090 max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING; 2091 client_->SetMaxSwapsPendingOnImplThread(max_frames_pending); 2092 client_->OnCanDrawStateChanged(CanDraw()); 2093 2094 // There will not be anything to draw here, so set high res 2095 // to avoid checkerboards, typically when we are recovering 2096 // from lost context. 2097 active_tree_->SetRequiresHighResToDraw(); 2098 2099 return true; 2100 } 2101 2102 void LayerTreeHostImpl::CommitVSyncParameters(base::TimeTicks timebase, 2103 base::TimeDelta interval) { 2104 client_->CommitVSyncParameters(timebase, interval); 2105 } 2106 2107 void LayerTreeHostImpl::DeferredInitialize() { 2108 DCHECK(output_surface_->capabilities().deferred_gl_initialization); 2109 DCHECK(settings_.impl_side_painting); 2110 DCHECK(output_surface_->context_provider()); 2111 2112 ReleaseTreeResources(); 2113 renderer_.reset(); 2114 DestroyTileManager(); 2115 2116 resource_provider_->InitializeGL(); 2117 2118 CreateAndSetRenderer(); 2119 EnforceZeroBudget(false); 2120 CreateAndSetTileManager(); 2121 2122 client_->SetNeedsCommitOnImplThread(); 2123 } 2124 2125 void LayerTreeHostImpl::ReleaseGL() { 2126 DCHECK(output_surface_->capabilities().deferred_gl_initialization); 2127 DCHECK(settings_.impl_side_painting); 2128 DCHECK(output_surface_->context_provider()); 2129 2130 ReleaseTreeResources(); 2131 renderer_.reset(); 2132 DestroyTileManager(); 2133 2134 resource_provider_->InitializeSoftware(); 2135 output_surface_->ReleaseContextProvider(); 2136 2137 CreateAndSetRenderer(); 2138 EnforceZeroBudget(true); 2139 CreateAndSetTileManager(); 2140 2141 client_->SetNeedsCommitOnImplThread(); 2142 } 2143 2144 void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { 2145 if (device_viewport_size == device_viewport_size_) 2146 return; 2147 2148 if (pending_tree_) 2149 active_tree_->SetViewportSizeInvalid(); 2150 2151 device_viewport_size_ = device_viewport_size; 2152 2153 UpdateInnerViewportContainerSize(); 2154 client_->OnCanDrawStateChanged(CanDraw()); 2155 SetFullRootLayerDamage(); 2156 active_tree_->set_needs_update_draw_properties(); 2157 } 2158 2159 void LayerTreeHostImpl::SetOverhangUIResource( 2160 UIResourceId overhang_ui_resource_id, 2161 const gfx::Size& overhang_ui_resource_size) { 2162 overhang_ui_resource_id_ = overhang_ui_resource_id; 2163 overhang_ui_resource_size_ = overhang_ui_resource_size; 2164 } 2165 2166 void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { 2167 if (device_scale_factor == device_scale_factor_) 2168 return; 2169 device_scale_factor_ = device_scale_factor; 2170 2171 SetFullRootLayerDamage(); 2172 } 2173 2174 const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const { 2175 if (viewport_rect_for_tile_priority_.IsEmpty()) 2176 return DeviceViewport(); 2177 2178 return viewport_rect_for_tile_priority_; 2179 } 2180 2181 gfx::Size LayerTreeHostImpl::DrawViewportSize() const { 2182 return DeviceViewport().size(); 2183 } 2184 2185 gfx::Rect LayerTreeHostImpl::DeviceViewport() const { 2186 if (external_viewport_.IsEmpty()) 2187 return gfx::Rect(device_viewport_size_); 2188 2189 return external_viewport_; 2190 } 2191 2192 gfx::Rect LayerTreeHostImpl::DeviceClip() const { 2193 if (external_clip_.IsEmpty()) 2194 return DeviceViewport(); 2195 2196 return external_clip_; 2197 } 2198 2199 const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { 2200 return external_transform_; 2201 } 2202 2203 void LayerTreeHostImpl::DidChangeTopControlsPosition() { 2204 UpdateInnerViewportContainerSize(); 2205 SetNeedsRedraw(); 2206 SetNeedsAnimate(); 2207 active_tree_->set_needs_update_draw_properties(); 2208 SetFullRootLayerDamage(); 2209 } 2210 2211 void LayerTreeHostImpl::SetControlsTopOffset(float offset) { 2212 float current_top_offset = active_tree_->top_controls_content_offset() - 2213 top_controls_manager_->top_controls_height(); 2214 active_tree_->set_top_controls_delta(offset - current_top_offset); 2215 } 2216 2217 float LayerTreeHostImpl::ControlsTopOffset() const { 2218 return active_tree_->total_top_controls_content_offset() - 2219 top_controls_manager_->top_controls_height(); 2220 } 2221 2222 void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { 2223 DCHECK(input_handler_client_ == NULL); 2224 input_handler_client_ = client; 2225 } 2226 2227 static LayerImpl* NextScrollLayer(LayerImpl* layer) { 2228 if (LayerImpl* scroll_parent = layer->scroll_parent()) 2229 return scroll_parent; 2230 return layer->parent(); 2231 } 2232 2233 LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( 2234 const gfx::PointF& device_viewport_point, 2235 InputHandler::ScrollInputType type, 2236 LayerImpl* layer_impl, 2237 bool* scroll_on_main_thread, 2238 bool* optional_has_ancestor_scroll_handler) const { 2239 DCHECK(scroll_on_main_thread); 2240 2241 // Walk up the hierarchy and look for a scrollable layer. 2242 LayerImpl* potentially_scrolling_layer_impl = NULL; 2243 for (; layer_impl; layer_impl = NextScrollLayer(layer_impl)) { 2244 // The content layer can also block attempts to scroll outside the main 2245 // thread. 2246 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); 2247 if (status == ScrollOnMainThread) { 2248 *scroll_on_main_thread = true; 2249 return NULL; 2250 } 2251 2252 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl); 2253 if (!scroll_layer_impl) 2254 continue; 2255 2256 status = scroll_layer_impl->TryScroll(device_viewport_point, type); 2257 // If any layer wants to divert the scroll event to the main thread, abort. 2258 if (status == ScrollOnMainThread) { 2259 *scroll_on_main_thread = true; 2260 return NULL; 2261 } 2262 2263 if (optional_has_ancestor_scroll_handler && 2264 scroll_layer_impl->have_scroll_event_handlers()) 2265 *optional_has_ancestor_scroll_handler = true; 2266 2267 if (status == ScrollStarted && !potentially_scrolling_layer_impl) 2268 potentially_scrolling_layer_impl = scroll_layer_impl; 2269 } 2270 2271 // Falling back to the root scroll layer ensures generation of root overscroll 2272 // notifications while preventing scroll updates from being unintentionally 2273 // forwarded to the main thread. 2274 if (!potentially_scrolling_layer_impl) 2275 potentially_scrolling_layer_impl = OuterViewportScrollLayer() 2276 ? OuterViewportScrollLayer() 2277 : InnerViewportScrollLayer(); 2278 2279 return potentially_scrolling_layer_impl; 2280 } 2281 2282 // Similar to LayerImpl::HasAncestor, but walks up the scroll parents. 2283 static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) { 2284 DCHECK(scroll_ancestor); 2285 for (LayerImpl* ancestor = child; ancestor; 2286 ancestor = NextScrollLayer(ancestor)) { 2287 if (ancestor->scrollable()) 2288 return ancestor == scroll_ancestor; 2289 } 2290 return false; 2291 } 2292 2293 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( 2294 const gfx::Point& viewport_point, 2295 InputHandler::ScrollInputType type) { 2296 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); 2297 2298 if (top_controls_manager_) 2299 top_controls_manager_->ScrollBegin(); 2300 2301 DCHECK(!CurrentlyScrollingLayer()); 2302 ClearCurrentlyScrollingLayer(); 2303 2304 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, 2305 device_scale_factor_); 2306 LayerImpl* layer_impl = 2307 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); 2308 2309 if (layer_impl) { 2310 LayerImpl* scroll_layer_impl = 2311 active_tree_->FindFirstScrollingLayerThatIsHitByPoint( 2312 device_viewport_point); 2313 if (scroll_layer_impl && !HasScrollAncestor(layer_impl, scroll_layer_impl)) 2314 return ScrollUnknown; 2315 } 2316 2317 bool scroll_on_main_thread = false; 2318 LayerImpl* scrolling_layer_impl = 2319 FindScrollLayerForDeviceViewportPoint(device_viewport_point, 2320 type, 2321 layer_impl, 2322 &scroll_on_main_thread, 2323 &scroll_affects_scroll_handler_); 2324 2325 if (scroll_on_main_thread) { 2326 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); 2327 return ScrollOnMainThread; 2328 } 2329 2330 if (scrolling_layer_impl) { 2331 active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl); 2332 should_bubble_scrolls_ = (type != NonBubblingGesture); 2333 wheel_scrolling_ = (type == Wheel); 2334 client_->RenewTreePriority(); 2335 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); 2336 return ScrollStarted; 2337 } 2338 return ScrollIgnored; 2339 } 2340 2341 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( 2342 const gfx::Point& viewport_point, 2343 const gfx::Vector2dF& scroll_delta) { 2344 if (LayerImpl* layer_impl = CurrentlyScrollingLayer()) { 2345 Animation* animation = 2346 layer_impl->layer_animation_controller()->GetAnimation( 2347 Animation::ScrollOffset); 2348 if (!animation) 2349 return ScrollIgnored; 2350 2351 ScrollOffsetAnimationCurve* curve = 2352 animation->curve()->ToScrollOffsetAnimationCurve(); 2353 2354 gfx::Vector2dF new_target = curve->target_value() + scroll_delta; 2355 new_target.SetToMax(gfx::Vector2dF()); 2356 new_target.SetToMin(layer_impl->MaxScrollOffset()); 2357 2358 curve->UpdateTarget(animation->TrimTimeToCurrentIteration( 2359 CurrentBeginFrameArgs().frame_time), 2360 new_target); 2361 2362 return ScrollStarted; 2363 } 2364 // ScrollAnimated is only used for wheel scrolls. We use the same bubbling 2365 // behavior as ScrollBy to determine which layer to animate, but we do not 2366 // do the Android-specific things in ScrollBy like showing top controls. 2367 InputHandler::ScrollStatus scroll_status = ScrollBegin(viewport_point, Wheel); 2368 if (scroll_status == ScrollStarted) { 2369 gfx::Vector2dF pending_delta = scroll_delta; 2370 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl; 2371 layer_impl = layer_impl->parent()) { 2372 if (!layer_impl->scrollable()) 2373 continue; 2374 2375 gfx::Vector2dF current_offset = layer_impl->TotalScrollOffset(); 2376 gfx::Vector2dF target_offset = current_offset + pending_delta; 2377 target_offset.SetToMax(gfx::Vector2dF()); 2378 target_offset.SetToMin(layer_impl->MaxScrollOffset()); 2379 gfx::Vector2dF actual_delta = target_offset - current_offset; 2380 2381 const float kEpsilon = 0.1f; 2382 bool can_layer_scroll = (std::abs(actual_delta.x()) > kEpsilon || 2383 std::abs(actual_delta.y()) > kEpsilon); 2384 2385 if (!can_layer_scroll) { 2386 layer_impl->ScrollBy(actual_delta); 2387 pending_delta -= actual_delta; 2388 continue; 2389 } 2390 2391 active_tree_->SetCurrentlyScrollingLayer(layer_impl); 2392 2393 scoped_ptr<ScrollOffsetAnimationCurve> curve = 2394 ScrollOffsetAnimationCurve::Create(target_offset, 2395 EaseInOutTimingFunction::Create()); 2396 curve->SetInitialValue(current_offset); 2397 2398 scoped_ptr<Animation> animation = 2399 Animation::Create(curve.PassAs<AnimationCurve>(), 2400 AnimationIdProvider::NextAnimationId(), 2401 AnimationIdProvider::NextGroupId(), 2402 Animation::ScrollOffset); 2403 animation->set_is_impl_only(true); 2404 2405 layer_impl->layer_animation_controller()->AddAnimation(animation.Pass()); 2406 2407 SetNeedsAnimate(); 2408 return ScrollStarted; 2409 } 2410 } 2411 ScrollEnd(); 2412 return scroll_status; 2413 } 2414 2415 gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta( 2416 LayerImpl* layer_impl, 2417 float scale_from_viewport_to_screen_space, 2418 const gfx::PointF& viewport_point, 2419 const gfx::Vector2dF& viewport_delta) { 2420 // Layers with non-invertible screen space transforms should not have passed 2421 // the scroll hit test in the first place. 2422 DCHECK(layer_impl->screen_space_transform().IsInvertible()); 2423 gfx::Transform inverse_screen_space_transform( 2424 gfx::Transform::kSkipInitialization); 2425 bool did_invert = layer_impl->screen_space_transform().GetInverse( 2426 &inverse_screen_space_transform); 2427 // TODO(shawnsingh): With the advent of impl-side crolling for non-root 2428 // layers, we may need to explicitly handle uninvertible transforms here. 2429 DCHECK(did_invert); 2430 2431 gfx::PointF screen_space_point = 2432 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space); 2433 2434 gfx::Vector2dF screen_space_delta = viewport_delta; 2435 screen_space_delta.Scale(scale_from_viewport_to_screen_space); 2436 2437 // First project the scroll start and end points to local layer space to find 2438 // the scroll delta in layer coordinates. 2439 bool start_clipped, end_clipped; 2440 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta; 2441 gfx::PointF local_start_point = 2442 MathUtil::ProjectPoint(inverse_screen_space_transform, 2443 screen_space_point, 2444 &start_clipped); 2445 gfx::PointF local_end_point = 2446 MathUtil::ProjectPoint(inverse_screen_space_transform, 2447 screen_space_end_point, 2448 &end_clipped); 2449 2450 // In general scroll point coordinates should not get clipped. 2451 DCHECK(!start_clipped); 2452 DCHECK(!end_clipped); 2453 if (start_clipped || end_clipped) 2454 return gfx::Vector2dF(); 2455 2456 // local_start_point and local_end_point are in content space but we want to 2457 // move them to layer space for scrolling. 2458 float width_scale = 1.f / layer_impl->contents_scale_x(); 2459 float height_scale = 1.f / layer_impl->contents_scale_y(); 2460 local_start_point.Scale(width_scale, height_scale); 2461 local_end_point.Scale(width_scale, height_scale); 2462 2463 // Apply the scroll delta. 2464 gfx::Vector2dF previous_delta = layer_impl->ScrollDelta(); 2465 layer_impl->ScrollBy(local_end_point - local_start_point); 2466 2467 // Get the end point in the layer's content space so we can apply its 2468 // ScreenSpaceTransform. 2469 gfx::PointF actual_local_end_point = local_start_point + 2470 layer_impl->ScrollDelta() - 2471 previous_delta; 2472 gfx::PointF actual_local_content_end_point = 2473 gfx::ScalePoint(actual_local_end_point, 2474 1.f / width_scale, 2475 1.f / height_scale); 2476 2477 // Calculate the applied scroll delta in viewport space coordinates. 2478 gfx::PointF actual_screen_space_end_point = 2479 MathUtil::MapPoint(layer_impl->screen_space_transform(), 2480 actual_local_content_end_point, 2481 &end_clipped); 2482 DCHECK(!end_clipped); 2483 if (end_clipped) 2484 return gfx::Vector2dF(); 2485 gfx::PointF actual_viewport_end_point = 2486 gfx::ScalePoint(actual_screen_space_end_point, 2487 1.f / scale_from_viewport_to_screen_space); 2488 return actual_viewport_end_point - viewport_point; 2489 } 2490 2491 static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, 2492 const gfx::Vector2dF& local_delta) { 2493 gfx::Vector2dF previous_delta(layer_impl->ScrollDelta()); 2494 layer_impl->ScrollBy(local_delta); 2495 return layer_impl->ScrollDelta() - previous_delta; 2496 } 2497 2498 bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, 2499 const gfx::Vector2dF& scroll_delta) { 2500 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); 2501 if (!CurrentlyScrollingLayer()) 2502 return false; 2503 2504 gfx::Vector2dF pending_delta = scroll_delta; 2505 gfx::Vector2dF unused_root_delta; 2506 bool did_scroll_x = false; 2507 bool did_scroll_y = false; 2508 bool did_scroll_top_controls = false; 2509 // TODO(wjmaclean) Should we guard against CurrentlyScrollingLayer() == 0 2510 // here? 2511 bool consume_by_top_controls = 2512 top_controls_manager_ && 2513 (((CurrentlyScrollingLayer() == InnerViewportScrollLayer() || 2514 CurrentlyScrollingLayer() == OuterViewportScrollLayer()) && 2515 InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) || 2516 scroll_delta.y() < 0); 2517 2518 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); 2519 layer_impl; 2520 layer_impl = layer_impl->parent()) { 2521 if (!layer_impl->scrollable()) 2522 continue; 2523 2524 if (layer_impl == InnerViewportScrollLayer()) { 2525 // Only allow bubble scrolling when the scroll is in the direction to make 2526 // the top controls visible. 2527 gfx::Vector2dF applied_delta; 2528 gfx::Vector2dF excess_delta; 2529 if (consume_by_top_controls) { 2530 excess_delta = top_controls_manager_->ScrollBy(pending_delta); 2531 applied_delta = pending_delta - excess_delta; 2532 pending_delta = excess_delta; 2533 // Force updating of vertical adjust values if needed. 2534 if (applied_delta.y() != 0) { 2535 did_scroll_top_controls = true; 2536 layer_impl->ScrollbarParametersDidChange(); 2537 } 2538 } 2539 // Track root layer deltas for reporting overscroll. 2540 unused_root_delta = pending_delta; 2541 } 2542 2543 gfx::Vector2dF applied_delta; 2544 // Gesture events need to be transformed from viewport coordinates to local 2545 // layer coordinates so that the scrolling contents exactly follow the 2546 // user's finger. In contrast, wheel events represent a fixed amount of 2547 // scrolling so we can just apply them directly. 2548 if (!wheel_scrolling_) { 2549 float scale_from_viewport_to_screen_space = device_scale_factor_; 2550 applied_delta = 2551 ScrollLayerWithViewportSpaceDelta(layer_impl, 2552 scale_from_viewport_to_screen_space, 2553 viewport_point, pending_delta); 2554 } else { 2555 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta); 2556 } 2557 2558 const float kEpsilon = 0.1f; 2559 if (layer_impl == InnerViewportScrollLayer()) { 2560 unused_root_delta.Subtract(applied_delta); 2561 if (std::abs(unused_root_delta.x()) < kEpsilon) 2562 unused_root_delta.set_x(0.0f); 2563 if (std::abs(unused_root_delta.y()) < kEpsilon) 2564 unused_root_delta.set_y(0.0f); 2565 // Disable overscroll on axes which is impossible to scroll. 2566 if (settings_.report_overscroll_only_for_scrollable_axes) { 2567 if (std::abs(active_tree_->TotalMaxScrollOffset().x()) <= kEpsilon) 2568 unused_root_delta.set_x(0.0f); 2569 if (std::abs(active_tree_->TotalMaxScrollOffset().y()) <= kEpsilon) 2570 unused_root_delta.set_y(0.0f); 2571 } 2572 } 2573 2574 // If the layer wasn't able to move, try the next one in the hierarchy. 2575 bool did_move_layer_x = std::abs(applied_delta.x()) > kEpsilon; 2576 bool did_move_layer_y = std::abs(applied_delta.y()) > kEpsilon; 2577 did_scroll_x |= did_move_layer_x; 2578 did_scroll_y |= did_move_layer_y; 2579 if (!did_move_layer_x && !did_move_layer_y) { 2580 // Scrolls should always bubble between the outer and inner viewports 2581 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_ || 2582 layer_impl == OuterViewportScrollLayer()) 2583 continue; 2584 else 2585 break; 2586 } 2587 2588 did_lock_scrolling_layer_ = true; 2589 if (!should_bubble_scrolls_) { 2590 active_tree_->SetCurrentlyScrollingLayer(layer_impl); 2591 break; 2592 } 2593 2594 // If the applied delta is within 45 degrees of the input delta, bail out to 2595 // make it easier to scroll just one layer in one direction without 2596 // affecting any of its parents. 2597 float angle_threshold = 45; 2598 if (MathUtil::SmallestAngleBetweenVectors( 2599 applied_delta, pending_delta) < angle_threshold) { 2600 pending_delta = gfx::Vector2d(); 2601 break; 2602 } 2603 2604 // Allow further movement only on an axis perpendicular to the direction in 2605 // which the layer moved. 2606 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x()); 2607 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis); 2608 2609 if (gfx::ToRoundedVector2d(pending_delta).IsZero()) 2610 break; 2611 } 2612 2613 bool did_scroll_content = did_scroll_x || did_scroll_y; 2614 if (did_scroll_content) { 2615 // If we are scrolling with an active scroll handler, forward latency 2616 // tracking information to the main thread so the delay introduced by the 2617 // handler is accounted for. 2618 if (scroll_affects_scroll_handler()) 2619 NotifySwapPromiseMonitorsOfForwardingToMainThread(); 2620 client_->SetNeedsCommitOnImplThread(); 2621 SetNeedsRedraw(); 2622 client_->RenewTreePriority(); 2623 } 2624 2625 // Scrolling along an axis resets accumulated root overscroll for that axis. 2626 if (did_scroll_x) 2627 accumulated_root_overscroll_.set_x(0); 2628 if (did_scroll_y) 2629 accumulated_root_overscroll_.set_y(0); 2630 2631 accumulated_root_overscroll_ += unused_root_delta; 2632 bool did_overscroll = !unused_root_delta.IsZero(); 2633 if (did_overscroll && input_handler_client_) { 2634 input_handler_client_->DidOverscroll( 2635 viewport_point, accumulated_root_overscroll_, unused_root_delta); 2636 } 2637 2638 return did_scroll_content || did_scroll_top_controls; 2639 } 2640 2641 // This implements scrolling by page as described here: 2642 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel 2643 // for events with WHEEL_PAGESCROLL set. 2644 bool LayerTreeHostImpl::ScrollVerticallyByPage(const gfx::Point& viewport_point, 2645 ScrollDirection direction) { 2646 DCHECK(wheel_scrolling_); 2647 2648 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); 2649 layer_impl; 2650 layer_impl = layer_impl->parent()) { 2651 if (!layer_impl->scrollable()) 2652 continue; 2653 2654 if (!layer_impl->HasScrollbar(VERTICAL)) 2655 continue; 2656 2657 float height = layer_impl->clip_height(); 2658 2659 // These magical values match WebKit and are designed to scroll nearly the 2660 // entire visible content height but leave a bit of overlap. 2661 float page = std::max(height * 0.875f, 1.f); 2662 if (direction == SCROLL_BACKWARD) 2663 page = -page; 2664 2665 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page); 2666 2667 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta); 2668 2669 if (!applied_delta.IsZero()) { 2670 client_->SetNeedsCommitOnImplThread(); 2671 SetNeedsRedraw(); 2672 client_->RenewTreePriority(); 2673 return true; 2674 } 2675 2676 active_tree_->SetCurrentlyScrollingLayer(layer_impl); 2677 } 2678 2679 return false; 2680 } 2681 2682 void LayerTreeHostImpl::SetRootLayerScrollOffsetDelegate( 2683 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) { 2684 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate; 2685 active_tree_->SetRootLayerScrollOffsetDelegate( 2686 root_layer_scroll_offset_delegate_); 2687 } 2688 2689 void LayerTreeHostImpl::OnRootLayerDelegatedScrollOffsetChanged() { 2690 DCHECK(root_layer_scroll_offset_delegate_ != NULL); 2691 client_->SetNeedsCommitOnImplThread(); 2692 active_tree_->set_needs_update_draw_properties(); 2693 } 2694 2695 void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { 2696 active_tree_->ClearCurrentlyScrollingLayer(); 2697 did_lock_scrolling_layer_ = false; 2698 scroll_affects_scroll_handler_ = false; 2699 accumulated_root_overscroll_ = gfx::Vector2dF(); 2700 } 2701 2702 void LayerTreeHostImpl::ScrollEnd() { 2703 if (top_controls_manager_) 2704 top_controls_manager_->ScrollEnd(); 2705 ClearCurrentlyScrollingLayer(); 2706 } 2707 2708 InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { 2709 if (!active_tree_->CurrentlyScrollingLayer()) 2710 return ScrollIgnored; 2711 2712 if (settings_.ignore_root_layer_flings && 2713 (active_tree_->CurrentlyScrollingLayer() == InnerViewportScrollLayer() || 2714 active_tree_->CurrentlyScrollingLayer() == OuterViewportScrollLayer())) { 2715 ClearCurrentlyScrollingLayer(); 2716 return ScrollIgnored; 2717 } 2718 2719 if (!wheel_scrolling_) { 2720 // Allow the fling to lock to the first layer that moves after the initial 2721 // fling |ScrollBy()| event. 2722 did_lock_scrolling_layer_ = false; 2723 should_bubble_scrolls_ = false; 2724 } 2725 2726 return ScrollStarted; 2727 } 2728 2729 float LayerTreeHostImpl::DeviceSpaceDistanceToLayer( 2730 const gfx::PointF& device_viewport_point, 2731 LayerImpl* layer_impl) { 2732 if (!layer_impl) 2733 return std::numeric_limits<float>::max(); 2734 2735 gfx::Rect layer_impl_bounds( 2736 layer_impl->content_bounds()); 2737 2738 gfx::RectF device_viewport_layer_impl_bounds = MathUtil::MapClippedRect( 2739 layer_impl->screen_space_transform(), 2740 layer_impl_bounds); 2741 2742 return device_viewport_layer_impl_bounds.ManhattanDistanceToPoint( 2743 device_viewport_point); 2744 } 2745 2746 void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { 2747 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, 2748 device_scale_factor_); 2749 LayerImpl* layer_impl = 2750 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); 2751 if (HandleMouseOverScrollbar(layer_impl, device_viewport_point)) 2752 return; 2753 2754 if (scroll_layer_id_when_mouse_over_scrollbar_) { 2755 LayerImpl* scroll_layer_impl = active_tree_->LayerById( 2756 scroll_layer_id_when_mouse_over_scrollbar_); 2757 2758 // The check for a null scroll_layer_impl below was added to see if it will 2759 // eliminate the crashes described in http://crbug.com/326635. 2760 // TODO(wjmaclean) Add a unit test if this fixes the crashes. 2761 ScrollbarAnimationController* animation_controller = 2762 scroll_layer_impl ? scroll_layer_impl->scrollbar_animation_controller() 2763 : NULL; 2764 if (animation_controller) 2765 animation_controller->DidMouseMoveOffScrollbar(); 2766 scroll_layer_id_when_mouse_over_scrollbar_ = 0; 2767 } 2768 2769 bool scroll_on_main_thread = false; 2770 LayerImpl* scroll_layer_impl = 2771 FindScrollLayerForDeviceViewportPoint(device_viewport_point, 2772 InputHandler::Gesture, 2773 layer_impl, 2774 &scroll_on_main_thread, 2775 NULL); 2776 if (scroll_on_main_thread || !scroll_layer_impl) 2777 return; 2778 2779 ScrollbarAnimationController* animation_controller = 2780 scroll_layer_impl->scrollbar_animation_controller(); 2781 if (!animation_controller) 2782 return; 2783 2784 // TODO(wjmaclean) Is it ok to choose distance from more than two scrollbars? 2785 float distance_to_scrollbar = std::numeric_limits<float>::max(); 2786 for (LayerImpl::ScrollbarSet::iterator it = 2787 scroll_layer_impl->scrollbars()->begin(); 2788 it != scroll_layer_impl->scrollbars()->end(); 2789 ++it) 2790 distance_to_scrollbar = 2791 std::min(distance_to_scrollbar, 2792 DeviceSpaceDistanceToLayer(device_viewport_point, *it)); 2793 2794 animation_controller->DidMouseMoveNear(distance_to_scrollbar / 2795 device_scale_factor_); 2796 } 2797 2798 bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl, 2799 const gfx::PointF& device_viewport_point) { 2800 if (layer_impl && layer_impl->ToScrollbarLayer()) { 2801 int scroll_layer_id = layer_impl->ToScrollbarLayer()->ScrollLayerId(); 2802 layer_impl = active_tree_->LayerById(scroll_layer_id); 2803 if (layer_impl && layer_impl->scrollbar_animation_controller()) { 2804 scroll_layer_id_when_mouse_over_scrollbar_ = scroll_layer_id; 2805 layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(0); 2806 } else { 2807 scroll_layer_id_when_mouse_over_scrollbar_ = 0; 2808 } 2809 2810 return true; 2811 } 2812 2813 return false; 2814 } 2815 2816 void LayerTreeHostImpl::PinchGestureBegin() { 2817 pinch_gesture_active_ = true; 2818 previous_pinch_anchor_ = gfx::Point(); 2819 client_->RenewTreePriority(); 2820 pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer(); 2821 if (active_tree_->OuterViewportScrollLayer()) { 2822 active_tree_->SetCurrentlyScrollingLayer( 2823 active_tree_->OuterViewportScrollLayer()); 2824 } else { 2825 active_tree_->SetCurrentlyScrollingLayer( 2826 active_tree_->InnerViewportScrollLayer()); 2827 } 2828 if (top_controls_manager_) 2829 top_controls_manager_->PinchBegin(); 2830 } 2831 2832 void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, 2833 const gfx::Point& anchor) { 2834 if (!InnerViewportScrollLayer()) 2835 return; 2836 2837 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate"); 2838 2839 // For a moment the scroll offset ends up being outside of the max range. This 2840 // confuses the delegate so we switch it off till after we're done processing 2841 // the pinch update. 2842 active_tree_->SetRootLayerScrollOffsetDelegate(NULL); 2843 2844 // Keep the center-of-pinch anchor specified by (x, y) in a stable 2845 // position over the course of the magnify. 2846 float page_scale_delta = active_tree_->page_scale_delta(); 2847 gfx::PointF previous_scale_anchor = 2848 gfx::ScalePoint(anchor, 1.f / page_scale_delta); 2849 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta); 2850 page_scale_delta = active_tree_->page_scale_delta(); 2851 gfx::PointF new_scale_anchor = 2852 gfx::ScalePoint(anchor, 1.f / page_scale_delta); 2853 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor; 2854 2855 previous_pinch_anchor_ = anchor; 2856 2857 move.Scale(1 / active_tree_->page_scale_factor()); 2858 // If clamping the inner viewport scroll offset causes a change, it should 2859 // be accounted for from the intended move. 2860 move -= InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset(); 2861 2862 // We manually manage the bubbling behaviour here as it is different to that 2863 // implemented in LayerTreeHostImpl::ScrollBy(). Specifically: 2864 // 1) we want to explicit limit the bubbling to the outer/inner viewports, 2865 // 2) we don't want the directional limitations on the unused parts that 2866 // ScrollBy() implements, and 2867 // 3) pinching should not engage the top controls manager. 2868 gfx::Vector2dF unused = OuterViewportScrollLayer() 2869 ? OuterViewportScrollLayer()->ScrollBy(move) 2870 : move; 2871 2872 if (!unused.IsZero()) { 2873 InnerViewportScrollLayer()->ScrollBy(unused); 2874 InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset(); 2875 } 2876 2877 active_tree_->SetRootLayerScrollOffsetDelegate( 2878 root_layer_scroll_offset_delegate_); 2879 2880 client_->SetNeedsCommitOnImplThread(); 2881 SetNeedsRedraw(); 2882 client_->RenewTreePriority(); 2883 } 2884 2885 void LayerTreeHostImpl::PinchGestureEnd() { 2886 pinch_gesture_active_ = false; 2887 if (pinch_gesture_end_should_clear_scrolling_layer_) { 2888 pinch_gesture_end_should_clear_scrolling_layer_ = false; 2889 ClearCurrentlyScrollingLayer(); 2890 } 2891 if (top_controls_manager_) 2892 top_controls_manager_->PinchEnd(); 2893 client_->SetNeedsCommitOnImplThread(); 2894 // When a pinch ends, we may be displaying content cached at incorrect scales, 2895 // so updating draw properties and drawing will ensure we are using the right 2896 // scales that we want when we're not inside a pinch. 2897 active_tree_->set_needs_update_draw_properties(); 2898 SetNeedsRedraw(); 2899 // TODO(danakj): Don't set root damage. Just updating draw properties and 2900 // getting new tiles rastered should be enough! crbug.com/427423 2901 SetFullRootLayerDamage(); 2902 } 2903 2904 static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, 2905 LayerImpl* layer_impl) { 2906 if (!layer_impl) 2907 return; 2908 2909 gfx::Vector2d scroll_delta = 2910 gfx::ToFlooredVector2d(layer_impl->ScrollDelta()); 2911 if (!scroll_delta.IsZero()) { 2912 LayerTreeHostCommon::ScrollUpdateInfo scroll; 2913 scroll.layer_id = layer_impl->id(); 2914 scroll.scroll_delta = scroll_delta; 2915 scroll_info->scrolls.push_back(scroll); 2916 layer_impl->SetSentScrollDelta(scroll_delta); 2917 } 2918 2919 for (size_t i = 0; i < layer_impl->children().size(); ++i) 2920 CollectScrollDeltas(scroll_info, layer_impl->children()[i]); 2921 } 2922 2923 scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { 2924 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); 2925 2926 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); 2927 scroll_info->page_scale_delta = active_tree_->page_scale_delta(); 2928 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta); 2929 scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_); 2930 scroll_info->top_controls_delta = active_tree()->top_controls_delta(); 2931 active_tree_->set_sent_top_controls_delta(scroll_info->top_controls_delta); 2932 2933 return scroll_info.Pass(); 2934 } 2935 2936 void LayerTreeHostImpl::SetFullRootLayerDamage() { 2937 SetViewportDamage(gfx::Rect(DrawViewportSize())); 2938 } 2939 2940 void LayerTreeHostImpl::ScrollViewportBy(gfx::Vector2dF scroll_delta) { 2941 DCHECK(InnerViewportScrollLayer()); 2942 LayerImpl* scroll_layer = OuterViewportScrollLayer() 2943 ? OuterViewportScrollLayer() 2944 : InnerViewportScrollLayer(); 2945 2946 gfx::Vector2dF unused_delta = scroll_layer->ScrollBy(scroll_delta); 2947 2948 if (!unused_delta.IsZero() && (scroll_layer == OuterViewportScrollLayer())) 2949 InnerViewportScrollLayer()->ScrollBy(unused_delta); 2950 } 2951 2952 void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { 2953 if (!page_scale_animation_) 2954 return; 2955 2956 gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); 2957 2958 if (!page_scale_animation_->IsAnimationStarted()) 2959 page_scale_animation_->StartAnimation(monotonic_time); 2960 2961 active_tree_->SetPageScaleDelta( 2962 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) / 2963 active_tree_->page_scale_factor()); 2964 gfx::Vector2dF next_scroll = 2965 page_scale_animation_->ScrollOffsetAtTime(monotonic_time); 2966 2967 ScrollViewportBy(next_scroll - scroll_total); 2968 SetNeedsRedraw(); 2969 2970 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { 2971 page_scale_animation_.reset(); 2972 client_->SetNeedsCommitOnImplThread(); 2973 client_->RenewTreePriority(); 2974 } else { 2975 SetNeedsAnimate(); 2976 } 2977 } 2978 2979 void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { 2980 if (!top_controls_manager_ || !top_controls_manager_->animation()) 2981 return; 2982 2983 gfx::Vector2dF scroll = top_controls_manager_->Animate(time); 2984 2985 if (top_controls_manager_->animation()) 2986 SetNeedsAnimate(); 2987 2988 if (active_tree_->TotalScrollOffset().y() == 0.f) 2989 return; 2990 2991 if (scroll.IsZero()) 2992 return; 2993 2994 ScrollViewportBy(gfx::ScaleVector2d( 2995 scroll, 1.f / active_tree_->total_page_scale_factor())); 2996 SetNeedsRedraw(); 2997 client_->SetNeedsCommitOnImplThread(); 2998 client_->RenewTreePriority(); 2999 } 3000 3001 void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { 3002 if (!settings_.accelerated_animation_enabled || 3003 !needs_animate_layers() || 3004 !active_tree_->root_layer()) 3005 return; 3006 3007 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers"); 3008 AnimationRegistrar::AnimationControllerMap copy = 3009 animation_registrar_->active_animation_controllers(); 3010 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 3011 iter != copy.end(); 3012 ++iter) 3013 (*iter).second->Animate(monotonic_time); 3014 3015 SetNeedsAnimate(); 3016 } 3017 3018 void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { 3019 if (!settings_.accelerated_animation_enabled || 3020 !needs_animate_layers() || 3021 !active_tree_->root_layer()) 3022 return; 3023 3024 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState"); 3025 scoped_ptr<AnimationEventsVector> events = 3026 make_scoped_ptr(new AnimationEventsVector); 3027 AnimationRegistrar::AnimationControllerMap copy = 3028 animation_registrar_->active_animation_controllers(); 3029 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 3030 iter != copy.end(); 3031 ++iter) 3032 (*iter).second->UpdateState(start_ready_animations, events.get()); 3033 3034 if (!events->empty()) { 3035 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass()); 3036 } 3037 3038 SetNeedsAnimate(); 3039 } 3040 3041 void LayerTreeHostImpl::ActivateAnimations() { 3042 if (!settings_.accelerated_animation_enabled || !needs_animate_layers() || 3043 !active_tree_->root_layer()) 3044 return; 3045 3046 TRACE_EVENT0("cc", "LayerTreeHostImpl::ActivateAnimations"); 3047 AnimationRegistrar::AnimationControllerMap copy = 3048 animation_registrar_->active_animation_controllers(); 3049 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 3050 iter != copy.end(); 3051 ++iter) 3052 (*iter).second->ActivateAnimations(); 3053 } 3054 3055 base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const { 3056 return base::TimeDelta::FromSeconds(1); 3057 } 3058 3059 std::string LayerTreeHostImpl::LayerTreeAsJson() const { 3060 std::string str; 3061 if (active_tree_->root_layer()) { 3062 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson()); 3063 base::JSONWriter::WriteWithOptions( 3064 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str); 3065 } 3066 return str; 3067 } 3068 3069 int LayerTreeHostImpl::SourceAnimationFrameNumber() const { 3070 return fps_counter_->current_frame_number(); 3071 } 3072 3073 void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) { 3074 AnimateScrollbarsRecursive(active_tree_->root_layer(), time); 3075 } 3076 3077 void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer, 3078 base::TimeTicks time) { 3079 if (!layer) 3080 return; 3081 3082 ScrollbarAnimationController* scrollbar_controller = 3083 layer->scrollbar_animation_controller(); 3084 if (scrollbar_controller) 3085 scrollbar_controller->Animate(time); 3086 3087 for (size_t i = 0; i < layer->children().size(); ++i) 3088 AnimateScrollbarsRecursive(layer->children()[i], time); 3089 } 3090 3091 void LayerTreeHostImpl::PostDelayedScrollbarFade( 3092 const base::Closure& start_fade, 3093 base::TimeDelta delay) { 3094 client_->PostDelayedScrollbarFadeOnImplThread(start_fade, delay); 3095 } 3096 3097 void LayerTreeHostImpl::SetNeedsScrollbarAnimationFrame() { 3098 TRACE_EVENT_INSTANT0( 3099 "cc", 3100 "LayerTreeHostImpl::SetNeedsRedraw due to scrollbar fade", 3101 TRACE_EVENT_SCOPE_THREAD); 3102 SetNeedsAnimate(); 3103 } 3104 3105 void LayerTreeHostImpl::SetTreePriority(TreePriority priority) { 3106 if (!tile_manager_) 3107 return; 3108 3109 if (global_tile_state_.tree_priority == priority) 3110 return; 3111 global_tile_state_.tree_priority = priority; 3112 DidModifyTilePriorities(); 3113 } 3114 3115 void LayerTreeHostImpl::UpdateCurrentBeginFrameArgs( 3116 const BeginFrameArgs& args) { 3117 DCHECK(!current_begin_frame_args_.IsValid()); 3118 current_begin_frame_args_ = args; 3119 // TODO(skyostil): Stop overriding the frame time once the usage of frame 3120 // timing is unified. 3121 current_begin_frame_args_.frame_time = gfx::FrameTime::Now(); 3122 } 3123 3124 void LayerTreeHostImpl::ResetCurrentBeginFrameArgsForNextFrame() { 3125 current_begin_frame_args_ = BeginFrameArgs(); 3126 } 3127 3128 BeginFrameArgs LayerTreeHostImpl::CurrentBeginFrameArgs() const { 3129 // Try to use the current frame time to keep animations non-jittery. But if 3130 // we're not in a frame (because this is during an input event or a delayed 3131 // task), fall back to physical time. This should still be monotonic. 3132 if (current_begin_frame_args_.IsValid()) 3133 return current_begin_frame_args_; 3134 return BeginFrameArgs::Create(gfx::FrameTime::Now(), 3135 base::TimeTicks(), 3136 BeginFrameArgs::DefaultInterval()); 3137 } 3138 3139 scoped_refptr<base::debug::ConvertableToTraceFormat> 3140 LayerTreeHostImpl::AsValue() const { 3141 return AsValueWithFrame(NULL); 3142 } 3143 3144 scoped_refptr<base::debug::ConvertableToTraceFormat> 3145 LayerTreeHostImpl::AsValueWithFrame(FrameData* frame) const { 3146 scoped_refptr<base::debug::TracedValue> state = 3147 new base::debug::TracedValue(); 3148 AsValueWithFrameInto(frame, state.get()); 3149 return state; 3150 } 3151 3152 void LayerTreeHostImpl::AsValueWithFrameInto( 3153 FrameData* frame, 3154 base::debug::TracedValue* state) const { 3155 if (this->pending_tree_) { 3156 state->BeginDictionary("activation_state"); 3157 ActivationStateAsValueInto(state); 3158 state->EndDictionary(); 3159 } 3160 state->BeginDictionary("device_viewport_size"); 3161 MathUtil::AddToTracedValue(device_viewport_size_, state); 3162 state->EndDictionary(); 3163 3164 std::set<const Tile*> tiles; 3165 active_tree_->GetAllTilesForTracing(&tiles); 3166 if (pending_tree_) 3167 pending_tree_->GetAllTilesForTracing(&tiles); 3168 3169 state->BeginArray("active_tiles"); 3170 for (std::set<const Tile*>::const_iterator it = tiles.begin(); 3171 it != tiles.end(); 3172 ++it) { 3173 const Tile* tile = *it; 3174 3175 state->BeginDictionary(); 3176 tile->AsValueInto(state); 3177 state->EndDictionary(); 3178 } 3179 state->EndArray(); 3180 3181 if (tile_manager_) { 3182 state->BeginDictionary("tile_manager_basic_state"); 3183 tile_manager_->BasicStateAsValueInto(state); 3184 state->EndDictionary(); 3185 } 3186 state->BeginDictionary("active_tree"); 3187 active_tree_->AsValueInto(state); 3188 state->EndDictionary(); 3189 if (pending_tree_) { 3190 state->BeginDictionary("pending_tree"); 3191 pending_tree_->AsValueInto(state); 3192 state->EndDictionary(); 3193 } 3194 if (frame) { 3195 state->BeginDictionary("frame"); 3196 frame->AsValueInto(state); 3197 state->EndDictionary(); 3198 } 3199 } 3200 3201 scoped_refptr<base::debug::ConvertableToTraceFormat> 3202 LayerTreeHostImpl::ActivationStateAsValue() const { 3203 scoped_refptr<base::debug::TracedValue> state = 3204 new base::debug::TracedValue(); 3205 ActivationStateAsValueInto(state.get()); 3206 return state; 3207 } 3208 3209 void LayerTreeHostImpl::ActivationStateAsValueInto( 3210 base::debug::TracedValue* state) const { 3211 TracedValue::SetIDRef(this, state, "lthi"); 3212 if (tile_manager_) { 3213 state->BeginDictionary("tile_manager"); 3214 tile_manager_->BasicStateAsValueInto(state); 3215 state->EndDictionary(); 3216 } 3217 } 3218 3219 void LayerTreeHostImpl::SetDebugState( 3220 const LayerTreeDebugState& new_debug_state) { 3221 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state)) 3222 return; 3223 if (debug_state_.continuous_painting != new_debug_state.continuous_painting) 3224 paint_time_counter_->ClearHistory(); 3225 3226 debug_state_ = new_debug_state; 3227 UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); 3228 SetFullRootLayerDamage(); 3229 } 3230 3231 void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, 3232 const UIResourceBitmap& bitmap) { 3233 DCHECK_GT(uid, 0); 3234 3235 GLint wrap_mode = 0; 3236 switch (bitmap.GetWrapMode()) { 3237 case UIResourceBitmap::CLAMP_TO_EDGE: 3238 wrap_mode = GL_CLAMP_TO_EDGE; 3239 break; 3240 case UIResourceBitmap::REPEAT: 3241 wrap_mode = GL_REPEAT; 3242 break; 3243 } 3244 3245 // Allow for multiple creation requests with the same UIResourceId. The 3246 // previous resource is simply deleted. 3247 ResourceProvider::ResourceId id = ResourceIdForUIResource(uid); 3248 if (id) 3249 DeleteUIResource(uid); 3250 3251 ResourceFormat format = resource_provider_->best_texture_format(); 3252 switch (bitmap.GetFormat()) { 3253 case UIResourceBitmap::RGBA8: 3254 break; 3255 case UIResourceBitmap::ALPHA_8: 3256 format = ALPHA_8; 3257 break; 3258 case UIResourceBitmap::ETC1: 3259 format = ETC1; 3260 break; 3261 } 3262 id = 3263 resource_provider_->CreateResource(bitmap.GetSize(), 3264 wrap_mode, 3265 ResourceProvider::TextureHintImmutable, 3266 format); 3267 3268 UIResourceData data; 3269 data.resource_id = id; 3270 data.size = bitmap.GetSize(); 3271 data.opaque = bitmap.GetOpaque(); 3272 3273 ui_resource_map_[uid] = data; 3274 3275 AutoLockUIResourceBitmap bitmap_lock(bitmap); 3276 resource_provider_->SetPixels(id, 3277 bitmap_lock.GetPixels(), 3278 gfx::Rect(bitmap.GetSize()), 3279 gfx::Rect(bitmap.GetSize()), 3280 gfx::Vector2d(0, 0)); 3281 MarkUIResourceNotEvicted(uid); 3282 } 3283 3284 void LayerTreeHostImpl::DeleteUIResource(UIResourceId uid) { 3285 ResourceProvider::ResourceId id = ResourceIdForUIResource(uid); 3286 if (id) { 3287 resource_provider_->DeleteResource(id); 3288 ui_resource_map_.erase(uid); 3289 } 3290 MarkUIResourceNotEvicted(uid); 3291 } 3292 3293 void LayerTreeHostImpl::EvictAllUIResources() { 3294 if (ui_resource_map_.empty()) 3295 return; 3296 3297 for (UIResourceMap::const_iterator iter = ui_resource_map_.begin(); 3298 iter != ui_resource_map_.end(); 3299 ++iter) { 3300 evicted_ui_resources_.insert(iter->first); 3301 resource_provider_->DeleteResource(iter->second.resource_id); 3302 } 3303 ui_resource_map_.clear(); 3304 3305 client_->SetNeedsCommitOnImplThread(); 3306 client_->OnCanDrawStateChanged(CanDraw()); 3307 client_->RenewTreePriority(); 3308 } 3309 3310 ResourceProvider::ResourceId LayerTreeHostImpl::ResourceIdForUIResource( 3311 UIResourceId uid) const { 3312 UIResourceMap::const_iterator iter = ui_resource_map_.find(uid); 3313 if (iter != ui_resource_map_.end()) 3314 return iter->second.resource_id; 3315 return 0; 3316 } 3317 3318 bool LayerTreeHostImpl::IsUIResourceOpaque(UIResourceId uid) const { 3319 UIResourceMap::const_iterator iter = ui_resource_map_.find(uid); 3320 DCHECK(iter != ui_resource_map_.end()); 3321 return iter->second.opaque; 3322 } 3323 3324 bool LayerTreeHostImpl::EvictedUIResourcesExist() const { 3325 return !evicted_ui_resources_.empty(); 3326 } 3327 3328 void LayerTreeHostImpl::MarkUIResourceNotEvicted(UIResourceId uid) { 3329 std::set<UIResourceId>::iterator found_in_evicted = 3330 evicted_ui_resources_.find(uid); 3331 if (found_in_evicted == evicted_ui_resources_.end()) 3332 return; 3333 evicted_ui_resources_.erase(found_in_evicted); 3334 if (evicted_ui_resources_.empty()) 3335 client_->OnCanDrawStateChanged(CanDraw()); 3336 } 3337 3338 void LayerTreeHostImpl::ScheduleMicroBenchmark( 3339 scoped_ptr<MicroBenchmarkImpl> benchmark) { 3340 micro_benchmark_controller_.ScheduleRun(benchmark.Pass()); 3341 } 3342 3343 void LayerTreeHostImpl::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) { 3344 swap_promise_monitor_.insert(monitor); 3345 } 3346 3347 void LayerTreeHostImpl::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) { 3348 swap_promise_monitor_.erase(monitor); 3349 } 3350 3351 void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() { 3352 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin(); 3353 for (; it != swap_promise_monitor_.end(); it++) 3354 (*it)->OnSetNeedsRedrawOnImpl(); 3355 } 3356 3357 void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfForwardingToMainThread() { 3358 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin(); 3359 for (; it != swap_promise_monitor_.end(); it++) 3360 (*it)->OnForwardScrollUpdateToMainThreadOnImpl(); 3361 } 3362 3363 void LayerTreeHostImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) { 3364 DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) == 3365 picture_layers_.end()); 3366 picture_layers_.push_back(layer); 3367 } 3368 3369 void LayerTreeHostImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { 3370 std::vector<PictureLayerImpl*>::iterator it = 3371 std::find(picture_layers_.begin(), picture_layers_.end(), layer); 3372 DCHECK(it != picture_layers_.end()); 3373 picture_layers_.erase(it); 3374 } 3375 3376 } // namespace cc 3377