Rework shadow interpolation

bug:16852257

Use pow(alpha, 1.5) to avoid harsh edges on shadow alpha ramps.

Also adjusts shadow constants to compensate.

Change-Id: I5869956d7d292db2a8e496bc320084b6d64c3fb7
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index e693d91..35baf9c 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1359,8 +1359,8 @@
         <item name="lightY">-200dp</item>
         <item name="lightZ">800dp</item>
         <item name="lightRadius">800dp</item>
-        <item name="ambientShadowAlpha">0.0471</item>
-        <item name="spotShadowAlpha">0.1765</item>
+        <item name="ambientShadowAlpha">0.06</item>
+        <item name="spotShadowAlpha">0.22</item>
     </style>
 
 </resources>
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 636f218..7123bfe 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1641,8 +1641,9 @@
     mCaches.disableTexCoordsVertexArray();
 }
 
-void OpenGLRenderer::setupDrawAA() {
+void OpenGLRenderer::setupDrawAA(bool useShadowInterp) {
     mDescription.isAA = true;
+    mDescription.isShadowAA = useShadowInterp;
 }
 
 void OpenGLRenderer::setupDrawColor(int color, int alpha) {
@@ -2365,7 +2366,7 @@
 }
 
 status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
-        const VertexBuffer& vertexBuffer, const SkPaint* paint, bool useOffset) {
+        const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) {
     // not missing call to quickReject/dirtyLayer, always done at a higher level
     if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
@@ -2381,13 +2382,14 @@
 
     setupDraw();
     setupDrawNoTexture();
-    if (isAA) setupDrawAA();
+    if (isAA) setupDrawAA((displayFlags & kVertexBuffer_ShadowAA));
     setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
     setupDrawColorFilter(getColorFilter(paint));
     setupDrawShader(getShader(paint));
     setupDrawBlending(paint, isAA);
     setupDrawProgram();
-    setupDrawModelView(kModelViewMode_Translate, useOffset, translateX, translateY, 0, 0);
+    setupDrawModelView(kModelViewMode_Translate, (displayFlags & kVertexBuffer_Offset),
+            translateX, translateY, 0, 0);
     setupDrawColorUniforms(getShader(paint));
     setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawShaderUniforms(getShader(paint));
@@ -2397,7 +2399,6 @@
     mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride);
     mCaches.resetTexCoordsVertexPointer();
 
-
     int alphaSlot = -1;
     if (isAA) {
         void* alphaCoords = ((GLbyte*) vertices) + gVertexAlphaOffset;
@@ -2466,8 +2467,8 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
+    return drawVertexBuffer(buffer, paint, displayFlags);
 }
 
 status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
@@ -2483,8 +2484,8 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
+    return drawVertexBuffer(buffer, paint, displayFlags);
 }
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -3167,12 +3168,12 @@
 
     if (ambientShadowVertexBuffer && mAmbientShadowAlpha > 0) {
         paint.setARGB(casterAlpha * mAmbientShadowAlpha, 0, 0, 0);
-        drawVertexBuffer(*ambientShadowVertexBuffer, &paint);
+        drawVertexBuffer(*ambientShadowVertexBuffer, &paint, kVertexBuffer_ShadowAA);
     }
 
     if (spotShadowVertexBuffer && mSpotShadowAlpha > 0) {
         paint.setARGB(casterAlpha * mSpotShadowAlpha, 0, 0, 0);
-        drawVertexBuffer(*spotShadowVertexBuffer, &paint);
+        drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowAA);
     }
 
     return DrawGlInfo::kStatusDrew;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index fd228db..2a9badd 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -94,6 +94,11 @@
     kClipSide_ConservativeFull = 0x1F
 };
 
+enum VertexBufferDisplayFlags {
+    kVertexBuffer_Offset = 0x1,
+    kVertexBuffer_ShadowAA = 0x2,
+};
+
 /**
  * Defines additional transformation that should be applied by the model view matrix, beyond that of
  * the currentTransform()
@@ -656,17 +661,17 @@
      *
      * @param vertexBuffer The VertexBuffer to be drawn
      * @param paint The paint to render with
-     * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
+     * @param flags flags with which to draw
      */
     status_t drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
