diff options
| -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 e2d9ea35f49d..3f940bb34abf 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 1d7b99dfc81e..fa17aad1b8b6 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 4aff23e48ac8..db610b03cef8 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 edd12093f474..9e59621eef30 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;  |