summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/HardwareRenderer.java17
-rw-r--r--libs/hwui/Program.cpp63
-rw-r--r--libs/hwui/Program.h8
-rw-r--r--libs/hwui/ProgramCache.cpp2
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);