-            const SkPaint* paint, bool useOffset = false);
+            const SkPaint* paint, int flags = 0);
 
     /**
      * Convenience for translating method
      */
     status_t drawVertexBuffer(const VertexBuffer& vertexBuffer,
-            const SkPaint* paint, bool useOffset = false) {
-        return drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, useOffset);
+            const SkPaint* paint, int flags = 0) {
+        return drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
     }
 
     /**
@@ -842,7 +847,7 @@
     void setupDrawWithTextureAndColor(bool isAlpha8 = false);
     void setupDrawWithExternalTexture();
     void setupDrawNoTexture();
-    void setupDrawAA();
+    void setupDrawAA(bool useShadowInterp);
     void setupDrawColor(int color, int alpha);
     void setupDrawColor(float r, float g, float b, float a);
     void setupDrawAlpha8Color(int color, int alpha);
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 3e191d0..1d95c40 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -72,19 +72,20 @@
 #define PROGRAM_MODULATE_SHIFT 35
 
 #define PROGRAM_HAS_AA_SHIFT 36
+#define PROGRAM_HAS_SHADOW_AA_SHIFT 37
 
-#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 37
-#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 38
+#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
+#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
 
-#define PROGRAM_HAS_GAMMA_CORRECTION 39
+#define PROGRAM_HAS_GAMMA_CORRECTION 40
 
-#define PROGRAM_IS_SIMPLE_GRADIENT 40
+#define PROGRAM_IS_SIMPLE_GRADIENT 41
 
-#define PROGRAM_HAS_COLORS 41
+#define PROGRAM_HAS_COLORS 42
 
-#define PROGRAM_HAS_DEBUG_HIGHLIGHT 42
-#define PROGRAM_EMULATE_STENCIL 43
-#define PROGRAM_HAS_ROUND_RECT_CLIP 44
+#define PROGRAM_HAS_DEBUG_HIGHLIGHT 43
+#define PROGRAM_EMULATE_STENCIL 44
+#define PROGRAM_HAS_ROUND_RECT_CLIP 45
 
 ///////////////////////////////////////////////////////////////////////////////
 // Types
@@ -135,6 +136,7 @@
     bool isBitmapNpot;
 
     bool isAA; // drawing with a per-vertex alpha
+    bool isShadowAA; // drawing per vertex alpha with shadow interpolation
 
     bool hasGradient;
     Gradient gradientType;
@@ -175,6 +177,7 @@
         hasColors = false;
 
         isAA = false;
+        isShadowAA = false;
 
         modulate = false;
 
@@ -262,6 +265,7 @@
         if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
         if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
         if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
+        if (isShadowAA) key |= programid(0x1) << PROGRAM_HAS_SHADOW_AA_SHIFT;
         if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
         if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
         if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 3ef2a71..2dd89b8 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -121,8 +121,12 @@
 const char* gVS_Main_Position =
         "    vec4 transformedPosition = projection * transform * position;\n"
         "    gl_Position = transformedPosition;\n";
+
+const char* gVS_Main_ShadowAAVertexShape =
+        "    alpha = pow(vtxAlpha, 0.667);\n";
 const char* gVS_Main_AAVertexShape =
         "    alpha = vtxAlpha;\n";
+
 const char* gVS_Main_HasRoundRectClip =
         "    roundRectPos = (roundRectInvTransform * transformedPosition).xy;\n";
 const char* gVS_Footer =
@@ -237,6 +241,8 @@
         "    fragColor *= color.a;\n";
 const char* gFS_Main_AccountForAAVertexShape =
         "    fragColor *= alpha;\n";
+const char* gFS_Main_AccountForShadowAAVertexShape =
+        "    fragColor *= pow(alpha, 1.5);\n";
 
 const char* gFS_Main_FetchTexture[2] = {
         // Don't modulate
@@ -515,7 +521,11 @@
             shader.append(gVS_Main_OutTexCoords);
         }
         if (description.isAA) {
-            shader.append(gVS_Main_AAVertexShape);
+            if (description.isShadowAA) {
+                shader.append(gVS_Main_ShadowAAVertexShape);
+            } else {
+                shader.append(gVS_Main_AAVertexShape);
+            }
         }
         if (description.hasColors) {
             shader.append(gVS_Main_OutColors);
@@ -750,7 +760,11 @@
         shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
 
         if (description.isAA) {
-            shader.append(gFS_Main_AccountForAAVertexShape);
+            if (description.isShadowAA) {
+                shader.append(gFS_Main_AccountForShadowAAVertexShape);
+            } else {
+                shader.append(gFS_Main_AccountForAAVertexShape);
+            }
         }
 
         // Output the fragment