| 1212 | } // OutputSchedulerThread::stopRender |
| 1213 | |
| 1214 | GenericSchedulerThread::ThreadStateEnum |
| 1215 | OutputSchedulerThread::threadLoopOnce(const GenericThreadStartArgsPtr &inArgs) |
| 1216 | { |
| 1217 | OutputSchedulerThreadStartArgsPtr args = std::dynamic_pointer_cast<OutputSchedulerThreadStartArgs>(inArgs); |
| 1218 | |
| 1219 | assert(args); |
| 1220 | _imp->runArgs = args; |
| 1221 | |
| 1222 | ThreadStateEnum state = eThreadStateActive; |
| 1223 | int expectedTimeToRenderPreviousIteration = std::numeric_limits<int>::min(); |
| 1224 | |
| 1225 | // This is the number of time this thread was woken up by a render thread because a frame was available for processing, |
| 1226 | // but this is not the frame this thread expects to render. If it reaches a certain amount, we detected a stall and abort. |
| 1227 | int nbIterationsWithoutProcessing = 0; |
| 1228 | |
| 1229 | startRender(); |
| 1230 | |
| 1231 | for (;; ) { |
| 1232 | ///When set to true, we don't sleep in the bufEmptyCondition but in the startCondition instead, indicating |
| 1233 | ///we finished a render |
| 1234 | bool renderFinished = false; |
| 1235 | |
| 1236 | { |
| 1237 | ///_imp->renderFinished might be set when in FFA scheduling policy |
| 1238 | QMutexLocker l(&_imp->renderFinishedMutex); |
| 1239 | if (_imp->renderFinished) { |
| 1240 | renderFinished = true; |
| 1241 | } |
| 1242 | } |
| 1243 | bool bufferEmpty; |
| 1244 | { |
| 1245 | QMutexLocker l(&_imp->bufMutex); |
| 1246 | bufferEmpty = _imp->buf.empty(); |
| 1247 | } |
| 1248 | int expectedTimeToRender; |
| 1249 | |
| 1250 | |
| 1251 | while (!bufferEmpty) { |
| 1252 | state = resolveState(); |
| 1253 | if ( (state == eThreadStateAborted) || (state == eThreadStateStopped) ) { |
| 1254 | ///Do not wait in the buf wait condition and go directly into the stopEngine() |
| 1255 | renderFinished = true; |
| 1256 | break; |
| 1257 | } |
| 1258 | |
| 1259 | |
| 1260 | { |
| 1261 | QMutexLocker k(&_imp->framesToRenderMutex); |
| 1262 | expectedTimeToRender = _imp->expectFrameToRender; |
| 1263 | } |
| 1264 | |
| 1265 | #ifdef TRACE_SCHEDULER |
| 1266 | if ( (expectedTimeToRenderPreviousIteration == std::numeric_limits<int>::min()) || (expectedTimeToRenderPreviousIteration != expectedTimeToRender) ) { |
| 1267 | qDebug() << "Scheduler Thread: waiting for " << expectedTimeToRender << " to be rendered..."; |
| 1268 | } |
| 1269 | #endif |
| 1270 | if (expectedTimeToRenderPreviousIteration == expectedTimeToRender) { |
| 1271 | ++nbIterationsWithoutProcessing; |
nothing calls this directly
no test coverage detected