diff options
Diffstat (limited to 'libs/rs')
| -rw-r--r-- | libs/rs/rsContext.cpp | 10 | ||||
| -rw-r--r-- | libs/rs/rsLocklessFifo.cpp | 97 | ||||
| -rw-r--r-- | libs/rs/rsLocklessFifo.h | 22 | ||||
| -rw-r--r-- | libs/rs/rsThreadIO.cpp | 5 | ||||
| -rw-r--r-- | libs/rs/rsThreadIO.h | 2 |
5 files changed, 112 insertions, 24 deletions
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 7248ecc..2a5f65d 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -130,14 +130,10 @@ void * Context::threadProc(void *vrsc) rsc->mRunning = true; bool mDraw = true; while (!rsc->mExit) { - mDraw |= gIO->playCoreCommands(rsc); + mDraw |= gIO->playCoreCommands(rsc, !mDraw); + mDraw &= (rsc->mRootScript.get() != NULL); - if (!mDraw || !rsc->mRootScript.get()) { - usleep(10000); - continue; - } - - if (rsc->mRootScript.get()) { + if (mDraw) { mDraw = rsc->runRootScript(); eglSwapBuffers(rsc->mDisplay, rsc->mSurface); } diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index 67ab434..37ec14b 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -37,16 +37,8 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes) return false; } - int status = pthread_mutex_init(&mMutex, NULL); - if (status) { - LOGE("LocklessFifo mutex init failure"); - free(mBuffer); - return false; - } - status = pthread_cond_init(&mCondition, NULL); - if (status) { - LOGE("LocklessFifo condition init failure"); - pthread_mutex_destroy(&mMutex); + if (!mSignalToControl.init() || !mSignalToWorker.init()) { + LOGE("Signal setup failed"); free(mBuffer); return false; } @@ -106,6 +98,7 @@ void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) mPut += ((sizeInBytes + 3) & ~3) + 4; //dumpState("commit 2"); + mSignalToWorker.set(); } void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) @@ -118,7 +111,7 @@ void LocklessCommandFifo::flush() { //dumpState("flush 1"); while(mPut != mGet) { - usleep(1); + mSignalToControl.wait(); } //dumpState("flush 2"); } @@ -126,8 +119,10 @@ void LocklessCommandFifo::flush() const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) { while(1) { + //dumpState("get"); while(isEmpty()) { - usleep(10); + mSignalToControl.set(); + mSignalToWorker.wait(); } //dumpState("get 3"); @@ -149,6 +144,9 @@ void LocklessCommandFifo::next() { uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1]; mGet += ((bytes + 3) & ~3) + 4; + if (isEmpty()) { + mSignalToControl.set(); + } //dumpState("next"); } @@ -179,4 +177,79 @@ void LocklessCommandFifo::dumpState(const char *s) const LOGE("%s put %p, get %p, buf %p, end %p", s, mPut, mGet, mBuffer, mEnd); } +LocklessCommandFifo::Signal::Signal() +{ + mSet = true; +} + +LocklessCommandFifo::Signal::~Signal() +{ + pthread_mutex_destroy(&mMutex); + pthread_cond_destroy(&mCondition); +} + +bool LocklessCommandFifo::Signal::init() +{ + int status = pthread_mutex_init(&mMutex, NULL); + if (status) { + LOGE("LocklessFifo mutex init failure"); + return false; + } + + status = pthread_cond_init(&mCondition, NULL); + if (status) { + LOGE("LocklessFifo condition init failure"); + pthread_mutex_destroy(&mMutex); + return false; + } + + return true; +} + +void LocklessCommandFifo::Signal::set() +{ + int status; + + status = pthread_mutex_lock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i locking for set condition.", status); + return; + } + + mSet = true; + + status = pthread_cond_signal(&mCondition); + if (status) { + LOGE("LocklessCommandFifo: error %i on set condition.", status); + } + + status = pthread_mutex_unlock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status); + } +} + +void LocklessCommandFifo::Signal::wait() +{ + int status; + + status = pthread_mutex_lock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i locking for condition.", status); + return; + } + + if (!mSet) { + status = pthread_cond_wait(&mCondition, &mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i waiting on condition.", status); + } + } + mSet = false; + + status = pthread_mutex_unlock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i unlocking for condition.", status); + } +} diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h index ddef382..2f4d5c5 100644 --- a/libs/rs/rsLocklessFifo.h +++ b/libs/rs/rsLocklessFifo.h @@ -41,14 +41,32 @@ public: protected: + class Signal { + public: + Signal(); + ~Signal(); + + bool init(); + + void set(); + void wait(); + + protected: + bool mSet; + pthread_mutex_t mMutex; + pthread_cond_t mCondition; + }; + uint8_t * volatile mPut; uint8_t * volatile mGet; uint8_t * mBuffer; uint8_t * mEnd; uint8_t mSize; - pthread_mutex_t mMutex; - pthread_cond_t mCondition; + Signal mSignalToWorker; + Signal mSignalToControl; + + public: void * reserve(uint32_t bytes); diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 23c808a..5641581 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -34,16 +34,17 @@ ThreadIO::~ThreadIO() { } -bool ThreadIO::playCoreCommands(Context *con) +bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { //LOGE("playCoreCommands 1"); uint32_t cmdID = 0; uint32_t cmdSize = 0; bool ret = false; - while(!mToCore.isEmpty()) { + while(!mToCore.isEmpty() || waitForCommand) { ret = true; //LOGE("playCoreCommands 2"); const void * data = mToCore.get(&cmdID, &cmdSize); + waitForCommand = false; //LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize); gPlaybackFuncs[cmdID](con, data); diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index ae2ffc0..973ee05 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 playCoreCommands(Context *con, bool waitForCommand); LocklessCommandFifo mToCore; |
