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/output/context_provider.h" | 9 #include "cc/output/context_provider.h" |
10 #include "cc/output/output_surface.h" | 10 #include "cc/output/output_surface.h" |
11 #include "cc/quads/draw_quad.h" | 11 #include "cc/quads/draw_quad.h" |
12 #include "cc/resources/prioritized_resource_manager.h" | 12 #include "cc/resources/prioritized_resource_manager.h" |
13 #include "cc/resources/resource_update_controller.h" | 13 #include "cc/resources/resource_update_controller.h" |
14 #include "cc/trees/layer_tree_host.h" | 14 #include "cc/trees/layer_tree_host.h" |
15 #include "cc/trees/layer_tree_impl.h" | 15 #include "cc/trees/layer_tree_impl.h" |
16 | 16 |
17 namespace cc { | 17 namespace cc { |
18 | 18 |
19 scoped_ptr<Proxy> SingleThreadProxy::Create(LayerTreeHost* layer_tree_host) { | 19 scoped_ptr<Proxy> SingleThreadProxy::Create(LayerTreeHost* layer_tree_host) { |
20 return make_scoped_ptr( | 20 return make_scoped_ptr( |
21 new SingleThreadProxy(layer_tree_host)).PassAs<Proxy>(); | 21 new SingleThreadProxy(layer_tree_host)).PassAs<Proxy>(); |
22 } | 22 } |
23 | 23 |
24 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host) | 24 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host) |
25 : Proxy(NULL), | 25 : Proxy(NULL), |
26 layer_tree_host_(layer_tree_host), | 26 layer_tree_host_(layer_tree_host), |
27 created_offscreen_context_provider_(false), | 27 created_offscreen_context_provider_(false), |
28 next_frame_is_newly_committed_frame_(false), | 28 next_frame_is_newly_committed_frame_(false), |
29 inside_draw_(false) { | 29 inside_draw_(false), |
| 30 can_cancel_commit_(false) { |
30 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); | 31 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); |
31 DCHECK(Proxy::IsMainThread()); | 32 DCHECK(Proxy::IsMainThread()); |
32 DCHECK(layer_tree_host); | 33 DCHECK(layer_tree_host); |
33 | 34 |
34 // Impl-side painting not supported without threaded compositing. | 35 // Impl-side painting not supported without threaded compositing. |
35 CHECK(!layer_tree_host->settings().impl_side_painting) | 36 CHECK(!layer_tree_host->settings().impl_side_painting) |
36 << "Threaded compositing must be enabled to use impl-side painting."; | 37 << "Threaded compositing must be enabled to use impl-side painting."; |
37 } | 38 } |
38 | 39 |
39 void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { | 40 void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 DCHECK(Proxy::IsMainThread()); | 165 DCHECK(Proxy::IsMainThread()); |
165 DCHECK(!layer_tree_host_->output_surface_lost()); | 166 DCHECK(!layer_tree_host_->output_surface_lost()); |
166 return renderer_capabilities_for_main_thread_; | 167 return renderer_capabilities_for_main_thread_; |
167 } | 168 } |
168 | 169 |
169 void SingleThreadProxy::SetNeedsAnimate() { | 170 void SingleThreadProxy::SetNeedsAnimate() { |
170 // Thread-only feature. | 171 // Thread-only feature. |
171 NOTREACHED(); | 172 NOTREACHED(); |
172 } | 173 } |
173 | 174 |
| 175 void SingleThreadProxy::SetNeedsUpdateLayers() { |
| 176 DCHECK(Proxy::IsMainThread()); |
| 177 layer_tree_host_->ScheduleComposite(); |
| 178 } |
| 179 |
174 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { | 180 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { |
175 DCHECK(Proxy::IsMainThread()); | 181 DCHECK(Proxy::IsMainThread()); |
176 // Commit immediately. | 182 // Commit immediately. |
177 { | 183 { |
178 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 184 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
179 DebugScopedSetImplThread impl(this); | 185 DebugScopedSetImplThread impl(this); |
180 | 186 |
181 RenderingStatsInstrumentation* stats_instrumentation = | 187 RenderingStatsInstrumentation* stats_instrumentation = |
182 layer_tree_host_->rendering_stats_instrumentation(); | 188 layer_tree_host_->rendering_stats_instrumentation(); |
183 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | 189 base::TimeTicks start_time = stats_instrumentation->StartRecording(); |
(...skipping 28 matching lines...) Expand all Loading... |
212 | 218 |
213 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | 219 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); |
214 stats_instrumentation->AddCommit(duration); | 220 stats_instrumentation->AddCommit(duration); |
215 } | 221 } |
216 layer_tree_host_->CommitComplete(); | 222 layer_tree_host_->CommitComplete(); |
217 next_frame_is_newly_committed_frame_ = true; | 223 next_frame_is_newly_committed_frame_ = true; |
218 } | 224 } |
219 | 225 |
220 void SingleThreadProxy::SetNeedsCommit() { | 226 void SingleThreadProxy::SetNeedsCommit() { |
221 DCHECK(Proxy::IsMainThread()); | 227 DCHECK(Proxy::IsMainThread()); |
| 228 can_cancel_commit_ = false; |
222 layer_tree_host_->ScheduleComposite(); | 229 layer_tree_host_->ScheduleComposite(); |
223 } | 230 } |
224 | 231 |
225 void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) { | 232 void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) { |
226 SetNeedsRedrawRectOnImplThread(damage_rect); | 233 SetNeedsRedrawRectOnImplThread(damage_rect); |
227 } | 234 } |
228 | 235 |
229 void SingleThreadProxy::OnHasPendingTreeStateChanged(bool have_pending_tree) { | 236 void SingleThreadProxy::OnHasPendingTreeStateChanged(bool have_pending_tree) { |
230 // Thread-only feature. | 237 // Thread-only feature. |
231 NOTREACHED(); | 238 NOTREACHED(); |
(...skipping 23 matching lines...) Expand all Loading... |
255 } | 262 } |
256 layer_tree_host_ = NULL; | 263 layer_tree_host_ = NULL; |
257 } | 264 } |
258 | 265 |
259 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 266 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
260 DCHECK(Proxy::IsImplThread()); | 267 DCHECK(Proxy::IsImplThread()); |
261 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!ShouldComposite()); | 268 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!ShouldComposite()); |
262 } | 269 } |
263 | 270 |
264 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { | 271 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { |
| 272 // Since commit+draw happens in a single pass for this proxy, |
| 273 // this also prevents cancelling a commit. |
| 274 can_cancel_commit_ = false; |
265 layer_tree_host_->ScheduleComposite(); | 275 layer_tree_host_->ScheduleComposite(); |
266 } | 276 } |
267 | 277 |
268 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) { | 278 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) { |
269 // TODO(brianderson): Once we move render_widget scheduling into this class, | 279 // TODO(brianderson): Once we move render_widget scheduling into this class, |
270 // we can treat redraw requests more efficiently than CommitAndRedraw | 280 // we can treat redraw requests more efficiently than CommitAndRedraw |
271 // requests. | 281 // requests. |
272 layer_tree_host_impl_->SetViewportDamage(damage_rect); | 282 layer_tree_host_impl_->SetViewportDamage(damage_rect); |
273 SetNeedsCommit(); | 283 SetNeedsCommit(); |
274 } | 284 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 layer_tree_host_->client()->OffscreenContextProviderForMainThread(); | 403 layer_tree_host_->client()->OffscreenContextProviderForMainThread(); |
394 if (offscreen_context_provider.get()) | 404 if (offscreen_context_provider.get()) |
395 created_offscreen_context_provider_ = true; | 405 created_offscreen_context_provider_ = true; |
396 } | 406 } |
397 | 407 |
398 if (layer_tree_host_->contents_texture_manager()) { | 408 if (layer_tree_host_->contents_texture_manager()) { |
399 layer_tree_host_->contents_texture_manager() | 409 layer_tree_host_->contents_texture_manager() |
400 ->UnlinkAndClearEvictedBackings(); | 410 ->UnlinkAndClearEvictedBackings(); |
401 } | 411 } |
402 | 412 |
| 413 // Reset this flag for the next commit. It's possible that UpdateLayers |
| 414 // will force another commit, so record this flag. |
| 415 bool can_cancel_this_commit = can_cancel_commit_ && !for_readback; |
| 416 can_cancel_commit_ = true; |
| 417 |
403 scoped_ptr<ResourceUpdateQueue> queue = | 418 scoped_ptr<ResourceUpdateQueue> queue = |
404 make_scoped_ptr(new ResourceUpdateQueue); | 419 make_scoped_ptr(new ResourceUpdateQueue); |
405 layer_tree_host_->UpdateLayers( | 420 bool updated = layer_tree_host_->UpdateLayers( |
406 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes()); | 421 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes()); |
407 | 422 |
| 423 if (!updated && can_cancel_this_commit) { |
| 424 TRACE_EVENT0("cc", "EarlyOut_NoUpdates"); |
| 425 return false; |
| 426 } |
| 427 |
408 layer_tree_host_->WillCommit(); | 428 layer_tree_host_->WillCommit(); |
409 DoCommit(queue.Pass()); | 429 DoCommit(queue.Pass()); |
410 bool result = DoComposite(offscreen_context_provider, | 430 bool result = DoComposite(offscreen_context_provider, |
411 frame_begin_time, | 431 frame_begin_time, |
412 device_viewport_damage_rect, | 432 device_viewport_damage_rect, |
413 for_readback, | 433 for_readback, |
414 frame); | 434 frame); |
415 layer_tree_host_->DidBeginFrame(); | 435 layer_tree_host_->DidBeginFrame(); |
| 436 |
416 return result; | 437 return result; |
417 } | 438 } |
418 | 439 |
419 bool SingleThreadProxy::ShouldComposite() const { | 440 bool SingleThreadProxy::ShouldComposite() const { |
420 DCHECK(Proxy::IsImplThread()); | 441 DCHECK(Proxy::IsImplThread()); |
421 return layer_tree_host_impl_->visible() && | 442 return layer_tree_host_impl_->visible() && |
422 layer_tree_host_impl_->CanDraw(); | 443 layer_tree_host_impl_->CanDraw(); |
423 } | 444 } |
424 | 445 |
425 bool SingleThreadProxy::DoComposite( | 446 bool SingleThreadProxy::DoComposite( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 | 507 |
487 bool SingleThreadProxy::CommitPendingForTesting() { return false; } | 508 bool SingleThreadProxy::CommitPendingForTesting() { return false; } |
488 | 509 |
489 skia::RefPtr<SkPicture> SingleThreadProxy::CapturePicture() { | 510 skia::RefPtr<SkPicture> SingleThreadProxy::CapturePicture() { |
490 // Impl-side painting only. | 511 // Impl-side painting only. |
491 NOTREACHED(); | 512 NOTREACHED(); |
492 return skia::RefPtr<SkPicture>(); | 513 return skia::RefPtr<SkPicture>(); |
493 } | 514 } |
494 | 515 |
495 } // namespace cc | 516 } // namespace cc |
OLD | NEW |