Chromium Code Reviews| 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/thread_proxy.h" | 5 #include "cc/trees/thread_proxy.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/metrics/histogram.h" | |
| 10 #include "cc/base/thread.h" | 11 #include "cc/base/thread.h" |
| 11 #include "cc/input/input_handler.h" | 12 #include "cc/input/input_handler.h" |
| 12 #include "cc/output/context_provider.h" | 13 #include "cc/output/context_provider.h" |
| 13 #include "cc/output/output_surface.h" | 14 #include "cc/output/output_surface.h" |
| 14 #include "cc/quads/draw_quad.h" | 15 #include "cc/quads/draw_quad.h" |
| 15 #include "cc/resources/prioritized_resource_manager.h" | 16 #include "cc/resources/prioritized_resource_manager.h" |
| 16 #include "cc/scheduler/delay_based_time_source.h" | 17 #include "cc/scheduler/delay_based_time_source.h" |
| 17 #include "cc/scheduler/frame_rate_controller.h" | 18 #include "cc/scheduler/frame_rate_controller.h" |
| 18 #include "cc/scheduler/scheduler.h" | 19 #include "cc/scheduler/scheduler.h" |
| 19 #include "cc/scheduler/vsync_time_source.h" | 20 #include "cc/scheduler/vsync_time_source.h" |
| 20 #include "cc/trees/layer_tree_host.h" | 21 #include "cc/trees/layer_tree_host.h" |
| 21 #include "cc/trees/layer_tree_impl.h" | 22 #include "cc/trees/layer_tree_impl.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 // Measured in seconds. | 26 // Measured in seconds. |
| 26 const double kContextRecreationTickRate = 0.03; | 27 const double kContextRecreationTickRate = 0.03; |
| 27 | 28 |
| 28 // Measured in seconds. | 29 // Measured in seconds. |
| 29 const double kSmoothnessTakesPriorityExpirationDelay = 0.25; | 30 const double kSmoothnessTakesPriorityExpirationDelay = 0.25; |
| 30 | 31 |
| 32 const size_t kDrawDurationHistorySize = 60; | |
| 33 const double kDrawDurationEstimationPercentile = 100.0; | |
| 34 const int kDrawDurationEstimatePaddingInMicroseconds = 0; | |
| 35 | |
| 31 } // namespace | 36 } // namespace |
| 32 | 37 |
| 33 namespace cc { | 38 namespace cc { |
| 34 | 39 |
| 35 scoped_ptr<Proxy> ThreadProxy::Create(LayerTreeHost* layer_tree_host, | 40 scoped_ptr<Proxy> ThreadProxy::Create(LayerTreeHost* layer_tree_host, |
| 36 scoped_ptr<Thread> impl_thread) { | 41 scoped_ptr<Thread> impl_thread) { |
| 37 return make_scoped_ptr( | 42 return make_scoped_ptr( |
| 38 new ThreadProxy(layer_tree_host, impl_thread.Pass())).PassAs<Proxy>(); | 43 new ThreadProxy(layer_tree_host, impl_thread.Pass())).PassAs<Proxy>(); |
| 39 } | 44 } |
| 40 | 45 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 60 next_frame_is_newly_committed_frame_on_impl_thread_(false), | 65 next_frame_is_newly_committed_frame_on_impl_thread_(false), |
| 61 throttle_frame_production_( | 66 throttle_frame_production_( |
| 62 layer_tree_host->settings().throttle_frame_production), | 67 layer_tree_host->settings().throttle_frame_production), |
| 63 begin_frame_scheduling_enabled_( | 68 begin_frame_scheduling_enabled_( |
| 64 layer_tree_host->settings().begin_frame_scheduling_enabled), | 69 layer_tree_host->settings().begin_frame_scheduling_enabled), |
| 65 using_synchronous_renderer_compositor_( | 70 using_synchronous_renderer_compositor_( |
| 66 layer_tree_host->settings().using_synchronous_renderer_compositor), | 71 layer_tree_host->settings().using_synchronous_renderer_compositor), |
| 67 vsync_client_(NULL), | 72 vsync_client_(NULL), |
| 68 inside_draw_(false), | 73 inside_draw_(false), |
| 69 defer_commits_(false), | 74 defer_commits_(false), |
| 70 renew_tree_priority_on_impl_thread_pending_(false) { | 75 renew_tree_priority_on_impl_thread_pending_(false), |
| 76 draw_duration_history_(kDrawDurationHistorySize) { | |
| 71 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); | 77 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); |
| 72 DCHECK(IsMainThread()); | 78 DCHECK(IsMainThread()); |
| 73 DCHECK(layer_tree_host_); | 79 DCHECK(layer_tree_host_); |
| 74 } | 80 } |
| 75 | 81 |
| 76 ThreadProxy::~ThreadProxy() { | 82 ThreadProxy::~ThreadProxy() { |
| 77 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy"); | 83 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy"); |
| 78 DCHECK(IsMainThread()); | 84 DCHECK(IsMainThread()); |
| 79 DCHECK(!started_); | 85 DCHECK(!started_); |
| 80 } | 86 } |
| (...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 DCHECK(IsImplThread()); | 876 DCHECK(IsImplThread()); |
| 871 Proxy::MainThread()->PostTask( | 877 Proxy::MainThread()->PostTask( |
| 872 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, | 878 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, |
| 873 main_thread_weak_ptr_)); | 879 main_thread_weak_ptr_)); |
| 874 } | 880 } |
| 875 | 881 |
| 876 ScheduledActionDrawAndSwapResult | 882 ScheduledActionDrawAndSwapResult |
| 877 ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { | 883 ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { |
| 878 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap"); | 884 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap"); |
| 879 | 885 |
| 886 base::TimeTicks start_time = base::TimeTicks::HighResNow(); | |
| 887 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); | |
| 880 base::AutoReset<bool> mark_inside(&inside_draw_, true); | 888 base::AutoReset<bool> mark_inside(&inside_draw_, true); |
| 881 | 889 |
| 882 ScheduledActionDrawAndSwapResult result; | 890 ScheduledActionDrawAndSwapResult result; |
| 883 result.did_draw = false; | 891 result.did_draw = false; |
| 884 result.did_swap = false; | 892 result.did_swap = false; |
| 885 DCHECK(IsImplThread()); | 893 DCHECK(IsImplThread()); |
| 886 DCHECK(layer_tree_host_impl_.get()); | 894 DCHECK(layer_tree_host_impl_.get()); |
| 887 if (!layer_tree_host_impl_) | 895 if (!layer_tree_host_impl_) |
| 888 return result; | 896 return result; |
| 889 | 897 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 961 DidSwapUseIncompleteTileOnImplThread(); | 969 DidSwapUseIncompleteTileOnImplThread(); |
| 962 } | 970 } |
| 963 | 971 |
| 964 // Tell the main thread that the the newly-commited frame was drawn. | 972 // Tell the main thread that the the newly-commited frame was drawn. |
| 965 if (next_frame_is_newly_committed_frame_on_impl_thread_) { | 973 if (next_frame_is_newly_committed_frame_on_impl_thread_) { |
| 966 next_frame_is_newly_committed_frame_on_impl_thread_ = false; | 974 next_frame_is_newly_committed_frame_on_impl_thread_ = false; |
| 967 Proxy::MainThread()->PostTask( | 975 Proxy::MainThread()->PostTask( |
| 968 base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_)); | 976 base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_)); |
| 969 } | 977 } |
| 970 | 978 |
| 971 if (draw_frame) | 979 if (draw_frame) { |
| 972 CheckOutputSurfaceStatusOnImplThread(); | 980 CheckOutputSurfaceStatusOnImplThread(); |
| 973 | 981 |
| 982 base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_time; | |
| 983 draw_duration_history_.InsertSample(draw_duration); | |
| 984 base::TimeDelta draw_duration_overestimate; | |
| 985 base::TimeDelta draw_duration_underestimate; | |
|
brianderson
2013/06/12 00:59:44
Instead of having over/underestimate, can we just
ajuma
2013/06/12 01:18:11
We need two different numbers here since UMA histo
| |
| 986 if (draw_duration > draw_duration_estimate) | |
| 987 draw_duration_underestimate = draw_duration - draw_duration_estimate; | |
| 988 else | |
| 989 draw_duration_overestimate = draw_duration_estimate - draw_duration; | |
| 990 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", | |
| 991 draw_duration, | |
| 992 base::TimeDelta::FromMilliseconds(1), | |
| 993 base::TimeDelta::FromMilliseconds(100), | |
| 994 50); | |
| 995 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate", | |
| 996 draw_duration_underestimate, | |
| 997 base::TimeDelta::FromMilliseconds(1), | |
| 998 base::TimeDelta::FromMilliseconds(100), | |
| 999 50); | |
| 1000 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate", | |
| 1001 draw_duration_overestimate, | |
| 1002 base::TimeDelta::FromMilliseconds(1), | |
| 1003 base::TimeDelta::FromMilliseconds(100), | |
| 1004 50); | |
| 1005 } | |
| 1006 | |
| 974 // Update the tile state after drawing. This prevents manage tiles from | 1007 // Update the tile state after drawing. This prevents manage tiles from |
| 975 // being in the critical path for getting things on screen, but still | 1008 // being in the critical path for getting things on screen, but still |
| 976 // makes sure that tile state is updated on a semi-regular basis. | 1009 // makes sure that tile state is updated on a semi-regular basis. |
| 977 if (layer_tree_host_impl_->settings().impl_side_painting) | 1010 if (layer_tree_host_impl_->settings().impl_side_painting) |
| 978 layer_tree_host_impl_->ManageTiles(); | 1011 layer_tree_host_impl_->ManageTiles(); |
| 979 | 1012 |
| 980 return result; | 1013 return result; |
| 981 } | 1014 } |
| 982 | 1015 |
| 983 void ThreadProxy::AcquireLayerTextures() { | 1016 void ThreadProxy::AcquireLayerTextures() { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1029 return ScheduledActionDrawAndSwapInternal(true); | 1062 return ScheduledActionDrawAndSwapInternal(true); |
| 1030 } | 1063 } |
| 1031 | 1064 |
| 1032 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { | 1065 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { |
| 1033 if (current_resource_update_controller_on_impl_thread_) | 1066 if (current_resource_update_controller_on_impl_thread_) |
| 1034 current_resource_update_controller_on_impl_thread_ | 1067 current_resource_update_controller_on_impl_thread_ |
| 1035 ->PerformMoreUpdates(time); | 1068 ->PerformMoreUpdates(time); |
| 1036 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | 1069 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| 1037 } | 1070 } |
| 1038 | 1071 |
| 1072 base::TimeDelta ThreadProxy::DrawDurationEstimate() { | |
| 1073 base::TimeDelta historical_estimate = | |
| 1074 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile); | |
| 1075 base::TimeDelta padding = base::TimeDelta::FromMicroseconds( | |
| 1076 kDrawDurationEstimatePaddingInMicroseconds); | |
| 1077 return historical_estimate + padding; | |
| 1078 } | |
| 1079 | |
| 1039 void ThreadProxy::ReadyToFinalizeTextureUpdates() { | 1080 void ThreadProxy::ReadyToFinalizeTextureUpdates() { |
| 1040 DCHECK(IsImplThread()); | 1081 DCHECK(IsImplThread()); |
| 1041 scheduler_on_impl_thread_->FinishCommit(); | 1082 scheduler_on_impl_thread_->FinishCommit(); |
| 1042 } | 1083 } |
| 1043 | 1084 |
| 1044 void ThreadProxy::DidCommitAndDrawFrame() { | 1085 void ThreadProxy::DidCommitAndDrawFrame() { |
| 1045 DCHECK(IsMainThread()); | 1086 DCHECK(IsMainThread()); |
| 1046 if (!layer_tree_host_) | 1087 if (!layer_tree_host_) |
| 1047 return; | 1088 return; |
| 1048 layer_tree_host_->DidCommitAndDrawFrame(); | 1089 layer_tree_host_->DidCommitAndDrawFrame(); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1383 !layer_tree_host_impl_->pending_tree()) { | 1424 !layer_tree_host_impl_->pending_tree()) { |
| 1384 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", | 1425 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", |
| 1385 TRACE_EVENT_SCOPE_THREAD); | 1426 TRACE_EVENT_SCOPE_THREAD); |
| 1386 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); | 1427 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); |
| 1387 completion_event_for_commit_held_on_tree_activation_->Signal(); | 1428 completion_event_for_commit_held_on_tree_activation_->Signal(); |
| 1388 completion_event_for_commit_held_on_tree_activation_ = NULL; | 1429 completion_event_for_commit_held_on_tree_activation_ = NULL; |
| 1389 } | 1430 } |
| 1390 } | 1431 } |
| 1391 | 1432 |
| 1392 } // namespace cc | 1433 } // namespace cc |
| OLD | NEW |