Merge latest Skia into master (2 commits)

https://skia.googlesource.com/skia.git/+log/70a309a..0831f1b

Test: Presubmit checks will test this change.
Change-Id: I68f06ec39c19a6c7f81637d937cfec501ab6dcc8
diff --git a/Android.bp b/Android.bp
index daaccac..aa98366 100644
--- a/Android.bp
+++ b/Android.bp
@@ -404,6 +404,7 @@
         "src/gpu/GrPrimitiveProcessor.cpp",
         "src/gpu/GrProcOptInfo.cpp",
         "src/gpu/GrProcessor.cpp",
+        "src/gpu/GrProcessorSet.cpp",
         "src/gpu/GrProcessorUnitTest.cpp",
         "src/gpu/GrProgramDesc.cpp",
         "src/gpu/GrRectanizer_pow2.cpp",
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 61dea74..8629ecd 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -144,6 +144,8 @@
   "$_src/gpu/GrPipelineBuilder.h",
   "$_src/gpu/GrPrimitiveProcessor.cpp",
   "$_src/gpu/GrPrimitiveProcessor.h",
+  "$_src/gpu/GrProcessorSet.cpp",
+  "$_src/gpu/GrProcessorSet.h",
   "$_src/gpu/GrProgramDesc.cpp",
   "$_src/gpu/GrProgramDesc.h",
   "$_src/gpu/GrProcessor.cpp",
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 6897679..3b136ac 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -169,7 +169,7 @@
 private:
     GrPaint& operator=(const GrPaint&) = delete;
 
-    friend class GrPipelineBuilder;
+    friend class GrProcessorSet;
 
     bool internalIsConstantBlendedColor(GrColor paintColor, GrColor* constantColor) const;
 
diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h
index 71905ac..0e065c2 100644
--- a/include/gpu/GrProgramElement.h
+++ b/include/gpu/GrProgramElement.h
@@ -117,6 +117,7 @@
 
     // Only this class can access addPendingExecution() and completedExecution().
     template <typename T> friend class GrPendingProgramElement;
+    friend class GrProcessorSet;
 
     typedef SkNoncopyable INHERITED;
 };
diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h
index f50af8b..c45de75 100644
--- a/include/private/SkTemplates.h
+++ b/include/private/SkTemplates.h
@@ -204,6 +204,14 @@
      */
     T* get() const { return fArray; }
 
