summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-12-12 16:47:48 -0800
committerRomain Guy <romainguy@google.com>2011-12-12 16:47:48 -0800
commit3e263fac8c9c0e0fb242186b514a7af8efb40961 (patch)
treec4333a2489886c933172a5cd271c8bda0796324a
parent6752d0ab029a185a42e34e7a933b669e6ed19e89 (diff)
downloadframeworks_base-3e263fac8c9c0e0fb242186b514a7af8efb40961.zip
frameworks_base-3e263fac8c9c0e0fb242186b514a7af8efb40961.tar.gz
frameworks_base-3e263fac8c9c0e0fb242186b514a7af8efb40961.tar.bz2
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
-rw-r--r--libs/hwui/LayerRenderer.cpp1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp17
-rw-r--r--libs/hwui/Program.cpp57
-rw-r--r--libs/hwui/Program.h14
4 files changed, 58 insertions, 31 deletions
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e2d9ea3..3f940bb 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -233,7 +233,6 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
layer->getTexture(), 0);
glDisable(GL_SCISSOR_TEST);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 1d7b99d..fa17aad 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -133,8 +133,6 @@ OpenGLRenderer::~OpenGLRenderer() {
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::setViewport(int width, int height) {
- glDisable(GL_DITHER);
- glViewport(0, 0, width, height);
mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
mWidth = width;
@@ -144,6 +142,13 @@ void OpenGLRenderer::setViewport(int width, int height) {
mFirstSnapshot->viewport.set(0, 0, width, height);
mDirtyClip = false;
+
+ glDisable(GL_DITHER);
+ glViewport(0, 0, width, height);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ glEnableVertexAttribArray(Program::kBindingPosition);
}
void OpenGLRenderer::prepare(bool opaque) {
@@ -159,14 +164,11 @@ void OpenGLRenderer::prepareDirty(float left, float top, float right, float bott
mSaveCount = 1;
- glViewport(0, 0, mWidth, mHeight);
-
glEnable(GL_SCISSOR_TEST);
glScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
mSnapshot->setClip(left, top, right, bottom);
if (!opaque) {
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
}
@@ -207,6 +209,8 @@ void OpenGLRenderer::resume() {
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
glEnable(GL_SCISSOR_TEST);
dirtyClip();
@@ -215,6 +219,8 @@ void OpenGLRenderer::resume() {
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glEnableVertexAttribArray(Program::kBindingPosition);
+
mCaches.blend = true;
glEnable(GL_BLEND);
glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode);
@@ -556,7 +562,6 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> sna
// Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
glScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f,
clip.getWidth() + 2.0f, clip.getHeight() + 2.0f);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
dirtyClip();
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 @@ namespace uirenderer {
// 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) {
+ mVertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ if (mVertexShader) {
+ mFragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ if (mFragmentShader) {
+ mProgramId = glCreateProgram();
- GLuint fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
- if (fragmentShader) {
+ glAttachShader(mProgramId, mVertexShader);
+ glAttachShader(mProgramId, mFragmentShader);
- mProgramId = glCreateProgram();
- glAttachShader(mProgramId, vertexShader);
- glAttachShader(mProgramId, fragmentShader);
+ position = bindAttrib("position", kBindingPosition);
glLinkProgram(mProgramId);
GLint status;
@@ -53,34 +56,35 @@ Program::Program(const char* vertex, const char* fragment) {
glGetProgramInfoLog(mProgramId, infoLen, 0, &log[0]);
LOGE("%s", log);
}
- } else {
- mInitialized = true;
- }
- glDetachShader(mProgramId, vertexShader);
- glDetachShader(mProgramId, fragmentShader);
+ glDetachShader(mProgramId, mVertexShader);
+ glDetachShader(mProgramId, mFragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
+ glDeleteShader(mVertexShader);
+ glDeleteShader(mFragmentShader);
- if (!mInitialized) {
glDeleteProgram(mProgramId);
+ } else {
+ mInitialized = true;
}
} 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 @@ int Program::addAttrib(const char* name) {
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::setColor(const float r, const float g, const float b, const float
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
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index edd1209..9e59621 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -33,6 +33,11 @@ namespace uirenderer {
*/
class Program {
public:
+ enum ShaderBindings {
+ kBindingPosition,
+ kBindingTexCoords
+ };
+
/**
* Creates a new program with the specified vertex and fragment
* shaders sources.
@@ -107,6 +112,11 @@ protected:
int addAttrib(const char* name);
/**
+ * Binds the specified attribute name to the specified slot.
+ */
+ int bindAttrib(const char* name, ShaderBindings bindingSlot);
+
+ /**
* Adds a uniform with the specified name.
*
* @return The OpenGL name of the uniform.
@@ -121,8 +131,10 @@ private:
*/
GLuint buildShader(const char* source, GLenum type);
- // Name of the OpenGL program
+ // Name of the OpenGL program and shaders
GLuint mProgramId;
+ GLuint mVertexShader;
+ GLuint mFragmentShader;
// Keeps track of attributes and uniforms slots
KeyedVector<const char*, int> mAttributes;