Fix tons of bugs and add new text rendering support.

Change-Id: I326c66b10784006f6df2f12d38e120cef94cd0d7
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 8d00e85..e807aba 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -69,16 +69,16 @@
     int width = (int) glyph->mBitmapWidth;
     int height = (int) glyph->mBitmapHeight;
 
-    if(bounds->bottom > nPenY) {
+    if (bounds->bottom > nPenY) {
         bounds->bottom = nPenY;
     }
-    if(bounds->left > nPenX) {
+    if (bounds->left > nPenX) {
         bounds->left = nPenX;
     }
-    if(bounds->right < nPenX + width) {
+    if (bounds->right < nPenX + width) {
         bounds->right = nPenX + width;
     }
-    if(bounds->top < nPenY + height) {
+    if (bounds->top < nPenY + height) {
         bounds->top = nPenY + height;
     }
 }
@@ -102,7 +102,7 @@
 }
 
 void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
-                             uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
+        uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
     int nPenX = x + glyph->mBitmapLeft;
     int nPenY = y + glyph->mBitmapTop;
 
@@ -116,7 +116,7 @@
     int32_t bX = 0, bY = 0;
     for (cacheX = glyph->mStartX, bX = nPenX; cacheX < endX; cacheX++, bX++) {
         for (cacheY = glyph->mStartY, bY = nPenY; cacheY < endY; cacheY++, bY++) {
-            if(bX < 0 || bY < 0 || bX >= (int32_t)bitmapW || bY >= (int32_t)bitmapH) {
+            if (bX < 0 || bY < 0 || bX >= (int32_t)bitmapW || bY >= (int32_t)bitmapH) {
                 LOGE("Skipping invalid index");
                 continue;
             }
@@ -143,22 +143,19 @@
 }
 
 void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
-                       int numGlyphs, int x, int y,
-                       uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
-    if(bitmap != NULL && bitmapW > 0 && bitmapH > 0) {
-        renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP,
-                   bitmap, bitmapW, bitmapH, NULL);
-    }
-    else {
-        renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER,
-                   NULL, 0, 0, NULL);
+        int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
+    if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) {
+        renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap,
+                bitmapW, bitmapH, NULL);
+    } else {
+        renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL);
     }
 
 }
 
 void Font::measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
-                       int numGlyphs, Rect *bounds) {
-    if(bounds == NULL) {
+        int numGlyphs, Rect *bounds) {
+    if (bounds == NULL) {
         LOGE("No return rectangle provided to measure text");
         return;
     }
@@ -167,9 +164,8 @@
 }
 
 void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
-                       int numGlyphs, int x, int y, RenderMode mode,
-                       uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
-                       Rect *bounds) {
+        int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
+        uint32_t bitmapW, uint32_t bitmapH,Rect *bounds) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
         return;
     }
@@ -185,7 +181,7 @@
     while (glyphsLeft > 0) {
         int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text);
 
-        // Reached the end of the string or encountered
+        // Reached the end of the string
         if (utfChar < 0) {
             break;
         }
@@ -422,7 +418,7 @@
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     // Initialize texture dimentions
     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0,
-                  GL_ALPHA, GL_UNSIGNED_BYTE, 0);
+            GL_ALPHA, GL_UNSIGNED_BYTE, 0);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -527,7 +523,6 @@
 }
 
 void FontRenderer::issueDrawCommand() {
-
     checkTextureUpdate();
 
     float* vtx = mTextMeshPtr;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 5d30b1a..ff00ba6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -435,6 +435,7 @@
         return;
     }
 
+    glActiveTexture(GL_TEXTURE0);
     const Texture* texture = mTextureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
@@ -451,6 +452,7 @@
         return;
     }
 
+    glActiveTexture(GL_TEXTURE0);
     const Texture* texture = mTextureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
@@ -466,6 +468,7 @@
         return;
     }
 
+    glActiveTexture(GL_TEXTURE0);
     const Texture* texture = mTextureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
@@ -491,6 +494,7 @@
         return;
     }
 
+    glActiveTexture(GL_TEXTURE0);
     const Texture* texture = mTextureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 4a01ffa..9a22dc0 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -162,7 +162,8 @@
     glGenTextures(1, &texture->id);
 
     glBindTexture(GL_TEXTURE_2D, texture->id);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap.bytesPerPixel());
+    // Textures are Alpha8
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
     texture->blend = true;
     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap.rowBytesAsPixels(), texture->height, 0,
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 8a97b4c..2449b6d 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -376,6 +376,9 @@
     }
     shader.append("    return vec2(");
     switch (wrapS) {
+        case GL_CLAMP_TO_EDGE:
+            shader.append("texCoords.x");
+            break;
         case GL_REPEAT:
             shader.append("mod(texCoords.x, 1.0)");
             break;
@@ -385,6 +388,9 @@
     }
     shader.append(", ");
     switch (wrapT) {
+        case GL_CLAMP_TO_EDGE:
+            shader.append("texCoords.y");
+            break;
         case GL_REPEAT:
             shader.append("mod(texCoords.y, 1.0)");
             break;
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 42c0621..15a4e88 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -89,7 +89,8 @@
     description.hasBitmap = true;
     // The driver does not support non-power of two mirrored/repeated
     // textures, so do it ourselves
-    if (!extensions.hasNPot() && !isPowerOfTwo(width) && !isPowerOfTwo(height)) {
+    if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) &&
+            (mTileX != SkShader::kClamp_TileMode || mTileY != SkShader::kClamp_TileMode)) {
         description.isBitmapNpot = true;
         description.bitmapWrapS = gTileModes[mTileX];
         description.bitmapWrapT = gTileModes[mTileY];
@@ -136,6 +137,9 @@
         SkMatrix* matrix, bool blend):
         SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend),
         mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) {
+    for (int i = 0; i < count; i++) {
+        LOGD("[GL] Gradient color %d = 0x%x", i, colors[i]);
+    }
 }
 
 SkiaLinearGradientShader::~SkiaLinearGradientShader() {