diff options
author | Romain Guy <romainguy@google.com> | 2010-12-07 20:09:23 -0800 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-12-07 20:12:50 -0800 |
commit | 67f27952c1bcb2230beef9b5ca0bf42edad436a9 (patch) | |
tree | 9cfec6c807b64d51fba041e2f6dd50c6abe3577e /libs | |
parent | dbf78bdb7a9aed3b8393c247128a7e8c760343b5 (diff) | |
download | frameworks_base-67f27952c1bcb2230beef9b5ca0bf42edad436a9.zip frameworks_base-67f27952c1bcb2230beef9b5ca0bf42edad436a9.tar.gz frameworks_base-67f27952c1bcb2230beef9b5ca0bf42edad436a9.tar.bz2 |
Correctly release the OpenGL Canvas on EGL error.
Change-Id: Ib31fd8445f7ce5f7aa7e0205de0e7db80d024fc2
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Program.cpp | 63 | ||||
-rw-r--r-- | libs/hwui/Program.h | 8 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 2 |
3 files changed, 49 insertions, 24 deletions
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index baed5fd..2187f24 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -26,39 +26,53 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// Program::Program(const char* vertex, const char* fragment) { - vertexShader = buildShader(vertex, GL_VERTEX_SHADER); - fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); - - id = glCreateProgram(); - glAttachShader(id, vertexShader); - glAttachShader(id, fragmentShader); - glLinkProgram(id); + mInitialized = false; - GLint status; - glGetProgramiv(id, GL_LINK_STATUS, &status); - if (status != GL_TRUE) { - GLint infoLen = 0; - glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); - if (infoLen > 1) { - GLchar log[infoLen]; - glGetProgramInfoLog(id, infoLen, 0, &log[0]); - LOGE("Error while linking shaders: %s", log); + vertexShader = buildShader(vertex, GL_VERTEX_SHADER); + if (vertexShader) { + + fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); + if (fragmentShader) { + + id = glCreateProgram(); + glAttachShader(id, vertexShader); + glAttachShader(id, fragmentShader); + glLinkProgram(id); + + GLint status; + glGetProgramiv(id, GL_LINK_STATUS, &status); + if (status != GL_TRUE) { + LOGE("Error while linking shaders:"); + GLint infoLen = 0; + glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) { + GLchar log[infoLen]; + glGetProgramInfoLog(id, infoLen, 0, &log[0]); + LOGE("%s", log); + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + glDeleteProgram(id); + } else { + mInitialized = true; + } } - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - glDeleteProgram(id); } mUse = false; - position = addAttrib("position"); - transform = addUniform("transform"); + if (mInitialized) { + position = addAttrib("position"); + transform = addUniform("transform"); + } } Program::~Program() { - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - glDeleteProgram(id); + if (mInitialized) { + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + glDeleteProgram(id); + } } int Program::addAttrib(const char* name) { @@ -103,6 +117,7 @@ GLuint Program::buildShader(const char* source, GLenum type) { glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); LOGE("Error while compiling shader: %s", log); glDeleteShader(shader); + return 0; } return shader; diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 5981662..afc6f3d 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -70,6 +70,13 @@ public: } /** + * Indicates whether this program was correctly compiled and linked. + */ + inline bool isInitialized() const { + return mInitialized; + } + + /** * Binds the program with the specified projection, modelView and * transform matrices. */ @@ -126,6 +133,7 @@ private: KeyedVector<const char*, int> uniforms; bool mUse; + bool mInitialized; }; // class Program }; // namespace uirenderer diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index f2f1adb..0b6c7b5 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -298,6 +298,8 @@ ProgramCache::~ProgramCache() { /////////////////////////////////////////////////////////////////////////////// void ProgramCache::clear() { + PROGRAM_LOGD("Clearing program cache"); + size_t count = mCache.size(); for (size_t i = 0; i < count; i++) { delete mCache.valueAt(i); |