Glop ColorFilter & VertexBuffer support, initial enable

Enables Glop rendering for supported Rects and VertexBuffers
Also removes unused Query object

Change-Id: Ibe227bc362685a153159f75077664f0947764e06
diff --git a/libs/hwui/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
index 93088e4..c751dba 100644
--- a/libs/hwui/renderstate/Blend.cpp
+++ b/libs/hwui/renderstate/Blend.cpp
@@ -127,6 +127,10 @@
     }
 }
 
+void Blend::dump() {
+    ALOGD("Blend: enabled %d, func src %d, dst %d", mEnabled, mSrcMode, mDstMode);
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
 
diff --git a/libs/hwui/renderstate/Blend.h b/libs/hwui/renderstate/Blend.h
index 31d7dde..6d0c115c 100644
--- a/libs/hwui/renderstate/Blend.h
+++ b/libs/hwui/renderstate/Blend.h
@@ -35,6 +35,8 @@
 
     static void getFactors(SkXfermode::Mode mode, bool swapSrcDst, GLenum* outSrc, GLenum* outDst);
     void setFactors(GLenum src, GLenum dst);
+
+    void dump();
 private:
     Blend();
     void invalidate();
diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp
index 50c09c8..ce6030d 100644
--- a/libs/hwui/renderstate/MeshState.cpp
+++ b/libs/hwui/renderstate/MeshState.cpp
@@ -23,22 +23,20 @@
 namespace uirenderer {
 
 MeshState::MeshState()
-        : mCurrentPositionPointer(this)
+        : mCurrentIndicesBuffer(0)
+        , mCurrentPixelBuffer(0)
+        , mCurrentPositionPointer(this)
         , mCurrentPositionStride(0)
         , mCurrentTexCoordsPointer(this)
         , mCurrentTexCoordsStride(0)
-        , mTexCoordsArrayEnabled(false) {
+        , mTexCoordsArrayEnabled(false)
+        , mQuadListIndices(0) {
 
     glGenBuffers(1, &mUnitQuadBuffer);
     glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
 
     mCurrentBuffer = mUnitQuadBuffer;
-    mCurrentIndicesBuffer = 0;
-    mCurrentPixelBuffer = 0;
-
-    mQuadListIndices = 0;
-    mShadowStripsIndices = 0;
 
     // position attribute always enabled
     glEnableVertexAttribArray(Program::kBindingPosition);
@@ -50,9 +48,10 @@
 
     glDeleteBuffers(1, &mQuadListIndices);
     mQuadListIndices = 0;
+}
 
-    glDeleteBuffers(1, &mShadowStripsIndices);
-    mShadowStripsIndices = 0;
+void MeshState::dump() {
+    ALOGD("MeshState vertices: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -65,18 +64,17 @@
 
 bool MeshState::bindMeshBuffer(GLuint buffer) {
     if (!buffer) buffer = mUnitQuadBuffer;
-    if (mCurrentBuffer != buffer) {
-        glBindBuffer(GL_ARRAY_BUFFER, buffer);
-        mCurrentBuffer = buffer;
-        return true;
-    }
-    return false;
+    return bindMeshBufferInternal(buffer);
 }
 
 bool MeshState::unbindMeshBuffer() {
-    if (mCurrentBuffer) {
-        glBindBuffer(GL_ARRAY_BUFFER, 0);
-        mCurrentBuffer = 0;
+    return bindMeshBufferInternal(0);
+}
+
+bool MeshState::bindMeshBufferInternal(GLuint buffer) {
+    if (mCurrentBuffer != buffer) {
+        glBindBuffer(GL_ARRAY_BUFFER, buffer);
+        mCurrentBuffer = buffer;
         return true;
     }
     return false;
@@ -163,20 +161,6 @@
     return bindIndicesBufferInternal(mQuadListIndices);
 }
 
-bool MeshState::bindShadowIndicesBuffer() {
-    if (!mShadowStripsIndices) {
-        std::unique_ptr<uint16_t[]> shadowIndices(new uint16_t[MAX_SHADOW_INDEX_COUNT]);
-        ShadowTessellator::generateShadowIndices(shadowIndices.get());
-        glGenBuffers(1, &mShadowStripsIndices);
-        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t),
-            shadowIndices.get(), GL_STATIC_DRAW);
-        return force;
-    }
-
-    return bindIndicesBufferInternal(mShadowStripsIndices);
-}
-
 bool MeshState::unbindIndicesBuffer() {
     if (mCurrentIndicesBuffer) {
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h
index 5cb1143..afc6267 100644
--- a/libs/hwui/renderstate/MeshState.h
+++ b/libs/hwui/renderstate/MeshState.h
@@ -47,7 +47,7 @@
 const GLsizei kVertexAlphaOffset = 2 * sizeof(float);
 const GLsizei kVertexAAWidthOffset = 2 * sizeof(float);
 const GLsizei kVertexAALengthOffset = 3 * sizeof(float);
-const GLsizei kMeshCount = 4;
+const GLsizei kUnitQuadCount = 4;
 
 class MeshState {
 private:
@@ -55,6 +55,7 @@
 
 public:
     ~MeshState();
+    void dump();
     ///////////////////////////////////////////////////////////////////////////////
     // Buffer objects
     ///////////////////////////////////////////////////////////////////////////////
@@ -107,7 +108,6 @@
      * gMaxNumberOfQuads quads.
      */
     bool bindQuadIndicesBuffer();
-    bool bindShadowIndicesBuffer();
     bool unbindIndicesBuffer();
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -116,9 +116,9 @@
     GLuint getUnitQuadVBO() { return mUnitQuadBuffer; }
 private:
     MeshState();
+    bool bindMeshBufferInternal(const GLuint buffer);
     bool bindIndicesBufferInternal(const GLuint buffer);
 
-    // VBO to draw with
     GLuint mUnitQuadBuffer;
 
     GLuint mCurrentBuffer;
@@ -134,7 +134,6 @@
 
     // Global index buffer
     GLuint mQuadListIndices;
-    GLuint mShadowStripsIndices;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index d3f6277..a819d9a 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -17,6 +17,7 @@
 
 #include "renderthread/CanvasContext.h"
 #include "renderthread/EglManager.h"
+#include "utils/GLUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -213,18 +214,41 @@
     const Glop::Mesh& mesh = glop.mesh;
     const Glop::Fill& shader = glop.fill;
 
+    // --------------------------------------------
     // ---------- Shader + uniform setup ----------
+    // --------------------------------------------
     mCaches->setProgram(shader.program);
 
-    Glop::Fill::Color color = shader.color;
+    Glop::FloatColor color = shader.color;
     shader.program->setColor(color.r, color.g, color.b, color.a);
 
     shader.program->set(glop.transform.ortho,
             glop.transform.modelView,
             glop.transform.canvas,
-            glop.transform.offset);
+            glop.transform.fudgingOffset);
 
+    if (glop.fill.filterMode == ProgramDescription::kColorBlend) {
+        const Glop::FloatColor& color = glop.fill.filter.color;
+        glUniform4f(mCaches->program().getUniform("colorBlend"),
+                color.r, color.g, color.b, color.a);
+    } else if (glop.fill.filterMode == ProgramDescription::kColorMatrix) {
+        glUniformMatrix4fv(mCaches->program().getUniform("colorMatrix"), 1, GL_FALSE,
+                glop.fill.filter.matrix.matrix);
+        glUniform4fv(mCaches->program().getUniform("colorMatrixVector"), 1,
+                glop.fill.filter.matrix.vector);
+    }
+
+    // --------------------------------
     // ---------- Mesh setup ----------
+    // --------------------------------
+    // vertices
+    bool force = meshState().bindMeshBufferInternal(mesh.vertexBufferObject)
+            || (mesh.vertices != nullptr);
+    meshState().bindPositionVertexPointer(force, mesh.vertices, mesh.stride);
+
+    // indices
+    meshState().bindIndicesBufferInternal(mesh.indexBufferObject);
+
     if (glop.mesh.vertexFlags & kTextureCoord_Attrib) {
         // TODO: support textures
         LOG_ALWAYS_FATAL("textures not yet supported");
@@ -232,40 +256,42 @@
         meshState().disableTexCoordsVertexArray();
     }
     if (glop.mesh.vertexFlags & kColor_Attrib) {
-        LOG_ALWAYS_FATAL("color attribute not yet supported");
+        LOG_ALWAYS_FATAL("color vertex attribute not yet supported");
         // TODO: enable color, disable when done
     }
+    int alphaSlot = -1;
     if (glop.mesh.vertexFlags & kAlpha_Attrib) {
-        LOG_ALWAYS_FATAL("alpha attribute not yet supported");
-        // TODO: enable alpha attribute, disable when done
+        const void* alphaCoords = ((const GLbyte*) glop.mesh.vertices) + kVertexAlphaOffset;
+        alphaSlot = shader.program->getAttrib("vtxAlpha");
+        glEnableVertexAttribArray(alphaSlot);
+        glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, kAlphaVertexStride, alphaCoords);
     }
 
-    /**
-    * Hard-coded vertex assumptions:
-     *     - required
-     *     - xy floats
-     *     - 0 offset
-     *     - in VBO
-     */
-    bool force = meshState().bindMeshBuffer(mesh.vertexBufferObject);
-    meshState().bindPositionVertexPointer(force, nullptr, mesh.stride);
-
-    /**
-     * Hard-coded index assumptions:
-     *     - optional
-     *     - 0 offset
-     *     - in IBO
-     */
-    meshState().bindIndicesBufferInternal(mesh.indexBufferObject);
-
+    // ------------------------------------
     // ---------- GL state setup ----------
+    // ------------------------------------
     blend().setFactors(glop.blend.src, glop.blend.dst);
 
-    if (mesh.indexBufferObject) {
-        glDrawElements(glop.mesh.primitiveMode, glop.mesh.vertexCount, GL_UNSIGNED_BYTE, nullptr);
+    // ------------------------------------
+    // ---------- GL state setup ----------
+    // ------------------------------------
+    if (mesh.indexBufferObject || mesh.indices) {
+        glDrawElements(glop.mesh.primitiveMode, glop.mesh.vertexCount,
+                GL_UNSIGNED_SHORT, mesh.indices);
     } else {
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, glop.mesh.vertexCount);
+        glDrawArrays(glop.mesh.primitiveMode, 0, glop.mesh.vertexCount);
     }
+
+    if (glop.mesh.vertexFlags & kAlpha_Attrib) {
+        glDisableVertexAttribArray(alphaSlot);
+    }
+}
+
+void RenderState::dump() {
+    blend().dump();
+    meshState().dump();
+    scissor().dump();
+    stencil().dump();
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 2e28ff6..4fd792c 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -91,6 +91,8 @@
     MeshState& meshState() { return *mMeshState; }
     Scissor& scissor() { return *mScissor; }
     Stencil& stencil() { return *mStencil; }
+
+    void dump();
 private:
     friend class renderthread::RenderThread;
     friend class Caches;
@@ -99,9 +101,6 @@
     void resumeFromFunctorInvoke();
     void assertOnGLThread();
 
-    void setupVertexAttributes(const Glop& glop);
-    void tearDownVertexAttributes(const Glop& glop);
-
     RenderState(renderthread::RenderThread& thread);
     ~RenderState();
 
diff --git a/libs/hwui/renderstate/Scissor.cpp b/libs/hwui/renderstate/Scissor.cpp
index 66c31a2..95dcd18 100644
--- a/libs/hwui/renderstate/Scissor.cpp
+++ b/libs/hwui/renderstate/Scissor.cpp
@@ -15,6 +15,8 @@
  */
 #include "renderstate/Scissor.h"
 
+#include <utils/Log.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -79,6 +81,11 @@
     reset();
 }
 
+void Scissor::dump() {
+    ALOGD("Scissor: enabled %d, %d %d %d %d",
+            mEnabled, mScissorX, mScissorY, mScissorWidth, mScissorHeight);
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
 
diff --git a/libs/hwui/renderstate/Scissor.h b/libs/hwui/renderstate/Scissor.h
index cc8b3dd..b37ec58 100644
--- a/libs/hwui/renderstate/Scissor.h
+++ b/libs/hwui/renderstate/Scissor.h
@@ -29,6 +29,7 @@
     bool set(GLint x, GLint y, GLint width, GLint height);
     void reset();
     bool isEnabled() { return mEnabled; }
+    void dump();
 private:
     Scissor();
     void invalidate();
diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp
index acbed14..cedb233 100644
--- a/libs/hwui/renderstate/Stencil.cpp
+++ b/libs/hwui/renderstate/Stencil.cpp
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
+#include "renderstate/Stencil.h"
+
+#include "Caches.h"
 #include "Debug.h"
 #include "Extensions.h"
 #include "Properties.h"
-#include "renderstate/Stencil.h"
 
 #include <GLES2/gl2ext.h>
 
@@ -42,7 +44,7 @@
 
 GLenum Stencil::getSmallestStencilFormat() {
 #if !DEBUG_STENCIL
-    const Extensions& extensions = Extensions::getInstance();
+    const Extensions& extensions = Caches::getInstance().extensions();
     if (extensions.has1BitStencil()) {
         return GL_STENCIL_INDEX1_OES;
     } else if (extensions.has4BitStencil()) {
@@ -123,5 +125,9 @@
     }
 }
 
+void Stencil::dump() {
+    ALOGD("Stencil: state %d", mState);
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/renderstate/Stencil.h b/libs/hwui/renderstate/Stencil.h
index 20bb955..a88beae 100644
--- a/libs/hwui/renderstate/Stencil.h
+++ b/libs/hwui/renderstate/Stencil.h
@@ -98,6 +98,8 @@
         return mState == kTest;
     }
 
+    void dump();
+
 private:
     void enable();