Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: cc/trees/single_thread_proxy.cc

Issue 12662021: cc: Don't draw and swap if the frame will not change. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add perf test Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/base/thread.h" 9 #include "cc/base/thread.h"
10 #include "cc/output/context_provider.h" 10 #include "cc/output/context_provider.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); 48 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
49 DCHECK(Proxy::IsMainThread()); 49 DCHECK(Proxy::IsMainThread());
50 DCHECK(!layer_tree_host_impl_.get() && 50 DCHECK(!layer_tree_host_impl_.get() &&
51 !layer_tree_host_); // make sure Stop() got called. 51 !layer_tree_host_); // make sure Stop() got called.
52 } 52 }
53 53
54 bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { 54 bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
55 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback"); 55 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
56 DCHECK(Proxy::IsMainThread()); 56 DCHECK(Proxy::IsMainThread());
57 57
58 if (!CommitAndComposite(base::TimeTicks::Now())) 58 gfx::Rect device_viewport_damage_rect = rect;
59
60 LayerTreeHostImpl::FrameData frame;
61 if (!CommitAndComposite(base::TimeTicks::Now(),
62 device_viewport_damage_rect,
63 &frame))
59 return false; 64 return false;
60 65
61 { 66 {
62 DebugScopedSetImplThread impl(this); 67 DebugScopedSetImplThread impl(this);
63 layer_tree_host_impl_->Readback(pixels, rect); 68 layer_tree_host_impl_->Readback(pixels, rect);
64 69
65 if (layer_tree_host_impl_->IsContextLost()) 70 if (layer_tree_host_impl_->IsContextLost())
66 return false; 71 return false;
67 72
68 layer_tree_host_impl_->SwapBuffers(); 73 layer_tree_host_impl_->SwapBuffers(frame);
69 } 74 }
70 DidSwapFrame(); 75 DidSwapFrame();
71 76
72 return true; 77 return true;
73 } 78 }
74 79
75 void SingleThreadProxy::StartPageScaleAnimation(gfx::Vector2d target_offset, 80 void SingleThreadProxy::StartPageScaleAnimation(gfx::Vector2d target_offset,
76 bool use_anchor, 81 bool use_anchor,
77 float scale, 82 float scale,
78 base::TimeDelta duration) { 83 base::TimeDelta duration) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } 332 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
328 333
329 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { 334 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
330 // Cause a commit so we can notice the lost context. 335 // Cause a commit so we can notice the lost context.
331 SetNeedsCommitOnImplThread(); 336 SetNeedsCommitOnImplThread();
332 } 337 }
333 338
334 // Called by the legacy scheduling path (e.g. where render_widget does the 339 // Called by the legacy scheduling path (e.g. where render_widget does the
335 // scheduling) 340 // scheduling)
336 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { 341 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
337 if (CommitAndComposite(frame_begin_time)) { 342 gfx::Rect device_viewport_damage_rect;
338 layer_tree_host_impl_->SwapBuffers(); 343
344 LayerTreeHostImpl::FrameData frame;
345 if (CommitAndComposite(frame_begin_time,
346 device_viewport_damage_rect,
347 &frame)) {
348 layer_tree_host_impl_->SwapBuffers(frame);
339 DidSwapFrame(); 349 DidSwapFrame();
340 } 350 }
341 } 351 }
342 352
343 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { 353 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
344 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 354 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
345 { 355 {
346 // The following line casts away const modifiers because it is just 356 // The following line casts away const modifiers because it is just
347 // setting debug state. We still want the AsValue() function and its 357 // setting debug state. We still want the AsValue() function and its
348 // call chain to be const throughout. 358 // call chain to be const throughout.
349 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); 359 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
350 360
351 state->Set("layer_tree_host_impl", 361 state->Set("layer_tree_host_impl",
352 layer_tree_host_impl_->AsValue().release()); 362 layer_tree_host_impl_->AsValue().release());
353 } 363 }
354 return state.PassAs<base::Value>(); 364 return state.PassAs<base::Value>();
355 } 365 }
356 366
357 void SingleThreadProxy::ForceSerializeOnSwapBuffers() { 367 void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
358 { 368 {
359 DebugScopedSetImplThread impl(this); 369 DebugScopedSetImplThread impl(this);
360 if (renderer_initialized_) 370 if (renderer_initialized_)
361 layer_tree_host_impl_->renderer()->DoNoOp(); 371 layer_tree_host_impl_->renderer()->DoNoOp();
362 } 372 }
363 } 373 }
364 374
365 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { NOTREACHED(); } 375 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { NOTREACHED(); }
366 376
367 bool SingleThreadProxy::CommitAndComposite(base::TimeTicks frame_begin_time) { 377 bool SingleThreadProxy::CommitAndComposite(
378 base::TimeTicks frame_begin_time,
379 gfx::Rect device_viewport_damage_rect,
380 LayerTreeHostImpl::FrameData* frame) {
368 DCHECK(Proxy::IsMainThread()); 381 DCHECK(Proxy::IsMainThread());
369 382
370 if (!layer_tree_host_->InitializeRendererIfNeeded()) 383 if (!layer_tree_host_->InitializeRendererIfNeeded())
371 return false; 384 return false;
372 385
373 scoped_refptr<cc::ContextProvider> offscreen_context_provider; 386 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
374 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d && 387 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
375 layer_tree_host_->needs_offscreen_context()) { 388 layer_tree_host_->needs_offscreen_context()) {
376 offscreen_context_provider = 389 offscreen_context_provider =
377 layer_tree_host_->client()->OffscreenContextProviderForMainThread(); 390 layer_tree_host_->client()->OffscreenContextProviderForMainThread();
378 if (offscreen_context_provider) 391 if (offscreen_context_provider)
379 created_offscreen_context_provider_ = true; 392 created_offscreen_context_provider_ = true;
380 } 393 }
381 394
382 layer_tree_host_->contents_texture_manager()->UnlinkAndClearEvictedBackings(); 395 layer_tree_host_->contents_texture_manager()->UnlinkAndClearEvictedBackings();
383 396
384 scoped_ptr<ResourceUpdateQueue> queue = 397 scoped_ptr<ResourceUpdateQueue> queue =
385 make_scoped_ptr(new ResourceUpdateQueue); 398 make_scoped_ptr(new ResourceUpdateQueue);
386 layer_tree_host_->UpdateLayers( 399 layer_tree_host_->UpdateLayers(
387 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes()); 400 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes());
388 401
389 layer_tree_host_->WillCommit(); 402 layer_tree_host_->WillCommit();
390 DoCommit(queue.Pass()); 403 DoCommit(queue.Pass());
391 bool result = DoComposite(offscreen_context_provider, frame_begin_time); 404 bool result = DoComposite(offscreen_context_provider,
405 frame_begin_time,
406 device_viewport_damage_rect,
407 frame);
392 layer_tree_host_->DidBeginFrame(); 408 layer_tree_host_->DidBeginFrame();
393 return result; 409 return result;
394 } 410 }
395 411
396 bool SingleThreadProxy::DoComposite( 412 bool SingleThreadProxy::DoComposite(
397 scoped_refptr<cc::ContextProvider> offscreen_context_provider, 413 scoped_refptr<cc::ContextProvider> offscreen_context_provider,
398 base::TimeTicks frame_begin_time) { 414 base::TimeTicks frame_begin_time,
415 gfx::Rect device_viewport_damage_rect,
416 LayerTreeHostImpl::FrameData* frame) {
399 DCHECK(!output_surface_lost_); 417 DCHECK(!output_surface_lost_);
400 { 418 {
401 DebugScopedSetImplThread impl(this); 419 DebugScopedSetImplThread impl(this);
402 base::AutoReset<bool> mark_inside(&inside_draw_, true); 420 base::AutoReset<bool> mark_inside(&inside_draw_, true);
403 421
404 layer_tree_host_impl_->resource_provider()-> 422 layer_tree_host_impl_->resource_provider()->
405 set_offscreen_context_provider(offscreen_context_provider); 423 set_offscreen_context_provider(offscreen_context_provider);
406 424
407 if (!layer_tree_host_impl_->visible()) 425 if (!layer_tree_host_impl_->visible())
408 return false; 426 return false;
409 427
410 layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now()); 428 layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now());
411 429
412 // We guard prepareToDraw() with canDraw() because it always returns a valid 430 // We guard prepareToDraw() with canDraw() because it always returns a valid
413 // frame, so can only be used when such a frame is possible. Since 431 // frame, so can only be used when such a frame is possible. Since
414 // drawLayers() depends on the result of prepareToDraw(), it is guarded on 432 // drawLayers() depends on the result of prepareToDraw(), it is guarded on
415 // canDraw() as well. 433 // canDraw() as well.
416 if (!layer_tree_host_impl_->CanDraw()) 434 if (!layer_tree_host_impl_->CanDraw())
417 return false; 435 return false;
418 436
419 LayerTreeHostImpl::FrameData frame; 437 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
420 layer_tree_host_impl_->PrepareToDraw(&frame); 438 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
421 layer_tree_host_impl_->DrawLayers(&frame, frame_begin_time); 439 layer_tree_host_impl_->DidDrawAllLayers(*frame);
422 layer_tree_host_impl_->DidDrawAllLayers(frame);
423 output_surface_lost_ = layer_tree_host_impl_->IsContextLost(); 440 output_surface_lost_ = layer_tree_host_impl_->IsContextLost();
424 441
425 layer_tree_host_impl_->BeginNextFrame(); 442 layer_tree_host_impl_->BeginNextFrame();
426 } 443 }
427 444
428 if (output_surface_lost_) { 445 if (output_surface_lost_) {
429 cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_-> 446 cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_->
430 resource_provider()->offscreen_context_provider(); 447 resource_provider()->offscreen_context_provider();
431 if (offscreen_contexts) 448 if (offscreen_contexts)
432 offscreen_contexts->VerifyContexts(); 449 offscreen_contexts->VerifyContexts();
(...skipping 13 matching lines...) Expand all
446 463
447 bool SingleThreadProxy::CommitPendingForTesting() { return false; } 464 bool SingleThreadProxy::CommitPendingForTesting() { return false; }
448 465
449 skia::RefPtr<SkPicture> SingleThreadProxy::CapturePicture() { 466 skia::RefPtr<SkPicture> SingleThreadProxy::CapturePicture() {
450 // Impl-side painting only. 467 // Impl-side painting only.
451 NOTREACHED(); 468 NOTREACHED();
452 return skia::RefPtr<SkPicture>(); 469 return skia::RefPtr<SkPicture>();
453 } 470 }
454 471
455 } // namespace cc 472 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698