opengl emulator: Added gl error tracking on the guest (encoder)
Sometimes we need to check parameter values before encoding to prevent crashes, for example: glDeleteBufferes(-1, ptr); - would crash For that we need to check some gl errors on the guest. The change adds error state to the encoder and also adds new feature to emugen which allows to insert parameter check code into the attribute file. Added such parameter check code in the appropiate gl functions in gl.attrib and gl2.attrib Change-Id: I7f317df52ac8fbd96979100a1031cf023a0b49d3
This commit is contained in:
committed by
Guy Zadickario
parent
dd3849c9ed
commit
d6f18cdf80
@@ -165,6 +165,12 @@ int ApiGen::genContext(const std::string & filename, SideType side)
|
||||
// init function
|
||||
fprintf(fp, "\tint initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);\n");
|
||||
|
||||
//client site set error virtual func
|
||||
if (side == CLIENT_SIDE) {
|
||||
fprintf(fp, "\tvirtual void setError(unsigned int error){};\n");
|
||||
fprintf(fp, "\tvirtual unsigned int getError(){ return 0; };\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "};\n");
|
||||
|
||||
fprintf(fp, "\n#endif\n");
|
||||
@@ -222,6 +228,13 @@ int ApiGen::genEntryPoints(const std::string & filename, SideType side)
|
||||
|
||||
bool shouldReturn = !e->retval().isVoid();
|
||||
bool shouldCallWithContext = (side == CLIENT_SIDE);
|
||||
//param check
|
||||
if (shouldCallWithContext) {
|
||||
for (size_t j=0; j<e->vars().size(); j++) {
|
||||
if (e->vars()[j].paramCheckExpression() != "")
|
||||
fprintf(fp, "\t%s\n", e->vars()[j].paramCheckExpression().c_str());
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\t %sctx->%s(%s",
|
||||
shouldReturn ? "return " : "",
|
||||
e->name().c_str(),
|
||||
|
||||
@@ -225,6 +225,24 @@ int EntryPoint::setAttribute(const std::string &line, size_t lc)
|
||||
// set the size expression into var
|
||||
pos = last;
|
||||
v->setLenExpression(line.substr(pos));
|
||||
} else if (token == "param_check") {
|
||||
pos = last;
|
||||
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
|
||||
|
||||
if (varname.size() == 0) {
|
||||
fprintf(stderr, "ERROR: %u: Missing variable name in 'param_check' attribute\n", (unsigned int)lc);
|
||||
return -1;
|
||||
}
|
||||
Var * v = var(varname);
|
||||
if (v == NULL) {
|
||||
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
|
||||
(unsigned int)lc, varname.c_str(), name().c_str());
|
||||
return -2;
|
||||
}
|
||||
// set the size expression into var
|
||||
pos = last;
|
||||
v->setParamCheckExpression(line.substr(pos));
|
||||
|
||||
} else if (token == "dir") {
|
||||
pos = last;
|
||||
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
|
||||
|
||||
@@ -30,7 +30,8 @@ public:
|
||||
m_lenExpression(""),
|
||||
m_pointerDir(POINTER_IN),
|
||||
m_nullAllowed(false),
|
||||
m_packExpression("")
|
||||
m_packExpression(""),
|
||||
m_paramCheckExpression("")
|
||||
|
||||
{
|
||||
}
|
||||
@@ -45,7 +46,8 @@ public:
|
||||
m_lenExpression(lenExpression),
|
||||
m_pointerDir(dir),
|
||||
m_nullAllowed(false),
|
||||
m_packExpression(packExpression)
|
||||
m_packExpression(packExpression),
|
||||
m_paramCheckExpression("")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,8 +69,10 @@ public:
|
||||
bool isVoid() const { return ((m_type->bytes() == 0) && (!m_type->isPointer())); }
|
||||
const std::string & lenExpression() const { return m_lenExpression; }
|
||||
const std::string & packExpression() const { return(m_packExpression); }
|
||||
const std::string & paramCheckExpression() const { return m_paramCheckExpression; }
|
||||
void setLenExpression(const std::string & lenExpression) { m_lenExpression = lenExpression; }
|
||||
void setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; }
|
||||
void setParamCheckExpression(const std::string & paramCheckExpression) { m_paramCheckExpression = paramCheckExpression; }
|
||||
void setPointerDir(PointerDir dir) { m_pointerDir = dir; }
|
||||
PointerDir pointerDir() { return m_pointerDir; }
|
||||
void setNullAllowed(bool state) { m_nullAllowed = state; }
|
||||
@@ -84,6 +88,7 @@ private:
|
||||
PointerDir m_pointerDir;
|
||||
bool m_nullAllowed;
|
||||
std::string m_packExpression; // an expression to pack data into the stream
|
||||
std::string m_paramCheckExpression; //an expression to check parameter value
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -48,4 +48,15 @@ typedef char *GLstr;
|
||||
/* JR XXX Treating this as an in handle - is this correct? */
|
||||
typedef void * GLeglImageOES;
|
||||
|
||||
/* ErrorCode */
|
||||
#ifndef GL_INVALID_ENUM
|
||||
#define GL_NO_ERROR 0
|
||||
#define GL_INVALID_ENUM 0x0500
|
||||
#define GL_INVALID_VALUE 0x0501
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
#define GL_STACK_OVERFLOW 0x0503
|
||||
#define GL_STACK_UNDERFLOW 0x0504
|
||||
#define GL_OUT_OF_MEMORY 0x0505
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,18 @@ static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this poin
|
||||
return ret; \
|
||||
}
|
||||
|
||||
GLenum GLEncoder::s_glGetError(void * self)
|
||||
{
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
GLenum err = ctx->getError();
|
||||
if(err != GL_NO_ERROR) {
|
||||
ctx->setError(GL_NO_ERROR);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ctx->m_glGetError_enc(self);
|
||||
|
||||
}
|
||||
|
||||
GLint * GLEncoder::getCompressedTextureFormats()
|
||||
{
|
||||
@@ -453,6 +465,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
|
||||
{
|
||||
m_initialized = false;
|
||||
m_state = NULL;
|
||||
m_error = GL_NO_ERROR;
|
||||
m_num_compressedTextureFormats = 0;
|
||||
m_compressedTextureFormats = NULL;
|
||||
// overrides;
|
||||
@@ -481,6 +494,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
|
||||
m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
|
||||
set_glGetString(s_glGetString);
|
||||
set_glFinish(s_glFinish);
|
||||
m_glGetError_enc = set_glGetError(s_glGetError);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,16 +34,21 @@ public:
|
||||
void setInitialized(){ m_initialized = true; };
|
||||
bool isInitialized(){ return m_initialized; };
|
||||
|
||||
virtual void setError(GLenum error){ m_error = error; };
|
||||
virtual GLenum getError() { return m_error; };
|
||||
|
||||
private:
|
||||
|
||||
bool m_initialized;
|
||||
GLClientState *m_state;
|
||||
GLenum m_error;
|
||||
FixedBuffer m_fixedBuffer;
|
||||
GLint *m_compressedTextureFormats;
|
||||
GLint m_num_compressedTextureFormats;
|
||||
|
||||
GLint *getCompressedTextureFormats();
|
||||
// original functions;
|
||||
glGetError_client_proc_t m_glGetError_enc;
|
||||
glGetIntegerv_client_proc_t m_glGetIntegerv_enc;
|
||||
glGetFloatv_client_proc_t m_glGetFloatv_enc;
|
||||
glGetFixedv_client_proc_t m_glGetFixedv_enc;
|
||||
@@ -69,6 +74,7 @@ private:
|
||||
glFlush_client_proc_t m_glFlush_enc;
|
||||
|
||||
// statics
|
||||
static GLenum s_glGetError(void * self);
|
||||
static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
|
||||
static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr);
|
||||
static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr);
|
||||
|
||||
@@ -99,10 +99,12 @@ glCompressedTexSubImage2D
|
||||
#void glDeleteBuffers(GLsizei n, GLuint *buffers)
|
||||
glDeleteBuffers
|
||||
len buffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDeleteTextures(GLsizei n, GLuint *textures)
|
||||
glDeleteTextures
|
||||
len textures (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#this function is marked as unsupported - it shouldn't be called directly
|
||||
#instead it translated into - glDrawDirectElements and glDrawIndirectElements
|
||||
@@ -129,11 +131,13 @@ glGetBufferParameteriv
|
||||
glGenBuffers
|
||||
len buffers (n * sizeof(GLuint))
|
||||
dir buffers out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenTextures(GLsizei n, GLuint *textures)
|
||||
glGenTextures
|
||||
len textures (n * sizeof(GLuint))
|
||||
dir textures out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGetFixedv(GLenum pname, GLfixed *params)
|
||||
glGetFixedv
|
||||
@@ -465,11 +469,13 @@ glTexParameterxvOES
|
||||
glDeleteRenderbuffersOES
|
||||
dir renderbuffers in
|
||||
len renderbuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
|
||||
glGenRenderbuffersOES
|
||||
dir renderbuffers in
|
||||
len renderbuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
|
||||
glGetRenderbufferParameterivOES
|
||||
@@ -480,11 +486,13 @@ glGetRenderbufferParameterivOES
|
||||
glDeleteFramebuffersOES
|
||||
dir framebuffers in
|
||||
len framebuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
|
||||
glGenFramebuffersOES
|
||||
dir framebuffers out
|
||||
len framebuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params)
|
||||
glGetFramebufferAttachmentParameterivOES
|
||||
@@ -559,11 +567,13 @@ glGetTexGenxvOES
|
||||
glDeleteVertexArraysOES
|
||||
dir arrays in
|
||||
len arrays (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
|
||||
glGenVertexArraysOES
|
||||
dir arrays out
|
||||
len arrays (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
|
||||
glDiscardFramebufferEXT
|
||||
@@ -590,11 +600,13 @@ glMultiDrawElementsSUN
|
||||
glDeleteFencesNV
|
||||
dir fences in
|
||||
len fences (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenFencesNV(GLsizei n, GLuint *fences)
|
||||
glGenFencesNV
|
||||
dir fences in
|
||||
len fences (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
|
||||
glGetFenceivNV
|
||||
|
||||
@@ -11,6 +11,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
|
||||
{
|
||||
m_initialized = false;
|
||||
m_state = NULL;
|
||||
m_error = GL_NO_ERROR;
|
||||
m_num_compressedTextureFormats = 0;
|
||||
m_compressedTextureFormats = NULL;
|
||||
//overrides
|
||||
@@ -31,6 +32,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
|
||||
m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
|
||||
set_glShaderSource(s_glShaderSource);
|
||||
set_glFinish(s_glFinish);
|
||||
m_glGetError_enc = set_glGetError(s_glGetError);
|
||||
}
|
||||
|
||||
GL2Encoder::~GL2Encoder()
|
||||
@@ -38,6 +40,19 @@ GL2Encoder::~GL2Encoder()
|
||||
delete m_compressedTextureFormats;
|
||||
}
|
||||
|
||||
GLenum GL2Encoder::s_glGetError(void * self)
|
||||
{
|
||||
GL2Encoder *ctx = (GL2Encoder *)self;
|
||||
GLenum err = ctx->getError();
|
||||
if(err != GL_NO_ERROR) {
|
||||
ctx->setError(GL_NO_ERROR);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ctx->m_glGetError_enc(self);
|
||||
|
||||
}
|
||||
|
||||
void GL2Encoder::s_glFlush(void *self)
|
||||
{
|
||||
GL2Encoder *ctx = (GL2Encoder *) self;
|
||||
|
||||
@@ -37,10 +37,14 @@ public:
|
||||
void setInitialized(){ m_initialized = true; };
|
||||
bool isInitialized(){ return m_initialized; };
|
||||
|
||||
virtual void setError(GLenum error){ m_error = error; };
|
||||
virtual GLenum getError() { return m_error; };
|
||||
|
||||
private:
|
||||
|
||||
bool m_initialized;
|
||||
GLClientState *m_state;
|
||||
GLenum m_error;
|
||||
|
||||
GLint *m_compressedTextureFormats;
|
||||
GLint m_num_compressedTextureFormats;
|
||||
@@ -50,6 +54,9 @@ private:
|
||||
|
||||
void sendVertexAttributes(GLint first, GLsizei count);
|
||||
|
||||
glGetError_client_proc_t m_glGetError_enc;
|
||||
static GLenum s_glGetError(void * self);
|
||||
|
||||
glFlush_client_proc_t m_glFlush_enc;
|
||||
static void s_glFlush(void * self);
|
||||
|
||||
|
||||
@@ -26,18 +26,22 @@ glCompressedTexSubImage2D
|
||||
#void glDeleteBuffers(GLsizei n, GLuint *buffers)
|
||||
glDeleteBuffers
|
||||
len buffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers)
|
||||
glDeleteFramebuffers
|
||||
len framebuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers)
|
||||
glDeleteRenderbuffers
|
||||
len renderbuffers (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDeleteTextures(GLsizei n, GLuint *textures)
|
||||
glDeleteTextures
|
||||
len textures (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices)
|
||||
glDrawElements
|
||||
@@ -47,21 +51,25 @@ glDrawElements
|
||||
glGenBuffers
|
||||
len buffers (n * sizeof(GLuint))
|
||||
dir buffers out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenFramebuffers(GLsizei n, GLuint *framebuffers)
|
||||
glGenFramebuffers
|
||||
len framebuffers (n * sizeof(GLuint))
|
||||
dir framebuffers out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
|
||||
glGenRenderbuffers
|
||||
len renderbuffers (n * sizeof(GLuint))
|
||||
dir renderbuffers out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenTextures(GLsizei n, GLuint *textures)
|
||||
glGenTextures
|
||||
len textures (n * sizeof(GLuint))
|
||||
dir textures out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
|
||||
glGetActiveAttrib
|
||||
@@ -330,11 +338,13 @@ glCompressedTexSubImage3DOES
|
||||
#void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays)
|
||||
glDeleteVertexArraysOES
|
||||
len arrays (n * sizeof(GLuint))
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
|
||||
glGenVertexArraysOES
|
||||
len arrays (n * sizeof(GLuint))
|
||||
dir arrays out
|
||||
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
|
||||
|
||||
|
||||
#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, GLenum *attachments)
|
||||
|
||||
Reference in New Issue
Block a user