Merge change Id22c0137 into eclair

* changes:
  Throttle low priority RS threads by sleeping once per frame to avoid starving other apps.
This commit is contained in:
Android (Google) Code Review
2009-12-09 11:07:16 -08:00
5 changed files with 45 additions and 33 deletions

View File

@@ -113,14 +113,14 @@ void Context::deinitEGL()
} }
bool Context::runScript(Script *s, uint32_t launchID) uint32_t Context::runScript(Script *s, uint32_t launchID)
{ {
ObjectBaseRef<ProgramFragment> frag(mFragment); ObjectBaseRef<ProgramFragment> frag(mFragment);
ObjectBaseRef<ProgramVertex> vtx(mVertex); ObjectBaseRef<ProgramVertex> vtx(mVertex);
ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
ObjectBaseRef<ProgramRaster> raster(mRaster); ObjectBaseRef<ProgramRaster> raster(mRaster);
bool ret = s->run(this, launchID); uint32_t ret = s->run(this, launchID);
mFragment.set(frag); mFragment.set(frag);
mVertex.set(vtx); mVertex.set(vtx);
@@ -130,11 +130,9 @@ bool Context::runScript(Script *s, uint32_t launchID)
} }
bool Context::runRootScript() uint32_t Context::runRootScript()
{ {
if (props.mLogTimes) { timerSet(RS_TIMER_CLEAR_SWAP);
timerSet(RS_TIMER_CLEAR_SWAP);
}
rsAssert(mRootScript->mEnviroment.mIsRoot); rsAssert(mRootScript->mEnviroment.mIsRoot);
eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
@@ -154,11 +152,9 @@ bool Context::runRootScript()
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
if (this->props.mLogTimes) { timerSet(RS_TIMER_SCRIPT);
timerSet(RS_TIMER_SCRIPT);
}
mStateFragmentStore.mLast.clear(); mStateFragmentStore.mLast.clear();
bool ret = runScript(mRootScript.get(), 0); uint32_t ret = runScript(mRootScript.get(), 0);
GLenum err = glGetError(); GLenum err = glGetError();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
@@ -212,13 +208,19 @@ void Context::timerPrint()
total += mTimers[ct]; total += mTimers[ct];
} }
uint64_t frame = mTimeFrame - mTimeLastFrame; uint64_t frame = mTimeFrame - mTimeLastFrame;
mTimeMSLastFrame = frame / 1000000;
mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000;
mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000;
LOGV("RS: Frame (%lli), Script %2.1f (%lli), Clear & Swap %2.1f (%lli), Idle %2.1f (%lli), Internal %2.1f (%lli)",
frame / 1000000, if (props.mLogTimes) {
100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimers[RS_TIMER_SCRIPT] / 1000000, LOGV("RS: Frame (%i), Script %2.1f (%i), Clear & Swap %2.1f (%i), Idle %2.1f (%lli), Internal %2.1f (%lli)",
100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimers[RS_TIMER_CLEAR_SWAP] / 1000000, mTimeMSLastFrame,
100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000); 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000);
}
} }
void Context::setupCheck() void Context::setupCheck()
@@ -242,6 +244,7 @@ void * Context::threadProc(void *vrsc)
rsc->mNativeThreadId = gettid(); rsc->mNativeThreadId = gettid();
setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY); setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
rsc->props.mLogTimes = getProp("debug.rs.profile"); rsc->props.mLogTimes = getProp("debug.rs.profile");
rsc->props.mLogScripts = getProp("debug.rs.script"); rsc->props.mLogScripts = getProp("debug.rs.script");
@@ -279,22 +282,26 @@ void * Context::threadProc(void *vrsc)
mDraw &= (rsc->mRootScript.get() != NULL); mDraw &= (rsc->mRootScript.get() != NULL);
mDraw &= (rsc->mWndSurface != NULL); mDraw &= (rsc->mWndSurface != NULL);
uint32_t targetTime = 0;
if (mDraw) { if (mDraw) {
mDraw = rsc->runRootScript() && !rsc->mPaused; targetTime = rsc->runRootScript();
if (rsc->props.mLogTimes) { mDraw = targetTime && !rsc->mPaused;
rsc->timerSet(RS_TIMER_CLEAR_SWAP); rsc->timerSet(RS_TIMER_CLEAR_SWAP);
}
eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
if (rsc->props.mLogTimes) { rsc->timerFrame();
rsc->timerFrame(); rsc->timerSet(RS_TIMER_INTERNAL);
rsc->timerSet(RS_TIMER_INTERNAL); rsc->timerPrint();
rsc->timerPrint(); rsc->timerReset();
rsc->timerReset();
}
} }
if (rsc->mObjDestroy.mNeedToEmpty) { if (rsc->mObjDestroy.mNeedToEmpty) {
rsc->objDestroyOOBRun(); rsc->objDestroyOOBRun();
} }
if (rsc->mThreadPriority > 0 && targetTime) {
int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
if (t > 0) {
usleep(t);
}
}
} }
LOGV("RS Thread exiting"); LOGV("RS Thread exiting");
@@ -330,6 +337,7 @@ void Context::setPriority(int32_t p)
// the wallpapers can become completly unresponsive at times. // the wallpapers can become completly unresponsive at times.
// This is probably not what we want for something the user is actively // This is probably not what we want for something the user is actively
// looking at. // looking at.
mThreadPriority = p;
#if 0 #if 0
SchedPolicy pol = SP_FOREGROUND; SchedPolicy pol = SP_FOREGROUND;
if (p > 0) { if (p > 0) {

View File

@@ -105,7 +105,7 @@ public:
uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait); uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait);
bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace); bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace);
bool runScript(Script *s, uint32_t launchID); uint32_t runScript(Script *s, uint32_t launchID);
void initToClient(); void initToClient();
void deinitToClient(); void deinitToClient();
@@ -194,6 +194,7 @@ protected:
uint32_t mWidth; uint32_t mWidth;
uint32_t mHeight; uint32_t mHeight;
int32_t mThreadPriority;
bool mRunning; bool mRunning;
bool mExit; bool mExit;
@@ -226,7 +227,7 @@ private:
void initEGL(); void initEGL();
void deinitEGL(); void deinitEGL();
bool runRootScript(); uint32_t runRootScript();
static void * threadProc(void *); static void * threadProc(void *);
@@ -241,6 +242,9 @@ private:
uint64_t mTimeLast; uint64_t mTimeLast;
uint64_t mTimeFrame; uint64_t mTimeFrame;
uint64_t mTimeLastFrame; uint64_t mTimeLastFrame;
uint32_t mTimeMSLastFrame;
uint32_t mTimeMSLastScript;
uint32_t mTimeMSLastSwap;
}; };
} }

