Remove GrGLSLFragProcs typedef. Use unique_ptr to for GrGLSLFragmentProcessor ownership.

Change-Id: Ifefbde2ec0002e7e41bed2e4bc2cd7bdd04504d0
Reviewed-on: https://skia-review.googlesource.com/132931
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 95b1f0c..1be8126 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -26,26 +26,28 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 GrGLProgram::GrGLProgram(GrGLGpu* gpu,
-                         const GrProgramDesc& desc,
-                         const BuiltinUniformHandles& builtinUniforms,
-                         GrGLuint programID,
-                         const UniformInfoArray& uniforms,
-                         const UniformInfoArray& textureSamplers,
-                         const UniformInfoArray& texelBuffers,
-                         const VaryingInfoArray& pathProcVaryings,
-                         std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
-                         std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
-                         const GrGLSLFragProcs& fragmentProcessors)
-    : fBuiltinUniformHandles(builtinUniforms)
-    , fProgramID(programID)
-    , fGeometryProcessor(std::move(geometryProcessor))
-    , fXferProcessor(std::move(xferProcessor))
-    , fFragmentProcessors(fragmentProcessors)
-    , fDesc(desc)
-    , fGpu(gpu)
-    , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
-    , fNumTextureSamplers(textureSamplers.count())
-    , fNumTexelBuffers(texelBuffers.count()) {
+        const GrProgramDesc& desc,
+        const BuiltinUniformHandles& builtinUniforms,
+        GrGLuint programID,
+        const UniformInfoArray& uniforms,
+        const UniformInfoArray& textureSamplers,
+        const UniformInfoArray& texelBuffers,
+        const VaryingInfoArray& pathProcVaryings,
+        std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
+        std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
+        std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
+        int fragmentProcessorCnt)
+        : fBuiltinUniformHandles(builtinUniforms)
+        , fProgramID(programID)
+        , fGeometryProcessor(std::move(geometryProcessor))
+        , fXferProcessor(std::move(xferProcessor))
+        , fFragmentProcessors(std::move(fragmentProcessors))
+        , fFragmentProcessorCnt(fragmentProcessorCnt)
+        , fDesc(desc)
+        , fGpu(gpu)
+        , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
+        , fNumTextureSamplers(textureSamplers.count())
+        , fNumTexelBuffers(texelBuffers.count()) {
     // Assign texture units to sampler uniforms one time up front.
     GL_CALL(UseProgram(fProgramID));
     fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
@@ -56,9 +58,6 @@
     if (fProgramID) {
         GL_CALL(DeleteProgram(fProgramID));
     }
-    for (int i = 0; i < fFragmentProcessors.count(); ++i) {
-        delete fFragmentProcessors[i];
-    }
 }
 
 void GrGLProgram::abandon() {
@@ -113,8 +112,7 @@
                                   int* nextTexSamplerIdx,
                                   int* nextTexelBufferIdx) {
     GrFragmentProcessor::Iter iter(pipeline);
-    GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
-                                           fFragmentProcessors.count());
+    GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
     const GrFragmentProcessor* fp = iter.next();
     GrGLSLFragmentProcessor* glslFP = glslIter.next();
     while (fp && glslFP) {
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index b49b410..79d27b0 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -116,7 +116,8 @@
                 const VaryingInfoArray&, // used for NVPR only currently
                 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
                 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
-                const GrGLSLFragProcs& fragmentProcessors);
+                std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
+                int fragmentProcessorCnt);
 
     // A helper to loop over effects, set the transforms (via subclass) and bind textures
     void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx,
@@ -139,7 +140,8 @@
     // the installed effects
     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
-    GrGLSLFragProcs fFragmentProcessors;
+    std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
+    int fFragmentProcessorCnt;
 
     GrProgramDesc fDesc;
     GrGLGpu* fGpu;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 071a091..6583902 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -55,7 +55,6 @@
         // to skip the SkSL->GLSL step on a cache hit.
     }
     if (!builder.emitAndInstallProcs()) {
-        builder.cleanupFragmentProcessors();
         return nullptr;
     }
     return builder.finalize();
