Free up resources by deleting shaders early on
Change-Id: I29a39775732c0a48d3e6823f7afa3e741cae8541
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 972dd87..516546f 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -27,35 +27,45 @@
Program::Program(const char* vertex, const char* fragment) {
mInitialized = false;
+ mHasColorUniform = false;
- vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ GLuint vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
if (vertexShader) {
- fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ GLuint fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
if (fragmentShader) {
- id = glCreateProgram();
- glAttachShader(id, vertexShader);
- glAttachShader(id, fragmentShader);
- glLinkProgram(id);
+ mProgramId = glCreateProgram();
+ glAttachShader(mProgramId, vertexShader);
+ glAttachShader(mProgramId, fragmentShader);
+ glLinkProgram(mProgramId);
GLint status;
- glGetProgramiv(id, GL_LINK_STATUS, &status);
+ glGetProgramiv(mProgramId, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
LOGE("Error while linking shaders:");
GLint infoLen = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
+ glGetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
GLchar log[infoLen];
- glGetProgramInfoLog(id, infoLen, 0, &log[0]);
+ glGetProgramInfoLog(mProgramId, infoLen, 0, &log[0]);
LOGE("%s", log);
}
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(id);
} else {
mInitialized = true;
}
+
+ glDetachShader(mProgramId, vertexShader);
+ glDetachShader(mProgramId, fragmentShader);
+
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+
+ if (!mInitialized) {
+ glDeleteProgram(mProgramId);
+ }
+ } else {
+ glDeleteShader(vertexShader);
}
}
@@ -69,36 +79,34 @@
Program::~Program() {
if (mInitialized) {
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(id);
+ glDeleteProgram(mProgramId);
}
}
int Program::addAttrib(const char* name) {
- int slot = glGetAttribLocation(id, name);
- attributes.add(name, slot);
+ int slot = glGetAttribLocation(mProgramId, name);
+ mAttributes.add(name, slot);
return slot;
}
int Program::getAttrib(const char* name) {
- ssize_t index = attributes.indexOfKey(name);
+ ssize_t index = mAttributes.indexOfKey(name);
if (index >= 0) {
- return attributes.valueAt(index);
+ return mAttributes.valueAt(index);
}
return addAttrib(name);
}
int Program::addUniform(const char* name) {
- int slot = glGetUniformLocation(id, name);
- uniforms.add(name, slot);
+ int slot = glGetUniformLocation(mProgramId, name);
+ mUniforms.add(name, slot);
return slot;
}
int Program::getUniform(const char* name) {
- ssize_t index = uniforms.indexOfKey(name);
+ ssize_t index = mUniforms.indexOfKey(name);
if (index >= 0) {
- return uniforms.valueAt(index);
+ return mUniforms.valueAt(index);
}
return addUniform(name);
}
@@ -140,20 +148,24 @@
}
void Program::setColor(const float r, const float g, const float b, const float a) {
- glUniform4f(getUniform("color"), r, g, b, a);
+ if (!mHasColorUniform) {
+ mColorUniform = getUniform("color");
+ mHasColorUniform = false;
+ }
+ glUniform4f(mColorUniform, r, g, b, a);
}
void Program::use() {
- glUseProgram(id);
+ glUseProgram(mProgramId);
mUse = true;
-
glEnableVertexAttribArray(position);
}
void Program::remove() {
mUse = false;
-
- glDisableVertexAttribArray(position);
+ // TODO: Is this necessary? It should not be since all of our shaders
+ // use slot 0 for the position attrib
+ // glDisableVertexAttribArray(position);
}
}; // namespace uirenderer
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 764cb05..edd1209 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -122,18 +122,17 @@
GLuint buildShader(const char* source, GLenum type);
// Name of the OpenGL program
- GLuint id;
-
- // Name of the shaders
- GLuint vertexShader;
- GLuint fragmentShader;
+ GLuint mProgramId;
// Keeps track of attributes and uniforms slots
- KeyedVector<const char*, int> attributes;
- KeyedVector<const char*, int> uniforms;
+ KeyedVector<const char*, int> mAttributes;
+ KeyedVector<const char*, int> mUniforms;
bool mUse;
bool mInitialized;
+
+ bool mHasColorUniform;
+ int mColorUniform;
}; // class Program
}; // namespace uirenderer
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 8c01e3a..47484d0 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -74,7 +74,7 @@
#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"
// Converts a number of mega-bytes into bytes
-#define MB(s) s * 1024 * 1024
+#define MB(s) (s * 1024 * 1024)
#define DEFAULT_TEXTURE_CACHE_SIZE 24.0f
#define DEFAULT_LAYER_CACHE_SIZE 16.0f