summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2010-03-03 13:03:18 -0800
committerJason Sams <rjsams@android.com>2010-03-03 14:14:37 -0800
commit156cce698093023d9e79a4ff4fb96f4e4d3019db (patch)
treeff5ce34e453d2f475bcab35d29f5a7d00d53554d
parenta034cd3e15b6626be03e60f2d6a0f929dcb950d9 (diff)
downloadframeworks_base-156cce698093023d9e79a4ff4fb96f4e4d3019db.zip
frameworks_base-156cce698093023d9e79a4ff4fb96f4e4d3019db.tar.gz
frameworks_base-156cce698093023d9e79a4ff4fb96f4e4d3019db.tar.bz2
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.
-rw-r--r--libs/rs/RenderScript.h6
-rw-r--r--libs/rs/rs.spec5
-rw-r--r--libs/rs/rsContext.cpp42
-rw-r--r--libs/rs/rsContext.h6
-rw-r--r--libs/rs/rsProgram.cpp3
-rw-r--r--libs/rs/rsProgram.h3
-rw-r--r--libs/rs/rsScript.cpp4
-rw-r--r--libs/rs/rsScriptC.cpp9
-rw-r--r--libs/rs/rsScriptC_Lib.cpp24
-rw-r--r--libs/rs/rsShaderCache.cpp3
-rw-r--r--libs/rs/rsShaderCache.h1
-rw-r--r--libs/rs/spec.l3
12 files changed, 99 insertions, 10 deletions
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index cd8361c..d280f50 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 4d97c0f..cb9937c 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 cc3a74f..d8a9a99 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 04bd748..82c3687 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 656a3c3..478a6dc 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 a34e89f..86f85fb 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<Allocation> mConstants[MAX_UNIFORMS];
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index cb1436b..a33933b 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<Script *>(vs);
+ if (s->mEnviroment.mInvokables[slot] == NULL) {
+ rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script");
+ return;
+ }
s->setupScript();
s->mEnviroment.mInvokables[slot]();
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index b7e0b86..1f23773 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -62,6 +62,11 @@ void ScriptC::setupScript()
uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex)
{
+ if (mProgram.mScript == NULL) {
+ rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script");
+ return 0;
+ }
+
Context::ScriptTLSStruct * tls =
(Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
rsAssert(tls);
@@ -154,7 +159,9 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
ACCchar buf[4096];
ACCsizei len;
accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf);
- LOGV(buf);
+ LOGE(buf);
+ rsc->setError(RS_ERROR_BAD_SCRIPT, "Error compiling user script.");
+ return;
}
if (s->mProgram.mInit) {
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 235c153..202ca3d 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -683,7 +683,9 @@ static void SC_drawLine(float x1, float y1, float z1,
float x2, float y2, float z2)
{
GET_TLS();
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
float vtx[] = { x1, y1, z1, x2, y2, z2 };
VertexArray va;
@@ -700,7 +702,9 @@ static void SC_drawLine(float x1, float y1, float z1,
static void SC_drawPoint(float x, float y, float z)
{
GET_TLS();
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
float vtx[] = { x, y, z };
@@ -725,7 +729,9 @@ static void SC_drawQuadTexCoords(float x1, float y1, float z1,
float u4, float v4)
{
GET_TLS();
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
//LOGE("Quad");
//LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
@@ -782,7 +788,9 @@ static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w,
float cx0, float cy0, float cx1, float cy1)
{
GET_TLS();
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
GLint crop[4] = {cx0, cy0, cx1, cy1};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
@@ -831,7 +839,9 @@ static void SC_drawSimpleMesh(RsSimpleMesh vsm)
{
GET_TLS();
SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
sm->render(rsc);
}
@@ -839,7 +849,9 @@ static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t le
{
GET_TLS();
SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
- rsc->setupCheck();
+ if (!rsc->setupCheck()) {
+ return;
+ }
sm->renderRange(rsc, start, len);
}
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp
index 3a1f370..4711d1b 100644
--- a/libs/rs/rsShaderCache.cpp
+++ b/libs/rs/rsShaderCache.cpp
@@ -123,6 +123,8 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
}
}
glDeleteProgram(pgm);
+ rsc->setError(RS_ERROR_BAD_SHADER, "Error linking GL Programs");
+ return false;
}
if (vtx->isUserProgram()) {
for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) {
@@ -146,6 +148,7 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
}
}
+ e->mIsValid = true;
//LOGV("SC made program %i", e->program);
glUseProgram(e->program);
mEntryCount++;
diff --git a/libs/rs/rsShaderCache.h b/libs/rs/rsShaderCache.h
index 7aa8183..df99ccc 100644
--- a/libs/rs/rsShaderCache.h
+++ b/libs/rs/rsShaderCache.h
@@ -56,6 +56,7 @@ protected:
int32_t mFragAttribSlots[Program::MAX_ATTRIBS];
int32_t mFragUniformSlots[Program::MAX_UNIFORMS];
bool mUserVertexProgram;
+ bool mIsValid;
} entry_t;
entry_t *mEntries;
entry_t *mCurrent;
diff --git a/libs/rs/spec.l b/libs/rs/spec.l
index d81d47e..6a9010fe 100644
--- a/libs/rs/spec.l
+++ b/libs/rs/spec.l
@@ -148,6 +148,9 @@ ID [a-zA-Z_][a-zA-Z0-9_]*
BEGIN(api_entry2);
}
+<api_entry2>"*" {
+ currType->ptrLevel ++;
+ }
<api_entry2>"}" {
apiCount++;