diff options
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 17 | ||||
-rw-r--r-- | libs/hwui/Program.cpp | 63 | ||||
-rw-r--r-- | libs/hwui/Program.h | 8 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 2 |
4 files changed, 63 insertions, 27 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 24a9f87..0e294f7 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -50,7 +50,7 @@ public abstract class HardwareRenderer { private boolean mRequested = true; /** - * Indicates that the current process cannot use hardware rendering. + * Invoke this method to disable hardware rendering in the current process. * * @hide */ @@ -207,7 +207,7 @@ public abstract class HardwareRenderer { EGLSurface mEglSurface; GL mGl; - GLES20Canvas mCanvas; + HardwareCanvas mCanvas; final int mGlVersion; final boolean mTranslucent; @@ -279,12 +279,15 @@ public abstract class HardwareRenderer { if (error != EGL11.EGL_CONTEXT_LOST) { // we'll try again if it was context lost setRequested(false); + } else { + Log.w(LOG_TAG, "Mountain View, we've had a problem here. " + + "Switching back to software rendering."); } Log.w(LOG_TAG, "EGL error: " + getEGLErrorString(error)); } } } - + @Override boolean initialize(SurfaceHolder holder) { if (isRequested() && !isEnabled()) { @@ -654,6 +657,14 @@ public abstract class HardwareRenderer { } @Override + void destroy(boolean full) { + super.destroy(full); + if (full && mGlCanvas != null) { + mGlCanvas = null; + } + } + + @Override DisplayList createDisplayList() { return new GLES20DisplayList(); } 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); |