From 156cce698093023d9e79a4ff4fb96f4e4d3019db Mon Sep 17 00:00:00 2001 From: Jason Sams Date: Wed, 3 Mar 2010 13:03:18 -0800 Subject: [PATCH] Improve RS error handling. On errors RS will now store the error and a message that can be read from the app. RS will then not continue rendering frames while an unchecked error is present until new state is received. --- libs/rs/RenderScript.h | 6 ++++++ libs/rs/rs.spec | 5 +++++ libs/rs/rsContext.cpp | 42 +++++++++++++++++++++++++++++++++++++-- libs/rs/rsContext.h | 6 +++++- libs/rs/rsProgram.cpp | 3 +++ libs/rs/rsProgram.h | 3 +++ libs/rs/rsScript.cpp | 4 ++++ libs/rs/rsScriptC.cpp | 9 ++++++++- libs/rs/rsScriptC_Lib.cpp | 24 ++++++++++++++++------ libs/rs/rsShaderCache.cpp | 3 +++ libs/rs/rsShaderCache.h | 1 + libs/rs/spec.l | 3 +++ 12 files changed, 99 insertions(+), 10 deletions(-) diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index cd8361cfd6fe6..d280f5053b037 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -202,6 +202,12 @@ enum RsPrimitive { RS_PRIMITIVE_TRIANGLE_FAN }; +enum RsError { + RS_ERROR_NONE, + RS_ERROR_BAD_SHADER, + RS_ERROR_BAD_SCRIPT +}; + #ifndef NO_RS_FUNCS #include "rsgApiFuncDecl.h" #endif diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 4d97c0fd7506f..cb9937c785a73 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -36,6 +36,11 @@ ContextDump { param int32_t bits } +ContextGetError { + param RsError *err + ret const char * + } + ContextSetPriority { param int32_t priority } diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index cc3a74fb75d0d..d8a9a997b9dfe 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -178,6 +178,11 @@ uint32_t Context::runRootScript() uint32_t ret = runScript(mRootScript.get(), 0); checkError("runRootScript"); + if (mError != RS_ERROR_NONE) { + // If we have an error condition we stop rendering until + // somthing changes that might fix it. + ret = 0; + } return ret; } @@ -240,10 +245,13 @@ void Context::timerPrint() } } -void Context::setupCheck() +bool Context::setupCheck() { if (checkVersion2_0()) { - mShaderCache.lookup(this, mVertex.get(), mFragment.get()); + if (!mShaderCache.lookup(this, mVertex.get(), mFragment.get())) { + LOGE("Context::setupCheck() 1 fail"); + return false; + } mFragmentStore->setupGL2(this, &mStateFragmentStore); mFragment->setupGL2(this, &mStateFragment, &mShaderCache); @@ -256,6 +264,7 @@ void Context::setupCheck() mRaster->setupGL(this, &mStateRaster); mVertex->setupGL(this, &mStateVertex); } + return true; } static bool getProp(const char *str) @@ -389,6 +398,9 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth) mUseDepth = useDepth; mPaused = false; mObjHead = NULL; + mError = RS_ERROR_NONE; + mErrorMsg = NULL; + memset(&mEGL, 0, sizeof(mEGL)); memset(&mGL, 0, sizeof(mGL)); mIsGraphicsContext = isGraphics; @@ -764,6 +776,23 @@ void Context::deinitToClient() mIO.mToClient.shutdown(); } +const char * Context::getError(RsError *err) +{ + *err = mError; + mError = RS_ERROR_NONE; + if (*err != RS_ERROR_NONE) { + return mErrorMsg; + } + return NULL; +} + +void Context::setError(RsError e, const char *msg) +{ + mError = e; + mErrorMsg = msg; +} + + void Context::dumpDebug() const { LOGE("RS Context debug %p", this); @@ -874,6 +903,15 @@ void rsi_ContextDump(Context *rsc, int32_t bits) ObjectBase::dumpAll(rsc); } +const char * rsi_ContextGetError(Context *rsc, RsError *e) +{ + const char *msg = rsc->getError(e); + if (*e != RS_ERROR_NONE) { + LOGE("RS Error %i %s", *e, msg); + } + return msg; +} + } } diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 04bd748679f7b..82c368747cc5e 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -93,7 +93,7 @@ public: const ProgramRaster * getRaster() {return mRaster.get();} const ProgramVertex * getVertex() {return mVertex.get();} - void setupCheck(); + bool setupCheck(); bool checkDriver() const {return mEGL.mSurface != 0;} void pause(); @@ -160,6 +160,8 @@ public: void dumpDebug() const; void checkError(const char *) const; + const char * getError(RsError *); + void setError(RsError e, const char *msg); mutable const ObjectBase * mObjHead; @@ -211,6 +213,8 @@ protected: bool mExit; bool mUseDepth; bool mPaused; + RsError mError; + const char *mErrorMsg; pthread_t mThreadId; pid_t mNativeThreadId; diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 656a3c3395298..478a6dcbcc210 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -39,6 +39,7 @@ Program::Program(Context *rsc) : ObjectBase(rsc) mInputCount = 0; mOutputCount = 0; mConstantCount = 0; + mIsValid = false; } Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, @@ -216,6 +217,7 @@ bool Program::loadShader(Context *rsc, uint32_t type) } glDeleteShader(mShaderID); mShaderID = 0; + rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,"); return false; } } @@ -224,6 +226,7 @@ bool Program::loadShader(Context *rsc, uint32_t type) if (rsc->props.mLogShaders) { LOGV("--Shader load result %x ", glGetError()); } + mIsValid = true; return true; } diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index a34e89fa40ffd..86f85fb70e48d 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -59,6 +59,8 @@ public: String8 getGLSLOutputString() const; String8 getGLSLConstantString() const; + bool isValid() const {return mIsValid;} + protected: // Components not listed in "in" will be passed though // unless overwritten by components in out. @@ -68,6 +70,7 @@ protected: uint32_t mInputCount; uint32_t mOutputCount; uint32_t mConstantCount; + bool mIsValid; ObjectBaseRef mConstants[MAX_UNIFORMS]; diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp index cb1436b0bacde..a33933b689c85 100644 --- a/libs/rs/rsScript.cpp +++ b/libs/rs/rsScript.cpp @@ -96,6 +96,10 @@ void rsi_ScriptSetInvoke(Context *rsc, const char *name, uint32_t slot) void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) { Script *s = static_cast