 Chromium Code Reviews
 Chromium Code Reviews Issue 134623005:
  Make SingleThreadProxy a SchedulerClient  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 134623005:
  Make SingleThreadProxy a SchedulerClient  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "cc/trees/single_thread_proxy.h" | 5 #include "cc/trees/single_thread_proxy.h" | 
| 6 | 6 | 
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" | 
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" | 
| 9 #include "cc/debug/benchmark_instrumentation.h" | 9 #include "cc/debug/benchmark_instrumentation.h" | 
| 10 #include "cc/output/context_provider.h" | 10 #include "cc/output/context_provider.h" | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 return make_scoped_ptr( | 26 return make_scoped_ptr( | 
| 27 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>(); | 27 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>(); | 
| 28 } | 28 } | 
| 29 | 29 | 
| 30 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, | 30 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, | 
| 31 LayerTreeHostSingleThreadClient* client) | 31 LayerTreeHostSingleThreadClient* client) | 
| 32 : Proxy(NULL), | 32 : Proxy(NULL), | 
| 33 layer_tree_host_(layer_tree_host), | 33 layer_tree_host_(layer_tree_host), | 
| 34 client_(client), | 34 client_(client), | 
| 35 next_frame_is_newly_committed_frame_(false), | 35 next_frame_is_newly_committed_frame_(false), | 
| 36 inside_draw_(false) { | 36 inside_draw_(false), | 
| 37 defer_commits_(false), | |
| 38 finish_commit_deferred_(false), | |
| 39 weak_factory_(this) { | |
| 37 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); | 40 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); | 
| 38 DCHECK(Proxy::IsMainThread()); | 41 DCHECK(Proxy::IsMainThread()); | 
| 39 DCHECK(layer_tree_host); | 42 DCHECK(layer_tree_host); | 
| 40 | 43 | 
| 41 // Impl-side painting not supported without threaded compositing. | 44 // Impl-side painting not supported without threaded compositing. | 
| 42 CHECK(!layer_tree_host->settings().impl_side_painting) | 45 CHECK(!layer_tree_host->settings().impl_side_painting) | 
| 43 << "Threaded compositing must be enabled to use impl-side painting."; | 46 << "Threaded compositing must be enabled to use impl-side painting."; | 
| 44 } | 47 } | 
| 45 | 48 | 
| 46 void SingleThreadProxy::Start() { | 49 void SingleThreadProxy::Start() { | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 66 | 69 | 
| 67 bool SingleThreadProxy::IsStarted() const { | 70 bool SingleThreadProxy::IsStarted() const { | 
| 68 DCHECK(Proxy::IsMainThread()); | 71 DCHECK(Proxy::IsMainThread()); | 
| 69 return layer_tree_host_impl_; | 72 return layer_tree_host_impl_; | 
| 70 } | 73 } | 
| 71 | 74 | 
| 72 void SingleThreadProxy::SetLayerTreeHostClientReady() { | 75 void SingleThreadProxy::SetLayerTreeHostClientReady() { | 
| 73 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); | 76 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); | 
| 74 // Scheduling is controlled by the embedder in the single thread case, so | 77 // Scheduling is controlled by the embedder in the single thread case, so | 
| 75 // nothing to do. | 78 // nothing to do. | 
| 79 DCHECK(Proxy::IsMainThread()); | |
| 80 DebugScopedSetImplThread impl(this); | |
| 81 if (layer_tree_host_->settings().single_thread_proxy_scheduler && | |
| 82 !scheduler_on_impl_thread_) { | |
| 83 SchedulerSettings scheduler_settings(layer_tree_host_->settings()); | |
| 84 scheduler_on_impl_thread_ = Scheduler::Create(this, | |
| 85 scheduler_settings, | |
| 86 layer_tree_host_->id(), | |
| 87 MainThreadTaskRunner()); | |
| 88 scheduler_on_impl_thread_->SetCanStart(); | |
| 89 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | |
| 90 } | |
| 76 } | 91 } | 
| 77 | 92 | 
| 78 void SingleThreadProxy::SetVisible(bool visible) { | 93 void SingleThreadProxy::SetVisible(bool visible) { | 
| 79 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); | 94 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); | 
| 80 DebugScopedSetImplThread impl(this); | 95 DebugScopedSetImplThread impl(this); | 
| 81 layer_tree_host_impl_->SetVisible(visible); | 96 layer_tree_host_impl_->SetVisible(visible); | 
| 82 | 97 if (scheduler_on_impl_thread_) | 
| 98 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | |
| 83 // Changing visibility could change ShouldComposite(). | 99 // Changing visibility could change ShouldComposite(). | 
| 84 UpdateBackgroundAnimateTicking(); | 100 UpdateBackgroundAnimateTicking(); | 
| 85 } | 101 } | 
| 86 | 102 | 
| 87 void SingleThreadProxy::CreateAndInitializeOutputSurface() { | 103 void SingleThreadProxy::CreateAndInitializeOutputSurface() { | 
| 88 TRACE_EVENT0( | 104 TRACE_EVENT0( | 
| 89 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); | 105 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); | 
| 90 DCHECK(Proxy::IsMainThread()); | 106 DCHECK(Proxy::IsMainThread()); | 
| 91 DCHECK(layer_tree_host_->output_surface_lost()); | 107 DCHECK(layer_tree_host_->output_surface_lost()); | 
| 92 | 108 | 
| 93 scoped_ptr<OutputSurface> output_surface = | 109 scoped_ptr<OutputSurface> output_surface = | 
| 94 layer_tree_host_->CreateOutputSurface(); | 110 layer_tree_host_->CreateOutputSurface(); | 
| 95 | 111 | 
| 96 renderer_capabilities_for_main_thread_ = RendererCapabilities(); | 112 renderer_capabilities_for_main_thread_ = RendererCapabilities(); | 
| 97 | 113 | 
| 98 bool success = !!output_surface; | 114 bool success = !!output_surface; | 
| 99 if (success) { | 115 if (success) { | 
| 100 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 116 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 
| 101 DebugScopedSetImplThread impl(this); | 117 DebugScopedSetImplThread impl(this); | 
| 102 layer_tree_host_->DeleteContentsTexturesOnImplThread( | 118 layer_tree_host_->DeleteContentsTexturesOnImplThread( | 
| 103 layer_tree_host_impl_->resource_provider()); | 119 layer_tree_host_impl_->resource_provider()); | 
| 104 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); | 120 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); | 
| 105 } | 121 } | 
| 106 | 122 | 
| 107 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); | 123 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); | 
| 108 | 124 | 
| 109 if (!success) { | 125 if (success) { | 
| 110 // Force another recreation attempt to happen by requesting another commit. | 126 if (scheduler_on_impl_thread_) | 
| 111 SetNeedsCommit(); | 127 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); | 
| 128 } else if (Proxy::MainThreadTaskRunner()) { | |
| 129 Proxy::MainThreadTaskRunner()->PostTask( | |
| 130 FROM_HERE, | |
| 131 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, | |
| 132 weak_factory_.GetWeakPtr())); | |
| 112 } | 133 } | 
| 113 } | 134 } | 
| 114 | 135 | 
| 115 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { | 136 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { | 
| 116 DCHECK(Proxy::IsMainThread()); | 137 DCHECK(Proxy::IsMainThread()); | 
| 117 DCHECK(!layer_tree_host_->output_surface_lost()); | 138 DCHECK(!layer_tree_host_->output_surface_lost()); | 
| 118 return renderer_capabilities_for_main_thread_; | 139 return renderer_capabilities_for_main_thread_; | 
| 119 } | 140 } | 
| 120 | 141 | 
| 121 void SingleThreadProxy::SetNeedsAnimate() { | 142 void SingleThreadProxy::SetNeedsAnimate() { | 
| 122 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); | 143 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); | 
| 123 DCHECK(Proxy::IsMainThread()); | 144 DCHECK(Proxy::IsMainThread()); | 
| 124 client_->ScheduleAnimation(); | 145 client_->ScheduleAnimation(); | 
| 146 SetNeedsCommit(); | |
| 125 } | 147 } | 
| 126 | 148 | 
| 127 void SingleThreadProxy::SetNeedsUpdateLayers() { | 149 void SingleThreadProxy::SetNeedsUpdateLayers() { | 
| 128 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); | 150 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); | 
| 129 DCHECK(Proxy::IsMainThread()); | 151 DCHECK(Proxy::IsMainThread()); | 
| 130 client_->ScheduleComposite(); | 152 SetNeedsCommit(); | 
| 131 } | 153 } | 
| 132 | 154 | 
| 133 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { | 155 void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { | 
| 134 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); | 156 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); | 
| 135 DCHECK(Proxy::IsMainThread()); | 157 DCHECK(Proxy::IsMainThread()); | 
| 158 layer_tree_host_->WillBeginMainFrame(); | |
| 159 layer_tree_host_->Layout(); | |
| 160 layer_tree_host_->AnimateLayers(frame_begin_time); | |
| 161 | |
| 162 if (PrioritizedResourceManager* contents_texture_manager = | |
| 163 layer_tree_host_->contents_texture_manager()) { | |
| 164 contents_texture_manager->UnlinkAndClearEvictedBackings(); | |
| 165 contents_texture_manager->SetMaxMemoryLimitBytes( | |
| 166 layer_tree_host_impl_->memory_allocation_limit_bytes()); | |
| 167 contents_texture_manager->SetExternalPriorityCutoff( | |
| 168 layer_tree_host_impl_->memory_allocation_priority_cutoff()); | |
| 169 } | |
| 170 | |
| 171 scoped_ptr<ResourceUpdateQueue> queue = | |
| 172 make_scoped_ptr(new ResourceUpdateQueue); | |
| 173 | |
| 174 layer_tree_host_->UpdateLayers(queue.get()); | |
| 175 | |
| 176 layer_tree_host_->WillCommit(); | |
| 177 | |
| 136 // Commit immediately. | 178 // Commit immediately. | 
| 137 { | 179 { | 
| 138 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 180 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 
| 139 DebugScopedSetImplThread impl(this); | 181 DebugScopedSetImplThread impl(this); | 
| 140 | 182 | 
| 141 // This CapturePostTasks should be destroyed before CommitComplete() is | 183 // This CapturePostTasks should be destroyed before CommitComplete() is | 
| 142 // called since that goes out to the embedder, and we want the embedder | 184 // called since that goes out to the embedder, and we want the embedder | 
| 143 // to receive its callbacks before that. | 185 // to receive its callbacks before that. | 
| 144 BlockingTaskRunner::CapturePostTasks blocked; | 186 BlockingTaskRunner::CapturePostTasks blocked; | 
| 145 | 187 | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 159 layer_tree_host_impl_->resource_provider()); | 201 layer_tree_host_impl_->resource_provider()); | 
| 160 update_controller->Finalize(); | 202 update_controller->Finalize(); | 
| 161 | 203 | 
| 162 if (layer_tree_host_impl_->EvictedUIResourcesExist()) | 204 if (layer_tree_host_impl_->EvictedUIResourcesExist()) | 
| 163 layer_tree_host_->RecreateUIResources(); | 205 layer_tree_host_->RecreateUIResources(); | 
| 164 | 206 | 
| 165 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); | 207 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); | 
| 166 | 208 | 
| 167 layer_tree_host_impl_->CommitComplete(); | 209 layer_tree_host_impl_->CommitComplete(); | 
| 168 | 210 | 
| 211 UpdateBackgroundAnimateTicking(); | |
| 212 | |
| 169 #if DCHECK_IS_ON | 213 #if DCHECK_IS_ON | 
| 170 // In the single-threaded case, the scale and scroll deltas should never be | 214 // In the single-threaded case, the scale and scroll deltas should never be | 
| 171 // touched on the impl layer tree. | 215 // touched on the impl layer tree. | 
| 172 scoped_ptr<ScrollAndScaleSet> scroll_info = | 216 scoped_ptr<ScrollAndScaleSet> scroll_info = | 
| 173 layer_tree_host_impl_->ProcessScrollDeltas(); | 217 layer_tree_host_impl_->ProcessScrollDeltas(); | 
| 174 DCHECK(!scroll_info->scrolls.size()); | 218 DCHECK(!scroll_info->scrolls.size()); | 
| 175 DCHECK_EQ(1.f, scroll_info->page_scale_delta); | 219 DCHECK_EQ(1.f, scroll_info->page_scale_delta); | 
| 176 #endif | 220 #endif | 
| 177 | 221 | 
| 178 RenderingStatsInstrumentation* stats_instrumentation = | 222 RenderingStatsInstrumentation* stats_instrumentation = | 
| 179 layer_tree_host_->rendering_stats_instrumentation(); | 223 layer_tree_host_->rendering_stats_instrumentation(); | 
| 180 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( | 224 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( | 
| 181 stats_instrumentation->main_thread_rendering_stats()); | 225 stats_instrumentation->main_thread_rendering_stats()); | 
| 182 stats_instrumentation->AccumulateAndClearMainThreadStats(); | 226 stats_instrumentation->AccumulateAndClearMainThreadStats(); | 
| 183 } | 227 } | 
| 184 layer_tree_host_->CommitComplete(); | 228 layer_tree_host_->CommitComplete(); | 
| 229 layer_tree_host_->DidBeginMainFrame(); | |
| 230 timing_history_.DidCommit(); | |
| 231 | |
| 185 next_frame_is_newly_committed_frame_ = true; | 232 next_frame_is_newly_committed_frame_ = true; | 
| 186 } | 233 } | 
| 187 | 234 | 
| 188 void SingleThreadProxy::SetNeedsCommit() { | 235 void SingleThreadProxy::SetNeedsCommit() { | 
| 189 DCHECK(Proxy::IsMainThread()); | 236 DCHECK(Proxy::IsMainThread()); | 
| 237 DebugScopedSetImplThread impl(this); | |
| 190 client_->ScheduleComposite(); | 238 client_->ScheduleComposite(); | 
| 239 if (scheduler_on_impl_thread_) | |
| 240 scheduler_on_impl_thread_->SetNeedsCommit(); | |
| 191 } | 241 } | 
| 192 | 242 | 
| 193 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { | 243 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { | 
| 194 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); | 244 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); | 
| 245 DCHECK(Proxy::IsMainThread()); | |
| 246 DebugScopedSetImplThread impl(this); | |
| 247 client_->ScheduleComposite(); | |
| 195 SetNeedsRedrawRectOnImplThread(damage_rect); | 248 SetNeedsRedrawRectOnImplThread(damage_rect); | 
| 196 client_->ScheduleComposite(); | |
| 197 } | 249 } | 
| 198 | 250 | 
| 199 void SingleThreadProxy::SetNextCommitWaitsForActivation() { | 251 void SingleThreadProxy::SetNextCommitWaitsForActivation() { | 
| 200 // There is no activation here other than commit. So do nothing. | 252 // There is no activation here other than commit. So do nothing. | 
| 253 DCHECK(Proxy::IsMainThread()); | |
| 201 } | 254 } | 
| 202 | 255 | 
| 203 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { | 256 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { | 
| 204 // Thread-only feature. | 257 DCHECK(Proxy::IsMainThread()); | 
| 205 NOTREACHED(); | 258 DCHECK(scheduler_on_impl_thread_); | 
| 259 if (defer_commits_ == defer_commits) | |
| 260 return; | |
| 261 | |
| 262 if (defer_commits) | |
| 263 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this); | |
| 264 else | |
| 265 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); | |
| 266 | |
| 267 defer_commits_ = defer_commits; | |
| 268 if (!defer_commits_ && finish_commit_deferred_) { | |
| 
danakj
2014/06/19 22:04:02
nit: finish_deferred_commit_? that's what it's say
 
enne (OOO)
2014/06/19 22:38:06
Months ago, this actually was deferring a function
 | |
| 269 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); | |
| 270 scheduler_on_impl_thread_->NotifyReadyToCommit(); | |
| 271 finish_commit_deferred_ = false; | |
| 272 } | |
| 206 } | 273 } | 
| 207 | 274 | 
| 208 bool SingleThreadProxy::CommitRequested() const { return false; } | 275 bool SingleThreadProxy::CommitRequested() const { | 
| 276 DCHECK(Proxy::IsMainThread()); | |
| 277 return finish_commit_deferred_; | |
| 
danakj
2014/06/19 22:04:02
Can you convince me why this shouldn't be true aft
 
enne (OOO)
2014/06/19 22:38:06
Ok, fixed up to call set it to true in SNC and fal
 | |
| 278 } | |
| 209 | 279 | 
| 210 bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } | 280 bool SingleThreadProxy::BeginMainFrameRequested() const { | 
| 281 DCHECK(Proxy::IsMainThread()); | |
| 282 return finish_commit_deferred_; | |
| 
danakj
2014/06/19 22:04:02
Can we NOTREACHED() with a comment about why here?
 
enne (OOO)
2014/06/19 22:38:06
Why put an extra landmine? I'd rather just have th
 
danakj
2014/06/19 22:41:21
I was thinking that we could remove it and make it
 | |
| 283 } | |
| 211 | 284 | 
| 212 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { | 285 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { | 
| 213 return std::numeric_limits<size_t>::max(); | 286 return std::numeric_limits<size_t>::max(); | 
| 214 } | 287 } | 
| 215 | 288 | 
| 216 void SingleThreadProxy::Stop() { | 289 void SingleThreadProxy::Stop() { | 
| 217 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); | 290 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); | 
| 218 DCHECK(Proxy::IsMainThread()); | 291 DCHECK(Proxy::IsMainThread()); | 
| 219 { | 292 { | 
| 220 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 293 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 
| 221 DebugScopedSetImplThread impl(this); | 294 DebugScopedSetImplThread impl(this); | 
| 222 | 295 | 
| 223 BlockingTaskRunner::CapturePostTasks blocked; | 296 BlockingTaskRunner::CapturePostTasks blocked; | 
| 224 layer_tree_host_->DeleteContentsTexturesOnImplThread( | 297 layer_tree_host_->DeleteContentsTexturesOnImplThread( | 
| 225 layer_tree_host_impl_->resource_provider()); | 298 layer_tree_host_impl_->resource_provider()); | 
| 299 scheduler_on_impl_thread_.reset(); | |
| 226 layer_tree_host_impl_.reset(); | 300 layer_tree_host_impl_.reset(); | 
| 227 } | 301 } | 
| 228 layer_tree_host_ = NULL; | 302 layer_tree_host_ = NULL; | 
| 229 } | 303 } | 
| 230 | 304 | 
| 231 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 305 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 
| 232 TRACE_EVENT1( | 306 TRACE_EVENT1( | 
| 233 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | 307 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | 
| 234 DCHECK(Proxy::IsImplThread()); | 308 DCHECK(Proxy::IsImplThread()); | 
| 235 UpdateBackgroundAnimateTicking(); | 309 UpdateBackgroundAnimateTicking(); | 
| 310 if (scheduler_on_impl_thread_) | |
| 311 scheduler_on_impl_thread_->SetCanDraw(can_draw); | |
| 236 } | 312 } | 
| 237 | 313 | 
| 238 void SingleThreadProxy::NotifyReadyToActivate() { | 314 void SingleThreadProxy::NotifyReadyToActivate() { | 
| 239 // Thread-only feature. | 315 // Impl-side painting only. | 
| 240 NOTREACHED(); | 316 NOTREACHED(); | 
| 241 } | 317 } | 
| 242 | 318 | 
| 243 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { | 319 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { | 
| 244 client_->ScheduleComposite(); | 320 client_->ScheduleComposite(); | 
| 321 if (scheduler_on_impl_thread_) | |
| 322 scheduler_on_impl_thread_->SetNeedsRedraw(); | |
| 245 } | 323 } | 
| 246 | 324 | 
| 247 void SingleThreadProxy::SetNeedsAnimateOnImplThread() { | 325 void SingleThreadProxy::SetNeedsAnimateOnImplThread() { | 
| 248 SetNeedsRedrawOnImplThread(); | 326 SetNeedsRedrawOnImplThread(); | 
| 249 } | 327 } | 
| 250 | 328 | 
| 251 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { | 329 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { | 
| 252 // Thread-only/Impl-side-painting-only feature. | 330 // Impl-side painting only. | 
| 253 NOTREACHED(); | 331 NOTREACHED(); | 
| 254 } | 332 } | 
| 255 | 333 | 
| 256 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( | 334 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( | 
| 257 const gfx::Rect& damage_rect) { | 335 const gfx::Rect& damage_rect) { | 
| 258 // TODO(brianderson): Once we move render_widget scheduling into this class, | |
| 259 // we can treat redraw requests more efficiently than CommitAndRedraw | |
| 260 // requests. | |
| 261 layer_tree_host_impl_->SetViewportDamage(damage_rect); | 336 layer_tree_host_impl_->SetViewportDamage(damage_rect); | 
| 262 SetNeedsCommit(); | 337 SetNeedsRedrawOnImplThread(); | 
| 263 } | 338 } | 
| 264 | 339 | 
| 265 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { | 340 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { | 
| 266 // Impl-side painting only. | 341 // Impl-side painting only. | 
| 267 NOTREACHED(); | 342 NOTREACHED(); | 
| 268 } | 343 } | 
| 269 | 344 | 
| 270 void SingleThreadProxy::SetNeedsCommitOnImplThread() { | 345 void SingleThreadProxy::SetNeedsCommitOnImplThread() { | 
| 271 client_->ScheduleComposite(); | 346 client_->ScheduleComposite(); | 
| 347 if (scheduler_on_impl_thread_) | |
| 348 scheduler_on_impl_thread_->SetNeedsCommit(); | |
| 272 } | 349 } | 
| 273 | 350 | 
| 274 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | 351 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | 
| 275 scoped_ptr<AnimationEventsVector> events) { | 352 scoped_ptr<AnimationEventsVector> events) { | 
| 276 TRACE_EVENT0( | 353 TRACE_EVENT0( | 
| 277 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); | 354 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); | 
| 278 DCHECK(Proxy::IsImplThread()); | 355 DCHECK(Proxy::IsImplThread()); | 
| 279 DebugScopedSetMainThread main(this); | 356 DebugScopedSetMainThread main(this); | 
| 280 layer_tree_host_->SetAnimationEvents(events.Pass()); | 357 layer_tree_host_->SetAnimationEvents(events.Pass()); | 
| 281 } | 358 } | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 298 } | 375 } | 
| 299 | 376 | 
| 300 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } | 377 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } | 
| 301 | 378 | 
| 302 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { | 379 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { | 
| 303 DCHECK(IsImplThread()); | 380 DCHECK(IsImplThread()); | 
| 304 renderer_capabilities_for_main_thread_ = | 381 renderer_capabilities_for_main_thread_ = | 
| 305 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); | 382 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); | 
| 306 } | 383 } | 
| 307 | 384 | 
| 385 void SingleThreadProxy::DidActivatePendingTree() { | |
| 386 // Impl-side painting only. | |
| 387 NOTREACHED(); | |
| 388 } | |
| 389 | |
| 390 void SingleThreadProxy::DidManageTiles() { | |
| 391 // Impl-side painting only. | |
| 392 NOTREACHED(); | |
| 393 } | |
| 394 | |
| 308 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { | 395 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { | 
| 309 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); | 396 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); | 
| 310 // Cause a commit so we can notice the lost context. | 397 { | 
| 311 SetNeedsCommitOnImplThread(); | 398 DebugScopedSetMainThread main(this); | 
| 399 // This must happen before we notify the scheduler as it may try to recreate | |
| 400 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. | |
| 401 layer_tree_host_->DidLoseOutputSurface(); | |
| 402 } | |
| 312 client_->DidAbortSwapBuffers(); | 403 client_->DidAbortSwapBuffers(); | 
| 404 if (scheduler_on_impl_thread_) | |
| 405 scheduler_on_impl_thread_->DidLoseOutputSurface(); | |
| 313 } | 406 } | 
| 314 | 407 | 
| 315 void SingleThreadProxy::DidSwapBuffersOnImplThread() { | 408 void SingleThreadProxy::DidSwapBuffersOnImplThread() { | 
| 409 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread"); | |
| 410 if (scheduler_on_impl_thread_) | |
| 411 scheduler_on_impl_thread_->DidSwapBuffers(); | |
| 316 client_->DidPostSwapBuffers(); | 412 client_->DidPostSwapBuffers(); | 
| 317 } | 413 } | 
| 318 | 414 | 
| 319 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { | 415 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { | 
| 320 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); | 416 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); | 
| 321 client_->DidCompleteSwapBuffers(); | 417 if (scheduler_on_impl_thread_) | 
| 418 scheduler_on_impl_thread_->DidSwapBuffersComplete(); | |
| 419 layer_tree_host_->DidCompleteSwapBuffers(); | |
| 322 } | 420 } | 
| 323 | 421 | 
| 324 // Called by the legacy scheduling path (e.g. where render_widget does the | 422 void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) { | 
| 325 // scheduling) | 423 TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame"); | 
| 424 if (scheduler_on_impl_thread_) | |
| 425 scheduler_on_impl_thread_->BeginImplFrame(args); | |
| 426 } | |
| 427 | |
| 326 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { | 428 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { | 
| 327 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); | 429 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); | 
| 328 DCHECK(Proxy::IsMainThread()); | 430 DCHECK(Proxy::IsMainThread()); | 
| 329 DCHECK(!layer_tree_host_->output_surface_lost()); | 431 DCHECK(!layer_tree_host_->output_surface_lost()); | 
| 330 | 432 | 
| 331 layer_tree_host_->AnimateLayers(frame_begin_time); | 433 DoCommit(frame_begin_time); | 
| 332 | |
| 333 if (PrioritizedResourceManager* contents_texture_manager = | |
| 334 layer_tree_host_->contents_texture_manager()) { | |
| 335 contents_texture_manager->UnlinkAndClearEvictedBackings(); | |
| 336 contents_texture_manager->SetMaxMemoryLimitBytes( | |
| 337 layer_tree_host_impl_->memory_allocation_limit_bytes()); | |
| 338 contents_texture_manager->SetExternalPriorityCutoff( | |
| 339 layer_tree_host_impl_->memory_allocation_priority_cutoff()); | |
| 340 } | |
| 341 | |
| 342 scoped_ptr<ResourceUpdateQueue> queue = | |
| 343 make_scoped_ptr(new ResourceUpdateQueue); | |
| 344 layer_tree_host_->UpdateLayers(queue.get()); | |
| 345 layer_tree_host_->WillCommit(); | |
| 346 DoCommit(queue.Pass()); | |
| 347 layer_tree_host_->DidBeginMainFrame(); | |
| 348 | 434 | 
| 349 LayerTreeHostImpl::FrameData frame; | 435 LayerTreeHostImpl::FrameData frame; | 
| 350 if (DoComposite(frame_begin_time, &frame)) { | 436 DoComposite(frame_begin_time, &frame); | 
| 351 { | |
| 352 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 353 DebugScopedSetImplThread impl(this); | |
| 354 | |
| 355 // This CapturePostTasks should be destroyed before | |
| 356 // DidCommitAndDrawFrame() is called since that goes out to the embedder, | |
| 357 // and we want the embedder to receive its callbacks before that. | |
| 358 // NOTE: This maintains consistent ordering with the ThreadProxy since | |
| 359 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread | |
| 360 // there as the main thread is not blocked, so any posted tasks inside | |
| 361 // the swap buffers will execute first. | |
| 362 BlockingTaskRunner::CapturePostTasks blocked; | |
| 363 | |
| 364 layer_tree_host_impl_->SwapBuffers(frame); | |
| 365 } | |
| 366 DidSwapFrame(); | |
| 367 } | |
| 368 } | 437 } | 
| 369 | 438 | 
| 370 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { | 439 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { | 
| 371 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 440 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 
| 372 { | 441 { | 
| 373 // The following line casts away const modifiers because it is just | 442 // The following line casts away const modifiers because it is just | 
| 374 // setting debug state. We still want the AsValue() function and its | 443 // setting debug state. We still want the AsValue() function and its | 
| 375 // call chain to be const throughout. | 444 // call chain to be const throughout. | 
| 376 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); | 445 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); | 
| 377 | 446 | 
| (...skipping 18 matching lines...) Expand all Loading... | |
| 396 return layer_tree_host_impl_->visible() && | 465 return layer_tree_host_impl_->visible() && | 
| 397 layer_tree_host_impl_->CanDraw(); | 466 layer_tree_host_impl_->CanDraw(); | 
| 398 } | 467 } | 
| 399 | 468 | 
| 400 void SingleThreadProxy::UpdateBackgroundAnimateTicking() { | 469 void SingleThreadProxy::UpdateBackgroundAnimateTicking() { | 
| 401 DCHECK(Proxy::IsImplThread()); | 470 DCHECK(Proxy::IsImplThread()); | 
| 402 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( | 471 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( | 
| 403 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); | 472 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); | 
| 404 } | 473 } | 
| 405 | 474 | 
| 406 bool SingleThreadProxy::DoComposite( | 475 DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, | 
| 407 base::TimeTicks frame_begin_time, | 476 LayerTreeHostImpl::FrameData* frame) { | 
| 408 LayerTreeHostImpl::FrameData* frame) { | |
| 409 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); | 477 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); | 
| 410 DCHECK(!layer_tree_host_->output_surface_lost()); | 478 DCHECK(!layer_tree_host_->output_surface_lost()); | 
| 411 | 479 | 
| 412 bool lost_output_surface = false; | |
| 413 { | 480 { | 
| 414 DebugScopedSetImplThread impl(this); | 481 DebugScopedSetImplThread impl(this); | 
| 415 base::AutoReset<bool> mark_inside(&inside_draw_, true); | 482 base::AutoReset<bool> mark_inside(&inside_draw_, true); | 
| 416 | 483 | 
| 417 // We guard PrepareToDraw() with CanDraw() because it always returns a valid | 484 // We guard PrepareToDraw() with CanDraw() because it always returns a valid | 
| 418 // frame, so can only be used when such a frame is possible. Since | 485 // frame, so can only be used when such a frame is possible. Since | 
| 419 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on | 486 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on | 
| 420 // CanDraw() as well. | 487 // CanDraw() as well. | 
| 421 if (!ShouldComposite()) { | 488 if (!ShouldComposite()) { | 
| 422 UpdateBackgroundAnimateTicking(); | 489 UpdateBackgroundAnimateTicking(); | 
| 423 return false; | 490 return DRAW_ABORTED_CANT_DRAW; | 
| 424 } | 491 } | 
| 425 | 492 | 
| 493 timing_history_.DidStartDrawing(); | |
| 494 | |
| 426 layer_tree_host_impl_->Animate( | 495 layer_tree_host_impl_->Animate( | 
| 427 layer_tree_host_impl_->CurrentFrameTimeTicks()); | 496 layer_tree_host_impl_->CurrentFrameTimeTicks()); | 
| 428 UpdateBackgroundAnimateTicking(); | 497 UpdateBackgroundAnimateTicking(); | 
| 429 | 498 | 
| 430 if (!layer_tree_host_impl_->IsContextLost()) { | 499 if (!layer_tree_host_impl_->IsContextLost()) { | 
| 431 layer_tree_host_impl_->PrepareToDraw(frame); | 500 layer_tree_host_impl_->PrepareToDraw(frame); | 
| 432 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); | 501 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); | 
| 433 layer_tree_host_impl_->DidDrawAllLayers(*frame); | 502 layer_tree_host_impl_->DidDrawAllLayers(*frame); | 
| 434 } | 503 } | 
| 435 lost_output_surface = layer_tree_host_impl_->IsContextLost(); | |
| 436 | 504 | 
| 437 bool start_ready_animations = true; | 505 bool start_ready_animations = true; | 
| 438 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); | 506 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); | 
| 439 | 507 | 
| 440 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | 508 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | 
| 509 | |
| 510 timing_history_.DidFinishDrawing(); | |
| 441 } | 511 } | 
| 442 | 512 | 
| 443 if (lost_output_surface) { | 513 { | 
| 444 layer_tree_host_->DidLoseOutputSurface(); | 514 DebugScopedSetImplThread impl(this); | 
| 445 return false; | 515 | 
| 516 if (layer_tree_host_impl_->IsContextLost()) { | |
| 517 DidLoseOutputSurfaceOnImplThread(); | |
| 518 } else { | |
| 519 // This CapturePostTasks should be destroyed before | |
| 520 // DidCommitAndDrawFrame() is called since that goes out to the embedder, | |
| 521 // and we want the embedder to receive its callbacks before that. | |
| 522 // NOTE: This maintains consistent ordering with the ThreadProxy since | |
| 523 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread | |
| 524 // there as the main thread is not blocked, so any posted tasks inside | |
| 525 // the swap buffers will execute first. | |
| 526 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 527 | |
| 528 BlockingTaskRunner::CapturePostTasks blocked; | |
| 529 layer_tree_host_impl_->SwapBuffers(*frame); | |
| 530 } | |
| 446 } | 531 } | 
| 532 DidCommitAndDrawFrame(); | |
| 447 | 533 | 
| 448 return true; | 534 return DRAW_SUCCESS; | 
| 449 } | 535 } | 
| 450 | 536 | 
| 451 void SingleThreadProxy::DidSwapFrame() { | 537 void SingleThreadProxy::DidCommitAndDrawFrame() { | 
| 452 if (next_frame_is_newly_committed_frame_) { | 538 if (next_frame_is_newly_committed_frame_) { | 
| 539 DebugScopedSetMainThread main(this); | |
| 453 next_frame_is_newly_committed_frame_ = false; | 540 next_frame_is_newly_committed_frame_ = false; | 
| 454 layer_tree_host_->DidCommitAndDrawFrame(); | 541 layer_tree_host_->DidCommitAndDrawFrame(); | 
| 455 } | 542 } | 
| 456 } | 543 } | 
| 457 | 544 | 
| 458 bool SingleThreadProxy::CommitPendingForTesting() { return false; } | 545 bool SingleThreadProxy::CommitPendingForTesting() { return false; } | 
| 459 | 546 | 
| 547 scoped_ptr<base::Value> SingleThreadProxy::SchedulerAsValueForTesting() { | |
| 548 DebugScopedSetImplThread impl(this); | |
| 549 if (!scheduler_on_impl_thread_) | |
| 550 return make_scoped_ptr(base::Value::CreateNullValue()).Pass(); | |
| 551 return scheduler_on_impl_thread_->AsValue().Pass(); | |
| 552 } | |
| 553 | |
| 554 void SingleThreadProxy::SetNeedsBeginFrame(bool enable) { | |
| 555 layer_tree_host_impl_->SetNeedsBeginFrame(enable); | |
| 556 } | |
| 557 | |
| 558 void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { | |
| 559 layer_tree_host_impl_->WillBeginImplFrame(args); | |
| 560 } | |
| 561 | |
| 562 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { | |
| 563 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame"); | |
| 564 if (defer_commits_) { | |
| 565 DCHECK(!finish_commit_deferred_); | |
| 566 finish_commit_deferred_ = true; | |
| 567 layer_tree_host_->DidDeferCommit(); | |
| 568 return; | |
| 569 } | |
| 570 timing_history_.DidBeginMainFrame(); | |
| 571 | |
| 572 DCHECK(scheduler_on_impl_thread_); | |
| 573 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); | |
| 574 scheduler_on_impl_thread_->NotifyReadyToCommit(); | |
| 575 } | |
| 576 | |
| 577 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { | |
| 578 DebugScopedSetImplThread impl(this); | |
| 579 if (layer_tree_host_impl_->IsContextLost()) { | |
| 580 DidCommitAndDrawFrame(); | |
| 581 return DRAW_SUCCESS; | |
| 582 } | |
| 583 | |
| 584 LayerTreeHostImpl::FrameData frame; | |
| 585 return DoComposite(gfx::FrameTime::Now(), &frame); | |
| 586 } | |
| 587 | |
| 588 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { | |
| 589 NOTREACHED(); | |
| 590 return INVALID_RESULT; | |
| 591 } | |
| 592 | |
| 593 void SingleThreadProxy::ScheduledActionCommit() { | |
| 594 DebugScopedSetMainThread main(this); | |
| 595 DoCommit(gfx::FrameTime::Now()); | |
| 596 } | |
| 597 | |
| 598 void SingleThreadProxy::ScheduledActionAnimate() { | |
| 599 TRACE_EVENT0("cc", "ScheduledActionAnimate"); | |
| 600 layer_tree_host_impl_->Animate( | |
| 601 layer_tree_host_impl_->CurrentFrameTimeTicks()); | |
| 602 } | |
| 603 | |
| 604 void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { | |
| 605 // Impl-side painting only. | |
| 606 NOTREACHED(); | |
| 607 } | |
| 608 | |
| 609 void SingleThreadProxy::ScheduledActionActivatePendingTree() { | |
| 610 // Impl-side painting only. | |
| 611 NOTREACHED(); | |
| 612 } | |
| 613 | |
| 614 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { | |
| 615 DebugScopedSetMainThread main(this); | |
| 616 DCHECK(scheduler_on_impl_thread_); | |
| 617 // If possible, create the output surface in a post task. Synchronously | |
| 618 // creating the output surface makes tests more awkward since this differs | |
| 619 // from the ThreadProxy behavior. However, sometimes there is no | |
| 620 // task runner. | |
| 621 if (Proxy::MainThreadTaskRunner()) { | |
| 622 Proxy::MainThreadTaskRunner()->PostTask( | |
| 623 FROM_HERE, | |
| 624 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, | |
| 625 weak_factory_.GetWeakPtr())); | |
| 626 } else { | |
| 627 CreateAndInitializeOutputSurface(); | |
| 628 } | |
| 629 } | |
| 630 | |
| 631 void SingleThreadProxy::ScheduledActionManageTiles() { | |
| 632 // Impl-side painting only. | |
| 633 NOTREACHED(); | |
| 634 } | |
| 635 | |
| 636 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { | |
| 637 } | |
| 638 | |
| 639 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { | |
| 640 return timing_history_.DrawDurationEstimate(); | |
| 641 } | |
| 642 | |
| 643 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { | |
| 644 return timing_history_.BeginMainFrameToCommitDurationEstimate(); | |
| 645 } | |
| 646 | |
| 647 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { | |
| 648 return timing_history_.CommitToActivateDurationEstimate(); | |
| 649 } | |
| 650 | |
| 651 void SingleThreadProxy::DidBeginImplFrameDeadline() { | |
| 652 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | |
| 653 } | |
| 654 | |
| 460 } // namespace cc | 655 } // namespace cc | 
| OLD | NEW |