diff options
author | Romain Guy <romainguy@google.com> | 2011-12-12 16:47:48 -0800 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2011-12-12 16:47:48 -0800 |
commit | 3e263fac8c9c0e0fb242186b514a7af8efb40961 (patch) | |
tree | c4333a2489886c933172a5cd271c8bda0796324a | |
parent | 6752d0ab029a185a42e34e7a933b669e6ed19e89 (diff) | |
download | frameworks_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.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 17 | ||||
-rw-r--r-- | libs/hwui/Program.cpp | 57 | ||||
-rw-r--r-- | libs/hwui/Program.h | 14 |
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; |