+    T* begin() { return fArray; }
+
+    const T* begin() const { return fArray; }
+
+    T* end() { return fArray + fCount; }
+
+    const T* end() const { return fArray + fCount; }
+
     /** Return the nth element in the array
      */
     T&  operator[](int index) const {
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 977974d..eb6a35c 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -341,7 +341,7 @@
 
     // Run the through the series, do the invariant output processing, and look for eliminations.
     GrProcOptInfo info(0x0, kNone_GrColorComponentFlags);
-    info.addProcessors(sk_sp_address_as_pointer_address(series), cnt);
+    info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt);
     if (kRGBA_GrColorComponentFlags == info.validFlags()) {
         // TODO: We need to preserve 4f and color spaces during invariant processing. This color
         // has definitely lost precision, and could easily be in the wrong gamut (or have been
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 7143b46..5bcd28a 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -46,8 +46,9 @@
 
 bool GrPaint::internalIsConstantBlendedColor(GrColor paintColor, GrColor* color) const {
     GrProcOptInfo colorProcInfo(paintColor, kRGBA_GrColorComponentFlags);
-    colorProcInfo.addProcessors(sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()),
-                                this->numColorFragmentProcessors());
+    colorProcInfo.analyzeProcessors(
+            sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()),
+            this->numColorFragmentProcessors());
 
     GrXPFactory::InvariantBlendedColor blendedColor;
     if (fXPFactory) {
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index fce8aa9..ce38718 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -18,18 +18,10 @@
 GrPipelineBuilder::GrPipelineBuilder(GrPaint&& paint, GrAAType aaType)
         : fFlags(0x0)
         , fUserStencilSettings(&GrUserStencilSettings::kUnused)
-        , fDrawFace(GrDrawFace::kBoth) {
-    for (int i = 0; i < paint.numColorFragmentProcessors(); ++i) {
-        fColorFragmentProcessors.emplace_back(paint.fColorFragmentProcessors[i].release());
-    }
-
-    for (int i = 0; i < paint.numCoverageFragmentProcessors(); ++i) {
-        fCoverageFragmentProcessors.emplace_back(paint.fCoverageFragmentProcessors[i].release());
-    }
-
-    fXPFactory = paint.getXPFactory();
-
+        , fDrawFace(GrDrawFace::kBoth)
+        , fProcessors(std::move(paint)) {
     this->setState(GrPipelineBuilder::kHWAntialias_Flag, GrAATypeIsHW(aaType));
+    // The processors have been moved out of paint, but its flags should still be unmodified.
     this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag,
                    paint.getDisableOutputConversionToSRGB());
     this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag,
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index fcc692a..e0c4d3d 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -8,26 +8,19 @@
 #ifndef GrPipelineBuilder_DEFINED
 #define GrPipelineBuilder_DEFINED
 
-#include "GrBlend.h"
-#include "GrCaps.h"
 #include "GrGpuResourceRef.h"
-#include "GrProcOptInfo.h"
+#include "GrProcessorSet.h"
 #include "GrRenderTarget.h"
 #include "GrUserStencilSettings.h"
 #include "GrXferProcessor.h"
-#include "SkMatrix.h"
-#include "SkRefCnt.h"
-#include "effects/GrCoverageSetOpXP.h"
-#include "effects/GrDisableColorXP.h"
-#include "effects/GrPorterDuffXferProcessor.h"
-#include "effects/GrSimpleTextureEffect.h"
 
-class GrDrawOp;
 class GrCaps;
+class GrDrawOp;
 class GrPaint;
+struct GrPipelineAnalysis;
 class GrTexture;
 
-class GrPipelineBuilder : public SkNoncopyable {
+class GrPipelineBuilder : private SkNoncopyable {
 public:
     /**
      * Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note
@@ -47,16 +40,21 @@
     /// feed their output to the GrXferProcessor which controls blending.
     ////
 
-    int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
-    int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
-    int numFragmentProcessors() const { return this->numColorFragmentProcessors() +
-                                               this->numCoverageFragmentProcessors(); }
+    int numColorFragmentProcessors() const { return fProcessors.numColorFragmentProcessors(); }
+    int numCoverageFragmentProcessors() const {
+        return fProcessors.numCoverageFragmentProcessors();
+    }
+    int numFragmentProcessors() const { return fProcessors.numFragmentProcessors(); }
 
     const GrFragmentProcessor* getColorFragmentProcessor(int idx) const {
-        return fColorFragmentProcessors[idx].get();
+        return fProcessors.colorFragmentProcessor(idx);
     }
     const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const {
-        return fCoverageFragmentProcessors[idx].get();
+        return fProcessors.coverageFragmentProcessor(idx);
+    }
+
+    void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const {
+        fProcessors.analyzeFragmentProcessors(analysis);
     }
 
     /// @}
@@ -65,7 +63,7 @@
     /// @name Blending
     ////
 
-    const GrXPFactory* getXPFactory() const { return fXPFactory; }
+    const GrXPFactory* getXPFactory() const { return fProcessors.xpFactory(); }
 
     /**
      * Checks whether the xp will need destination in a texture to correctly blend.
@@ -201,20 +199,10 @@
     bool usePLSDstRead(const GrDrawOp*) const;
 
 private:
-    typedef SkSTArray<4, sk_sp<GrFragmentProcessor>> FragmentProcessorArray;
-
-    uint32_t                                fFlags;
-    const GrUserStencilSettings*            fUserStencilSettings;
-    GrDrawFace                              fDrawFace;
-    const GrXPFactory*                      fXPFactory;
-    FragmentProcessorArray                  fColorFragmentProcessors;
-    FragmentProcessorArray                  fCoverageFragmentProcessors;
-
-    friend class GrPipeline;
-    // This gives the GrRenderTargetOpList raw access to fColorFragmentProcessors &
-    // fCoverageFragmentProcessors
-    // TODO: that access seems a little dodgy
-    friend class GrRenderTargetOpList;
+    uint32_t fFlags;
+    const GrUserStencilSettings* fUserStencilSettings;
+    GrDrawFace fDrawFace;
+    GrProcessorSet fProcessors;
 };
 
 #endif
diff --git a/src/gpu/GrProcOptInfo.cpp b/src/gpu/GrProcOptInfo.cpp
index 1493206..f184823 100644
--- a/src/gpu/GrProcOptInfo.cpp
+++ b/src/gpu/GrProcOptInfo.cpp
@@ -9,7 +9,7 @@
 #include "GrGeometryProcessor.h"
 #include "ops/GrDrawOp.h"
 
-void GrProcOptInfo::addProcessors(const GrFragmentProcessor* const* processors, int cnt) {
+void GrProcOptInfo::analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt) {
     for (int i = 0; i < cnt; ++i) {
         const GrFragmentProcessor* processor = processors[i];
         fInOut.resetWillUseInputColor();
diff --git a/src/gpu/GrProcOptInfo.h b/src/gpu/GrProcOptInfo.h
index 8149f2c..6b04004 100644
--- a/src/gpu/GrProcOptInfo.h
+++ b/src/gpu/GrProcOptInfo.h
@@ -43,7 +43,7 @@
      * Runs through a series of processors and updates calculated values. This can be called
      * repeatedly for cases when the sequence of processors is not in a contiguous array.
      */
-    void addProcessors(const GrFragmentProcessor* const* processors, int cnt);
+    void analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt);
 
     bool isSolidWhite() const { return fInOut.isSolidWhite(); }
     bool isOpaque() const { return fInOut.isOpaque(); }
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
new file mode 100644
index 0000000..0d72d9b
--- /dev/null
+++ b/src/gpu/GrProcessorSet.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrProcessorSet.h"
+
+GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
+    fXPFactory = paint.fXPFactory;
+    fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
+    fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
+    int i = 0;
+    for (auto& fp : paint.fColorFragmentProcessors) {
+        fFragmentProcessors[i++] = fp.release();
+    }
+    for (auto& fp : paint.fCoverageFragmentProcessors) {
+        fFragmentProcessors[i++] = fp.release();
+    }
+}
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
new file mode 100644
index 0000000..de9c0a6
--- /dev/null
+++ b/src/gpu/GrProcessorSet.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProcessorSet_DEFINED
+#define GrProcessorSet_DEFINED
+
+#include "GrFragmentProcessor.h"
+#include "GrPaint.h"
+#include "GrPipeline.h"
+#include "SkTemplates.h"
+
+class GrXPFactory;
+
+class GrProcessorSet : private SkNoncopyable {
+public:
+    GrProcessorSet(GrPaint&& paint);
+
+    ~GrProcessorSet() {
+        // We are deliberately not using sk_sp here because this will be updated to work with
+        // "pending execution" refs.
+        for (auto fp : fFragmentProcessors) {
+            fp->unref();
+        }
+    }
+
+    int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
+    int numCoverageFragmentProcessors() const {
+        return fFragmentProcessors.count() - fColorFragmentProcessorCnt;
+    }
+    int numFragmentProcessors() const { return fFragmentProcessors.count(); }
+
+    const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
+        SkASSERT(idx < fColorFragmentProcessorCnt);
+        return fFragmentProcessors[idx];
+    }
+    const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
+        return fFragmentProcessors[idx + fColorFragmentProcessorCnt];
+    }
+
+    const GrXPFactory* xpFactory() const { return fXPFactory; }
+
+    void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const {
+        const GrFragmentProcessor* const* fps = fFragmentProcessors.get();
+        analysis->fColorPOI.analyzeProcessors(fps, fColorFragmentProcessorCnt);
+        fps += fColorFragmentProcessorCnt;
+        analysis->fCoveragePOI.analyzeProcessors(fps, this->numCoverageFragmentProcessors());
+    }
+
+private:
+    const GrXPFactory* fXPFactory = nullptr;
+    SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
+    int fColorFragmentProcessorCnt;
+};
+
+#endif
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index e4bb34e..144b399 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -264,8 +264,7 @@
 void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
                                      GrRenderTargetContext* renderTargetContext,
                                      const GrClip& clip,
-                                     std::unique_ptr<GrDrawOp>
-                                             op) {
+                                     std::unique_ptr<GrDrawOp> op) {
     // Setup clip
     SkRect bounds;
     op_bounds(&bounds, op.get());
@@ -312,14 +311,9 @@
             return;
         }
     }
-    args.fAnalysis.fColorPOI.addProcessors(
-            sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
-            pipelineBuilder.numColorFragmentProcessors());
-    args.fAnalysis.fCoveragePOI.addProcessors(
-            sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
-            pipelineBuilder.numCoverageFragmentProcessors());
+    pipelineBuilder.analyzeFragmentProcessors(&args.fAnalysis);
     if (const GrFragmentProcessor* clipFP = appliedClip.clipCoverageFragmentProcessor()) {
-        args.fAnalysis.fCoveragePOI.addProcessors(&clipFP, 1);
+        args.fAnalysis.fCoveragePOI.analyzeProcessors(&clipFP, 1);
     }
 
     if (!renderTargetContext->accessRenderTarget()) {