Cache all stencil related glGet's
This is used in testufo a lot (per frame).
Change-Id: I882e7b542c75702326474438eeb77aaeea0e1c4c
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 017bf71..93f9d5d 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -39,6 +39,24 @@
void GLClientState::init() {
m_initialized = false;
+ state_GL_STENCIL_TEST = false;
+ state_GL_STENCIL_FUNC = GL_ALWAYS;
+ state_GL_STENCIL_VALUE_MASK = ~(0);
+ state_GL_STENCIL_REF = 0;
+ state_GL_STENCIL_FAIL = GL_KEEP;
+ state_GL_STENCIL_PASS_DEPTH_FAIL = GL_KEEP;
+ state_GL_STENCIL_PASS_DEPTH_PASS = GL_KEEP;
+ state_GL_STENCIL_BACK_FUNC = GL_ALWAYS;
+ state_GL_STENCIL_BACK_VALUE_MASK = ~(0);
+ state_GL_STENCIL_BACK_REF = 0;
+ state_GL_STENCIL_BACK_FAIL = GL_KEEP;
+ state_GL_STENCIL_BACK_PASS_DEPTH_FAIL = GL_KEEP;
+ state_GL_STENCIL_BACK_PASS_DEPTH_PASS = GL_KEEP;
+ state_GL_STENCIL_WRITEMASK = ~(0);
+ state_GL_STENCIL_BACK_WRITEMASK = ~(0);
+ state_GL_STENCIL_CLEAR_VALUE = 0;
+
+
m_arrayBuffer = 0;
m_arrayBuffer_lastEncode = 0;
@@ -2939,6 +2957,44 @@
return m_transformFeedbackVaryingsCountForLinking;
}
+void GLClientState::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_FUNC = func;
+ state_GL_STENCIL_REF = ref;
+ state_GL_STENCIL_VALUE_MASK = mask;
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_BACK_FUNC = func;
+ state_GL_STENCIL_BACK_REF = ref;
+ state_GL_STENCIL_BACK_VALUE_MASK = mask;
+ }
+}
+
+void GLClientState::stencilMaskSeparate(GLenum face, GLuint mask) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_WRITEMASK = mask;
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_BACK_WRITEMASK = mask;
+ }
+}
+
+void GLClientState::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_FAIL = fail;
+ state_GL_STENCIL_PASS_DEPTH_FAIL = zfail;
+ state_GL_STENCIL_PASS_DEPTH_PASS = zpass;
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_GL_STENCIL_BACK_FAIL = fail;
+ state_GL_STENCIL_BACK_PASS_DEPTH_FAIL = zfail;
+ state_GL_STENCIL_BACK_PASS_DEPTH_PASS = zpass;
+ }
+}
+
void GLClientState::setTextureData(SharedTextureDataMap* sharedTexData) {
m_tex.textureRecs = sharedTexData;
}
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index 147e3d4..c0ca53a 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -514,6 +514,11 @@
bool getTransformFeedbackActiveUnpaused() const;
uint32_t getTransformFeedbackVaryingsCountForLinking() const;
+ // Stencil state
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
void setTextureData(SharedTextureDataMap* sharedTexData);
void setRenderbufferInfo(RenderbufferInfo* rbInfo);
void setSamplerInfo(SamplerInfo* samplerInfo);
@@ -554,6 +559,23 @@
// Attrib validation
bool isAttribIndexUsedByProgram(int attribIndex);
+ // Fast access to some enables and stencil related glGet's
+ bool state_GL_STENCIL_TEST;
+ GLenum state_GL_STENCIL_FUNC;
+ unsigned int state_GL_STENCIL_VALUE_MASK;
+ int state_GL_STENCIL_REF;
+ GLenum state_GL_STENCIL_FAIL;
+ GLenum state_GL_STENCIL_PASS_DEPTH_FAIL;
+ GLenum state_GL_STENCIL_PASS_DEPTH_PASS;
+ GLenum state_GL_STENCIL_BACK_FUNC;
+ unsigned int state_GL_STENCIL_BACK_VALUE_MASK;
+ int state_GL_STENCIL_BACK_REF;
+ GLenum state_GL_STENCIL_BACK_FAIL;
+ GLenum state_GL_STENCIL_BACK_PASS_DEPTH_FAIL;
+ GLenum state_GL_STENCIL_BACK_PASS_DEPTH_PASS;
+ unsigned int state_GL_STENCIL_WRITEMASK;
+ unsigned int state_GL_STENCIL_BACK_WRITEMASK;
+ int state_GL_STENCIL_CLEAR_VALUE;
private:
void init();
bool m_initialized;
@@ -967,6 +989,79 @@
isClientStateParam = true;
break;
}
+ case GL_FRAMEBUFFER_BINDING:
+ // also case GL_DRAW_FRAMEBUFFER_BINDING:
+ *out = (T)mFboState.boundDrawFramebuffer;
+ isClientStateParam = true;
+ break;
+ case 0x8CAA: // GL_READ_FRAMEBUFFER_BINDING
+ *out = (T)mFboState.boundReadFramebuffer;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_TEST:
+ *out = (T)state_GL_STENCIL_TEST;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_FUNC:
+ *out = (T)state_GL_STENCIL_FUNC;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ *out = (T)state_GL_STENCIL_VALUE_MASK;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_REF:
+ *out = (T)state_GL_STENCIL_REF;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_FAIL:
+ *out = (T)state_GL_STENCIL_FAIL;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ *out = (T)state_GL_STENCIL_PASS_DEPTH_FAIL;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ *out = (T)state_GL_STENCIL_PASS_DEPTH_PASS;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ *out = (T)state_GL_STENCIL_BACK_FUNC;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ *out = (T)state_GL_STENCIL_BACK_VALUE_MASK;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_REF:
+ *out = (T)state_GL_STENCIL_BACK_REF;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ *out = (T)state_GL_STENCIL_BACK_FAIL;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_FAIL;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_PASS;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_WRITEMASK:
+ *out = (T)state_GL_STENCIL_WRITEMASK;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_BACK_WRITEMASK:
+ *out = (T)state_GL_STENCIL_BACK_WRITEMASK;
+ isClientStateParam = true;
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ *out = (T)state_GL_STENCIL_CLEAR_VALUE;
+ isClientStateParam = true;
+ break;
}
return isClientStateParam;
}
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index ba6944c..6f328d6 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -454,6 +454,9 @@
OVERRIDE(glHint);
OVERRIDE(glGetFragDataLocation);
+
+ OVERRIDE(glStencilMask);
+ OVERRIDE(glClearStencil);
}
GL2Encoder::~GL2Encoder()
@@ -811,16 +814,15 @@
}
break;
case GL_TEXTURE_BINDING_2D:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
+ if (!state) return;
*ptr = state->getBoundTexture(GL_TEXTURE_2D);
break;
case GL_TEXTURE_BINDING_EXTERNAL_OES:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
+ if (!state) return;
*ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
break;
case GL_MAX_VERTEX_ATTRIBS:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
*ptr = CODEC_MAX_VERTEX_ATTRIBUTES;
break;
case GL_MAX_VERTEX_ATTRIB_STRIDE:
@@ -973,7 +975,7 @@
*ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
break;
default:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
+ if (!state) return;
if (!state->getClientStateParameter<GLint>(param, ptr)) {
ctx->safe_glGetIntegerv(param, ptr);
}
@@ -1037,7 +1039,7 @@
}
default:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
+ if (!state) return;
if (!state->getClientStateParameter<GLfloat>(param, ptr)) {
ctx->safe_glGetFloatv(param, ptr);
}
@@ -1101,7 +1103,7 @@
}
default:
- SET_ERROR_IF(!state, GL_INVALID_OPERATION);
+ if (!state) return;
if (!state->getClientStateParameter<GLboolean>(param, ptr)) {
ctx->safe_glGetBooleanv(param, ptr);
}
@@ -4866,11 +4868,15 @@
GL2Encoder *ctx = (GL2Encoder *)self;
SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
switch (what) {
case GL_PRIMITIVE_RESTART_FIXED_INDEX:
ctx->m_primitiveRestartEnabled = true;
break;
+ case GL_STENCIL_TEST:
+ ctx->m_state->state_GL_STENCIL_TEST = true;
+ break;
}
ctx->m_glEnable_enc(ctx, what);
@@ -4880,11 +4886,15 @@
GL2Encoder *ctx = (GL2Encoder *)self;
SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
switch (what) {
case GL_PRIMITIVE_RESTART_FIXED_INDEX:
ctx->m_primitiveRestartEnabled = false;
break;
+ case GL_STENCIL_TEST:
+ ctx->m_state->state_GL_STENCIL_TEST = false;
+ break;
}
ctx->m_glDisable_enc(ctx, what);
@@ -6307,12 +6317,16 @@
void GL2Encoder::s_glStencilFunc(void *self , GLenum func, GLint ref, GLuint mask) {
GL2Encoder* ctx = (GL2Encoder*)self;
SET_ERROR_IF(!GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
ctx->m_glStencilFunc_enc(ctx, func, ref, mask);
}
void GL2Encoder::s_glStencilFuncSeparate(void *self , GLenum face, GLenum func, GLint ref, GLuint mask) {
GL2Encoder* ctx = (GL2Encoder*)self;
SET_ERROR_IF(!GLESv2Validation::allowedFace(face) || !GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilFuncSeparate(face, func, ref, mask);
ctx->m_glStencilFuncSeparate_enc(ctx, face, func, ref, mask);
}
@@ -6323,6 +6337,8 @@
!GLESv2Validation::allowedStencilOp(zfail) ||
!GLESv2Validation::allowedStencilOp(zpass),
GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
ctx->m_glStencilOp_enc(ctx, fail, zfail, zpass);
}
@@ -6334,6 +6350,8 @@
!GLESv2Validation::allowedStencilOp(zfail) ||
!GLESv2Validation::allowedStencilOp(zpass),
GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilOpSeparate(face, fail, zfail, zpass);
ctx->m_glStencilOpSeparate_enc(ctx, face, fail, zfail, zpass);
}
@@ -6342,6 +6360,8 @@
SET_ERROR_IF(
!GLESv2Validation::allowedFace(face),
GL_INVALID_ENUM);
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilMaskSeparate(face, mask);
ctx->m_glStencilMaskSeparate_enc(ctx, face, mask);
}
@@ -6570,3 +6590,17 @@
RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
return ctx->m_glGetFragDataLocation_enc(ctx, program, name);
}
+
+void GL2Encoder::s_glStencilMask(void* self, GLuint mask) {
+ GL2Encoder* ctx = (GL2Encoder*)self;
+ if (!ctx->m_state) return;
+ ctx->m_state->stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+ ctx->m_glStencilMask_enc(ctx, mask);
+}
+
+void GL2Encoder::s_glClearStencil(void* self, int v) {
+ GL2Encoder* ctx = (GL2Encoder*)self;
+ if (!ctx->m_state) return;
+ ctx->m_state->state_GL_STENCIL_CLEAR_VALUE = v;
+ ctx->m_glClearStencil_enc(ctx, v);
+}
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index 6be2687..93108eb 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -890,6 +890,9 @@
static void s_glHint(void *self , GLenum target, GLenum mode);
static GLint s_glGetFragDataLocation (void *self , GLuint program, const char* name);
+ static void s_glStencilMask(void* self, GLuint mask);
+ static void s_glClearStencil(void* self, int v);
+
#define LIST_REMAINING_FUNCTIONS_FOR_VALIDATION(f) \
f(glBindAttribLocation) \
f(glUniformBlockBinding) \
@@ -933,6 +936,8 @@
f(glIsEnabled) \
f(glHint) \
f(glGetFragDataLocation) \
+ f(glStencilMask) \
+ f(glClearStencil) \
#define DECLARE_CLIENT_ENCODER_PROC(n) \
n##_client_proc_t m_##n##_enc;