Fold alpha to the draw in savelayer-draw-restore patterns with non-opaque draw

Fold alpha of a save layer call to the subsequent draw call paint, even when
the draw call paint color is already non-opaque.

Comparing the difference of the unoptimized and the optimized call pattern
with all (layer alpha, draw alpha) combinations, this produces
off-by-one pixels ~50% of the time.

Reduces layers of current desk_carsvg.skp (recorded with cross-process
picture image filters allowed) from 122 to 115.

BUG=skia:3119

Review URL: https://codereview.chromium.org/840483005
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
index 7ab8054..df29b1b 100644
--- a/src/core/SkRecordOpts.cpp
+++ b/src/core/SkRecordOpts.cpp
@@ -106,14 +106,12 @@
 
         const uint32_t layerColor = layerPaint->getColor();
         const uint32_t  drawColor =  drawPaint->getColor();
-        if (!IsOnlyAlpha(layerColor)  || !IsOpaque(drawColor) ||
-            HasAnyEffect(*layerPaint) || CantFoldAlpha(*drawPaint)) {
-            // Too fancy for us.  Actually, as long as layerColor is just an alpha
-            // we can blend it into drawColor's alpha; drawColor doesn't strictly have to be opaque.
+        if (!IsOnlyAlpha(layerColor) || HasAnyEffect(*layerPaint) || CantFoldAlpha(*drawPaint)) {
+            // Too fancy for us.
             return false;
         }
 
-        drawPaint->setColor(SkColorSetA(drawColor, SkColorGetA(layerColor)));
+        drawPaint->setAlpha(SkMulDiv255Round(SkColorGetA(drawColor), SkColorGetA(layerColor)));
         return KillSaveLayerAndRestore(record, begin);
     }
 
@@ -145,9 +143,6 @@
                paint.getImageFilter();
     }
 
-    static bool IsOpaque(SkColor color) {
-        return SkColorGetA(color) == SK_AlphaOPAQUE;
-    }
     static bool IsOnlyAlpha(SkColor color) {
         return SK_ColorTRANSPARENT == SkColorSetA(color, SK_AlphaTRANSPARENT);
     }
diff --git a/tests/RecordOptsTest.cpp b/tests/RecordOptsTest.cpp
index eaeb737..b6bfba4 100644
--- a/tests/RecordOptsTest.cpp
+++ b/tests/RecordOptsTest.cpp
@@ -118,50 +118,50 @@
     SkRect bounds = SkRect::MakeWH(100, 200);
     SkRect   draw = SkRect::MakeWH(50, 60);
 
-    SkPaint goodLayerPaint, badLayerPaint, worseLayerPaint;
-    goodLayerPaint.setColor(0x03000000);  // Only alpha.
-    badLayerPaint.setColor( 0x03040506);  // Not only alpha.
-    worseLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
+    SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint;
+    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
+    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
+    xfermodeLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
 
-    SkPaint goodDrawPaint, badDrawPaint;
-    goodDrawPaint.setColor(0xFF020202);  // Opaque.
-    badDrawPaint.setColor( 0x0F020202);  // Not opaque.
+    SkPaint opaqueDrawPaint, translucentDrawPaint;
+    opaqueDrawPaint.setColor(0xFF020202);  // Opaque.
+    translucentDrawPaint.setColor(0x0F020202);  // Not opaque.
 
     // SaveLayer/Restore removed: No paint = no point.
     recorder.saveLayer(NULL, NULL);
-        recorder.drawRect(draw, goodDrawPaint);
+        recorder.drawRect(draw, opaqueDrawPaint);
     recorder.restore();
     assert_savelayer_restore(r, &record, 0, true);
 
     // Bounds don't matter.
     recorder.saveLayer(&bounds, NULL);
-        recorder.drawRect(draw, goodDrawPaint);
+        recorder.drawRect(draw, opaqueDrawPaint);
     recorder.restore();
     assert_savelayer_restore(r, &record, 3, true);
 
     // TODO(mtklein): test case with null draw paint
 
     // No change: layer paint isn't alpha-only.
-    recorder.saveLayer(NULL, &badLayerPaint);
-        recorder.drawRect(draw, goodDrawPaint);
+    recorder.saveLayer(NULL, &translucentLayerPaint);
+        recorder.drawRect(draw, opaqueDrawPaint);
     recorder.restore();
     assert_savelayer_restore(r, &record, 6, false);
 
     // No change: layer paint has an effect.
-    recorder.saveLayer(NULL, &worseLayerPaint);
-        recorder.drawRect(draw, goodDrawPaint);
+    recorder.saveLayer(NULL, &xfermodeLayerPaint);
+        recorder.drawRect(draw, opaqueDrawPaint);
     recorder.restore();
     assert_savelayer_restore(r, &record, 9, false);
 
-    // No change: draw paint isn't opaque.
-    recorder.saveLayer(NULL, &goodLayerPaint);
-        recorder.drawRect(draw, badDrawPaint);
+    // SaveLayer/Restore removed: we can fold in the alpha!
+    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
+        recorder.drawRect(draw, translucentDrawPaint);
     recorder.restore();
-    assert_savelayer_restore(r, &record, 12, false);
+    assert_savelayer_restore(r, &record, 12, true);
 
     // SaveLayer/Restore removed: we can fold in the alpha!
-    recorder.saveLayer(NULL, &goodLayerPaint);
-        recorder.drawRect(draw, goodDrawPaint);
+    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
+        recorder.drawRect(draw, opaqueDrawPaint);
     recorder.restore();
     assert_savelayer_restore(r, &record, 15, true);