| OLD | NEW |
| (Empty) |
| 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/single_thread_proxy.h" | |
| 6 | |
| 7 #include "base/auto_reset.h" | |
| 8 #include "base/profiler/scoped_tracker.h" | |
| 9 #include "base/trace_event/trace_event.h" | |
| 10 #include "cc/debug/benchmark_instrumentation.h" | |
| 11 #include "cc/debug/devtools_instrumentation.h" | |
| 12 #include "cc/output/context_provider.h" | |
| 13 #include "cc/output/output_surface.h" | |
| 14 #include "cc/quads/draw_quad.h" | |
| 15 #include "cc/resources/prioritized_resource_manager.h" | |
| 16 #include "cc/resources/resource_update_controller.h" | |
| 17 #include "cc/scheduler/commit_earlyout_reason.h" | |
| 18 #include "cc/trees/layer_tree_host.h" | |
| 19 #include "cc/trees/layer_tree_host_single_thread_client.h" | |
| 20 #include "cc/trees/layer_tree_impl.h" | |
| 21 #include "cc/trees/scoped_abort_remaining_swap_promises.h" | |
| 22 #include "ui/gfx/frame_time.h" | |
| 23 | |
| 24 namespace cc { | |
| 25 | |
| 26 scoped_ptr<Proxy> SingleThreadProxy::Create( | |
| 27 LayerTreeHost* layer_tree_host, | |
| 28 LayerTreeHostSingleThreadClient* client, | |
| 29 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
| 30 scoped_ptr<BeginFrameSource> external_begin_frame_source) { | |
| 31 return make_scoped_ptr(new SingleThreadProxy( | |
| 32 layer_tree_host, | |
| 33 client, | |
| 34 main_task_runner, | |
| 35 external_begin_frame_source.Pass())); | |
| 36 } | |
| 37 | |
| 38 SingleThreadProxy::SingleThreadProxy( | |
| 39 LayerTreeHost* layer_tree_host, | |
| 40 LayerTreeHostSingleThreadClient* client, | |
| 41 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
| 42 scoped_ptr<BeginFrameSource> external_begin_frame_source) | |
| 43 : Proxy(main_task_runner, NULL), | |
| 44 layer_tree_host_(layer_tree_host), | |
| 45 client_(client), | |
| 46 timing_history_(layer_tree_host->rendering_stats_instrumentation()), | |
| 47 next_frame_is_newly_committed_frame_(false), | |
| 48 inside_draw_(false), | |
| 49 defer_commits_(false), | |
| 50 commit_requested_(false), | |
| 51 inside_synchronous_composite_(false), | |
| 52 output_surface_creation_requested_(false), | |
| 53 external_begin_frame_source_(external_begin_frame_source.Pass()), | |
| 54 weak_factory_(this) { | |
| 55 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); | |
| 56 DCHECK(Proxy::IsMainThread()); | |
| 57 DCHECK(layer_tree_host); | |
| 58 } | |
| 59 | |
| 60 void SingleThreadProxy::Start() { | |
| 61 DebugScopedSetImplThread impl(this); | |
| 62 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); | |
| 63 } | |
| 64 | |
| 65 SingleThreadProxy::~SingleThreadProxy() { | |
| 66 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); | |
| 67 DCHECK(Proxy::IsMainThread()); | |
| 68 // Make sure Stop() got called or never Started. | |
| 69 DCHECK(!layer_tree_host_impl_); | |
| 70 } | |
| 71 | |
| 72 void SingleThreadProxy::FinishAllRendering() { | |
| 73 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering"); | |
| 74 DCHECK(Proxy::IsMainThread()); | |
| 75 { | |
| 76 DebugScopedSetImplThread impl(this); | |
| 77 layer_tree_host_impl_->FinishAllRendering(); | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 bool SingleThreadProxy::IsStarted() const { | |
| 82 DCHECK(Proxy::IsMainThread()); | |
| 83 return layer_tree_host_impl_; | |
| 84 } | |
| 85 | |
| 86 bool SingleThreadProxy::CommitToActiveTree() const { | |
| 87 // With SingleThreadProxy we skip the pending tree and commit directly to the | |
| 88 // active tree. | |
| 89 return true; | |
| 90 } | |
| 91 | |
| 92 void SingleThreadProxy::SetLayerTreeHostClientReady() { | |
| 93 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); | |
| 94 // Scheduling is controlled by the embedder in the single thread case, so | |
| 95 // nothing to do. | |
| 96 DCHECK(Proxy::IsMainThread()); | |
| 97 DebugScopedSetImplThread impl(this); | |
| 98 if (layer_tree_host_->settings().single_thread_proxy_scheduler && | |
| 99 !scheduler_on_impl_thread_) { | |
| 100 SchedulerSettings scheduler_settings( | |
| 101 layer_tree_host_->settings().ToSchedulerSettings()); | |
| 102 // SingleThreadProxy should run in main thread low latency mode. | |
| 103 scheduler_settings.main_thread_should_always_be_low_latency = true; | |
| 104 scheduler_on_impl_thread_ = | |
| 105 Scheduler::Create(this, | |
| 106 scheduler_settings, | |
| 107 layer_tree_host_->id(), | |
| 108 MainThreadTaskRunner(), | |
| 109 external_begin_frame_source_.Pass()); | |
| 110 scheduler_on_impl_thread_->SetCanStart(); | |
| 111 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 void SingleThreadProxy::SetVisible(bool visible) { | |
| 116 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible); | |
| 117 DebugScopedSetImplThread impl(this); | |
| 118 layer_tree_host_impl_->SetVisible(visible); | |
| 119 if (scheduler_on_impl_thread_) | |
| 120 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | |
| 121 // Changing visibility could change ShouldComposite(). | |
| 122 } | |
| 123 | |
| 124 void SingleThreadProxy::SetThrottleFrameProduction(bool throttle) { | |
| 125 TRACE_EVENT1("cc", "SingleThreadProxy::SetThrottleFrameProduction", | |
| 126 "throttle", throttle); | |
| 127 DebugScopedSetImplThread impl(this); | |
| 128 if (scheduler_on_impl_thread_) | |
| 129 scheduler_on_impl_thread_->SetThrottleFrameProduction(throttle); | |
| 130 } | |
| 131 | |
| 132 void SingleThreadProxy::RequestNewOutputSurface() { | |
| 133 DCHECK(Proxy::IsMainThread()); | |
| 134 DCHECK(layer_tree_host_->output_surface_lost()); | |
| 135 output_surface_creation_callback_.Cancel(); | |
| 136 if (output_surface_creation_requested_) | |
| 137 return; | |
| 138 output_surface_creation_requested_ = true; | |
| 139 layer_tree_host_->RequestNewOutputSurface(); | |
| 140 } | |
| 141 | |
| 142 void SingleThreadProxy::SetOutputSurface( | |
| 143 scoped_ptr<OutputSurface> output_surface) { | |
| 144 DCHECK(Proxy::IsMainThread()); | |
| 145 DCHECK(layer_tree_host_->output_surface_lost()); | |
| 146 DCHECK(output_surface_creation_requested_); | |
| 147 renderer_capabilities_for_main_thread_ = RendererCapabilities(); | |
| 148 | |
| 149 bool success; | |
| 150 { | |
| 151 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 152 DebugScopedSetImplThread impl(this); | |
| 153 layer_tree_host_->DeleteContentsTexturesOnImplThread( | |
| 154 layer_tree_host_impl_->resource_provider()); | |
| 155 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); | |
| 156 } | |
| 157 | |
| 158 if (success) { | |
| 159 layer_tree_host_->DidInitializeOutputSurface(); | |
| 160 if (scheduler_on_impl_thread_) | |
| 161 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); | |
| 162 else if (!inside_synchronous_composite_) | |
| 163 SetNeedsCommit(); | |
| 164 output_surface_creation_requested_ = false; | |
| 165 } else { | |
| 166 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface, | |
| 167 // and so output_surface_creation_requested remains true. | |
| 168 layer_tree_host_->DidFailToInitializeOutputSurface(); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { | |
| 173 DCHECK(Proxy::IsMainThread()); | |
| 174 DCHECK(!layer_tree_host_->output_surface_lost()); | |
| 175 return renderer_capabilities_for_main_thread_; | |
| 176 } | |
| 177 | |
| 178 void SingleThreadProxy::SetNeedsAnimate() { | |
| 179 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); | |
| 180 DCHECK(Proxy::IsMainThread()); | |
| 181 client_->ScheduleAnimation(); | |
| 182 SetNeedsCommit(); | |
| 183 } | |
| 184 | |
| 185 void SingleThreadProxy::SetNeedsUpdateLayers() { | |
| 186 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); | |
| 187 DCHECK(Proxy::IsMainThread()); | |
| 188 SetNeedsCommit(); | |
| 189 } | |
| 190 | |
| 191 void SingleThreadProxy::DoAnimate() { | |
| 192 // Don't animate if there is no root layer. | |
| 193 // TODO(mithro): Both Animate and UpdateAnimationState already have a | |
| 194 // "!active_tree_->root_layer()" check? | |
| 195 if (!layer_tree_host_impl_->active_tree()->root_layer()) { | |
| 196 return; | |
| 197 } | |
| 198 | |
| 199 layer_tree_host_impl_->Animate( | |
| 200 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); | |
| 201 | |
| 202 // If animations are not visible, update the animation state now as it | |
| 203 // won't happen in DoComposite. | |
| 204 if (!layer_tree_host_impl_->AnimationsAreVisible()) { | |
| 205 layer_tree_host_impl_->UpdateAnimationState(true); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void SingleThreadProxy::DoCommit() { | |
| 210 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); | |
| 211 DCHECK(Proxy::IsMainThread()); | |
| 212 | |
| 213 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is | |
| 214 // fixed. | |
| 215 tracked_objects::ScopedTracker tracking_profile1( | |
| 216 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1")); | |
| 217 commit_requested_ = false; | |
| 218 layer_tree_host_->WillCommit(); | |
| 219 devtools_instrumentation::ScopedCommitTrace commit_task( | |
| 220 layer_tree_host_->id()); | |
| 221 | |
| 222 // Commit immediately. | |
| 223 { | |
| 224 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 225 // is fixed. | |
| 226 tracked_objects::ScopedTracker tracking_profile2( | |
| 227 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 228 "461509 SingleThreadProxy::DoCommit2")); | |
| 229 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 230 DebugScopedSetImplThread impl(this); | |
| 231 | |
| 232 // This CapturePostTasks should be destroyed before CommitComplete() is | |
| 233 // called since that goes out to the embedder, and we want the embedder | |
| 234 // to receive its callbacks before that. | |
| 235 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks( | |
| 236 blocking_main_thread_task_runner())); | |
| 237 | |
| 238 layer_tree_host_impl_->BeginCommit(); | |
| 239 | |
| 240 if (PrioritizedResourceManager* contents_texture_manager = | |
| 241 layer_tree_host_->contents_texture_manager()) { | |
| 242 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 243 // is fixed. | |
| 244 tracked_objects::ScopedTracker tracking_profile3( | |
| 245 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 246 "461509 SingleThreadProxy::DoCommit3")); | |
| 247 contents_texture_manager->PushTexturePrioritiesToBackings(); | |
| 248 } | |
| 249 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get()); | |
| 250 | |
| 251 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 252 // is fixed. | |
| 253 tracked_objects::ScopedTracker tracking_profile4( | |
| 254 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 255 "461509 SingleThreadProxy::DoCommit4")); | |
| 256 scoped_ptr<ResourceUpdateController> update_controller = | |
| 257 ResourceUpdateController::Create( | |
| 258 NULL, | |
| 259 MainThreadTaskRunner(), | |
| 260 queue_for_commit_.Pass(), | |
| 261 layer_tree_host_impl_->resource_provider()); | |
| 262 | |
| 263 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 264 // is fixed. | |
| 265 tracked_objects::ScopedTracker tracking_profile5( | |
| 266 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 267 "461509 SingleThreadProxy::DoCommit5")); | |
| 268 update_controller->Finalize(); | |
| 269 | |
| 270 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 271 // is fixed. | |
| 272 tracked_objects::ScopedTracker tracking_profile6( | |
| 273 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 274 "461509 SingleThreadProxy::DoCommit6")); | |
| 275 if (layer_tree_host_impl_->EvictedUIResourcesExist()) | |
| 276 layer_tree_host_->RecreateUIResources(); | |
| 277 | |
| 278 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 279 // is fixed. | |
| 280 tracked_objects::ScopedTracker tracking_profile7( | |
| 281 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 282 "461509 SingleThreadProxy::DoCommit7")); | |
| 283 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); | |
| 284 | |
| 285 #if DCHECK_IS_ON() | |
| 286 // In the single-threaded case, the scale and scroll deltas should never be | |
| 287 // touched on the impl layer tree. | |
| 288 scoped_ptr<ScrollAndScaleSet> scroll_info = | |
| 289 layer_tree_host_impl_->ProcessScrollDeltas(); | |
| 290 DCHECK(!scroll_info->scrolls.size()); | |
| 291 DCHECK_EQ(1.f, scroll_info->page_scale_delta); | |
| 292 #endif | |
| 293 | |
| 294 if (layer_tree_host_->settings().impl_side_painting) { | |
| 295 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 296 // is fixed. | |
| 297 tracked_objects::ScopedTracker tracking_profile8( | |
| 298 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 299 "461509 SingleThreadProxy::DoCommit8")); | |
| 300 // Commit goes directly to the active tree, but we need to synchronously | |
| 301 // "activate" the tree still during commit to satisfy any potential | |
| 302 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree | |
| 303 // might not be ready to draw, so DidActivateSyncTree must set | |
| 304 // the flag to force the tree to not draw until textures are ready. | |
| 305 NotifyReadyToActivate(); | |
| 306 } else { | |
| 307 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 308 // is fixed. | |
| 309 tracked_objects::ScopedTracker tracking_profile9( | |
| 310 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 311 "461509 SingleThreadProxy::DoCommit9")); | |
| 312 CommitComplete(); | |
| 313 } | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 void SingleThreadProxy::CommitComplete() { | |
| 318 DCHECK(!layer_tree_host_impl_->pending_tree()) | |
| 319 << "Activation is expected to have synchronously occurred by now."; | |
| 320 DCHECK(commit_blocking_task_runner_); | |
| 321 | |
| 322 // Notify commit complete on the impl side after activate to satisfy any | |
| 323 // SetNextCommitWaitsForActivation calls. | |
| 324 layer_tree_host_impl_->CommitComplete(); | |
| 325 | |
| 326 DebugScopedSetMainThread main(this); | |
| 327 commit_blocking_task_runner_.reset(); | |
| 328 layer_tree_host_->CommitComplete(); | |
| 329 layer_tree_host_->DidBeginMainFrame(); | |
| 330 timing_history_.DidCommit(); | |
| 331 | |
| 332 next_frame_is_newly_committed_frame_ = true; | |
| 333 } | |
| 334 | |
| 335 void SingleThreadProxy::SetNeedsCommit() { | |
| 336 DCHECK(Proxy::IsMainThread()); | |
| 337 DebugScopedSetImplThread impl(this); | |
| 338 client_->ScheduleComposite(); | |
| 339 if (scheduler_on_impl_thread_) | |
| 340 scheduler_on_impl_thread_->SetNeedsCommit(); | |
| 341 commit_requested_ = true; | |
| 342 } | |
| 343 | |
| 344 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { | |
| 345 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); | |
| 346 DCHECK(Proxy::IsMainThread()); | |
| 347 DebugScopedSetImplThread impl(this); | |
| 348 client_->ScheduleComposite(); | |
| 349 SetNeedsRedrawRectOnImplThread(damage_rect); | |
| 350 } | |
| 351 | |
| 352 void SingleThreadProxy::SetNextCommitWaitsForActivation() { | |
| 353 // Activation always forced in commit, so nothing to do. | |
| 354 DCHECK(Proxy::IsMainThread()); | |
| 355 } | |
| 356 | |
| 357 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { | |
| 358 DCHECK(Proxy::IsMainThread()); | |
| 359 // Deferring commits only makes sense if there's a scheduler. | |
| 360 if (!scheduler_on_impl_thread_) | |
| 361 return; | |
| 362 if (defer_commits_ == defer_commits) | |
| 363 return; | |
| 364 | |
| 365 if (defer_commits) | |
| 366 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this); | |
| 367 else | |
| 368 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); | |
| 369 | |
| 370 defer_commits_ = defer_commits; | |
| 371 scheduler_on_impl_thread_->SetDeferCommits(defer_commits); | |
| 372 } | |
| 373 | |
| 374 bool SingleThreadProxy::CommitRequested() const { | |
| 375 DCHECK(Proxy::IsMainThread()); | |
| 376 return commit_requested_; | |
| 377 } | |
| 378 | |
| 379 bool SingleThreadProxy::BeginMainFrameRequested() const { | |
| 380 DCHECK(Proxy::IsMainThread()); | |
| 381 // If there is no scheduler, then there can be no pending begin frame, | |
| 382 // as all frames are all manually initiated by the embedder of cc. | |
| 383 if (!scheduler_on_impl_thread_) | |
| 384 return false; | |
| 385 return commit_requested_; | |
| 386 } | |
| 387 | |
| 388 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { | |
| 389 return std::numeric_limits<size_t>::max(); | |
| 390 } | |
| 391 | |
| 392 void SingleThreadProxy::Stop() { | |
| 393 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); | |
| 394 DCHECK(Proxy::IsMainThread()); | |
| 395 { | |
| 396 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 397 DebugScopedSetImplThread impl(this); | |
| 398 | |
| 399 BlockingTaskRunner::CapturePostTasks blocked( | |
| 400 blocking_main_thread_task_runner()); | |
| 401 layer_tree_host_->DeleteContentsTexturesOnImplThread( | |
| 402 layer_tree_host_impl_->resource_provider()); | |
| 403 scheduler_on_impl_thread_ = nullptr; | |
| 404 layer_tree_host_impl_ = nullptr; | |
| 405 } | |
| 406 layer_tree_host_ = NULL; | |
| 407 } | |
| 408 | |
| 409 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { | |
| 410 TRACE_EVENT1( | |
| 411 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | |
| 412 DCHECK(Proxy::IsImplThread()); | |
| 413 if (scheduler_on_impl_thread_) | |
| 414 scheduler_on_impl_thread_->SetCanDraw(can_draw); | |
| 415 } | |
| 416 | |
| 417 void SingleThreadProxy::NotifyReadyToActivate() { | |
| 418 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate"); | |
| 419 DebugScopedSetImplThread impl(this); | |
| 420 if (scheduler_on_impl_thread_) | |
| 421 scheduler_on_impl_thread_->NotifyReadyToActivate(); | |
| 422 } | |
| 423 | |
| 424 void SingleThreadProxy::NotifyReadyToDraw() { | |
| 425 } | |
| 426 | |
| 427 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { | |
| 428 client_->ScheduleComposite(); | |
| 429 if (scheduler_on_impl_thread_) | |
| 430 scheduler_on_impl_thread_->SetNeedsRedraw(); | |
| 431 } | |
| 432 | |
| 433 void SingleThreadProxy::SetNeedsAnimateOnImplThread() { | |
| 434 client_->ScheduleComposite(); | |
| 435 if (scheduler_on_impl_thread_) | |
| 436 scheduler_on_impl_thread_->SetNeedsAnimate(); | |
| 437 } | |
| 438 | |
| 439 void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() { | |
| 440 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread"); | |
| 441 if (scheduler_on_impl_thread_) | |
| 442 scheduler_on_impl_thread_->SetNeedsPrepareTiles(); | |
| 443 } | |
| 444 | |
| 445 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( | |
| 446 const gfx::Rect& damage_rect) { | |
| 447 layer_tree_host_impl_->SetViewportDamage(damage_rect); | |
| 448 SetNeedsRedrawOnImplThread(); | |
| 449 } | |
| 450 | |
| 451 void SingleThreadProxy::SetNeedsCommitOnImplThread() { | |
| 452 client_->ScheduleComposite(); | |
| 453 if (scheduler_on_impl_thread_) | |
| 454 scheduler_on_impl_thread_->SetNeedsCommit(); | |
| 455 } | |
| 456 | |
| 457 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | |
| 458 scoped_ptr<AnimationEventsVector> events) { | |
| 459 TRACE_EVENT0( | |
| 460 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); | |
| 461 DCHECK(Proxy::IsImplThread()); | |
| 462 DebugScopedSetMainThread main(this); | |
| 463 layer_tree_host_->SetAnimationEvents(events.Pass()); | |
| 464 } | |
| 465 | |
| 466 bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread( | |
| 467 size_t limit_bytes, | |
| 468 int priority_cutoff) { | |
| 469 DCHECK(IsImplThread()); | |
| 470 PrioritizedResourceManager* contents_texture_manager = | |
| 471 layer_tree_host_->contents_texture_manager(); | |
| 472 | |
| 473 ResourceProvider* resource_provider = | |
| 474 layer_tree_host_impl_->resource_provider(); | |
| 475 | |
| 476 if (!contents_texture_manager || !resource_provider) | |
| 477 return false; | |
| 478 | |
| 479 return contents_texture_manager->ReduceMemoryOnImplThread( | |
| 480 limit_bytes, priority_cutoff, resource_provider); | |
| 481 } | |
| 482 | |
| 483 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } | |
| 484 | |
| 485 void SingleThreadProxy::DidActivateSyncTree() { | |
| 486 // Non-impl-side painting finishes commit in DoCommit. Impl-side painting | |
| 487 // defers until here to simulate SetNextCommitWaitsForActivation. | |
| 488 if (layer_tree_host_impl_->settings().impl_side_painting) { | |
| 489 // This is required because NotifyReadyToActivate gets called immediately | |
| 490 // after commit since single thread commits directly to the active tree. | |
| 491 layer_tree_host_impl_->SetRequiresHighResToDraw(); | |
| 492 | |
| 493 // Synchronously call to CommitComplete. Resetting | |
| 494 // |commit_blocking_task_runner| would make sure all tasks posted during | |
| 495 // commit/activation before CommitComplete. | |
| 496 CommitComplete(); | |
| 497 } | |
| 498 | |
| 499 timing_history_.DidActivateSyncTree(); | |
| 500 } | |
| 501 | |
| 502 void SingleThreadProxy::DidPrepareTiles() { | |
| 503 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); | |
| 504 DCHECK(Proxy::IsImplThread()); | |
| 505 if (scheduler_on_impl_thread_) | |
| 506 scheduler_on_impl_thread_->DidPrepareTiles(); | |
| 507 } | |
| 508 | |
| 509 void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() { | |
| 510 layer_tree_host_->DidCompletePageScaleAnimation(); | |
| 511 } | |
| 512 | |
| 513 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { | |
| 514 DCHECK(IsImplThread()); | |
| 515 renderer_capabilities_for_main_thread_ = | |
| 516 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); | |
| 517 } | |
| 518 | |
| 519 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { | |
| 520 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); | |
| 521 { | |
| 522 DebugScopedSetMainThread main(this); | |
| 523 // This must happen before we notify the scheduler as it may try to recreate | |
| 524 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. | |
| 525 layer_tree_host_->DidLoseOutputSurface(); | |
| 526 } | |
| 527 client_->DidAbortSwapBuffers(); | |
| 528 if (scheduler_on_impl_thread_) | |
| 529 scheduler_on_impl_thread_->DidLoseOutputSurface(); | |
| 530 } | |
| 531 | |
| 532 void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase, | |
| 533 base::TimeDelta interval) { | |
| 534 if (scheduler_on_impl_thread_) | |
| 535 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval); | |
| 536 } | |
| 537 | |
| 538 void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { | |
| 539 if (scheduler_on_impl_thread_) | |
| 540 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time); | |
| 541 } | |
| 542 | |
| 543 void SingleThreadProxy::DidSwapBuffersOnImplThread() { | |
| 544 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread"); | |
| 545 if (scheduler_on_impl_thread_) | |
| 546 scheduler_on_impl_thread_->DidSwapBuffers(); | |
| 547 client_->DidPostSwapBuffers(); | |
| 548 } | |
| 549 | |
| 550 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { | |
| 551 TRACE_EVENT0("cc,benchmark", | |
| 552 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); | |
| 553 if (scheduler_on_impl_thread_) | |
| 554 scheduler_on_impl_thread_->DidSwapBuffersComplete(); | |
| 555 layer_tree_host_->DidCompleteSwapBuffers(); | |
| 556 } | |
| 557 | |
| 558 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { | |
| 559 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately"); | |
| 560 DCHECK(Proxy::IsMainThread()); | |
| 561 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true); | |
| 562 | |
| 563 if (layer_tree_host_->output_surface_lost()) { | |
| 564 RequestNewOutputSurface(); | |
| 565 // RequestNewOutputSurface could have synchronously created an output | |
| 566 // surface, so check again before returning. | |
| 567 if (layer_tree_host_->output_surface_lost()) | |
| 568 return; | |
| 569 } | |
| 570 | |
| 571 { | |
| 572 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create( | |
| 573 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(), | |
| 574 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::SYNCHRONOUS)); | |
| 575 DoBeginMainFrame(begin_frame_args); | |
| 576 DoCommit(); | |
| 577 | |
| 578 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises()) | |
| 579 << "Commit should always succeed and transfer promises."; | |
| 580 } | |
| 581 | |
| 582 { | |
| 583 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); | |
| 584 if (layer_tree_host_impl_->settings().impl_side_painting) { | |
| 585 layer_tree_host_impl_->ActivateSyncTree(); | |
| 586 DCHECK(!layer_tree_host_impl_->active_tree() | |
| 587 ->needs_update_draw_properties()); | |
| 588 layer_tree_host_impl_->PrepareTiles(); | |
| 589 layer_tree_host_impl_->SynchronouslyInitializeAllTiles(); | |
| 590 } | |
| 591 | |
| 592 DoAnimate(); | |
| 593 | |
| 594 LayerTreeHostImpl::FrameData frame; | |
| 595 DoComposite(frame_begin_time, &frame); | |
| 596 | |
| 597 // DoComposite could abort, but because this is a synchronous composite | |
| 598 // another draw will never be scheduled, so break remaining promises. | |
| 599 layer_tree_host_impl_->active_tree()->BreakSwapPromises( | |
| 600 SwapPromise::SWAP_FAILS); | |
| 601 } | |
| 602 } | |
| 603 | |
| 604 void SingleThreadProxy::ForceSerializeOnSwapBuffers() { | |
| 605 { | |
| 606 DebugScopedSetImplThread impl(this); | |
| 607 if (layer_tree_host_impl_->renderer()) { | |
| 608 DCHECK(!layer_tree_host_->output_surface_lost()); | |
| 609 layer_tree_host_impl_->renderer()->DoNoOp(); | |
| 610 } | |
| 611 } | |
| 612 } | |
| 613 | |
| 614 bool SingleThreadProxy::SupportsImplScrolling() const { | |
| 615 return false; | |
| 616 } | |
| 617 | |
| 618 bool SingleThreadProxy::ShouldComposite() const { | |
| 619 DCHECK(Proxy::IsImplThread()); | |
| 620 return layer_tree_host_impl_->visible() && | |
| 621 layer_tree_host_impl_->CanDraw(); | |
| 622 } | |
| 623 | |
| 624 void SingleThreadProxy::ScheduleRequestNewOutputSurface() { | |
| 625 if (output_surface_creation_callback_.IsCancelled() && | |
| 626 !output_surface_creation_requested_) { | |
| 627 output_surface_creation_callback_.Reset( | |
| 628 base::Bind(&SingleThreadProxy::RequestNewOutputSurface, | |
| 629 weak_factory_.GetWeakPtr())); | |
| 630 MainThreadTaskRunner()->PostTask( | |
| 631 FROM_HERE, output_surface_creation_callback_.callback()); | |
| 632 } | |
| 633 } | |
| 634 | |
| 635 DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, | |
| 636 LayerTreeHostImpl::FrameData* frame) { | |
| 637 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); | |
| 638 DCHECK(!layer_tree_host_->output_surface_lost()); | |
| 639 | |
| 640 DrawResult draw_result; | |
| 641 bool draw_frame; | |
| 642 { | |
| 643 DebugScopedSetImplThread impl(this); | |
| 644 base::AutoReset<bool> mark_inside(&inside_draw_, true); | |
| 645 | |
| 646 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 647 // is fixed. | |
| 648 tracked_objects::ScopedTracker tracking_profile1( | |
| 649 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 650 "461509 SingleThreadProxy::DoComposite1")); | |
| 651 | |
| 652 // We guard PrepareToDraw() with CanDraw() because it always returns a valid | |
| 653 // frame, so can only be used when such a frame is possible. Since | |
| 654 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on | |
| 655 // CanDraw() as well. | |
| 656 if (!ShouldComposite()) { | |
| 657 return DRAW_ABORTED_CANT_DRAW; | |
| 658 } | |
| 659 | |
| 660 timing_history_.DidStartDrawing(); | |
| 661 | |
| 662 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 663 // is fixed. | |
| 664 tracked_objects::ScopedTracker tracking_profile2( | |
| 665 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 666 "461509 SingleThreadProxy::DoComposite2")); | |
| 667 draw_result = layer_tree_host_impl_->PrepareToDraw(frame); | |
| 668 draw_frame = draw_result == DRAW_SUCCESS; | |
| 669 if (draw_frame) { | |
| 670 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 671 // is fixed. | |
| 672 tracked_objects::ScopedTracker tracking_profile3( | |
| 673 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 674 "461509 SingleThreadProxy::DoComposite3")); | |
| 675 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); | |
| 676 } | |
| 677 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 678 // is fixed. | |
| 679 tracked_objects::ScopedTracker tracking_profile4( | |
| 680 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 681 "461509 SingleThreadProxy::DoComposite4")); | |
| 682 layer_tree_host_impl_->DidDrawAllLayers(*frame); | |
| 683 | |
| 684 bool start_ready_animations = draw_frame; | |
| 685 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 686 // is fixed. | |
| 687 tracked_objects::ScopedTracker tracking_profile5( | |
| 688 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 689 "461509 SingleThreadProxy::DoComposite5")); | |
| 690 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); | |
| 691 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 692 // is fixed. | |
| 693 tracked_objects::ScopedTracker tracking_profile6( | |
| 694 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 695 "461509 SingleThreadProxy::DoComposite6")); | |
| 696 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); | |
| 697 | |
| 698 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 699 // is fixed. | |
| 700 tracked_objects::ScopedTracker tracking_profile7( | |
| 701 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 702 "461509 SingleThreadProxy::DoComposite7")); | |
| 703 timing_history_.DidFinishDrawing(); | |
| 704 } | |
| 705 | |
| 706 if (draw_frame) { | |
| 707 DebugScopedSetImplThread impl(this); | |
| 708 | |
| 709 // This CapturePostTasks should be destroyed before | |
| 710 // DidCommitAndDrawFrame() is called since that goes out to the | |
| 711 // embedder, | |
| 712 // and we want the embedder to receive its callbacks before that. | |
| 713 // NOTE: This maintains consistent ordering with the ThreadProxy since | |
| 714 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread | |
| 715 // there as the main thread is not blocked, so any posted tasks inside | |
| 716 // the swap buffers will execute first. | |
| 717 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 718 | |
| 719 BlockingTaskRunner::CapturePostTasks blocked( | |
| 720 blocking_main_thread_task_runner()); | |
| 721 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 | |
| 722 // is fixed. | |
| 723 tracked_objects::ScopedTracker tracking_profile8( | |
| 724 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 725 "461509 SingleThreadProxy::DoComposite8")); | |
| 726 layer_tree_host_impl_->SwapBuffers(*frame); | |
| 727 } | |
| 728 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is | |
| 729 // fixed. | |
| 730 tracked_objects::ScopedTracker tracking_profile9( | |
| 731 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 732 "461509 SingleThreadProxy::DoComposite9")); | |
| 733 DidCommitAndDrawFrame(); | |
| 734 | |
| 735 return draw_result; | |
| 736 } | |
| 737 | |
| 738 void SingleThreadProxy::DidCommitAndDrawFrame() { | |
| 739 if (next_frame_is_newly_committed_frame_) { | |
| 740 DebugScopedSetMainThread main(this); | |
| 741 next_frame_is_newly_committed_frame_ = false; | |
| 742 layer_tree_host_->DidCommitAndDrawFrame(); | |
| 743 } | |
| 744 } | |
| 745 | |
| 746 bool SingleThreadProxy::MainFrameWillHappenForTesting() { | |
| 747 return false; | |
| 748 } | |
| 749 | |
| 750 void SingleThreadProxy::SetChildrenNeedBeginFrames( | |
| 751 bool children_need_begin_frames) { | |
| 752 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames( | |
| 753 children_need_begin_frames); | |
| 754 } | |
| 755 | |
| 756 void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { | |
| 757 layer_tree_host_impl_->WillBeginImplFrame(args); | |
| 758 } | |
| 759 | |
| 760 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { | |
| 761 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame"); | |
| 762 // Although this proxy is single-threaded, it's problematic to synchronously | |
| 763 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This | |
| 764 // could cause a commit to occur in between a series of SetNeedsCommit calls | |
| 765 // (i.e. property modifications) causing some to fall on one frame and some to | |
| 766 // fall on the next. Doing it asynchronously instead matches the semantics of | |
| 767 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a | |
| 768 // synchronous commit. | |
| 769 MainThreadTaskRunner()->PostTask( | |
| 770 FROM_HERE, | |
| 771 base::Bind(&SingleThreadProxy::BeginMainFrame, | |
| 772 weak_factory_.GetWeakPtr())); | |
| 773 } | |
| 774 | |
| 775 void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() { | |
| 776 layer_tree_host_->BeginMainFrameNotExpectedSoon(); | |
| 777 } | |
| 778 | |
| 779 void SingleThreadProxy::BeginMainFrame() { | |
| 780 if (defer_commits_) { | |
| 781 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit", | |
| 782 TRACE_EVENT_SCOPE_THREAD); | |
| 783 BeginMainFrameAbortedOnImplThread( | |
| 784 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT); | |
| 785 return; | |
| 786 } | |
| 787 | |
| 788 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous | |
| 789 // commit. | |
| 790 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_); | |
| 791 | |
| 792 if (!layer_tree_host_->visible()) { | |
| 793 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); | |
| 794 BeginMainFrameAbortedOnImplThread( | |
| 795 CommitEarlyOutReason::ABORTED_NOT_VISIBLE); | |
| 796 return; | |
| 797 } | |
| 798 | |
| 799 if (layer_tree_host_->output_surface_lost()) { | |
| 800 TRACE_EVENT_INSTANT0( | |
| 801 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD); | |
| 802 BeginMainFrameAbortedOnImplThread( | |
| 803 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST); | |
| 804 return; | |
| 805 } | |
| 806 | |
| 807 const BeginFrameArgs& begin_frame_args = | |
| 808 layer_tree_host_impl_->CurrentBeginFrameArgs(); | |
| 809 DoBeginMainFrame(begin_frame_args); | |
| 810 } | |
| 811 | |
| 812 void SingleThreadProxy::DoBeginMainFrame( | |
| 813 const BeginFrameArgs& begin_frame_args) { | |
| 814 layer_tree_host_->WillBeginMainFrame(); | |
| 815 layer_tree_host_->BeginMainFrame(begin_frame_args); | |
| 816 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); | |
| 817 layer_tree_host_->Layout(); | |
| 818 | |
| 819 if (PrioritizedResourceManager* contents_texture_manager = | |
| 820 layer_tree_host_->contents_texture_manager()) { | |
| 821 contents_texture_manager->UnlinkAndClearEvictedBackings(); | |
| 822 contents_texture_manager->SetMaxMemoryLimitBytes( | |
| 823 layer_tree_host_impl_->memory_allocation_limit_bytes()); | |
| 824 contents_texture_manager->SetExternalPriorityCutoff( | |
| 825 layer_tree_host_impl_->memory_allocation_priority_cutoff()); | |
| 826 } | |
| 827 | |
| 828 DCHECK(!queue_for_commit_); | |
| 829 queue_for_commit_ = make_scoped_ptr(new ResourceUpdateQueue); | |
| 830 | |
| 831 layer_tree_host_->UpdateLayers(queue_for_commit_.get()); | |
| 832 | |
| 833 timing_history_.DidBeginMainFrame(); | |
| 834 | |
| 835 // TODO(enne): SingleThreadProxy does not support cancelling commits yet, | |
| 836 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside | |
| 837 // thread_proxy.cc | |
| 838 if (scheduler_on_impl_thread_) { | |
| 839 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); | |
| 840 scheduler_on_impl_thread_->NotifyReadyToCommit(); | |
| 841 } | |
| 842 } | |
| 843 | |
| 844 void SingleThreadProxy::BeginMainFrameAbortedOnImplThread( | |
| 845 CommitEarlyOutReason reason) { | |
| 846 DebugScopedSetImplThread impl(this); | |
| 847 DCHECK(scheduler_on_impl_thread_->CommitPending()); | |
| 848 DCHECK(!layer_tree_host_impl_->pending_tree()); | |
| 849 | |
| 850 layer_tree_host_impl_->BeginMainFrameAborted(reason); | |
| 851 scheduler_on_impl_thread_->BeginMainFrameAborted(reason); | |
| 852 } | |
| 853 | |
| 854 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { | |
| 855 DebugScopedSetImplThread impl(this); | |
| 856 LayerTreeHostImpl::FrameData frame; | |
| 857 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time, | |
| 858 &frame); | |
| 859 } | |
| 860 | |
| 861 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { | |
| 862 NOTREACHED(); | |
| 863 return INVALID_RESULT; | |
| 864 } | |
| 865 | |
| 866 void SingleThreadProxy::ScheduledActionCommit() { | |
| 867 DebugScopedSetMainThread main(this); | |
| 868 DoCommit(); | |
| 869 } | |
| 870 | |
| 871 void SingleThreadProxy::ScheduledActionAnimate() { | |
| 872 TRACE_EVENT0("cc", "ScheduledActionAnimate"); | |
| 873 DebugScopedSetImplThread impl(this); | |
| 874 DoAnimate(); | |
| 875 } | |
| 876 | |
| 877 void SingleThreadProxy::ScheduledActionActivateSyncTree() { | |
| 878 DebugScopedSetImplThread impl(this); | |
| 879 layer_tree_host_impl_->ActivateSyncTree(); | |
| 880 } | |
| 881 | |
| 882 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { | |
| 883 DebugScopedSetMainThread main(this); | |
| 884 DCHECK(scheduler_on_impl_thread_); | |
| 885 // If possible, create the output surface in a post task. Synchronously | |
| 886 // creating the output surface makes tests more awkward since this differs | |
| 887 // from the ThreadProxy behavior. However, sometimes there is no | |
| 888 // task runner. | |
| 889 if (Proxy::MainThreadTaskRunner()) { | |
| 890 ScheduleRequestNewOutputSurface(); | |
| 891 } else { | |
| 892 RequestNewOutputSurface(); | |
| 893 } | |
| 894 } | |
| 895 | |
| 896 void SingleThreadProxy::ScheduledActionPrepareTiles() { | |
| 897 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles"); | |
| 898 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); | |
| 899 DebugScopedSetImplThread impl(this); | |
| 900 layer_tree_host_impl_->PrepareTiles(); | |
| 901 } | |
| 902 | |
| 903 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { | |
| 904 } | |
| 905 | |
| 906 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { | |
| 907 return timing_history_.DrawDurationEstimate(); | |
| 908 } | |
| 909 | |
| 910 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { | |
| 911 return timing_history_.BeginMainFrameToCommitDurationEstimate(); | |
| 912 } | |
| 913 | |
| 914 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { | |
| 915 return timing_history_.CommitToActivateDurationEstimate(); | |
| 916 } | |
| 917 | |
| 918 void SingleThreadProxy::DidBeginImplFrameDeadline() { | |
| 919 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); | |
| 920 } | |
| 921 | |
| 922 void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) { | |
| 923 layer_tree_host_->SendBeginFramesToChildren(args); | |
| 924 } | |
| 925 | |
| 926 } // namespace cc | |
| OLD | NEW |