View File

@@ -70,7 +70,7 @@ public:
virtual void setupScript() = 0; virtual void setupScript() = 0;
virtual bool run(Context *, uint32_t launchID) = 0; virtual uint32_t run(Context *, uint32_t launchID) = 0;
}; };

View File

@@ -60,7 +60,7 @@ void ScriptC::setupScript()
} }
bool ScriptC::run(Context *rsc, uint32_t launchIndex) uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex)
{ {
Context::ScriptTLSStruct * tls = Context::ScriptTLSStruct * tls =
(Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
@@ -85,9 +85,9 @@ bool ScriptC::run(Context *rsc, uint32_t launchIndex)
} }
setupScript(); setupScript();
bool ret = false; uint32_t ret = 0;
tls->mScript = this; tls->mScript = this;
ret = mProgram.mScript(launchIndex) != 0; ret = mProgram.mScript(launchIndex);
tls->mScript = NULL; tls->mScript = NULL;
return ret; return ret;
} }

View File

@@ -55,7 +55,7 @@ public:
ACCscript* mAccScript; ACCscript* mAccScript;
virtual void setupScript(); virtual void setupScript();
virtual bool run(Context *, uint32_t launchID); virtual uint32_t run(Context *, uint32_t launchID);
}; };
class ScriptCState class ScriptCState