Fix the RS frame timeout.
Previous a slow app would block from receiving new commands until the timer expired. This change will expire the timer immediatly. Change-Id: I42b949d21f98ee0f1d3156763cd723c3e9cabb67
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user