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.

This commit is contained in:
Jason Sams
2010-03-03 13:03:18 -08:00
parent a034cd3e15
commit 156cce6980
12 changed files with 99 additions and 10 deletions

View File

@@ -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

View File

@@ -36,6 +36,11 @@ ContextDump {
param int32_t bits
}
ContextGetError {
param RsError *err
ret const char *
}
ContextSetPriority {
param int32_t priority
}

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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];

View File

@@ -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]();
}

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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++;

View File

@@ -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;

View File

@@ -148,6 +148,9 @@ ID [a-zA-Z_][a-zA-Z0-9_]*
BEGIN(api_entry2);
}
<api_entry2>"*" {
currType->ptrLevel ++;
}
<api_entry2>"}" {
apiCount++;