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 "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "CCFrameRateController.h" | 7 #include "CCFrameRateController.h" |
| 8 | 8 |
| 9 #include "CCDelayBasedTimeSource.h" | 9 #include "CCDelayBasedTimeSource.h" |
| 10 #include "CCRenderingStats.h" | |
| 10 #include "CCTimeSource.h" | 11 #include "CCTimeSource.h" |
| 11 #include "TraceEvent.h" | 12 #include "TraceEvent.h" |
| 12 #include <wtf/CurrentTime.h> | 13 #include <wtf/CurrentTime.h> |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 // This will be the maximum number of pending frames unless | 17 // This will be the maximum number of pending frames unless |
| 17 // CCFrameRateController::setMaxFramesPending is called. | 18 // CCFrameRateController::setMaxFramesPending is called. |
| 18 const int defaultMaxFramesPending = 2; | 19 const int defaultMaxFramesPending = 2; |
| 19 | 20 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 36 | 37 |
| 37 CCFrameRateController* m_frameRateController; | 38 CCFrameRateController* m_frameRateController; |
| 38 }; | 39 }; |
| 39 | 40 |
| 40 CCFrameRateController::CCFrameRateController(PassRefPtr<CCTimeSource> timer) | 41 CCFrameRateController::CCFrameRateController(PassRefPtr<CCTimeSource> timer) |
| 41 : m_client(0) | 42 : m_client(0) |
| 42 , m_numFramesPending(0) | 43 , m_numFramesPending(0) |
| 43 , m_maxFramesPending(defaultMaxFramesPending) | 44 , m_maxFramesPending(defaultMaxFramesPending) |
| 44 , m_timeSource(timer) | 45 , m_timeSource(timer) |
| 45 , m_active(false) | 46 , m_active(false) |
| 47 , m_drawActive(false) | |
| 48 , m_commitActive(false) | |
| 46 , m_swapBuffersCompleteSupported(true) | 49 , m_swapBuffersCompleteSupported(true) |
| 50 , m_numCsyncs(0) | |
| 51 , m_numActiveCsyncs(0) | |
| 52 , m_numBeginFrames(0) | |
| 53 , m_interval(m_timeSource->interval()) | |
| 47 , m_isTimeSourceThrottling(true) | 54 , m_isTimeSourceThrottling(true) |
| 48 { | 55 { |
| 49 m_timeSourceClientAdapter = CCFrameRateControllerTimeSourceAdapter::create(t his); | 56 m_timeSourceClientAdapter = CCFrameRateControllerTimeSourceAdapter::create(t his); |
| 50 m_timeSource->setClient(m_timeSourceClientAdapter.get()); | 57 m_timeSource->setClient(m_timeSourceClientAdapter.get()); |
| 51 } | 58 } |
| 52 | 59 |
| 53 CCFrameRateController::CCFrameRateController(CCThread* thread) | 60 CCFrameRateController::CCFrameRateController(CCThread* thread) |
| 54 : m_client(0) | 61 : m_client(0) |
| 55 , m_numFramesPending(0) | 62 , m_numFramesPending(0) |
| 56 , m_maxFramesPending(defaultMaxFramesPending) | 63 , m_maxFramesPending(defaultMaxFramesPending) |
| 57 , m_active(false) | 64 , m_active(false) |
| 65 , m_drawActive(false) | |
| 66 , m_commitActive(false) | |
| 58 , m_swapBuffersCompleteSupported(true) | 67 , m_swapBuffersCompleteSupported(true) |
| 68 , m_numCsyncs(0) | |
| 69 , m_numActiveCsyncs(0) | |
| 70 , m_numBeginFrames(0) | |
| 59 , m_isTimeSourceThrottling(false) | 71 , m_isTimeSourceThrottling(false) |
| 60 { | 72 { |
| 61 m_manualTicker = adoptPtr(new CCTimer(thread, this)); | 73 m_manualTicker = adoptPtr(new CCTimer(thread, this)); |
| 62 } | 74 } |
| 63 | 75 |
| 64 CCFrameRateController::~CCFrameRateController() | 76 CCFrameRateController::~CCFrameRateController() |
| 65 { | 77 { |
| 66 if (m_isTimeSourceThrottling) | 78 if (m_isTimeSourceThrottling) |
| 67 m_timeSource->setActive(false); | 79 m_timeSource->setActive(false); |
| 68 } | 80 } |
| 69 | 81 |
| 70 void CCFrameRateController::setActive(bool active) | 82 void CCFrameRateController::setActive(bool drawActive, bool commitActive) |
| 71 { | 83 { |
| 72 if (m_active == active) | 84 if (m_drawActive == drawActive && m_commitActive == commitActive) |
| 73 return; | 85 return; |
| 74 TRACE_EVENT1("cc", "CCFrameRateController::setActive", "active", active); | 86 |
| 87 TRACE_EVENT2("cc", "CCFrameRateController::setActive", "draw", drawActive, " commit", commitActive); | |
| 88 | |
| 89 if (m_drawActive != drawActive) { | |
| 90 if (m_isTimeSourceThrottling) | |
| 91 m_timeSource->setActive(drawActive); | |
| 92 else { | |
| 93 if (drawActive) | |
| 94 postManualTick(); | |
| 95 else | |
| 96 m_manualTicker->stop(); | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 bool active = drawActive || commitActive; | |
| 101 if (m_active != active) { | |
| 102 base::TimeTicks now = base::TimeTicks::Now(); | |
| 103 if (active) | |
| 104 m_activeTimestamp = now; | |
| 105 else if (m_interval != base::TimeDelta()) { | |
| 106 base::TimeDelta epsilon = base::TimeDelta::FromMicroseconds(1); | |
| 107 m_numActiveCsyncs += (now - m_activeTimestamp + m_interval - epsilon ) / m_interval; | |
| 108 } | |
| 109 } | |
| 110 | |
| 75 m_active = active; | 111 m_active = active; |
| 76 | 112 m_drawActive = drawActive; |
| 77 if (m_isTimeSourceThrottling) | 113 m_commitActive = commitActive; |
| 78 m_timeSource->setActive(active); | |
| 79 else { | |
| 80 if (active) | |
| 81 postManualTick(); | |
| 82 else | |
| 83 m_manualTicker->stop(); | |
| 84 } | |
| 85 } | 114 } |
| 86 | 115 |
| 87 void CCFrameRateController::setMaxFramesPending(int maxFramesPending) | 116 void CCFrameRateController::setMaxFramesPending(int maxFramesPending) |
| 88 { | 117 { |
| 89 ASSERT(maxFramesPending > 0); | 118 ASSERT(maxFramesPending > 0); |
| 90 m_maxFramesPending = maxFramesPending; | 119 m_maxFramesPending = maxFramesPending; |
| 91 } | 120 } |
| 92 | 121 |
| 93 void CCFrameRateController::setTimebaseAndInterval(base::TimeTicks timebase, bas e::TimeDelta interval) | 122 void CCFrameRateController::setTimebaseAndInterval(base::TimeTicks timebase, bas e::TimeDelta interval) |
| 94 { | 123 { |
| 124 if (interval != m_interval) { | |
| 125 base::TimeTicks now = base::TimeTicks::Now(); | |
| 126 if (m_interval != base::TimeDelta()) | |
| 127 m_numCsyncs += (now - m_intervalChangedTime) / m_interval; | |
| 128 m_intervalChangedTime = now; | |
| 129 m_interval = interval; | |
| 130 } | |
| 131 | |
| 95 if (m_isTimeSourceThrottling) | 132 if (m_isTimeSourceThrottling) |
| 96 m_timeSource->setTimebaseAndInterval(timebase, interval); | 133 m_timeSource->setTimebaseAndInterval(timebase, interval); |
| 97 } | 134 } |
| 98 | 135 |
| 99 void CCFrameRateController::setSwapBuffersCompleteSupported(bool supported) | 136 void CCFrameRateController::setSwapBuffersCompleteSupported(bool supported) |
| 100 { | 137 { |
| 101 m_swapBuffersCompleteSupported = supported; | 138 m_swapBuffersCompleteSupported = supported; |
| 102 } | 139 } |
| 103 | 140 |
| 104 void CCFrameRateController::onTimerTick() | 141 void CCFrameRateController::onTimerTick() |
| 105 { | 142 { |
| 106 ASSERT(m_active); | 143 ASSERT(m_drawActive); |
| 107 | 144 |
| 108 // Check if we have too many frames in flight. | 145 // Check if we have too many frames in flight. |
| 109 bool throttled = m_numFramesPending >= m_maxFramesPending; | 146 bool throttled = m_numFramesPending >= m_maxFramesPending; |
| 110 | 147 |
| 111 if (m_client) | 148 if (m_client) |
| 112 m_client->vsyncTick(throttled); | 149 m_client->vsyncTick(throttled); |
| 113 | 150 |
| 114 if (m_swapBuffersCompleteSupported && !m_isTimeSourceThrottling && m_numFram esPending < m_maxFramesPending) | 151 if (m_swapBuffersCompleteSupported && !m_isTimeSourceThrottling && m_numFram esPending < m_maxFramesPending) |
| 115 postManualTick(); | 152 postManualTick(); |
| 116 } | 153 } |
| 117 | 154 |
| 118 void CCFrameRateController::postManualTick() | 155 void CCFrameRateController::postManualTick() |
| 119 { | 156 { |
| 120 if (m_active) | 157 if (m_drawActive) |
| 121 m_manualTicker->startOneShot(0); | 158 m_manualTicker->startOneShot(0); |
| 122 } | 159 } |
| 123 | 160 |
| 124 void CCFrameRateController::onTimerFired() | 161 void CCFrameRateController::onTimerFired() |
| 125 { | 162 { |
| 126 onTimerTick(); | 163 onTimerTick(); |
| 127 } | 164 } |
| 128 | 165 |
| 129 void CCFrameRateController::didBeginFrame() | 166 void CCFrameRateController::didBeginFrame() |
| 130 { | 167 { |
| 168 ASSERT(m_drawActive); | |
| 169 | |
| 170 m_numBeginFrames++; | |
| 171 | |
| 131 if (m_swapBuffersCompleteSupported) | 172 if (m_swapBuffersCompleteSupported) |
| 132 m_numFramesPending++; | 173 m_numFramesPending++; |
| 133 else if (!m_isTimeSourceThrottling) | 174 else if (!m_isTimeSourceThrottling) |
| 134 postManualTick(); | 175 postManualTick(); |
| 135 } | 176 } |
| 136 | 177 |
| 137 void CCFrameRateController::didFinishFrame() | 178 void CCFrameRateController::didFinishFrame() |
| 138 { | 179 { |
| 139 ASSERT(m_swapBuffersCompleteSupported); | 180 ASSERT(m_swapBuffersCompleteSupported); |
| 140 | 181 |
| 141 m_numFramesPending--; | 182 m_numFramesPending--; |
| 142 if (!m_isTimeSourceThrottling) | 183 if (!m_isTimeSourceThrottling) |
| 143 postManualTick(); | 184 postManualTick(); |
| 144 } | 185 } |
| 145 | 186 |
| 146 void CCFrameRateController::didAbortAllPendingFrames() | 187 void CCFrameRateController::didAbortAllPendingFrames() |
| 147 { | 188 { |
| 148 m_numFramesPending = 0; | 189 m_numFramesPending = 0; |
| 149 } | 190 } |
| 150 | 191 |
| 151 base::TimeTicks CCFrameRateController::nextTickTime() | 192 base::TimeTicks CCFrameRateController::nextTickTime() |
| 152 { | 193 { |
| 153 if (m_isTimeSourceThrottling) | 194 if (m_isTimeSourceThrottling) |
| 154 return m_timeSource->nextTickTime(); | 195 return m_timeSource->nextTickTime(); |
| 155 | 196 |
| 156 return base::TimeTicks(); | 197 return base::TimeTicks(); |
| 157 } | 198 } |
| 158 | 199 |
| 200 | |
| 201 void CCFrameRateController::renderingStats(CCRenderingStats* stats) const | |
| 202 { | |
| 203 base::TimeTicks now = base::TimeTicks::Now(); | |
| 204 | |
| 205 stats->numCSyncs = m_numCsyncs; | |
| 206 if (m_interval != base::TimeDelta()) | |
| 207 stats->numCSyncs += (now - m_intervalChangedTime) / m_interval; | |
| 208 | |
| 209 stats->numActiveCSyncs = m_numActiveCsyncs; | |
| 210 if (m_active && m_interval != base::TimeDelta()) | |
| 211 stats->numActiveCSyncs += (now - m_activeTimestamp) / m_interval; | |
| 212 | |
| 213 stats->numFramesSentToScreen = m_numBeginFrames; | |
| 214 stats->droppedFrameCount = stats->numActiveCSyncs - m_numBeginFrames; | |
| 215 | |
| 216 return; | |
|
reveman
2012/10/04 02:15:56
nit: unnecessary return statement
brianderson
2012/10/04 20:11:59
Done.
| |
| 159 } | 217 } |
| 218 | |
| 219 } | |
| OLD | NEW |