void wyDirector_android::backgroundLooper(wyTargetSelector* sel) { while(gDirector->m_backgroundRunning) { // process auto release pool wyClearAutoReleasePool(); // check frame rate setting, but neglect it if in screenshot mode #ifndef SCREENSHOT_MODE if(gDirector->m_maxFrameRate > 0) { int64_t now = wyUtils::currentTimeMillis(); gDirector->m_savedDelta += now - gDirector->m_lastFrameTime; gDirector->m_lastFrameTime = now; if(gDirector->m_savedDelta < gDirector->m_minFrameInterval) { // sleep to save power usleep((gDirector->m_minFrameInterval - gDirector->m_savedDelta) * 1000); // recalculate saved delta now = wyUtils::currentTimeMillis(); gDirector->m_savedDelta += now - gDirector->m_lastFrameTime; gDirector->m_lastFrameTime = now; gDirector->m_savedDelta %= gDirector->m_minFrameInterval; } else { gDirector->m_savedDelta %= gDirector->m_minFrameInterval; } } #endif // calculate global delta gDirector->calculateDeltaTime(); // update scheduler gScheduler->tickLocked(gDirector->m_delta); // update actions gActionManager->tick(gDirector->m_delta); } // notify anybody wait on m_backgroundRunning flag pthread_mutex_lock(&gCondMutex); gDirector->setMaxFrameRate(gDirector->m_originalMaxFrameRate); gDirector->setNextDeltaTimeZero(true); pthread_cond_signal(&sBackgroundLooperCond); pthread_mutex_unlock(&gCondMutex); }
void wyDirector::drawFrame() { // process auto release pool wyClearAutoReleasePool(); // check frame rate setting, but neglect it if in screenshot mode #ifndef WY_CFLAG_SCREENSHOT_MODE if(m_maxFrameRate > 0) { int64_t now = wyUtils::currentTimeMillis(); m_savedDelta += now - m_lastFrameTime; m_lastFrameTime = now; if(m_savedDelta < m_minFrameInterval) { // sleep to save power usleep((m_minFrameInterval - m_savedDelta) * 1000); // recalculate saved delta now = wyUtils::currentTimeMillis(); m_savedDelta += now - m_lastFrameTime; m_lastFrameTime = now; m_savedDelta %= m_minFrameInterval; } else { m_savedDelta %= m_minFrameInterval; } } #endif // need check texture? if(m_needCheckTexture) { gTextureManager->invalidateAllTextures(); m_needCheckTexture = false; } // set default state glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); // if we have next scene to set, reset delta time if(!m_UIPaused) { if(m_nextScene != NULL) { m_nextDeltaTimeZero = true; } } // calculate global delta calculateDeltaTime(); // if in screenshot mode, use 60fps always #ifdef WY_CFLAG_SCREENSHOT_MODE m_delta = 1.f / 60.f; #endif if (!m_UIPaused) { // update scheduler and actions if(!m_paused) { gScheduler->tickLocked(m_delta * m_tickFactor); } // to avoid flicker, nextScene MUST be here: after tick and before draw if(m_nextScene != NULL) { gotoNextScene(); } } if(!m_paused) { // draw the scene if(m_runningScene != NULL) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_runningScene->visit(); } /* * can't move action tick before visit running scene. sometimes the internal * state may not consistent because scheduler already updated before visit. * an example is: move a particle system with an action, can see particle system * shaked consistently. */ if(!m_UIPaused) gActionManager->tick(m_delta * m_tickFactor); #ifndef WY_CFLAG_SCREENSHOT_MODE // calcuate fps or not // but don't calculate fps if in screenshot mode if(m_calculateFPS) calculateFPS(); // show fps or not // but don't show fps if in screenshot mode if(m_displayFPS) showFPS(); // make screenshot if(m_makeScreenshot) { m_makeScreenshot = false; // make screenshot wyUtils::makeScreenshot(m_screenshotPath, m_screenshotRect); // notify notifyDirectorScreenCaptured(); // free path wyFree((void*)m_screenshotPath); m_screenshotPath = NULL; } #endif // #ifndef WY_CFLAG_SCREENSHOT_MODE } // make screenshot #ifdef WY_CFLAG_SCREENSHOT_MODE char fsPath[128]; sprintf(fsPath, "/sdcard/WiEngine/%06d.png", sScreenshotFrameIndex++); const char* path = wyUtils::mapLocalPath(fsPath); wyUtils::makeScreenshot(path); wyFree((void*)path); #endif // #ifdef WY_CFLAG_SCREENSHOT_MODE // process events gEventDispatcher->processEventsLocked(); }