@@ -137,7 +136,6 @@
     GrGLuint programID;
     GL_CALL_RET(programID, CreateProgram());
     if (0 == programID) {
-        this->cleanupFragmentProcessors();
         return nullptr;
     }
 
@@ -378,7 +376,6 @@
 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
     GL_CALL(DeleteProgram(programID));
     this->cleanupShaders(shaderIDs);
-    this->cleanupFragmentProcessors();
 }
 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
     for (int i = 0; i < shaderIDs.count(); ++i) {
@@ -397,5 +394,6 @@
                            fVaryingHandler.fPathProcVaryingInfos,
                            std::move(fGeometryProcessor),
                            std::move(fXferProcessor),
-                           fFragmentProcessors);
+                           std::move(fFragmentProcessors),
+                           fFragmentProcessorCnt);
 }
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 0fed0ea..1b12fb6 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -169,9 +169,9 @@
     class Iter : public SkNoncopyable {
     public:
         explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
-        explicit Iter(GrGLSLFragmentProcessor* fps[], int cnt) {
+        explicit Iter(std::unique_ptr<GrGLSLFragmentProcessor> fps[], int cnt) {
             for (int i = cnt - 1; i >= 0; --i) {
-                fFPStack.push_back(fps[i]);
+                fFPStack.push_back(fps[i].get());
             }
         }
         GrGLSLFragmentProcessor* next();
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 91ac5c3..cae1c2a 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -128,28 +128,37 @@
 void GrGLSLProgramBuilder::emitAndInstallFragProcs(SkString* color, SkString* coverage) {
     int transformedCoordVarsIdx = 0;
     SkString** inOut = &color;
+    SkSTArray<8, std::unique_ptr<GrGLSLFragmentProcessor>> glslFragmentProcessors;
     for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) {
         if (i == this->pipeline().numColorFragmentProcessors()) {
             inOut = &coverage;
         }
         SkString output;
         const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i);
-        output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output);
+        output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output,
+                                              &glslFragmentProcessors);
         GrFragmentProcessor::Iter iter(&fp);
         while (const GrFragmentProcessor* fp = iter.next()) {
             transformedCoordVarsIdx += fp->numCoordTransforms();
         }
         **inOut = output;
     }
+    fFragmentProcessorCnt = glslFragmentProcessors.count();
+    fFragmentProcessors.reset(new std::unique_ptr<GrGLSLFragmentProcessor>[fFragmentProcessorCnt]);
+    for (int i = 0; i < fFragmentProcessorCnt; ++i) {
+        fFragmentProcessors[i] = std::move(glslFragmentProcessors[i]);
+    }
 }
 
 // TODO Processors cannot output zeros because an empty string is all 1s
 // the fix is to allow effects to take the SkString directly
-SkString GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
-                                                      int index,
-                                                      int transformedCoordVarsIdx,
-                                                      const SkString& input,
-                                                      SkString output) {
+SkString GrGLSLProgramBuilder::emitAndInstallFragProc(
+        const GrFragmentProcessor& fp,
+        int index,
+        int transformedCoordVarsIdx,
+        const SkString& input,
+        SkString output,
+        SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>* glslFragmentProcessors) {
     SkASSERT(input.size());
     // Program builders have a bit of state we need to clear with each effect
     AutoStageAdvance adv(this);
@@ -188,7 +197,7 @@
     // We have to check that effects and the code they emit are consistent, ie if an effect
     // asks for dst color, then the emit code needs to follow suit
     SkDEBUGCODE(verify(fp);)
-    fFragmentProcessors.push_back(fragProc);
+    glslFragmentProcessors->emplace_back(fragProc);
 
     fFS.codeAppend("}");
     return output;
@@ -403,12 +412,6 @@
                                                     name, false, 0, nullptr);
 }
 
