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:
@@ -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
|
||||
|
||||
@@ -36,6 +36,11 @@ ContextDump {
|
||||
param int32_t bits
|
||||
}
|
||||
|
||||
ContextGetError {
|
||||
param RsError *err
|
||||
ret const char *
|
||||
}
|
||||
|
||||
ContextSetPriority {
|
||||
param int32_t priority
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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]();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -148,6 +148,9 @@ ID [a-zA-Z_][a-zA-Z0-9_]*
|
||||
BEGIN(api_entry2);
|
||||
}
|
||||
|
||||
<api_entry2>"*" {
|
||||
currType->ptrLevel ++;
|
||||
}
|
||||
|
||||
<api_entry2>"}" {
|
||||
apiCount++;
|
||||
|
||||
Reference in New Issue
Block a user