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

Side by Side Diff: cc/trees/layer_tree_host_impl.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/layer_tree_host_impl.h" 5 #include "cc/trees/layer_tree_host_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 time_source_->SetClient(this); 127 time_source_->SetClient(this);
128 } 128 }
129 129
130 LayerTreeHostImpl* layer_tree_host_impl_; 130 LayerTreeHostImpl* layer_tree_host_impl_;
131 scoped_refptr<DelayBasedTimeSource> time_source_; 131 scoped_refptr<DelayBasedTimeSource> time_source_;
132 132
133 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter); 133 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
134 }; 134 };
135 135
136 LayerTreeHostImpl::FrameData::FrameData() 136 LayerTreeHostImpl::FrameData::FrameData()
137 : contains_incomplete_tile(false) {} 137 : contains_incomplete_tile(false), has_no_damage(false) {}
138 138
139 LayerTreeHostImpl::FrameData::~FrameData() {} 139 LayerTreeHostImpl::FrameData::~FrameData() {}
140 140
141 scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( 141 scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
142 const LayerTreeSettings& settings, 142 const LayerTreeSettings& settings,
143 LayerTreeHostImplClient* client, 143 LayerTreeHostImplClient* client,
144 Proxy* proxy, 144 Proxy* proxy,
145 RenderingStatsInstrumentation* rendering_stats_instrumentation) { 145 RenderingStatsInstrumentation* rendering_stats_instrumentation) {
146 return make_scoped_ptr( 146 return make_scoped_ptr(
147 new LayerTreeHostImpl(settings, 147 new LayerTreeHostImpl(settings,
(...skipping 22 matching lines...) Expand all
170 0, 170 0,
171 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING), 171 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
172 pinch_gesture_active_(false), 172 pinch_gesture_active_(false),
173 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())), 173 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
174 paint_time_counter_(PaintTimeCounter::Create()), 174 paint_time_counter_(PaintTimeCounter::Create()),
175 memory_history_(MemoryHistory::Create()), 175 memory_history_(MemoryHistory::Create()),
176 debug_rect_history_(DebugRectHistory::Create()), 176 debug_rect_history_(DebugRectHistory::Create()),
177 last_sent_memory_visible_bytes_(0), 177 last_sent_memory_visible_bytes_(0),
178 last_sent_memory_visible_and_nearby_bytes_(0), 178 last_sent_memory_visible_and_nearby_bytes_(0),
179 last_sent_memory_use_bytes_(0), 179 last_sent_memory_use_bytes_(0),
180 next_frame_damages_full_device_viewport_(false),
180 animation_registrar_(AnimationRegistrar::Create()), 181 animation_registrar_(AnimationRegistrar::Create()),
181 rendering_stats_instrumentation_(rendering_stats_instrumentation) { 182 rendering_stats_instrumentation_(rendering_stats_instrumentation) {
182 DCHECK(proxy_->IsImplThread()); 183 DCHECK(proxy_->IsImplThread());
183 DidVisibilityChange(this, visible_); 184 DidVisibilityChange(this, visible_);
184 185
185 SetDebugState(settings.initial_debug_state); 186 SetDebugState(settings.initial_debug_state);
186 187
187 if (settings.calculate_top_controls_position) { 188 if (settings.calculate_top_controls_position) {
188 top_controls_manager_ = 189 top_controls_manager_ =
189 TopControlsManager::Create(this, 190 TopControlsManager::Create(this,
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 492
492 bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { 493 bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
493 DCHECK(frame->render_passes.empty()); 494 DCHECK(frame->render_passes.empty());
494 495
495 if (!CanDraw() || !active_tree_->root_layer()) 496 if (!CanDraw() || !active_tree_->root_layer())
496 return false; 497 return false;
497 498
498 TrackDamageForAllSurfaces(active_tree_->root_layer(), 499 TrackDamageForAllSurfaces(active_tree_->root_layer(),
499 *frame->render_surface_layer_list); 500 *frame->render_surface_layer_list);
500 501
502 // If the root render surface has no visible damage, then don't generate a
503 // frame at all.
504 RenderSurfaceImpl* root_surface =
505 active_tree_->root_layer()->render_surface();
506 bool root_surface_has_no_visible_damage =
507 gfx::IntersectRects(root_surface->damage_tracker()->current_damage_rect(),
enne (OOO) 2013/03/26 01:42:07 I think you're looking for gfx::Rect::Intersects
danakj 2013/03/26 02:00:10 So I am!
508 root_surface->content_rect()).IsEmpty();
509 bool root_surface_has_contributing_layers =
510 !root_surface->layer_list().empty();
511 if (root_surface_has_contributing_layers &&
512 root_surface_has_no_visible_damage) {
513 TRACE_EVENT0("cc",
514 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
515 frame->has_no_damage = true;
516 return true;
517 }
518
501 TRACE_EVENT1("cc", 519 TRACE_EVENT1("cc",
502 "LayerTreeHostImpl::CalculateRenderPasses", 520 "LayerTreeHostImpl::CalculateRenderPasses",
503 "render_surface_layer_list.size()", 521 "render_surface_layer_list.size()",
504 static_cast<long long unsigned>( 522 static_cast<long long unsigned>(
505 frame->render_surface_layer_list->size())); 523 frame->render_surface_layer_list->size()));
506 524
507 // Create the render passes in dependency order. 525 // Create the render passes in dependency order.
508 for (int surface_index = frame->render_surface_layer_list->size() - 1; 526 for (int surface_index = frame->render_surface_layer_list->size() - 1;
509 surface_index >= 0 ; 527 surface_index >= 0 ;
510 --surface_index) { 528 --surface_index) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 occlusion_tracker); 675 occlusion_tracker);
658 } 676 }
659 677
660 if (draw_frame) 678 if (draw_frame)
661 occlusion_tracker.overdraw_metrics()->RecordMetrics(this); 679 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
662 680
663 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); 681 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
664 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); 682 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
665 RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame); 683 RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame);
666 684
685 // If we're making a frame to draw, it better have at least one render pass.
686 DCHECK(!frame->render_passes.empty());
667 return draw_frame; 687 return draw_frame;
668 } 688 }
669 689
670 void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) { 690 void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) {
671 // Lazily create the time_source adapter so that we can vary the interval for 691 // Lazily create the time_source adapter so that we can vary the interval for
672 // testing. 692 // testing.
673 if (!time_source_client_adapter_) { 693 if (!time_source_client_adapter_) {
674 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create( 694 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
675 this, 695 this,
676 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(), 696 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 // change. So, capture the iterator position from the end of the 825 // change. So, capture the iterator position from the end of the
806 // list, and restore it after the change. 826 // list, and restore it after the change.
807 size_t position_from_end = frame->render_passes.size() - it; 827 size_t position_from_end = frame->render_passes.size() - it;
808 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame); 828 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
809 it = frame->render_passes.size() - position_from_end; 829 it = frame->render_passes.size() - position_from_end;
810 DCHECK_GE(frame->render_passes.size(), position_from_end); 830 DCHECK_GE(frame->render_passes.size(), position_from_end);
811 } 831 }
812 } 832 }
813 } 833 }
814 834
815 bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { 835 bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
836 gfx::Rect device_viewport_damage_rect) {
816 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw"); 837 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
817 838
818 active_tree_->UpdateDrawProperties( 839 active_tree_->UpdateDrawProperties(
819 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW); 840 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
820 841
821 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList(); 842 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
822 frame->render_passes.clear(); 843 frame->render_passes.clear();
823 frame->render_passes_by_id.clear(); 844 frame->render_passes_by_id.clear();
824 frame->will_draw_layers.clear(); 845 frame->will_draw_layers.clear();
846 frame->contains_incomplete_tile = false;
847 frame->has_no_damage = false;
848
849 if (active_tree_->root_layer()) {
enne (OOO) 2013/03/26 01:42:07 Why only do this if there's a root layer? If there
danakj 2013/03/26 02:00:10 That is true, but it may not be a full frame if th
850 if (next_frame_damages_full_device_viewport_)
851 device_viewport_damage_rect.Union(gfx::Rect(device_viewport_size_));
852
853 active_tree_->root_layer()->render_surface()->damage_tracker()->
854 AddDamageNextUpdate(device_viewport_damage_rect);
855 }
856 next_frame_damages_full_device_viewport_ = false;
825 857
826 if (!CalculateRenderPasses(frame)) 858 if (!CalculateRenderPasses(frame))
827 return false; 859 return false;
828 860
829 // If we return true, then we expect DrawLayers() to be called before this 861 // If we return true, then we expect DrawLayers() to be called before this
830 // function is called again. 862 // function is called again.
831 return true; 863 return true;
832 } 864 }
833 865
834 void LayerTreeHostImpl::EnforceManagedMemoryPolicy( 866 void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 975
944 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset(); 976 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
945 977
946 return metadata; 978 return metadata;
947 } 979 }
948 980
949 void LayerTreeHostImpl::DrawLayers(FrameData* frame, 981 void LayerTreeHostImpl::DrawLayers(FrameData* frame,
950 base::TimeTicks frame_begin_time) { 982 base::TimeTicks frame_begin_time) {
951 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); 983 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
952 DCHECK(CanDraw()); 984 DCHECK(CanDraw());
985
986 if (frame->has_no_damage)
987 return;
988
953 DCHECK(!frame->render_passes.empty()); 989 DCHECK(!frame->render_passes.empty());
954 990
955 fps_counter_->SaveTimeStamp(frame_begin_time); 991 fps_counter_->SaveTimeStamp(frame_begin_time);
956 992
957 rendering_stats_instrumentation_->SetScreenFrameCount( 993 rendering_stats_instrumentation_->SetScreenFrameCount(
958 fps_counter_->current_frame_number()); 994 fps_counter_->current_frame_number());
959 rendering_stats_instrumentation_->SetDroppedFrameCount( 995 rendering_stats_instrumentation_->SetDroppedFrameCount(
960 fps_counter_->dropped_frame_count()); 996 fps_counter_->dropped_frame_count());
961 997
962 if (tile_manager_) { 998 if (tile_manager_) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 1051
1016 bool LayerTreeHostImpl::IsContextLost() { 1052 bool LayerTreeHostImpl::IsContextLost() {
1017 DCHECK(proxy_->IsImplThread()); 1053 DCHECK(proxy_->IsImplThread());
1018 return renderer_ && renderer_->IsContextLost(); 1054 return renderer_ && renderer_->IsContextLost();
1019 } 1055 }
1020 1056
1021 const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const { 1057 const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1022 return renderer_->Capabilities(); 1058 return renderer_->Capabilities();
1023 } 1059 }
1024 1060
1025 bool LayerTreeHostImpl::SwapBuffers() { 1061 bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
1062 if (frame.has_no_damage)
1063 return false;
1026 return renderer_->SwapBuffers(); 1064 return renderer_->SwapBuffers();
1027 } 1065 }
1028 1066
1029 gfx::Size LayerTreeHostImpl::DeviceViewportSize() const { 1067 gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1030 return device_viewport_size(); 1068 return device_viewport_size();
1031 } 1069 }
1032 1070
1033 gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const { 1071 gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1034 gfx::SizeF dip_size = 1072 gfx::SizeF dip_size =
1035 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor()); 1073 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); 1754 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
1717 1755
1718 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); 1756 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
1719 scroll_info->page_scale_delta = active_tree_->page_scale_delta(); 1757 scroll_info->page_scale_delta = active_tree_->page_scale_delta();
1720 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta); 1758 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
1721 1759
1722 return scroll_info.Pass(); 1760 return scroll_info.Pass();
1723 } 1761 }
1724 1762
1725 void LayerTreeHostImpl::SetFullRootLayerDamage() { 1763 void LayerTreeHostImpl::SetFullRootLayerDamage() {
1726 if (active_tree_->root_layer()) { 1764 next_frame_damages_full_device_viewport_ = true;
1727 RenderSurfaceImpl* render_surface =
1728 active_tree_->root_layer()->render_surface();
1729 if (render_surface)
1730 render_surface->damage_tracker()->ForceFullDamageNextUpdate();
1731 }
1732 } 1765 }
1733 1766
1734 void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { 1767 void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1735 if (!page_scale_animation_ || !RootScrollLayer()) 1768 if (!page_scale_animation_ || !RootScrollLayer())
1736 return; 1769 return;
1737 1770
1738 double monotonic_time = (time - base::TimeTicks()).InSecondsF(); 1771 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1739 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() + 1772 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1740 RootScrollLayer()->scroll_delta(); 1773 RootScrollLayer()->scroll_delta();
1741 1774
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 debug_state_ = debug_state; 2055 debug_state_ = debug_state;
2023 } 2056 }
2024 2057
2025 void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time, 2058 void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time,
2026 int commit_number) { 2059 int commit_number) {
2027 DCHECK(debug_state_.continuous_painting); 2060 DCHECK(debug_state_.continuous_painting);
2028 paint_time_counter_->SavePaintTime(total_paint_time, commit_number); 2061 paint_time_counter_->SavePaintTime(total_paint_time, commit_number);
2029 } 2062 }
2030 2063
2031 } // namespace cc 2064 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698