diff options
Diffstat (limited to 'libs/rs')
-rw-r--r-- | libs/rs/rsContext.cpp | 26 | ||||
-rw-r--r-- | libs/rs/rsLocklessFifo.cpp | 14 | ||||
-rw-r--r-- | libs/rs/rsLocklessFifo.h | 4 | ||||
-rw-r--r-- | libs/rs/rsSignal.cpp | 29 | ||||
-rw-r--r-- | libs/rs/rsSignal.h | 5 | ||||
-rw-r--r-- | libs/rs/rsThreadIO.cpp | 16 | ||||
-rw-r--r-- | libs/rs/rsThreadIO.h | 2 |
7 files changed, 67 insertions, 29 deletions
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 6a30b17..bffe3c0 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -245,20 +245,32 @@ void * Context::threadProc(void *vrsc) { rsc->mRunning = true; bool mDraw = true; + bool doWait = true; + + uint64_t targetTime = rsc->getTime(); while (!rsc->mExit) { - mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw); + uint64_t waitTime = 0; + uint64_t now = rsc->getTime(); + if (now < targetTime) { + waitTime = targetTime - now; + } else { + doWait = false; + } + + mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime); mDraw &= (rsc->mRootScript.get() != NULL); mDraw &= rsc->mHasSurface; - uint32_t targetTime = 0; if (mDraw && rsc->mIsGraphicsContext) { - targetTime = rsc->runRootScript(); + uint64_t delay = rsc->runRootScript() * 1000000; + targetTime = rsc->getTime() + delay; + doWait = delay != 0; if (rsc->props.mLogVisual) { rsc->displayDebugStats(); } - mDraw = targetTime && !rsc->mPaused; + mDraw = !rsc->mPaused; rsc->timerSet(RS_TIMER_CLEAR_SWAP); rsc->mHal.funcs.swap(rsc); rsc->timerFrame(); @@ -266,12 +278,6 @@ void * Context::threadProc(void *vrsc) { rsc->timerPrint(); rsc->timerReset(); } - if (targetTime > 1) { - int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000; - if (t > 0) { - usleep(t); - } - } } LOGV("%p, RS Thread exiting", rsc); diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index 7023a1f..02a76ab 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -129,21 +129,23 @@ void LocklessCommandFifo::flush() { //dumpState("flush 2"); } -void LocklessCommandFifo::wait() { +bool LocklessCommandFifo::wait(uint64_t timeout) { while (isEmpty() && !mInShutdown) { mSignalToControl.set(); - mSignalToWorker.wait(); + return mSignalToWorker.wait(timeout); } + return true; } -const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) { +const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData, uint64_t timeout) { while (1) { //dumpState("get"); - wait(); - if (mInShutdown) { + wait(timeout); + + if (isEmpty() || mInShutdown) { *command = 0; *bytesData = 0; - return 0; + return NULL; } *command = reinterpret_cast<const uint16_t *>(mGet)[0]; diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h index eabdc3e..4962ef6 100644 --- a/libs/rs/rsLocklessFifo.h +++ b/libs/rs/rsLocklessFifo.h @@ -57,9 +57,9 @@ public: void commitSync(uint32_t command, uint32_t bytes); void flush(); - void wait(); + bool wait(uint64_t timeout = 0); - const void * get(uint32_t *command, uint32_t *bytesData); + const void * get(uint32_t *command, uint32_t *bytesData, uint64_t timeout = 0); void next(); void makeSpace(uint32_t bytes); diff --git a/libs/rs/rsSignal.cpp b/libs/rs/rsSignal.cpp index ccd20b9..413ac2b 100644 --- a/libs/rs/rsSignal.cpp +++ b/libs/rs/rsSignal.cpp @@ -68,26 +68,43 @@ void Signal::set() { } } -void Signal::wait() { +bool Signal::wait(uint64_t timeout) { int status; + bool ret = false; status = pthread_mutex_lock(&mMutex); if (status) { LOGE("LocklessCommandFifo: error %i locking for condition.", status); - return; + return false; } if (!mSet) { - status = pthread_cond_wait(&mCondition, &mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i waiting on condition.", status); + if (!timeout) { + status = pthread_cond_wait(&mCondition, &mMutex); + } else { +#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) + status = pthread_cond_timeout_np(&mCondition, &mMutex, timeout / 1000000); +#else + // This is safe it will just make things less reponsive + status = pthread_cond_wait(&mCondition, &mMutex); +#endif + } + } + + if (!status) { + mSet = false; + ret = true; + } else { + if (status != ETIMEDOUT) { + LOGE("LocklessCommandFifo: error %i waiting for condition.", status); } } - mSet = false; status = pthread_mutex_unlock(&mMutex); if (status) { LOGE("LocklessCommandFifo: error %i unlocking for condition.", status); } + + return ret; } diff --git a/libs/rs/rsSignal.h b/libs/rs/rsSignal.h index 2e760f1..fc31883 100644 --- a/libs/rs/rsSignal.h +++ b/libs/rs/rsSignal.h @@ -31,7 +31,10 @@ public: bool init(); void set(); - void wait(); + + // returns true if the signal occured + // false for timeout + bool wait(uint64_t timeout = 0); protected: bool mSet; diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 1c8b89c..fe2c52e 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -113,8 +113,10 @@ void ThreadIO::coreGetReturn(void *data, size_t dataLen) { } -bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { +bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait) { bool ret = false; + uint64_t startTime = con->getTime(); + while (!mToCore.isEmpty() || waitForCommand) { uint32_t cmdID = 0; uint32_t cmdSize = 0; @@ -122,9 +124,17 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { if (con->props.mLogTimes) { con->timerSet(Context::RS_TIMER_IDLE); } - const void * data = mToCore.get(&cmdID, &cmdSize); + + uint64_t delay = 0; + if (waitForCommand) { + delay = timeToWait - (con->getTime() - startTime); + if (delay > timeToWait) { + delay = 0; + } + } + const void * data = mToCore.get(&cmdID, &cmdSize, delay); if (!cmdSize) { - // exception occured, probably shutdown. + // exception or timeout occurred. return false; } if (con->props.mLogTimes) { diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index cad7318..9036118 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -37,7 +37,7 @@ public: // Plays back commands from the client. // Returns true if any commands were processed. - bool playCoreCommands(Context *con, bool waitForCommand); + bool playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait); //LocklessCommandFifo mToCore; |