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 "CCSchedulerStateMachine.h" | 7 #include "CCSchedulerStateMachine.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 | 9 |
10 | 10 |
11 namespace cc { | 11 namespace cc { |
12 | 12 |
13 CCSchedulerStateMachine::CCSchedulerStateMachine() | 13 SchedulerStateMachine::SchedulerStateMachine() |
14 : m_commitState(COMMIT_STATE_IDLE) | 14 : m_commitState(COMMIT_STATE_IDLE) |
15 , m_currentFrameNumber(0) | 15 , m_currentFrameNumber(0) |
16 , m_lastFrameNumberWhereDrawWasCalled(-1) | 16 , m_lastFrameNumberWhereDrawWasCalled(-1) |
17 , m_consecutiveFailedDraws(0) | 17 , m_consecutiveFailedDraws(0) |
18 , m_maximumNumberOfFailedDrawsBeforeDrawIsForced(3) | 18 , m_maximumNumberOfFailedDrawsBeforeDrawIsForced(3) |
19 , m_needsRedraw(false) | 19 , m_needsRedraw(false) |
20 , m_needsForcedRedraw(false) | 20 , m_needsForcedRedraw(false) |
21 , m_needsForcedRedrawAfterNextCommit(false) | 21 , m_needsForcedRedrawAfterNextCommit(false) |
22 , m_needsCommit(false) | 22 , m_needsCommit(false) |
23 , m_needsForcedCommit(false) | 23 , m_needsForcedCommit(false) |
24 , m_mainThreadNeedsLayerTextures(false) | 24 , m_mainThreadNeedsLayerTextures(false) |
25 , m_insideVSync(false) | 25 , m_insideVSync(false) |
26 , m_visible(false) | 26 , m_visible(false) |
27 , m_canBeginFrame(false) | 27 , m_canBeginFrame(false) |
28 , m_canDraw(false) | 28 , m_canDraw(false) |
29 , m_drawIfPossibleFailed(false) | 29 , m_drawIfPossibleFailed(false) |
30 , m_textureState(LAYER_TEXTURE_STATE_UNLOCKED) | 30 , m_textureState(LAYER_TEXTURE_STATE_UNLOCKED) |
31 , m_contextState(CONTEXT_ACTIVE) | 31 , m_contextState(CONTEXT_ACTIVE) |
32 { | 32 { |
33 } | 33 } |
34 | 34 |
35 std::string CCSchedulerStateMachine::toString() | 35 std::string SchedulerStateMachine::toString() |
36 { | 36 { |
37 std::string str; | 37 std::string str; |
38 base::StringAppendF(&str, "m_commitState = %d; ", m_commitState); | 38 base::StringAppendF(&str, "m_commitState = %d; ", m_commitState); |
39 base::StringAppendF(&str, "m_currentFrameNumber = %d; ", m_currentFrameNumbe
r); | 39 base::StringAppendF(&str, "m_currentFrameNumber = %d; ", m_currentFrameNumbe
r); |
40 base::StringAppendF(&str, "m_lastFrameNumberWhereDrawWasCalled = %d; ", m_la
stFrameNumberWhereDrawWasCalled); | 40 base::StringAppendF(&str, "m_lastFrameNumberWhereDrawWasCalled = %d; ", m_la
stFrameNumberWhereDrawWasCalled); |
41 base::StringAppendF(&str, "m_consecutiveFailedDraws = %d; ", m_consecutiveFa
iledDraws); | 41 base::StringAppendF(&str, "m_consecutiveFailedDraws = %d; ", m_consecutiveFa
iledDraws); |
42 base::StringAppendF(&str, "m_maximumNumberOfFailedDrawsBeforeDrawIsForced =
%d; ", m_maximumNumberOfFailedDrawsBeforeDrawIsForced); | 42 base::StringAppendF(&str, "m_maximumNumberOfFailedDrawsBeforeDrawIsForced =
%d; ", m_maximumNumberOfFailedDrawsBeforeDrawIsForced); |
43 base::StringAppendF(&str, "m_needsRedraw = %d; ", m_needsRedraw); | 43 base::StringAppendF(&str, "m_needsRedraw = %d; ", m_needsRedraw); |
44 base::StringAppendF(&str, "m_needsForcedRedraw = %d; ", m_needsForcedRedraw)
; | 44 base::StringAppendF(&str, "m_needsForcedRedraw = %d; ", m_needsForcedRedraw)
; |
45 base::StringAppendF(&str, "m_needsForcedRedrawAfterNextCommit = %d; ", m_nee
dsForcedRedrawAfterNextCommit); | 45 base::StringAppendF(&str, "m_needsForcedRedrawAfterNextCommit = %d; ", m_nee
dsForcedRedrawAfterNextCommit); |
46 base::StringAppendF(&str, "m_needsCommit = %d; ", m_needsCommit); | 46 base::StringAppendF(&str, "m_needsCommit = %d; ", m_needsCommit); |
47 base::StringAppendF(&str, "m_needsForcedCommit = %d; ", m_needsForcedCommit)
; | 47 base::StringAppendF(&str, "m_needsForcedCommit = %d; ", m_needsForcedCommit)
; |
48 base::StringAppendF(&str, "m_mainThreadNeedsLayerTextures = %d; ", m_mainThr
eadNeedsLayerTextures); | 48 base::StringAppendF(&str, "m_mainThreadNeedsLayerTextures = %d; ", m_mainThr
eadNeedsLayerTextures); |
49 base::StringAppendF(&str, "m_insideVSync = %d; ", m_insideVSync); | 49 base::StringAppendF(&str, "m_insideVSync = %d; ", m_insideVSync); |
50 base::StringAppendF(&str, "m_visible = %d; ", m_visible); | 50 base::StringAppendF(&str, "m_visible = %d; ", m_visible); |
51 base::StringAppendF(&str, "m_canBeginFrame = %d; ", m_canBeginFrame); | 51 base::StringAppendF(&str, "m_canBeginFrame = %d; ", m_canBeginFrame); |
52 base::StringAppendF(&str, "m_canDraw = %d; ", m_canDraw); | 52 base::StringAppendF(&str, "m_canDraw = %d; ", m_canDraw); |
53 base::StringAppendF(&str, "m_drawIfPossibleFailed = %d; ", m_drawIfPossibleF
ailed); | 53 base::StringAppendF(&str, "m_drawIfPossibleFailed = %d; ", m_drawIfPossibleF
ailed); |
54 base::StringAppendF(&str, "m_textureState = %d; ", m_textureState); | 54 base::StringAppendF(&str, "m_textureState = %d; ", m_textureState); |
55 base::StringAppendF(&str, "m_contextState = %d; ", m_contextState); | 55 base::StringAppendF(&str, "m_contextState = %d; ", m_contextState); |
56 return str; | 56 return str; |
57 } | 57 } |
58 | 58 |
59 bool CCSchedulerStateMachine::hasDrawnThisFrame() const | 59 bool SchedulerStateMachine::hasDrawnThisFrame() const |
60 { | 60 { |
61 return m_currentFrameNumber == m_lastFrameNumberWhereDrawWasCalled; | 61 return m_currentFrameNumber == m_lastFrameNumberWhereDrawWasCalled; |
62 } | 62 } |
63 | 63 |
64 bool CCSchedulerStateMachine::drawSuspendedUntilCommit() const | 64 bool SchedulerStateMachine::drawSuspendedUntilCommit() const |
65 { | 65 { |
66 if (!m_canDraw) | 66 if (!m_canDraw) |
67 return true; | 67 return true; |
68 if (!m_visible) | 68 if (!m_visible) |
69 return true; | 69 return true; |
70 if (m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD) | 70 if (m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD) |
71 return true; | 71 return true; |
72 return false; | 72 return false; |
73 } | 73 } |
74 | 74 |
75 bool CCSchedulerStateMachine::scheduledToDraw() const | 75 bool SchedulerStateMachine::scheduledToDraw() const |
76 { | 76 { |
77 if (!m_needsRedraw) | 77 if (!m_needsRedraw) |
78 return false; | 78 return false; |
79 if (drawSuspendedUntilCommit()) | 79 if (drawSuspendedUntilCommit()) |
80 return false; | 80 return false; |
81 return true; | 81 return true; |
82 } | 82 } |
83 | 83 |
84 bool CCSchedulerStateMachine::shouldDraw() const | 84 bool SchedulerStateMachine::shouldDraw() const |
85 { | 85 { |
86 if (m_needsForcedRedraw) | 86 if (m_needsForcedRedraw) |
87 return true; | 87 return true; |
88 | 88 |
89 if (!scheduledToDraw()) | 89 if (!scheduledToDraw()) |
90 return false; | 90 return false; |
91 if (!m_insideVSync) | 91 if (!m_insideVSync) |
92 return false; | 92 return false; |
93 if (hasDrawnThisFrame()) | 93 if (hasDrawnThisFrame()) |
94 return false; | 94 return false; |
95 if (m_contextState != CONTEXT_ACTIVE) | 95 if (m_contextState != CONTEXT_ACTIVE) |
96 return false; | 96 return false; |
97 return true; | 97 return true; |
98 } | 98 } |
99 | 99 |
100 bool CCSchedulerStateMachine::shouldAcquireLayerTexturesForMainThread() const | 100 bool SchedulerStateMachine::shouldAcquireLayerTexturesForMainThread() const |
101 { | 101 { |
102 if (!m_mainThreadNeedsLayerTextures) | 102 if (!m_mainThreadNeedsLayerTextures) |
103 return false; | 103 return false; |
104 if (m_textureState == LAYER_TEXTURE_STATE_UNLOCKED) | 104 if (m_textureState == LAYER_TEXTURE_STATE_UNLOCKED) |
105 return true; | 105 return true; |
106 ASSERT(m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); | 106 ASSERT(m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); |
107 // Transfer the lock from impl thread to main thread immediately if the | 107 // Transfer the lock from impl thread to main thread immediately if the |
108 // impl thread is not even scheduled to draw. Guards against deadlocking. | 108 // impl thread is not even scheduled to draw. Guards against deadlocking. |
109 if (!scheduledToDraw()) | 109 if (!scheduledToDraw()) |
110 return true; | 110 return true; |
111 if (!vsyncCallbackNeeded()) | 111 if (!vsyncCallbackNeeded()) |
112 return true; | 112 return true; |
113 return false; | 113 return false; |
114 } | 114 } |
115 | 115 |
116 CCSchedulerStateMachine::Action CCSchedulerStateMachine::nextAction() const | 116 SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const |
117 { | 117 { |
118 if (shouldAcquireLayerTexturesForMainThread()) | 118 if (shouldAcquireLayerTexturesForMainThread()) |
119 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; | 119 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; |
120 switch (m_commitState) { | 120 switch (m_commitState) { |
121 case COMMIT_STATE_IDLE: | 121 case COMMIT_STATE_IDLE: |
122 if (m_contextState != CONTEXT_ACTIVE && m_needsForcedRedraw) | 122 if (m_contextState != CONTEXT_ACTIVE && m_needsForcedRedraw) |
123 return ACTION_DRAW_FORCED; | 123 return ACTION_DRAW_FORCED; |
124 if (m_contextState != CONTEXT_ACTIVE && m_needsForcedCommit) | 124 if (m_contextState != CONTEXT_ACTIVE && m_needsForcedCommit) |
125 return ACTION_BEGIN_FRAME; | 125 return ACTION_BEGIN_FRAME; |
126 if (m_contextState == CONTEXT_LOST) | 126 if (m_contextState == CONTEXT_LOST) |
(...skipping 21 matching lines...) Expand all Loading... |
148 // or textures are not available, proceed to the next step (similar as i
n COMMIT_STATE_IDLE). | 148 // or textures are not available, proceed to the next step (similar as i
n COMMIT_STATE_IDLE). |
149 bool canCommit = m_visible || m_needsForcedCommit; | 149 bool canCommit = m_visible || m_needsForcedCommit; |
150 if (m_needsCommit && canCommit && drawSuspendedUntilCommit()) | 150 if (m_needsCommit && canCommit && drawSuspendedUntilCommit()) |
151 return ACTION_BEGIN_FRAME; | 151 return ACTION_BEGIN_FRAME; |
152 return ACTION_NONE; | 152 return ACTION_NONE; |
153 } | 153 } |
154 ASSERT_NOT_REACHED(); | 154 ASSERT_NOT_REACHED(); |
155 return ACTION_NONE; | 155 return ACTION_NONE; |
156 } | 156 } |
157 | 157 |
158 void CCSchedulerStateMachine::updateState(Action action) | 158 void SchedulerStateMachine::updateState(Action action) |
159 { | 159 { |
160 switch (action) { | 160 switch (action) { |
161 case ACTION_NONE: | 161 case ACTION_NONE: |
162 return; | 162 return; |
163 | 163 |
164 case ACTION_BEGIN_FRAME: | 164 case ACTION_BEGIN_FRAME: |
165 ASSERT(m_visible || m_needsForcedCommit); | 165 ASSERT(m_visible || m_needsForcedCommit); |
166 m_commitState = COMMIT_STATE_FRAME_IN_PROGRESS; | 166 m_commitState = COMMIT_STATE_FRAME_IN_PROGRESS; |
167 m_needsCommit = false; | 167 m_needsCommit = false; |
168 m_needsForcedCommit = false; | 168 m_needsForcedCommit = false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 | 203 |
204 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 204 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
205 m_textureState = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; | 205 m_textureState = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; |
206 m_mainThreadNeedsLayerTextures = false; | 206 m_mainThreadNeedsLayerTextures = false; |
207 if (m_commitState != COMMIT_STATE_FRAME_IN_PROGRESS) | 207 if (m_commitState != COMMIT_STATE_FRAME_IN_PROGRESS) |
208 m_needsCommit = true; | 208 m_needsCommit = true; |
209 return; | 209 return; |
210 } | 210 } |
211 } | 211 } |
212 | 212 |
213 void CCSchedulerStateMachine::setMainThreadNeedsLayerTextures() | 213 void SchedulerStateMachine::setMainThreadNeedsLayerTextures() |
214 { | 214 { |
215 ASSERT(!m_mainThreadNeedsLayerTextures); | 215 ASSERT(!m_mainThreadNeedsLayerTextures); |
216 ASSERT(m_textureState != LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); | 216 ASSERT(m_textureState != LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); |
217 m_mainThreadNeedsLayerTextures = true; | 217 m_mainThreadNeedsLayerTextures = true; |
218 } | 218 } |
219 | 219 |
220 bool CCSchedulerStateMachine::vsyncCallbackNeeded() const | 220 bool SchedulerStateMachine::vsyncCallbackNeeded() const |
221 { | 221 { |
222 // If we can't draw, don't tick until we are notified that we can draw again
. | 222 // If we can't draw, don't tick until we are notified that we can draw again
. |
223 if (!m_canDraw) | 223 if (!m_canDraw) |
224 return false; | 224 return false; |
225 | 225 |
226 if (m_needsForcedRedraw) | 226 if (m_needsForcedRedraw) |
227 return true; | 227 return true; |
228 | 228 |
229 return m_needsRedraw && m_visible && m_contextState == CONTEXT_ACTIVE; | 229 return m_needsRedraw && m_visible && m_contextState == CONTEXT_ACTIVE; |
230 } | 230 } |
231 | 231 |
232 void CCSchedulerStateMachine::didEnterVSync() | 232 void SchedulerStateMachine::didEnterVSync() |
233 { | 233 { |
234 m_insideVSync = true; | 234 m_insideVSync = true; |
235 } | 235 } |
236 | 236 |
237 void CCSchedulerStateMachine::didLeaveVSync() | 237 void SchedulerStateMachine::didLeaveVSync() |
238 { | 238 { |
239 m_currentFrameNumber++; | 239 m_currentFrameNumber++; |
240 m_insideVSync = false; | 240 m_insideVSync = false; |
241 } | 241 } |
242 | 242 |
243 void CCSchedulerStateMachine::setVisible(bool visible) | 243 void SchedulerStateMachine::setVisible(bool visible) |
244 { | 244 { |
245 m_visible = visible; | 245 m_visible = visible; |
246 } | 246 } |
247 | 247 |
248 void CCSchedulerStateMachine::setNeedsRedraw() | 248 void SchedulerStateMachine::setNeedsRedraw() |
249 { | 249 { |
250 m_needsRedraw = true; | 250 m_needsRedraw = true; |
251 } | 251 } |
252 | 252 |
253 void CCSchedulerStateMachine::setNeedsForcedRedraw() | 253 void SchedulerStateMachine::setNeedsForcedRedraw() |
254 { | 254 { |
255 m_needsForcedRedraw = true; | 255 m_needsForcedRedraw = true; |
256 } | 256 } |
257 | 257 |
258 void CCSchedulerStateMachine::didDrawIfPossibleCompleted(bool success) | 258 void SchedulerStateMachine::didDrawIfPossibleCompleted(bool success) |
259 { | 259 { |
260 m_drawIfPossibleFailed = !success; | 260 m_drawIfPossibleFailed = !success; |
261 if (m_drawIfPossibleFailed) { | 261 if (m_drawIfPossibleFailed) { |
262 m_needsRedraw = true; | 262 m_needsRedraw = true; |
263 m_needsCommit = true; | 263 m_needsCommit = true; |
264 m_consecutiveFailedDraws++; | 264 m_consecutiveFailedDraws++; |
265 if (m_consecutiveFailedDraws >= m_maximumNumberOfFailedDrawsBeforeDrawIs
Forced) { | 265 if (m_consecutiveFailedDraws >= m_maximumNumberOfFailedDrawsBeforeDrawIs
Forced) { |
266 m_consecutiveFailedDraws = 0; | 266 m_consecutiveFailedDraws = 0; |
267 // We need to force a draw, but it doesn't make sense to do this unt
il | 267 // We need to force a draw, but it doesn't make sense to do this unt
il |
268 // we've committed and have new textures. | 268 // we've committed and have new textures. |
269 m_needsForcedRedrawAfterNextCommit = true; | 269 m_needsForcedRedrawAfterNextCommit = true; |
270 } | 270 } |
271 } else | 271 } else |
272 m_consecutiveFailedDraws = 0; | 272 m_consecutiveFailedDraws = 0; |
273 } | 273 } |
274 | 274 |
275 void CCSchedulerStateMachine::setNeedsCommit() | 275 void SchedulerStateMachine::setNeedsCommit() |
276 { | 276 { |
277 m_needsCommit = true; | 277 m_needsCommit = true; |
278 } | 278 } |
279 | 279 |
280 void CCSchedulerStateMachine::setNeedsForcedCommit() | 280 void SchedulerStateMachine::setNeedsForcedCommit() |
281 { | 281 { |
282 m_needsForcedCommit = true; | 282 m_needsForcedCommit = true; |
283 } | 283 } |
284 | 284 |
285 void CCSchedulerStateMachine::beginFrameComplete() | 285 void SchedulerStateMachine::beginFrameComplete() |
286 { | 286 { |
287 ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS); | 287 ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS); |
288 m_commitState = COMMIT_STATE_READY_TO_COMMIT; | 288 m_commitState = COMMIT_STATE_READY_TO_COMMIT; |
289 } | 289 } |
290 | 290 |
291 void CCSchedulerStateMachine::beginFrameAborted() | 291 void SchedulerStateMachine::beginFrameAborted() |
292 { | 292 { |
293 ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS); | 293 ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS); |
294 m_commitState = COMMIT_STATE_IDLE; | 294 m_commitState = COMMIT_STATE_IDLE; |
295 setNeedsCommit(); | 295 setNeedsCommit(); |
296 } | 296 } |
297 | 297 |
298 void CCSchedulerStateMachine::didLoseContext() | 298 void SchedulerStateMachine::didLoseContext() |
299 { | 299 { |
300 if (m_contextState == CONTEXT_LOST || m_contextState == CONTEXT_RECREATING) | 300 if (m_contextState == CONTEXT_LOST || m_contextState == CONTEXT_RECREATING) |
301 return; | 301 return; |
302 m_contextState = CONTEXT_LOST; | 302 m_contextState = CONTEXT_LOST; |
303 } | 303 } |
304 | 304 |
305 void CCSchedulerStateMachine::didRecreateContext() | 305 void SchedulerStateMachine::didRecreateContext() |
306 { | 306 { |
307 ASSERT(m_contextState == CONTEXT_RECREATING); | 307 ASSERT(m_contextState == CONTEXT_RECREATING); |
308 m_contextState = CONTEXT_ACTIVE; | 308 m_contextState = CONTEXT_ACTIVE; |
309 setNeedsCommit(); | 309 setNeedsCommit(); |
310 } | 310 } |
311 | 311 |
312 void CCSchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced(in
t numDraws) | 312 void SchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced(int
numDraws) |
313 { | 313 { |
314 m_maximumNumberOfFailedDrawsBeforeDrawIsForced = numDraws; | 314 m_maximumNumberOfFailedDrawsBeforeDrawIsForced = numDraws; |
315 } | 315 } |
316 | 316 |
317 } | 317 } |
OLD | NEW |