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/scheduler/frame_rate_controller.h" | 5 #include "cc/scheduler/frame_rate_controller.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "cc/base/thread.h" | 9 #include "cc/base/thread.h" |
10 #include "cc/scheduler/delay_based_time_source.h" | 10 #include "cc/scheduler/delay_based_time_source.h" |
11 #include "cc/scheduler/time_source.h" | 11 #include "cc/scheduler/time_source.h" |
12 | 12 |
13 namespace cc { | 13 namespace cc { |
14 | 14 |
15 class FrameRateControllerTimeSourceAdapter : public TimeSourceClient { | 15 class FrameRateControllerTimeSourceAdapter : public TimeSourceClient { |
16 public: | 16 public: |
17 static scoped_ptr<FrameRateControllerTimeSourceAdapter> Create(FrameRateCont
roller* frameRateController) { | 17 static scoped_ptr<FrameRateControllerTimeSourceAdapter> Create( |
18 return make_scoped_ptr(new FrameRateControllerTimeSourceAdapter(frameRat
eController)); | 18 FrameRateController* frame_rate_controller) { |
19 } | 19 return make_scoped_ptr( |
20 virtual ~FrameRateControllerTimeSourceAdapter() {} | 20 new FrameRateControllerTimeSourceAdapter(frame_rate_controller)); |
| 21 } |
| 22 virtual ~FrameRateControllerTimeSourceAdapter() {} |
21 | 23 |
22 virtual void onTimerTick() OVERRIDE { | 24 virtual void onTimerTick() OVERRIDE { frame_rate_controller_->OnTimerTick(); } |
23 m_frameRateController->onTimerTick(); | |
24 } | |
25 | 25 |
26 private: | 26 private: |
27 explicit FrameRateControllerTimeSourceAdapter(FrameRateController* frameRate
Controller) | 27 explicit FrameRateControllerTimeSourceAdapter( |
28 : m_frameRateController(frameRateController) {} | 28 FrameRateController* frame_rate_controller) |
| 29 : frame_rate_controller_(frame_rate_controller) {} |
29 | 30 |
30 FrameRateController* m_frameRateController; | 31 FrameRateController* frame_rate_controller_; |
31 }; | 32 }; |
32 | 33 |
33 FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) | 34 FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) |
34 : m_client(0) | 35 : client_(NULL), |
35 , m_numFramesPending(0) | 36 num_frames_pending_(0), |
36 , m_maxFramesPending(0) | 37 max_frames_pending_(0), |
37 , m_timeSource(timer) | 38 time_source_(timer), |
38 , m_active(false) | 39 active_(false), |
39 , m_swapBuffersCompleteSupported(true) | 40 swap_buffers_complete_supported_(true), |
40 , m_isTimeSourceThrottling(true) | 41 is_time_source_throttling_(true), |
41 , m_thread(0) | 42 thread_(NULL), |
42 , m_weakFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) | 43 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
43 { | 44 time_source_client_adapter_ = |
44 m_timeSourceClientAdapter = FrameRateControllerTimeSourceAdapter::Create(thi
s); | 45 FrameRateControllerTimeSourceAdapter::Create(this); |
45 m_timeSource->setClient(m_timeSourceClientAdapter.get()); | 46 time_source_->setClient(time_source_client_adapter_.get()); |
46 } | 47 } |
47 | 48 |
48 FrameRateController::FrameRateController(Thread* thread) | 49 FrameRateController::FrameRateController(Thread* thread) |
49 : m_client(0) | 50 : client_(NULL), |
50 , m_numFramesPending(0) | 51 num_frames_pending_(0), |
51 , m_maxFramesPending(0) | 52 max_frames_pending_(0), |
52 , m_active(false) | 53 active_(false), |
53 , m_swapBuffersCompleteSupported(true) | 54 swap_buffers_complete_supported_(true), |
54 , m_isTimeSourceThrottling(false) | 55 is_time_source_throttling_(false), |
55 , m_thread(thread) | 56 thread_(thread), |
56 , m_weakFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) | 57 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} |
57 { | 58 |
| 59 FrameRateController::~FrameRateController() { |
| 60 if (is_time_source_throttling_) |
| 61 time_source_->setActive(false); |
58 } | 62 } |
59 | 63 |
60 FrameRateController::~FrameRateController() | 64 void FrameRateController::SetActive(bool active) { |
61 { | 65 if (active_ == active) |
62 if (m_isTimeSourceThrottling) | 66 return; |
63 m_timeSource->setActive(false); | 67 TRACE_EVENT1("cc", "FrameRateController::SetActive", "active", active); |
| 68 active_ = active; |
| 69 |
| 70 if (is_time_source_throttling_) { |
| 71 time_source_->setActive(active); |
| 72 } else { |
| 73 if (active) |
| 74 PostManualTick(); |
| 75 else |
| 76 weak_factory_.InvalidateWeakPtrs(); |
| 77 } |
64 } | 78 } |
65 | 79 |
66 void FrameRateController::setActive(bool active) | 80 void FrameRateController::SetMaxFramesPending(int max_frames_pending) { |
67 { | 81 DCHECK_GE(max_frames_pending, 0); |
68 if (m_active == active) | 82 max_frames_pending_ = max_frames_pending; |
69 return; | |
70 TRACE_EVENT1("cc", "FrameRateController::setActive", "active", active); | |
71 m_active = active; | |
72 | |
73 if (m_isTimeSourceThrottling) | |
74 m_timeSource->setActive(active); | |
75 else { | |
76 if (active) | |
77 postManualTick(); | |
78 else | |
79 m_weakFactory.InvalidateWeakPtrs(); | |
80 } | |
81 } | 83 } |
82 | 84 |
83 void FrameRateController::setMaxFramesPending(int maxFramesPending) | 85 void FrameRateController::SetTimebaseAndInterval(base::TimeTicks timebase, |
84 { | 86 base::TimeDelta interval) { |
85 DCHECK_GE(maxFramesPending, 0); | 87 if (is_time_source_throttling_) |
86 m_maxFramesPending = maxFramesPending; | 88 time_source_->setTimebaseAndInterval(timebase, interval); |
87 } | 89 } |
88 | 90 |
89 void FrameRateController::setTimebaseAndInterval(base::TimeTicks timebase, base:
:TimeDelta interval) | 91 void FrameRateController::SetSwapBuffersCompleteSupported(bool supported) { |
90 { | 92 swap_buffers_complete_supported_ = supported; |
91 if (m_isTimeSourceThrottling) | |
92 m_timeSource->setTimebaseAndInterval(timebase, interval); | |
93 } | 93 } |
94 | 94 |
95 void FrameRateController::setSwapBuffersCompleteSupported(bool supported) | 95 void FrameRateController::OnTimerTick() { |
96 { | 96 DCHECK(active_); |
97 m_swapBuffersCompleteSupported = supported; | 97 |
| 98 // Check if we have too many frames in flight. |
| 99 bool throttled = |
| 100 max_frames_pending_ && num_frames_pending_ >= max_frames_pending_; |
| 101 TRACE_COUNTER_ID1("cc", "ThrottledVSyncInterval", thread_, throttled); |
| 102 |
| 103 if (client_) |
| 104 client_->VSyncTick(throttled); |
| 105 |
| 106 if (swap_buffers_complete_supported_ && !is_time_source_throttling_ && |
| 107 !throttled) |
| 108 PostManualTick(); |
98 } | 109 } |
99 | 110 |
100 void FrameRateController::onTimerTick() | 111 void FrameRateController::PostManualTick() { |
101 { | 112 if (active_) { |
102 DCHECK(m_active); | 113 thread_->PostTask(base::Bind(&FrameRateController::ManualTick, |
103 | 114 weak_factory_.GetWeakPtr())); |
104 // Check if we have too many frames in flight. | 115 } |
105 bool throttled = m_maxFramesPending && m_numFramesPending >= m_maxFramesPend
ing; | |
106 TRACE_COUNTER_ID1("cc", "ThrottledVSyncInterval", m_thread, throttled); | |
107 | |
108 if (m_client) | |
109 m_client->vsyncTick(throttled); | |
110 | |
111 if (m_swapBuffersCompleteSupported && !m_isTimeSourceThrottling && !throttle
d) | |
112 postManualTick(); | |
113 } | 116 } |
114 | 117 |
115 void FrameRateController::postManualTick() | 118 void FrameRateController::ManualTick() { OnTimerTick(); } |
116 { | 119 |
117 if (m_active) | 120 void FrameRateController::DidBeginFrame() { |
118 m_thread->PostTask(base::Bind(&FrameRateController::manualTick, m_weakFa
ctory.GetWeakPtr())); | 121 if (swap_buffers_complete_supported_) |
| 122 num_frames_pending_++; |
| 123 else if (!is_time_source_throttling_) |
| 124 PostManualTick(); |
119 } | 125 } |
120 | 126 |
121 void FrameRateController::manualTick() | 127 void FrameRateController::DidFinishFrame() { |
122 { | 128 DCHECK(swap_buffers_complete_supported_); |
123 onTimerTick(); | 129 |
| 130 num_frames_pending_--; |
| 131 if (!is_time_source_throttling_) |
| 132 PostManualTick(); |
124 } | 133 } |
125 | 134 |
126 void FrameRateController::didBeginFrame() | 135 void FrameRateController::DidAbortAllPendingFrames() { |
127 { | 136 num_frames_pending_ = 0; |
128 if (m_swapBuffersCompleteSupported) | |
129 m_numFramesPending++; | |
130 else if (!m_isTimeSourceThrottling) | |
131 postManualTick(); | |
132 } | 137 } |
133 | 138 |
134 void FrameRateController::didFinishFrame() | 139 base::TimeTicks FrameRateController::NextTickTime() { |
135 { | 140 if (is_time_source_throttling_) |
136 DCHECK(m_swapBuffersCompleteSupported); | 141 return time_source_->nextTickTime(); |
137 | 142 |
138 m_numFramesPending--; | 143 return base::TimeTicks(); |
139 if (!m_isTimeSourceThrottling) | |
140 postManualTick(); | |
141 } | 144 } |
142 | 145 |
143 void FrameRateController::didAbortAllPendingFrames() | 146 base::TimeTicks FrameRateController::LastTickTime() { |
144 { | 147 if (is_time_source_throttling_) |
145 m_numFramesPending = 0; | 148 return time_source_->lastTickTime(); |
146 } | |
147 | 149 |
148 base::TimeTicks FrameRateController::nextTickTime() | 150 return base::TimeTicks::Now(); |
149 { | |
150 if (m_isTimeSourceThrottling) | |
151 return m_timeSource->nextTickTime(); | |
152 | |
153 return base::TimeTicks(); | |
154 } | |
155 | |
156 base::TimeTicks FrameRateController::lastTickTime() | |
157 { | |
158 if (m_isTimeSourceThrottling) | |
159 return m_timeSource->lastTickTime(); | |
160 | |
161 return base::TimeTicks::Now(); | |
162 } | 151 } |
163 | 152 |
164 } // namespace cc | 153 } // namespace cc |
OLD | NEW |