Keep shaders to render properly
I don't know who's to blame, SGX or Tegra2 but one of those two GPUs is not
following the OpenGL ES 2.0 spec.
Change-Id: I2624e0efbc9c57d571c55c8b440a5e43f08a54f2
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 4aff23e..db610b0 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -25,21 +25,24 @@
// Base program
///////////////////////////////////////////////////////////////////////////////
+// TODO: Program instance should be created from a factory method
Program::Program(const char* vertex, const char* fragment) {
mInitialized = false;
mHasColorUniform = false;
+ mUse = false;
// No need to cache compiled shaders, rely instead on Android's
// persistent shaders cache
- GLuint vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
- if (vertexShader) {
-
- GLuint fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
- if (fragmentShader) {
-
+ mVertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ if (mVertexShader) {
+ mFragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ if (mFragmentShader) {
mProgramId = glCreateProgram();
- glAttachShader(mProgramId, vertexShader);
- glAttachShader(mProgramId, fragmentShader);
+
+ glAttachShader(mProgramId, mVertexShader);
+ glAttachShader(mProgramId, mFragmentShader);
+
+ position = bindAttrib("position", kBindingPosition);
glLinkProgram(mProgramId);
GLint status;
@@ -53,34 +56,35 @@
glGetProgramInfoLog(mProgramId, infoLen, 0, &log[0]);
LOGE("%s", log);
}
+
+ glDetachShader(mProgramId, mVertexShader);
+ glDetachShader(mProgramId, mFragmentShader);
+
+ glDeleteShader(mVertexShader);
+ glDeleteShader(mFragmentShader);
+
+ glDeleteProgram(mProgramId);
} else {
mInitialized = true;
}
-
- glDetachShader(mProgramId, vertexShader);
- glDetachShader(mProgramId, fragmentShader);
-
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
-
- if (!mInitialized) {
- glDeleteProgram(mProgramId);
- }
} else {
- glDeleteShader(vertexShader);
+ glDeleteShader(mVertexShader);
}
}
- mUse = false;
-
if (mInitialized) {
- position = addAttrib("position");
transform = addUniform("transform");
}
}
Program::~Program() {
if (mInitialized) {
+ glDetachShader(mProgramId, mVertexShader);
+ glDetachShader(mProgramId, mFragmentShader);
+
+ glDeleteShader(mVertexShader);
+ glDeleteShader(mFragmentShader);
+
glDeleteProgram(mProgramId);
}
}
@@ -91,6 +95,17 @@
return slot;
}
+int Program::bindAttrib(const char* name, ShaderBindings bindingSlot) {
+ glBindAttribLocation(mProgramId, bindingSlot, name);
+ GLenum status = GL_NO_ERROR;
+ while ((status = glGetError()) != GL_NO_ERROR) {
+ LOGD("Program::GL error from OpenGLRenderer: 0x%x", status);
+ }
+
+ mAttributes.add(name, bindingSlot);
+ return bindingSlot;
+}
+
int Program::getAttrib(const char* name) {
ssize_t index = mAttributes.indexOfKey(name);
if (index >= 0) {
@@ -161,14 +176,10 @@
void Program::use() {
glUseProgram(mProgramId);
mUse = true;
- glEnableVertexAttribArray(position);
}
void Program::remove() {
mUse = false;
- // TODO: Is this necessary? It should not be since all of our shaders
- // use slot 0 for the position attrib
- // glDisableVertexAttribArray(position);
}
}; // namespace uirenderer