| 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 16 matching lines...) Expand all Loading... |
| 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 created_offscreen_context_provider_(false), | 35 created_offscreen_context_provider_(false), |
| 36 next_frame_is_newly_committed_frame_(false), | 36 next_frame_is_newly_committed_frame_(false), |
| 37 inside_draw_(false) { | 37 inside_draw_(false), |
| 38 defer_commits_(false), |
| 39 finish_commit_deferred_(false), |
| 40 weak_factory_(this) { |
| 38 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); | 41 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); |
| 39 DCHECK(Proxy::IsMainThread()); | 42 DCHECK(Proxy::IsMainThread()); |
| 40 DCHECK(layer_tree_host); | 43 DCHECK(layer_tree_host); |
| 41 | 44 |
| 42 // Impl-side painting not supported without threaded compositing. | 45 // Impl-side painting not supported without threaded compositing. |
| 43 CHECK(!layer_tree_host->settings().impl_side_painting) | 46 CHECK(!layer_tree_host->settings().impl_side_painting) |
| 44 << "Threaded compositing must be enabled to use impl-side painting."; | 47 << "Threaded compositing must be enabled to use impl-side painting."; |
| 45 } | 48 } |
| 46 | 49 |
| 47 void SingleThreadProxy::Start() { | 50 void SingleThreadProxy::Start() { |
| 48 DebugScopedSetImplThread impl(this); | 51 DebugScopedSetImplThread impl(this); |
| 49 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); | 52 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); |
| 53 SchedulerSettings scheduler_settings(layer_tree_host_->settings()); |
| 54 scheduler_on_impl_thread_ = |
| 55 Scheduler::Create(this, scheduler_settings, layer_tree_host_->id()); |
| 56 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
| 50 } | 57 } |
| 51 | 58 |
| 52 SingleThreadProxy::~SingleThreadProxy() { | 59 SingleThreadProxy::~SingleThreadProxy() { |
| 53 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); | 60 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); |
| 54 DCHECK(Proxy::IsMainThread()); | 61 DCHECK(Proxy::IsMainThread()); |
| 55 // Make sure Stop() got called or never Started. | 62 // Make sure Stop() got called or never Started. |
| 56 DCHECK(!layer_tree_host_impl_); | 63 DCHECK(!layer_tree_host_impl_); |
| 57 } | 64 } |
| 58 | 65 |
| 59 bool SingleThreadProxy::CompositeAndReadback(void* pixels, | 66 bool SingleThreadProxy::CompositeAndReadback(void* pixels, |
| 60 const gfx::Rect& rect) { | 67 const gfx::Rect& rect) { |
| 61 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback"); | 68 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback"); |
| 62 DCHECK(Proxy::IsMainThread()); | 69 DCHECK(Proxy::IsMainThread()); |
| 63 | 70 // TODO(enne): make this go through the SetNeedsForcedCommitForReadback logic. |
| 64 gfx::Rect device_viewport_damage_rect = rect; | 71 bool do_commit = true; |
| 65 | 72 bool for_readback = true; |
| 66 LayerTreeHostImpl::FrameData frame; | 73 gfx::Rect device_viewport_damage_rect(rect); |
| 67 if (!CommitAndComposite(gfx::FrameTime::Now(), | 74 if (CommitAndCompositeInternal(gfx::FrameTime::Now(), |
| 68 device_viewport_damage_rect, | 75 device_viewport_damage_rect, |
| 69 true, // for_readback | 76 do_commit, |
| 70 &frame)) | 77 for_readback).draw_result != |
| 78 DrawSwapReadbackResult::DRAW_SUCCESS) |
| 71 return false; | 79 return false; |
| 72 | 80 |
| 73 { | 81 { |
| 74 DebugScopedSetImplThread impl(this); | 82 DebugScopedSetImplThread impl(this); |
| 75 layer_tree_host_impl_->Readback(pixels, rect); | 83 layer_tree_host_impl_->Readback(pixels, rect); |
| 76 | 84 |
| 77 if (layer_tree_host_impl_->IsContextLost()) | 85 if (layer_tree_host_impl_->IsContextLost()) |
| 78 return false; | 86 return false; |
| 79 } | 87 } |
| 80 | 88 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 92 | 100 |
| 93 bool SingleThreadProxy::IsStarted() const { | 101 bool SingleThreadProxy::IsStarted() const { |
| 94 DCHECK(Proxy::IsMainThread()); | 102 DCHECK(Proxy::IsMainThread()); |
| 95 return layer_tree_host_impl_; | 103 return layer_tree_host_impl_; |
| 96 } | 104 } |
| 97 | 105 |
| 98 void SingleThreadProxy::SetLayerTreeHostClientReady() { | 106 void SingleThreadProxy::SetLayerTreeHostClientReady() { |
| 99 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); | 107 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); |
| 100 // Scheduling is controlled by the embedder in the single thread case, so | 108 // Scheduling is controlled by the embedder in the single thread case, so |
| 101 // nothing to do. | 109 // nothing to do. |
| 110 DCHECK(Proxy::IsMainThread()); |
| 111 DebugScopedSetImplThread impl(this); |
| 112 scheduler_on_impl_thread_->SetCanStart(); |
| 102 } | 113 } |
| 103 | 114 |
| 104 void SingleThreadProxy::SetVisible(bool visible) { | 115 void SingleThreadProxy::SetVisible(bool visible) { |
| 105 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); | 116 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); |
| 106 DebugScopedSetImplThread impl(this); | 117 DebugScopedSetImplThread impl(this); |
| 107 layer_tree_host_impl_->SetVisible(visible); | 118 layer_tree_host_impl_->SetVisible(visible); |
| 119 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
| 108 | 120 |
| 109 // Changing visibility could change ShouldComposite(). | 121 // Changing visibility could change ShouldComposite(). |
| 110 UpdateBackgroundAnimateTicking(); | 122 UpdateBackgroundAnimateTicking(); |
| 111 } | 123 } |
| 112 | 124 |
| 113 void SingleThreadProxy::CreateAndInitializeOutputSurface() { | 125 void SingleThreadProxy::CreateAndInitializeOutputSurface() { |
| 114 TRACE_EVENT0( | 126 TRACE_EVENT0( |
| 115 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); | 127 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); |
| 116 DCHECK(Proxy::IsMainThread()); | 128 DCHECK(Proxy::IsMainThread()); |
| 117 | 129 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 if (!initialized && offscreen_context_provider.get()) { | 162 if (!initialized && offscreen_context_provider.get()) { |
| 151 offscreen_context_provider->VerifyContexts(); | 163 offscreen_context_provider->VerifyContexts(); |
| 152 offscreen_context_provider = NULL; | 164 offscreen_context_provider = NULL; |
| 153 } | 165 } |
| 154 | 166 |
| 155 layer_tree_host_impl_->SetOffscreenContextProvider( | 167 layer_tree_host_impl_->SetOffscreenContextProvider( |
| 156 offscreen_context_provider); | 168 offscreen_context_provider); |
| 157 } | 169 } |
| 158 | 170 |
| 159 OnOutputSurfaceInitializeAttempted(initialized); | 171 OnOutputSurfaceInitializeAttempted(initialized); |
| 172 |
| 173 // This must happen after OnCreateAndInitializeOutputSurfaceAttempted as it |
| 174 // causes a commit and the output surface needs to be initialized beforehand. |
| 175 if (initialized) { |
| 176 DebugScopedSetImplThread impl(this); |
| 177 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); |
| 178 } |
| 160 } | 179 } |
| 161 | 180 |
| 162 void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) { | 181 void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) { |
| 163 LayerTreeHost::CreateResult result = | 182 LayerTreeHost::CreateResult result = |
| 164 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); | 183 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); |
| 165 if (result == LayerTreeHost::CreateFailedButTryAgain) { | 184 if (result == LayerTreeHost::CreateFailedButTryAgain) { |
| 166 // Force another recreation attempt to happen by requesting another commit. | 185 Proxy::MainThreadTaskRunner()->PostTask( |
| 167 SetNeedsCommit(); | 186 FROM_HERE, |
| 187 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, |
| 188 weak_factory_.GetWeakPtr())); |
| 168 } | 189 } |
| 169 } | 190 } |
| 170 | 191 |
| 171 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { | 192 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { |
| 172 DCHECK(Proxy::IsMainThread()); | 193 DCHECK(Proxy::IsMainThread()); |
| 173 DCHECK(!layer_tree_host_->output_surface_lost()); | 194 DCHECK(!layer_tree_host_->output_surface_lost()); |
| 174 return renderer_capabilities_for_main_thread_; | 195 return renderer_capabilities_for_main_thread_; |
| 175 } | 196 } |
| 176 | 197 |
| 177 void SingleThreadProxy::SetNeedsAnimate() { | 198 void SingleThreadProxy::SetNeedsAnimate() { |
| 178 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); | 199 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); |
| 179 DCHECK(Proxy::IsMainThread()); | 200 DCHECK(Proxy::IsMainThread()); |
| 180 client_->ScheduleAnimation(); | 201 SetNeedsCommit(); |
| 181 } | 202 } |
| 182 | 203 |
| 183 void SingleThreadProxy::SetNeedsUpdateLayers() { | 204 void SingleThreadProxy::SetNeedsUpdateLayers() { |
| 184 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); | 205 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); |
| 185 DCHECK(Proxy::IsMainThread()); | 206 DCHECK(Proxy::IsMainThread()); |
| 186 client_->ScheduleComposite(); | 207 SetNeedsCommit(); |
| 187 } | 208 } |
| 188 | 209 |
| 189 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { | 210 void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { |
| 190 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); | 211 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); |
| 191 DCHECK(Proxy::IsMainThread()); | 212 DCHECK(Proxy::IsMainThread()); |
| 213 layer_tree_host_->WillBeginMainFrame(); |
| 214 layer_tree_host_->Layout(); |
| 215 layer_tree_host_->AnimateLayers(frame_begin_time); |
| 216 |
| 217 if (PrioritizedResourceManager* contents_texture_manager = |
| 218 layer_tree_host_->contents_texture_manager()) { |
| 219 contents_texture_manager->UnlinkAndClearEvictedBackings(); |
| 220 contents_texture_manager->SetMaxMemoryLimitBytes( |
| 221 layer_tree_host_impl_->memory_allocation_limit_bytes()); |
| 222 contents_texture_manager->SetExternalPriorityCutoff( |
| 223 layer_tree_host_impl_->memory_allocation_priority_cutoff()); |
| 224 } |
| 225 |
| 226 scoped_ptr<ResourceUpdateQueue> queue = |
| 227 make_scoped_ptr(new ResourceUpdateQueue); |
| 228 |
| 229 layer_tree_host_->UpdateLayers(queue.get()); |
| 230 |
| 231 layer_tree_host_->WillCommit(); |
| 232 |
| 192 // Commit immediately. | 233 // Commit immediately. |
| 193 { | 234 { |
| 194 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 235 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| 195 DebugScopedSetImplThread impl(this); | 236 DebugScopedSetImplThread impl(this); |
| 196 | 237 |
| 197 // This CapturePostTasks should be destroyed before CommitComplete() is | 238 // This CapturePostTasks should be destroyed before CommitComplete() is |
| 198 // called since that goes out to the embedder, and we want the embedder | 239 // called since that goes out to the embedder, and we want the embedder |
| 199 // to receive its callbacks before that. | 240 // to receive its callbacks before that. |
| 200 BlockingTaskRunner::CapturePostTasks blocked; | 241 BlockingTaskRunner::CapturePostTasks blocked; |
| 201 | 242 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 215 layer_tree_host_impl_->resource_provider()); | 256 layer_tree_host_impl_->resource_provider()); |
| 216 update_controller->Finalize(); | 257 update_controller->Finalize(); |
| 217 | 258 |
| 218 if (layer_tree_host_impl_->EvictedUIResourcesExist()) | 259 if (layer_tree_host_impl_->EvictedUIResourcesExist()) |
| 219 layer_tree_host_->RecreateUIResources(); | 260 layer_tree_host_->RecreateUIResources(); |
| 220 | 261 |
| 221 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); | 262 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); |
| 222 | 263 |
| 223 layer_tree_host_impl_->CommitComplete(); | 264 layer_tree_host_impl_->CommitComplete(); |
| 224 | 265 |
| 266 UpdateBackgroundAnimateTicking(); |
| 267 |
| 225 #ifndef NDEBUG | 268 #ifndef NDEBUG |
| 226 // In the single-threaded case, the scale and scroll deltas should never be | 269 // In the single-threaded case, the scale and scroll deltas should never be |
| 227 // touched on the impl layer tree. | 270 // touched on the impl layer tree. |
| 228 scoped_ptr<ScrollAndScaleSet> scroll_info = | 271 scoped_ptr<ScrollAndScaleSet> scroll_info = |
| 229 layer_tree_host_impl_->ProcessScrollDeltas(); | 272 layer_tree_host_impl_->ProcessScrollDeltas(); |
| 230 DCHECK(!scroll_info->scrolls.size()); | 273 DCHECK(!scroll_info->scrolls.size()); |
| 231 DCHECK_EQ(1.f, scroll_info->page_scale_delta); | 274 DCHECK_EQ(1.f, scroll_info->page_scale_delta); |
| 232 #endif | 275 #endif |
| 233 | 276 |
| 234 RenderingStatsInstrumentation* stats_instrumentation = | 277 RenderingStatsInstrumentation* stats_instrumentation = |
| 235 layer_tree_host_->rendering_stats_instrumentation(); | 278 layer_tree_host_->rendering_stats_instrumentation(); |
| 236 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( | 279 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( |
| 237 stats_instrumentation->main_thread_rendering_stats()); | 280 stats_instrumentation->main_thread_rendering_stats()); |
| 238 stats_instrumentation->AccumulateAndClearMainThreadStats(); | 281 stats_instrumentation->AccumulateAndClearMainThreadStats(); |
| 239 } | 282 } |
| 240 layer_tree_host_->CommitComplete(); | 283 layer_tree_host_->CommitComplete(); |
| 284 layer_tree_host_->DidBeginMainFrame(); |
| 285 timing_history_.DidCommit(); |
| 286 |
| 241 next_frame_is_newly_committed_frame_ = true; | 287 next_frame_is_newly_committed_frame_ = true; |
| 242 } | 288 } |
| 243 | 289 |
| 244 void SingleThreadProxy::SetNeedsCommit() { | 290 void SingleThreadProxy::SetNeedsCommit() { |
| 245 DCHECK(Proxy::IsMainThread()); | 291 scheduler_on_impl_thread_->SetNeedsCommit(); |
| 246 client_->ScheduleComposite(); | |
| 247 } | 292 } |
| 248 | 293 |
| 249 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { | 294 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { |
| 250 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); | 295 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); |
| 296 DCHECK(Proxy::IsMainThread()); |
| 297 DebugScopedSetImplThread impl(this); |
| 251 SetNeedsRedrawRectOnImplThread(damage_rect); | 298 SetNeedsRedrawRectOnImplThread(damage_rect); |
| 252 client_->ScheduleComposite(); | |
| 253 } | 299 } |
| 254 | 300 |
| 255 void SingleThreadProxy::SetNextCommitWaitsForActivation() { | 301 void SingleThreadProxy::SetNextCommitWaitsForActivation() { |
| 256 // There is no activation here other than commit. So do nothing. | 302 // There is no activation here other than commit. So do nothing. |
| 303 DCHECK(Proxy::IsMainThread()); |
| 257 } | 304 } |
| 258 | 305 |
| 259 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { | 306 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { |
| 260 // Thread-only feature. | 307 DCHECK(Proxy::IsMainThread()); |
| 261 NOTREACHED(); | 308 if (defer_commits_ == defer_commits) |
| 309 return; |
| 310 |
| 311 defer_commits_ = defer_commits; |
| 312 if (!defer_commits_ && finish_commit_deferred_) { |
| 313 scheduler_on_impl_thread_->FinishCommit(); |
| 314 finish_commit_deferred_ = false; |
| 315 } |
| 262 } | 316 } |
| 263 | 317 |
| 264 bool SingleThreadProxy::CommitRequested() const { return false; } | 318 bool SingleThreadProxy::CommitRequested() const { |
| 319 DCHECK(Proxy::IsMainThread()); |
| 320 return finish_commit_deferred_; |
| 321 } |
| 265 | 322 |
| 266 bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } | 323 bool SingleThreadProxy::BeginMainFrameRequested() const { |
| 324 DCHECK(Proxy::IsMainThread()); |
| 325 return finish_commit_deferred_; |
| 326 } |
| 267 | 327 |
| 268 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { | 328 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { |
| 269 return std::numeric_limits<size_t>::max(); | 329 return std::numeric_limits<size_t>::max(); |
| 270 } | 330 } |
| 271 | 331 |
| 272 void SingleThreadProxy::Stop() { | 332 void SingleThreadProxy::Stop() { |
| 273 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); | 333 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); |
| 274 DCHECK(Proxy::IsMainThread()); | 334 DCHECK(Proxy::IsMainThread()); |
| 275 { | 335 { |
| 276 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 336 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| 277 DebugScopedSetImplThread impl(this); | 337 DebugScopedSetImplThread impl(this); |
| 278 | 338 |
| 279 layer_tree_host_->DeleteContentsTexturesOnImplThread( | 339 layer_tree_host_->DeleteContentsTexturesOnImplThread( |
| 280 layer_tree_host_impl_->resource_provider()); | 340 layer_tree_host_impl_->resource_provider()); |
| 341 scheduler_on_impl_thread_.reset(); |
| 281 layer_tree_host_impl_.reset(); | 342 layer_tree_host_impl_.reset(); |
| 282 } | 343 } |
| 283 layer_tree_host_ = NULL; | 344 layer_tree_host_ = NULL; |
| 284 } | 345 } |
| 285 | 346 |
| 286 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 347 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
| 287 TRACE_EVENT1( | 348 TRACE_EVENT1( |
| 288 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | 349 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); |
| 289 DCHECK(Proxy::IsImplThread()); | 350 DCHECK(Proxy::IsImplThread()); |
| 290 UpdateBackgroundAnimateTicking(); | 351 UpdateBackgroundAnimateTicking(); |
| 352 scheduler_on_impl_thread_->SetCanDraw(can_draw); |
| 291 } | 353 } |
| 292 | 354 |
| 293 void SingleThreadProxy::NotifyReadyToActivate() { | 355 void SingleThreadProxy::NotifyReadyToActivate() { |
| 294 // Thread-only feature. | 356 // Impl-side painting only. |
| 295 NOTREACHED(); | 357 NOTREACHED(); |
| 296 } | 358 } |
| 297 | 359 |
| 298 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { | 360 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { |
| 299 client_->ScheduleComposite(); | 361 scheduler_on_impl_thread_->SetNeedsRedraw(); |
| 300 } | 362 } |
| 301 | 363 |
| 302 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { | 364 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { |
| 303 // Thread-only/Impl-side-painting-only feature. | 365 // Impl-side painting only. |
| 304 NOTREACHED(); | 366 NOTREACHED(); |
| 305 } | 367 } |
| 306 | 368 |
| 307 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( | 369 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( |
| 308 const gfx::Rect& damage_rect) { | 370 const gfx::Rect& damage_rect) { |
| 309 // TODO(brianderson): Once we move render_widget scheduling into this class, | |
| 310 // we can treat redraw requests more efficiently than CommitAndRedraw | |
| 311 // requests. | |
| 312 layer_tree_host_impl_->SetViewportDamage(damage_rect); | 371 layer_tree_host_impl_->SetViewportDamage(damage_rect); |
| 313 SetNeedsCommit(); | 372 SetNeedsRedrawOnImplThread(); |
| 314 } | 373 } |
| 315 | 374 |
| 316 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { | 375 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { |
| 317 // Impl-side painting only. | 376 // Impl-side painting only. |
| 318 NOTREACHED(); | 377 NOTREACHED(); |
| 319 } | 378 } |
| 320 | 379 |
| 321 void SingleThreadProxy::SetNeedsCommitOnImplThread() { | 380 void SingleThreadProxy::SetNeedsCommitOnImplThread() { |
| 322 client_->ScheduleComposite(); | 381 scheduler_on_impl_thread_->SetNeedsCommit(); |
| 323 } | 382 } |
| 324 | 383 |
| 325 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | 384 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
| 326 scoped_ptr<AnimationEventsVector> events, | 385 scoped_ptr<AnimationEventsVector> events, |
| 327 base::Time wall_clock_time) { | 386 base::Time wall_clock_time) { |
| 328 TRACE_EVENT0( | 387 TRACE_EVENT0( |
| 329 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); | 388 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); |
| 330 DCHECK(Proxy::IsImplThread()); | 389 DCHECK(Proxy::IsImplThread()); |
| 331 DebugScopedSetMainThread main(this); | 390 DebugScopedSetMainThread main(this); |
| 332 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time); | 391 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 } | 424 } |
| 366 | 425 |
| 367 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } | 426 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } |
| 368 | 427 |
| 369 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { | 428 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { |
| 370 DCHECK(IsImplThread()); | 429 DCHECK(IsImplThread()); |
| 371 renderer_capabilities_for_main_thread_ = | 430 renderer_capabilities_for_main_thread_ = |
| 372 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); | 431 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); |
| 373 } | 432 } |
| 374 | 433 |
| 434 void SingleThreadProxy::DidActivatePendingTree() { |
| 435 // Impl-side painting only. |
| 436 NOTREACHED(); |
| 437 } |
| 438 |
| 439 void SingleThreadProxy::DidManageTiles() { |
| 440 // Impl-side painting only. |
| 441 NOTREACHED(); |
| 442 } |
| 443 |
| 375 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { | 444 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { |
| 376 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); | 445 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); |
| 377 // Cause a commit so we can notice the lost context. | 446 { |
| 378 SetNeedsCommitOnImplThread(); | 447 DebugScopedSetMainThread main(this); |
| 448 // This must happen before we notify the scheduler as it may try to recreate |
| 449 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. |
| 450 layer_tree_host_->DidLoseOutputSurface(); |
| 451 } |
| 452 |
| 453 // TODO(enne): this client call could maybe be removed. |
| 379 client_->DidAbortSwapBuffers(); | 454 client_->DidAbortSwapBuffers(); |
| 455 |
| 456 scheduler_on_impl_thread_->DidLoseOutputSurface(); |
| 380 } | 457 } |
| 381 | 458 |
| 382 void SingleThreadProxy::DidSwapBuffersOnImplThread() { | 459 void SingleThreadProxy::DidSwapBuffersOnImplThread() { |
| 460 // TODO(enne): Maybe this is redundant with DidCommitAndDrawFrame and can be |
| 461 // removed? |
| 383 client_->DidPostSwapBuffers(); | 462 client_->DidPostSwapBuffers(); |
| 384 } | 463 } |
| 385 | 464 |
| 386 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { | 465 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { |
| 387 TRACE_EVENT0("cc", "SingleThreadProxy::OnSwapBuffersCompleteOnImplThread"); | 466 TRACE_EVENT0("cc", "SingleThreadProxy::OnSwapBuffersCompleteOnImplThread"); |
| 388 client_->DidCompleteSwapBuffers(); | 467 client_->DidCompleteSwapBuffers(); |
| 389 } | 468 } |
| 390 | 469 |
| 391 // Called by the legacy scheduling path (e.g. where render_widget does the | 470 void SingleThreadProxy::BeginImplFrame(const BeginFrameArgs& args) { |
| 392 // scheduling) | 471 TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame"); |
| 472 scheduler_on_impl_thread_->BeginImplFrame(args); |
| 473 } |
| 474 |
| 393 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { | 475 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { |
| 394 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); | 476 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); |
| 477 bool do_commit = true; |
| 478 bool for_readback = false; |
| 395 gfx::Rect device_viewport_damage_rect; | 479 gfx::Rect device_viewport_damage_rect; |
| 396 | 480 CommitAndCompositeInternal(gfx::FrameTime::Now(), |
| 397 LayerTreeHostImpl::FrameData frame; | 481 device_viewport_damage_rect, |
| 398 if (CommitAndComposite(frame_begin_time, | 482 do_commit, |
| 399 device_viewport_damage_rect, | 483 for_readback); |
| 400 false, // for_readback | |
| 401 &frame)) { | |
| 402 { | |
| 403 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
| 404 DebugScopedSetImplThread impl(this); | |
| 405 | |
| 406 // This CapturePostTasks should be destroyed before | |
| 407 // DidCommitAndDrawFrame() is called since that goes out to the embedder, | |
| 408 // and we want the embedder to receive its callbacks before that. | |
| 409 // NOTE: This maintains consistent ordering with the ThreadProxy since | |
| 410 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread | |
| 411 // there as the main thread is not blocked, so any posted tasks inside | |
| 412 // the swap buffers will execute first. | |
| 413 BlockingTaskRunner::CapturePostTasks blocked; | |
| 414 | |
| 415 layer_tree_host_impl_->SwapBuffers(frame); | |
| 416 } | |
| 417 DidSwapFrame(); | |
| 418 } | |
| 419 } | 484 } |
| 420 | 485 |
| 421 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { | 486 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { |
| 422 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 487 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 423 { | 488 { |
| 424 // The following line casts away const modifiers because it is just | 489 // The following line casts away const modifiers because it is just |
| 425 // setting debug state. We still want the AsValue() function and its | 490 // setting debug state. We still want the AsValue() function and its |
| 426 // call chain to be const throughout. | 491 // call chain to be const throughout. |
| 427 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); | 492 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); |
| 428 | 493 |
| 429 state->Set("layer_tree_host_impl", | 494 state->Set("layer_tree_host_impl", |
| 430 layer_tree_host_impl_->AsValue().release()); | 495 layer_tree_host_impl_->AsValue().release()); |
| 431 } | 496 } |
| 432 return state.PassAs<base::Value>(); | 497 return state.PassAs<base::Value>(); |
| 433 } | 498 } |
| 434 | 499 |
| 435 void SingleThreadProxy::ForceSerializeOnSwapBuffers() { | 500 void SingleThreadProxy::ForceSerializeOnSwapBuffers() { |
| 436 { | 501 { |
| 437 DebugScopedSetImplThread impl(this); | 502 DebugScopedSetImplThread impl(this); |
| 438 if (layer_tree_host_impl_->renderer()) { | 503 if (layer_tree_host_impl_->renderer()) { |
| 439 DCHECK(!layer_tree_host_->output_surface_lost()); | 504 DCHECK(!layer_tree_host_->output_surface_lost()); |
| 440 layer_tree_host_impl_->renderer()->DoNoOp(); | 505 layer_tree_host_impl_->renderer()->DoNoOp(); |
| 441 } | 506 } |
| 442 } | 507 } |
| 443 } | 508 } |
| 444 | 509 |
| 445 bool SingleThreadProxy::CommitAndComposite( | 510 bool SingleThreadProxy::ShouldComposite() const { |
| 446 base::TimeTicks frame_begin_time, | 511 DCHECK(Proxy::IsImplThread()); |
| 447 const gfx::Rect& device_viewport_damage_rect, | 512 return scheduler_on_impl_thread_->WillDrawIfNeeded(); |
| 448 bool for_readback, | 513 } |
| 449 LayerTreeHostImpl::FrameData* frame) { | |
| 450 TRACE_EVENT0("cc", "SingleThreadProxy::CommitAndComposite"); | |
| 451 DCHECK(Proxy::IsMainThread()); | |
| 452 | 514 |
| 453 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) | 515 void SingleThreadProxy::UpdateBackgroundAnimateTicking() { |
| 454 return false; | 516 DCHECK(Proxy::IsImplThread()); |
| 517 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
| 518 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); |
| 519 } |
| 455 | 520 |
| 456 layer_tree_host_->AnimateLayers(frame_begin_time); | 521 scoped_refptr<ContextProvider> SingleThreadProxy::OffscreenContextProvider() { |
| 457 | |
| 458 if (PrioritizedResourceManager* contents_texture_manager = | |
| 459 layer_tree_host_->contents_texture_manager()) { | |
| 460 contents_texture_manager->UnlinkAndClearEvictedBackings(); | |
| 461 contents_texture_manager->SetMaxMemoryLimitBytes( | |
| 462 layer_tree_host_impl_->memory_allocation_limit_bytes()); | |
| 463 contents_texture_manager->SetExternalPriorityCutoff( | |
| 464 layer_tree_host_impl_->memory_allocation_priority_cutoff()); | |
| 465 } | |
| 466 | |
| 467 scoped_ptr<ResourceUpdateQueue> queue = | |
| 468 make_scoped_ptr(new ResourceUpdateQueue); | |
| 469 layer_tree_host_->UpdateLayers(queue.get()); | |
| 470 | |
| 471 layer_tree_host_->WillCommit(); | |
| 472 | |
| 473 scoped_refptr<ContextProvider> offscreen_context_provider; | 522 scoped_refptr<ContextProvider> offscreen_context_provider; |
| 474 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d && | 523 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d && |
| 475 layer_tree_host_->needs_offscreen_context()) { | 524 layer_tree_host_->needs_offscreen_context()) { |
| 476 offscreen_context_provider = | 525 offscreen_context_provider = |
| 477 layer_tree_host_->client()->OffscreenContextProvider(); | 526 layer_tree_host_->client()->OffscreenContextProvider(); |
| 478 if (offscreen_context_provider.get() && | 527 if (offscreen_context_provider.get() && |
| 479 !offscreen_context_provider->BindToCurrentThread()) | 528 !offscreen_context_provider->BindToCurrentThread()) |
| 480 offscreen_context_provider = NULL; | 529 offscreen_context_provider = NULL; |
| 481 | 530 |
| 482 if (offscreen_context_provider.get()) | 531 if (offscreen_context_provider.get()) |
| 483 created_offscreen_context_provider_ = true; | 532 created_offscreen_context_provider_ = true; |
| 484 } | 533 } |
| 485 | 534 return offscreen_context_provider; |
| 486 DoCommit(queue.Pass()); | |
| 487 bool result = DoComposite(offscreen_context_provider, | |
| 488 frame_begin_time, | |
| 489 device_viewport_damage_rect, | |
| 490 for_readback, | |
| 491 frame); | |
| 492 layer_tree_host_->DidBeginMainFrame(); | |
| 493 return result; | |
| 494 } | 535 } |
| 495 | 536 |
| 496 bool SingleThreadProxy::ShouldComposite() const { | 537 DrawSwapReadbackResult::DrawResult SingleThreadProxy::DoComposite( |
| 497 DCHECK(Proxy::IsImplThread()); | |
| 498 return layer_tree_host_impl_->visible() && | |
| 499 layer_tree_host_impl_->CanDraw(); | |
| 500 } | |
| 501 | |
| 502 void SingleThreadProxy::UpdateBackgroundAnimateTicking() { | |
| 503 DCHECK(Proxy::IsImplThread()); | |
| 504 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( | |
| 505 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); | |
| 506 } | |
| 507 | |
| 508 bool SingleThreadProxy::DoComposite( | |
| 509 scoped_refptr<ContextProvider> offscreen_context_provider, | 538 scoped_refptr<ContextProvider> offscreen_context_provider, |
| 510 base::TimeTicks frame_begin_time, | 539 base::TimeTicks frame_begin_time, |
| 511 const gfx::Rect& device_viewport_damage_rect, | 540 const gfx::Rect& device_viewport_damage_rect, |
| 512 bool for_readback, | 541 bool for_readback, |
| 513 LayerTreeHostImpl::FrameData* frame) { | 542 LayerTreeHostImpl::FrameData* frame) { |
| 514 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); | 543 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); |
| 515 DCHECK(!layer_tree_host_->output_surface_lost()); | 544 DCHECK(!layer_tree_host_->output_surface_lost()); |
| 516 | 545 |
| 517 bool lost_output_surface = false; | 546 bool lost_output_surface = false; |
| 518 { | 547 { |
| 519 DebugScopedSetImplThread impl(this); | 548 DebugScopedSetImplThread impl(this); |
| 520 base::AutoReset<bool> mark_inside(&inside_draw_, true); | 549 base::AutoReset<bool> mark_inside(&inside_draw_, true); |
| 521 | 550 |
| 522 layer_tree_host_impl_->SetOffscreenContextProvider( | 551 layer_tree_host_impl_->SetOffscreenContextProvider( |
| 523 offscreen_context_provider); | 552 offscreen_context_provider); |
| 524 | 553 |
| 525 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); | 554 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); |
| 526 | 555 |
| 527 // We guard PrepareToDraw() with CanDraw() because it always returns a valid | 556 // We guard PrepareToDraw() with CanDraw() because it always returns a valid |
| 528 // frame, so can only be used when such a frame is possible. Since | 557 // frame, so can only be used when such a frame is possible. Since |
| 529 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on | 558 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on |
| 530 // CanDraw() as well. | 559 // CanDraw() as well. |
| 531 if (!ShouldComposite() || (for_readback && !can_do_readback)) { | 560 if (!ShouldComposite() || (for_readback && !can_do_readback)) { |
| 532 UpdateBackgroundAnimateTicking(); | 561 UpdateBackgroundAnimateTicking(); |
| 533 return false; | 562 return DrawSwapReadbackResult::DRAW_ABORTED_CANT_DRAW; |
| 534 } | 563 } |
| 535 | 564 |
| 536 layer_tree_host_impl_->Animate( | 565 layer_tree_host_impl_->Animate( |
| 537 layer_tree_host_impl_->CurrentFrameTimeTicks(), | 566 layer_tree_host_impl_->CurrentFrameTimeTicks(), |
| 538 layer_tree_host_impl_->CurrentFrameTime()); | 567 layer_tree_host_impl_->CurrentFrameTime()); |
| 539 UpdateBackgroundAnimateTicking(); | 568 UpdateBackgroundAnimateTicking(); |
| 540 | 569 |
| 541 if (!layer_tree_host_impl_->IsContextLost()) { | 570 if (!layer_tree_host_impl_->IsContextLost()) { |
| 542 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect); | 571 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect); |
| 543 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); | 572 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); |
| 544 layer_tree_host_impl_->DidDrawAllLayers(*frame); | 573 layer_tree_host_impl_->DidDrawAllLayers(*frame); |
| 545 } | 574 } |
| 546 lost_output_surface = layer_tree_host_impl_->IsContextLost(); | 575 lost_output_surface = layer_tree_host_impl_->IsContextLost(); |
| 547 | 576 |
| 548 bool start_ready_animations = true; | 577 bool start_ready_animations = true; |
| 549 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); | 578 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); |
| 550 | 579 |
| 551 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | 580 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| 552 } | 581 } |
| 553 | 582 |
| 554 if (lost_output_surface) { | 583 if (lost_output_surface) { |
| 555 ContextProvider* offscreen_contexts = | 584 ContextProvider* offscreen_contexts = |
| 556 layer_tree_host_impl_->offscreen_context_provider(); | 585 layer_tree_host_impl_->offscreen_context_provider(); |
| 557 if (offscreen_contexts) | 586 if (offscreen_contexts) |
| 558 offscreen_contexts->VerifyContexts(); | 587 offscreen_contexts->VerifyContexts(); |
| 559 layer_tree_host_->DidLoseOutputSurface(); | 588 DidLoseOutputSurfaceOnImplThread(); |
| 560 return false; | 589 if (for_readback) |
| 590 return DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST; |
| 561 } | 591 } |
| 562 | 592 |
| 563 return true; | 593 return DrawSwapReadbackResult::DRAW_SUCCESS; |
| 564 } | 594 } |
| 565 | 595 |
| 566 void SingleThreadProxy::DidSwapFrame() { | 596 void SingleThreadProxy::DidCommitAndDrawFrame() { |
| 567 if (next_frame_is_newly_committed_frame_) { | 597 if (next_frame_is_newly_committed_frame_) { |
| 568 next_frame_is_newly_committed_frame_ = false; | 598 next_frame_is_newly_committed_frame_ = false; |
| 569 layer_tree_host_->DidCommitAndDrawFrame(); | 599 layer_tree_host_->DidCommitAndDrawFrame(); |
| 570 } | 600 } |
| 571 } | 601 } |
| 572 | 602 |
| 573 bool SingleThreadProxy::CommitPendingForTesting() { return false; } | 603 bool SingleThreadProxy::CommitPendingForTesting() { return false; } |
| 574 | 604 |
| 605 scoped_ptr<base::Value> SingleThreadProxy::SchedulerStateAsValueForTesting() { |
| 606 DebugScopedSetImplThread impl(this); |
| 607 return scheduler_on_impl_thread_->StateAsValue().Pass(); |
| 608 } |
| 609 |
| 610 void SingleThreadProxy::SetNeedsBeginImplFrame(bool enable) { |
| 611 if (OutputSurface* surface = layer_tree_host_impl_->output_surface()) |
| 612 surface->SetNeedsBeginImplFrame(enable); |
| 613 } |
| 614 |
| 615 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { |
| 616 if (defer_commits_) { |
| 617 DCHECK(!finish_commit_deferred_); |
| 618 finish_commit_deferred_ = true; |
| 619 return; |
| 620 } |
| 621 timing_history_.DidBeginMainFrame(); |
| 622 |
| 623 // This is poorly named, but tells the scheduler that we are ready to |
| 624 // start the commit. In threaded mode, this is when the uploads are done. |
| 625 // In single-threaded mode, it doesn't really matter. Doing no work here |
| 626 // and all the work in commit prevents needless carrying of state (like |
| 627 // the upload queue) from BeginMainFrame to commit. |
| 628 scheduler_on_impl_thread_->FinishCommit(); |
| 629 } |
| 630 |
| 631 DrawSwapReadbackResult |
| 632 SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
| 633 bool do_commit = false; |
| 634 bool for_readback = false; |
| 635 gfx::Rect device_viewport_damage_rect; |
| 636 return CommitAndCompositeInternal(gfx::FrameTime::Now(), |
| 637 device_viewport_damage_rect, |
| 638 do_commit, |
| 639 for_readback); |
| 640 } |
| 641 |
| 642 DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { |
| 643 return ScheduledActionDrawAndSwapIfPossible(); |
| 644 } |
| 645 |
| 646 DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndReadback() { |
| 647 // The SingleThreadProxy never asks for a commit for readback, |
| 648 // so this should never happen. |
| 649 NOTREACHED(); |
| 650 DrawSwapReadbackResult result; |
| 651 return result; |
| 652 } |
| 653 |
| 654 DrawSwapReadbackResult SingleThreadProxy::CommitAndCompositeInternal( |
| 655 base::TimeTicks frame_begin_time, |
| 656 gfx::Rect device_viewport_damage_rect, |
| 657 bool do_commit, |
| 658 bool for_readback) { |
| 659 DCHECK(Proxy::IsMainThread()); |
| 660 DrawSwapReadbackResult result; |
| 661 |
| 662 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { |
| 663 result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST; |
| 664 return result; |
| 665 } |
| 666 |
| 667 if (do_commit) |
| 668 DoCommit(frame_begin_time); |
| 669 |
| 670 scoped_refptr<ContextProvider> offscreen_context_provider = |
| 671 OffscreenContextProvider(); |
| 672 LayerTreeHostImpl::FrameData frame; |
| 673 timing_history_.DidStartDrawing(); |
| 674 result.draw_result = DoComposite(offscreen_context_provider, |
| 675 frame_begin_time, |
| 676 device_viewport_damage_rect, |
| 677 for_readback, |
| 678 &frame); |
| 679 if (result.draw_result != DrawSwapReadbackResult::DRAW_SUCCESS) |
| 680 return result; |
| 681 |
| 682 timing_history_.DidFinishDrawing(); |
| 683 |
| 684 result.did_readback = for_readback; |
| 685 |
| 686 { |
| 687 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| 688 DebugScopedSetImplThread impl(this); |
| 689 |
| 690 // This CapturePostTasks should be destroyed before |
| 691 // DidCommitAndDrawFrame() is called since that goes out to the embedder, |
| 692 // and we want the embedder to receive its callbacks before that. |
| 693 // NOTE: This maintains consistent ordering with the ThreadProxy since |
| 694 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread |
| 695 // there as the main thread is not blocked, so any posted tasks inside |
| 696 // the swap buffers will execute first. |
| 697 BlockingTaskRunner::CapturePostTasks blocked; |
| 698 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); |
| 699 } |
| 700 |
| 701 DidCommitAndDrawFrame(); |
| 702 |
| 703 return result; |
| 704 } |
| 705 |
| 706 void SingleThreadProxy::ScheduledActionCommit() { |
| 707 DebugScopedSetMainThread main(this); |
| 708 DoCommit(gfx::FrameTime::Now()); |
| 709 } |
| 710 |
| 711 void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { |
| 712 // Impl-side painting only. |
| 713 NOTREACHED(); |
| 714 } |
| 715 |
| 716 void SingleThreadProxy::ScheduledActionActivatePendingTree() { |
| 717 // Impl-side painting only. |
| 718 NOTREACHED(); |
| 719 } |
| 720 |
| 721 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
| 722 DebugScopedSetMainThread main(this); |
| 723 layer_tree_host_->InitializeOutputSurfaceIfNeeded(); |
| 724 } |
| 725 |
| 726 void SingleThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { |
| 727 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); |
| 728 } |
| 729 |
| 730 void SingleThreadProxy::ScheduledActionManageTiles() { |
| 731 // Impl-side painting only. |
| 732 NOTREACHED(); |
| 733 } |
| 734 |
| 735 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {} |
| 736 |
| 737 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { |
| 738 return timing_history_.DrawDurationEstimate(); |
| 739 } |
| 740 |
| 741 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { |
| 742 return timing_history_.BeginMainFrameToCommitDurationEstimate(); |
| 743 } |
| 744 |
| 745 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { |
| 746 return timing_history_.CommitToActivateDurationEstimate(); |
| 747 } |
| 748 |
| 749 void SingleThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure, |
| 750 base::TimeTicks deadline) { |
| 751 base::TimeDelta delta = deadline - gfx::FrameTime::Now(); |
| 752 if (delta <= base::TimeDelta()) |
| 753 delta = base::TimeDelta(); |
| 754 Proxy::MainThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta); |
| 755 } |
| 756 |
| 757 void SingleThreadProxy::DidBeginImplFrameDeadline() { |
| 758 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| 759 } |
| 760 |
| 575 } // namespace cc | 761 } // namespace cc |
| OLD | NEW |