-void GrGLSLProgramBuilder::cleanupFragmentProcessors() {
-    for (int i = 0; i < fFragmentProcessors.count(); ++i) {
-        delete fFragmentProcessors[i];
-    }
-}
-
 void GrGLSLProgramBuilder::finalizeShaders() {
     this->varyingHandler()->finalize();
     fVS.finalize(kVertex_GrShaderFlag);
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index d4d2099..04d169d 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -24,8 +24,6 @@
 class SkString;
 class GrShaderCaps;
 
-typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
-
 class GrGLSLProgramBuilder {
 public:
     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
@@ -100,7 +98,8 @@
 
     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
-    GrGLSLFragProcs fFragmentProcessors;
+    std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
+    int fFragmentProcessorCnt;
 
 protected:
     explicit GrGLSLProgramBuilder(const GrPipeline&,
@@ -111,8 +110,6 @@
 
     bool emitAndInstallProcs();
 
-    void cleanupFragmentProcessors();
-
     void finalizeShaders();
 
     bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
@@ -151,7 +148,8 @@
                                     int index,
                                     int transformedCoordVarsIdx,
                                     const SkString& input,
-                                    SkString output);
+                                    SkString output,
+                                    SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
     void emitSamplers(const GrResourceIOProcessor& processor,
                       SkTArray<SamplerHandle>* outTexSamplerHandles,
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 5d4189f..f49e636 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -30,33 +30,35 @@
 #include "SkMipMap.h"
 
 GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
-                                     const GrVkPipelineState::Desc& desc,
-                                     GrVkPipeline* pipeline,
-                                     VkPipelineLayout layout,
-                                     const GrVkDescriptorSetManager::Handle& samplerDSHandle,
-                                     const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
-                                     const BuiltinUniformHandles& builtinUniformHandles,
-                                     const UniformInfoArray& uniforms,
-                                     uint32_t geometryUniformSize,
-                                     uint32_t fragmentUniformSize,
-                                     uint32_t numSamplers,
-                                     uint32_t numTexelBuffers,
-                                     std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
-                                     std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
-                                     const GrGLSLFragProcs& fragmentProcessors)
-    : fPipeline(pipeline)
-    , fPipelineLayout(layout)
-    , fUniformDescriptorSet(nullptr)
-    , fSamplerDescriptorSet(nullptr)
-    , fTexelBufferDescriptorSet(nullptr)
-    , fSamplerDSHandle(samplerDSHandle)
-    , fTexelBufferDSHandle(texelBufferDSHandle)
-    , fBuiltinUniformHandles(builtinUniformHandles)
-    , fGeometryProcessor(std::move(geometryProcessor))
-    , fXferProcessor(std::move(xferProcessor))
-    , fFragmentProcessors(fragmentProcessors)
-    , fDesc(desc)
-    , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
+        const GrVkPipelineState::Desc& desc,
+        GrVkPipeline* pipeline,
+        VkPipelineLayout layout,
+        const GrVkDescriptorSetManager::Handle& samplerDSHandle,
+        const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
+        const BuiltinUniformHandles& builtinUniformHandles,
+        const UniformInfoArray& uniforms,
+        uint32_t geometryUniformSize,
+        uint32_t fragmentUniformSize,
+        uint32_t numSamplers,
+        uint32_t numTexelBuffers,
+        std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
+        std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
+        std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
+        int fragmentProcessorCnt)
+        : fPipeline(pipeline)
+        , fPipelineLayout(layout)
+        , fUniformDescriptorSet(nullptr)
+        , fSamplerDescriptorSet(nullptr)
+        , fTexelBufferDescriptorSet(nullptr)
+        , fSamplerDSHandle(samplerDSHandle)
+        , fTexelBufferDSHandle(texelBufferDSHandle)
+        , fBuiltinUniformHandles(builtinUniformHandles)
+        , fGeometryProcessor(std::move(geometryProcessor))
+        , fXferProcessor(std::move(xferProcessor))
+        , fFragmentProcessors(std::move(fragmentProcessors))
+        , fFragmentProcessorCnt(fragmentProcessorCnt)
+        , fDesc(desc)
+        , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
     fSamplers.setReserve(numSamplers);
     fTextureViews.setReserve(numSamplers);
     fTextures.setReserve(numSamplers);
@@ -83,10 +85,6 @@
     SkASSERT(!fTextures.count());
     SkASSERT(!fBufferViews.count());
     SkASSERT(!fTexelBuffers.count());
-
-    for (int i = 0; i < fFragmentProcessors.count(); ++i) {
-        delete fFragmentProcessors[i];
-    }
 }
 
 void GrVkPipelineState::freeTempResources(const GrVkGpu* gpu) {
@@ -245,8 +243,7 @@
     append_texture_bindings(primProc, &textureBindings, &bufferAccesses);
 
     GrFragmentProcessor::Iter iter(pipeline);
-    GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
-                                           fFragmentProcessors.count());
+    GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
     const GrFragmentProcessor* fp = iter.next();
     GrGLSLFragmentProcessor* glslFP = glslIter.next();
     while (fp && glslFP) {
diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h
index 4ccd1d6..92fa5e5 100644
--- a/src/gpu/vk/GrVkPipelineState.h
+++ b/src/gpu/vk/GrVkPipelineState.h
@@ -88,21 +88,23 @@
     typedef GrVkPipelineStateDataManager::UniformInfoArray UniformInfoArray;
     typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
 
-    GrVkPipelineState(GrVkGpu* gpu,
-                      const GrVkPipelineState::Desc&,
-                      GrVkPipeline* pipeline,
-                      VkPipelineLayout layout,
-                      const GrVkDescriptorSetManager::Handle& samplerDSHandle,
-                      const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
-                      const BuiltinUniformHandles& builtinUniformHandles,
-                      const UniformInfoArray& uniforms,
-                      uint32_t geometryUniformSize,
-                      uint32_t fragmentUniformSize,
-                      uint32_t numSamplers,
-                      uint32_t numTexelBuffers,
-                      std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
-                      std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
-                      const GrGLSLFragProcs& fragmentProcessors);
+    GrVkPipelineState(
+            GrVkGpu* gpu,
+            const GrVkPipelineState::Desc&,
+            GrVkPipeline* pipeline,
+            VkPipelineLayout layout,
+            const GrVkDescriptorSetManager::Handle& samplerDSHandle,
+            const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
+            const BuiltinUniformHandles& builtinUniformHandles,
+            const UniformInfoArray& uniforms,
+            uint32_t geometryUniformSize,
+            uint32_t fragmentUniformSize,
+            uint32_t numSamplers,
+            uint32_t numTexelBuffers,
+            std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
+            std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
+            std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
+            int fFragmentProcessorCnt);
 
     void writeUniformBuffers(const GrVkGpu* gpu);
 
@@ -193,7 +195,8 @@
     // Processors in the GrVkPipelineState
     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
-    GrGLSLFragProcs fFragmentProcessors;
+    std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
+    int fFragmentProcessorCnt;
 
     Desc fDesc;
 
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index 392c152..2893a3e 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -28,7 +28,6 @@
     GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);
 
     if (!builder.emitAndInstallProcs()) {
-        builder.cleanupFragmentProcessors();
         return nullptr;
     }
 
@@ -192,7 +191,6 @@
     if (!pipeline) {
         GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
                                                               nullptr));
-        this->cleanupFragmentProcessors();
         return nullptr;
     }
 
@@ -210,6 +208,7 @@
                                  (uint32_t)fUniformHandler.numTexelBuffers(),
                                  std::move(fGeometryProcessor),
                                  std::move(fXferProcessor),
-                                 fFragmentProcessors);
+                                 std::move(fFragmentProcessors),
+                                 fFragmentProcessorCnt);
 }