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