Revert of Refactor how we store and use samplers in Ganesh (patchset #7 id:120001 of https://codereview.chromium.org/1885863004/ )

Reason for revert:
breaking bots

Original issue's description:
> Refactor how we store and use samplers in Ganesh
>
> The main goal of this refactorization is to allow Vulkan to use separate
> sampler and texture objects in the shader and descriptor sets and combine
> them into a sampler2d in the shader where needed.
>
> A large part of this is separating how we store samplers and uniforms in the
> UniformHandler. We no longer need to store handles to samplers besides when
> we are initially emitting code. After we emit code all we ever do is loop over
> all samplers and do some processor independent work on them, so we have no need
> for direct access to individual samplers.
>
> In the GLProgram all we ever do is set the sampler uniforms in the ctor and never
> touch them again, so no need to save sampler info there. The texture access on
> program reuse just assume that they come in the same order as we set the texture
> units for the samplers
>
> For Vulkan, it is a similar story. We create the descriptor set layouts with the samplers,
> then when we get new textures, we just assume they come in in the same order as we
> set the samplers on the descriptor sets. Thus no need to save direct vulkan info.
>
> BUG=skia:
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1885863004
>
> Committed: https://skia.googlesource.com/skia/+/45b61a1c4c0be896e7b12fd1405abfece799114f

TBR=bsalomon@google.com,jvanverth@google.com,cdalton@nvidia.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1896013003
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 999b806..0b8c2e8 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -344,7 +344,6 @@
       '<(skia_src_path)/gpu/gl/GrGLProgramDataManager.h',
       '<(skia_src_path)/gpu/gl/GrGLRenderTarget.cpp',
       '<(skia_src_path)/gpu/gl/GrGLRenderTarget.h',
-      '<(skia_src_path)/gpu/gl/GrGLSampler.h',
       '<(skia_src_path)/gpu/gl/GrGLStencilAttachment.cpp',
       '<(skia_src_path)/gpu/gl/GrGLStencilAttachment.h',
       '<(skia_src_path)/gpu/gl/GrGLTestInterface.cpp',
@@ -442,7 +441,6 @@
       '<(skia_src_path)/gpu/vk/GrVkExtensions.h',
       '<(skia_src_path)/gpu/vk/GrVkFramebuffer.cpp',
       '<(skia_src_path)/gpu/vk/GrVkFramebuffer.h',
-      '<(skia_src_path)/gpu/vk/GrVkGLSLSampler.h',
       '<(skia_src_path)/gpu/vk/GrVkGpu.cpp',
       '<(skia_src_path)/gpu/vk/GrVkGpu.h',
       '<(skia_src_path)/gpu/vk/GrVkImage.cpp',
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 2afb42f..a1acf65 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -691,7 +691,7 @@
 };
 
 void OutputRectBlurProfileLookup(GrGLSLFPFragmentBuilder* fragBuilder,
-                                 GrGLSLFragmentProcessor::SamplerHandle sampler,
+                                 const GrGLSLSampler& sampler,
                                  const char *output,
                                  const char *profileSize, const char *loc,
                                  const char *blurred_width,
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index fdb6e59..779756f 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -1027,7 +1027,7 @@
                                    const char* gradientTValue,
                                    const char* outputColor,
                                    const char* inputColor,
-                                   const SamplerHandle* texSamplers) {
+                                   const SamplerArray& texSamplers) {
     if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){
         fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
                                  uniformHandler->getUniformVariable(fColorStartUni).c_str(),
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 0280fca..0677cf0 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -423,7 +423,7 @@
                    const char* gradientTValue,
                    const char* outputColor,
                    const char* inputColor,
-                   const SamplerHandle* texSamplers);
+                   const SamplerArray& texSamplers);
 
 private:
     enum {
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index cf6ebe5..4394c0e 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -49,7 +49,7 @@
                                               const GrTextureDomain& textureDomain,
                                               const char* outColor,
                                               const SkString& inCoords,
-                                              GrGLSLFragmentProcessor::SamplerHandle sampler,
+                                              const GrGLSLSampler& sampler,
                                               const char* inModulateColor) {
     SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
     SkDEBUGCODE(fMode = textureDomain.mode();)
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 387016e..2877c39 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -120,7 +120,7 @@
                            const GrTextureDomain& textureDomain,
                            const char* outColor,
                            const SkString& inCoords,
-                           GrGLSLFragmentProcessor::SamplerHandle sampler,
+                           const GrGLSLSampler& sampler,
                            const char* inModulateColor = nullptr);
 
         /**
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index c270858..6a433e1 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -31,11 +31,11 @@
                          const BuiltinUniformHandles& builtinUniforms,
                          GrGLuint programID,
                          const UniformInfoArray& uniforms,
-                         const SkTArray<GrGLSampler>& samplers,
                          const VaryingInfoArray& pathProcVaryings,
                          GrGLSLPrimitiveProcessor* geometryProcessor,
                          GrGLSLXferProcessor* xferProcessor,
-                         const GrGLSLFragProcs& fragmentProcessors)
+                         const GrGLSLFragProcs& fragmentProcessors,
+                         SkTArray<UniformHandle>* passSamplerUniforms)
     : fBuiltinUniformHandles(builtinUniforms)
     , fProgramID(programID)
     , fGeometryProcessor(geometryProcessor)
@@ -44,9 +44,12 @@
     , fDesc(desc)
     , fGpu(gpu)
     , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
+    fSamplerUniforms.swap(passSamplerUniforms);
     // Assign texture units to sampler uniforms one time up front.
     GL_CALL(UseProgram(fProgramID));
-    fProgramDataManager.setSamplers(samplers);
+    for (int i = 0; i < fSamplerUniforms.count(); i++) {
+        fProgramDataManager.setSampler(fSamplerUniforms[i], i);
+    }
 }
 
 GrGLProgram::~GrGLProgram() {
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 7487a1e..c70b1bd 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -106,11 +106,11 @@
                 const BuiltinUniformHandles&,
                 GrGLuint programID,
                 const UniformInfoArray&,
-                const SkTArray<GrGLSampler>&,
                 const VaryingInfoArray&, // used for NVPR only currently
                 GrGLSLPrimitiveProcessor* geometryProcessor,
                 GrGLSLXferProcessor* xferProcessor,
-                const GrGLSLFragProcs& fragmentProcessors);
+                const GrGLSLFragProcs& fragmentProcessors,
+                SkTArray<UniformHandle>* passSamplerUniforms);
 
     // A helper to loop over effects, set the transforms (via subclass) and bind textures
     void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx);
@@ -135,6 +135,7 @@
     GrProgramDesc fDesc;
     GrGLGpu* fGpu;
     GrGLProgramDataManager fProgramDataManager;
+    SkTArray<UniformHandle> fSamplerUniforms;
 
     friend class GrGLProgramBuilder;
 
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index 9513a3f..6b2e111 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -61,31 +61,19 @@
     }
 }
 
-void GrGLProgramDataManager::setSamplers(const SkTArray<GrGLSampler>& samplers) const {
-    for (int i = 0; i < samplers.count(); ++i) {
-        GrGLint vsLocation;
-        GrGLint fsLocation;
-        const GrGLSampler& sampler = samplers[i];
-        if (kVertex_GrShaderFlag & sampler.visibility()) {
-            vsLocation = sampler.location();
-        } else {
-            vsLocation = kUnusedUniform;
-        }
-        if (kFragment_GrShaderFlag & sampler.visibility()) {
-            fsLocation = sampler.location();
-        } else {
-            fsLocation = kUnusedUniform;
-        }
-        // FIXME: We still insert a single sampler uniform for every stage. If the shader does not
-        // reference the sampler then the compiler may have optimized it out. Uncomment this assert
-        // once stages insert their own samplers.
-        // this->printUnused(uni);
-        if (kUnusedUniform != fsLocation) {
-            GR_GL_CALL(fGpu->glInterface(), Uniform1i(fsLocation, i));
-        }
-        if (kUnusedUniform != vsLocation && vsLocation != fsLocation) {
-            GR_GL_CALL(fGpu->glInterface(), Uniform1i(vsLocation, i));
-        }
+void GrGLProgramDataManager::setSampler(UniformHandle u, int texUnit) const {
+    const Uniform& uni = fUniforms[u.toIndex()];
+    SkASSERT(GrSLTypeIsSamplerType(uni.fType));
+    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
+    // FIXME: We still insert a single sampler uniform for every stage. If the shader does not
+    // reference the sampler then the compiler may have optimized it out. Uncomment this assert
+    // once stages insert their own samplers.
+    // this->printUnused(uni);
+    if (kUnusedUniform != uni.fFSLocation) {
+        GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fFSLocation, texUnit));
+    }
+    if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
+        GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fVSLocation, texUnit));
     }
 }
 
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 513b6a4..c2cb8fc 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -11,7 +11,6 @@
 #include "glsl/GrGLSLProgramDataManager.h"
 
 #include "GrAllocator.h"
-#include "gl/GrGLSampler.h"
 #include "gl/GrGLTypes.h"
 #include "glsl/GrGLSLShaderVar.h"
 
@@ -47,12 +46,11 @@
     GrGLProgramDataManager(GrGLGpu*, GrGLuint programID, const UniformInfoArray&,
                            const VaryingInfoArray&);
 
-
-    void setSamplers(const SkTArray<GrGLSampler>& samplers) const;
-
     /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
-    *  array of uniforms. arrayCount must be <= the array count of the uniform.
-    */
+     *  array of uniforms. arrayCount must be <= the array count of the uniform.
+     */
+    void setSampler(UniformHandle, int texUnit) const;
+
     void set1f(UniformHandle, float v0) const override;
     void set1fv(UniformHandle, int arrayCount, const float v[]) const override;
     void set2f(UniformHandle, float, float) const override;
diff --git a/src/gpu/gl/GrGLSampler.h b/src/gpu/gl/GrGLSampler.h
deleted file mode 100644
index e270f5d..0000000
--- a/src/gpu/gl/GrGLSampler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef GrGLSampler_DEFINED
-#define GrGLSampler_DEFINED
-
-#include "glsl/GrGLSLSampler.h"
-
-#include "gl/GrGLTypes.h"
-#include "glsl/GrGLSLShaderVar.h"
-
-class GrGLSampler : public GrGLSLSampler {
-public:
-    GrGLSampler(uint32_t visibility,
-                GrPixelConfig config,
-                GrSLType type,
-                GrSLPrecision precision,
-                const char* name) : INHERITED(visibility, config) {
-        SkASSERT(GrSLTypeIsSamplerType(type));
-        fShaderVar.setType(type);
-        fShaderVar.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
-        fShaderVar.setPrecision(precision);
-        fShaderVar.accessName()->set(name);
-    }
-
-    GrGLint location() const { return fLocation; }
-    GrSLType type() const override { return fShaderVar.getType(); }
-
-    const char* onGetSamplerNameForTexture2D() const override { return fShaderVar.c_str(); }
-    const char* getSamplerNameForTexelFetch() const override { return fShaderVar.c_str(); }
-
-private:
-    GrGLSLShaderVar fShaderVar;
-    GrGLint         fLocation;
-
-    friend class GrGLUniformHandler;
-
-    typedef GrGLSLSampler INHERITED;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLUniformHandler.cpp b/src/gpu/gl/GrGLUniformHandler.cpp
index c418926..94da1f1 100644
--- a/src/gpu/gl/GrGLUniformHandler.cpp
+++ b/src/gpu/gl/GrGLUniformHandler.cpp
@@ -52,22 +52,6 @@
     return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
 }
 
-GrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::internalAddSampler(uint32_t visibility,
-                                                                           GrPixelConfig config,
-                                                                           GrSLType type,
-                                                                           GrSLPrecision precision,
-                                                                           const char* name) {
-    SkASSERT(name && strlen(name));
-    SkDEBUGCODE(static const uint32_t kVisMask = kVertex_GrShaderFlag | kFragment_GrShaderFlag);
-    SkASSERT(0 == (~kVisMask & visibility));
-    SkASSERT(0 != visibility);
-    SkString mangleName;
-    char prefix = 'u';
-    fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
-    fSamplers.emplace_back(visibility, config, type, precision, mangleName.c_str());
-    return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
-}
-
 void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
     for (int i = 0; i < fUniforms.count(); ++i) {
         if (fUniforms[i].fVisibility & visibility) {
@@ -75,12 +59,6 @@
             out->append(";\n");
         }
     }
-    for (int i = 0; i < fSamplers.count(); ++i) {
-        if (fSamplers[i].visibility() & visibility) {
-            fSamplers[i].fShaderVar.appendDecl(fProgramBuilder->glslCaps(), out);
-            out->append(";\n");
-        }
-    }
 }
 
 void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) {
@@ -90,10 +68,6 @@
             GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
             fUniforms[i].fLocation = i;
         }
-        for (int i = 0; i < fSamplers.count(); ++i) {
-            GL_CALL(BindUniformLocation(programID, i, fSamplers[i].fShaderVar.c_str()));
-            fSamplers[i].fLocation = i;
-        }
     }
 }
 
@@ -105,11 +79,6 @@
             GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
             fUniforms[i].fLocation = location;
         }
-        for (int i = 0; i < fSamplers.count(); ++i) {
-            GrGLint location;
-            GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fShaderVar.c_str()));
-            fSamplers[i].fLocation = location;
-        }
     }
 }
 
diff --git a/src/gpu/gl/GrGLUniformHandler.h b/src/gpu/gl/GrGLUniformHandler.h
index 3656d3a..1dac8d9 100644
--- a/src/gpu/gl/GrGLUniformHandler.h
+++ b/src/gpu/gl/GrGLUniformHandler.h
@@ -11,7 +11,6 @@
 #include "glsl/GrGLSLUniformHandler.h"
 
 #include "gl/GrGLProgramDataManager.h"
-#include "gl/GrGLSampler.h"
 
 class GrGLCaps;
 
@@ -39,17 +38,6 @@
                                           int arrayCount,
                                           const char** outName) override;
 
-    SamplerHandle internalAddSampler(uint32_t visibility,
-                                     GrPixelConfig config,
-                                     GrSLType type,
-                                     GrSLPrecision precision,
-                                     const char* name) override;
-
-    int numSamplers() const override { return fSamplers.count(); }
-    const GrGLSLSampler& getSampler(SamplerHandle handle) const override {
-        return fSamplers[handle.toIndex()];
-    }
-
     void appendUniformDecls(GrShaderFlags visibility, SkString*) const override;
 
     // Manually set uniform locations for all our uniforms.
@@ -65,8 +53,6 @@
 
     UniformInfoArray fUniforms;
 
-    SkTArray<GrGLSampler> fSamplers;
-
     friend class GrGLProgramBuilder;
 
     typedef GrGLSLUniformHandler INHERITED;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index c6422ca..fbe1722 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -233,9 +233,9 @@
                            fUniformHandles,
                            programID,
                            fUniformHandler.fUniforms,
-                           fUniformHandler.fSamplers,
                            fVaryingHandler.fPathProcVaryingInfos,
                            fGeometryProcessor,
                            fXferProcessor,
-                           fFragmentProcessors);
+                           fFragmentProcessors,
+                           &fSamplerUniforms);
 }
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 9533d5a..42538ea 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -83,16 +83,17 @@
         firstBufferAt += args.fFp.childProcessor(i).numBuffers();
     }
     GrGLSLTransformedCoordsArray childCoords;
-    const SamplerHandle* childTexSamplers = nullptr;
-    const SamplerHandle* childBufferSamplers =  nullptr;
+    SamplerArray childTexSamplers;
+    SamplerArray childBufferSamplers;
     if (childProc.numTransforms() > 0) {
         childCoords.push_back_n(childProc.numTransforms(), &args.fCoords[firstCoordAt]);
     }
     if (childProc.numTextures() > 0) {
-        childTexSamplers = &args.fTexSamplers[firstTextureAt];
+        childTexSamplers.push_back_n(childProc.numTextures(), &args.fTexSamplers[firstTextureAt]);
     }
     if (childProc.numBuffers() > 0) {
-        childBufferSamplers = &args.fBufferSamplers[firstBufferAt];
+        childBufferSamplers.push_back_n(childProc.numBuffers(),
+                                        &args.fBufferSamplers[firstBufferAt]);
     }
 
     // emit the code for the child in its own scope
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 43614f2..9fc4a8c 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -31,7 +31,7 @@
     }
 
     typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
-    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+    typedef GrGLSLSampler::SamplerArray SamplerArray;
 
     /** Called when the program stage should insert its code into the shaders. The code in each
         shader will be in its own block ({}) and so locally scoped names will not collide across
@@ -60,8 +60,8 @@
                  const char* outputColor,
                  const char* inputColor,
                  const GrGLSLTransformedCoordsArray& coords,
-                 const SamplerHandle* texSamplers,
-                 const SamplerHandle* bufferSamplers)
+                 const SamplerArray& texSamplers,
+                 const SamplerArray& bufferSamplers)
             : fFragBuilder(fragBuilder)
             , fUniformHandler(uniformHandler)
             , fGLSLCaps(caps)
@@ -78,8 +78,8 @@
         const char* fOutputColor;
         const char* fInputColor;
         const GrGLSLTransformedCoordsArray& fCoords;
-        const SamplerHandle* fTexSamplers;
-        const SamplerHandle* fBufferSamplers;
+        const SamplerArray& fTexSamplers;
+        const SamplerArray& fBufferSamplers;
     };
 
     virtual void emitCode(EmitArgs&) = 0;
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index 3bb1db9..4bd5fef 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -27,7 +27,7 @@
     virtual ~GrGLSLPrimitiveProcessor() {}
 
     typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
-    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+    typedef GrGLSLSampler::SamplerArray SamplerArray;
 
     typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
     typedef SkSTArray<8, ProcCoords> TransformsIn;
@@ -42,8 +42,8 @@
                  const GrPrimitiveProcessor& gp,
                  const char* outputColor,
                  const char* outputCoverage,
-                 const SamplerHandle* texSamplers,
-                 const SamplerHandle* bufferSamplers,
+                 const SamplerArray& texSamplers,
+                 const SamplerArray& bufferSamplers,
                  const TransformsIn& transformsIn,
                  TransformsOut* transformsOut)
             : fVertBuilder(vertBuilder)
@@ -66,8 +66,8 @@
         const GrPrimitiveProcessor& fGP;
         const char* fOutputColor;
         const char* fOutputCoverage;
-        const SamplerHandle* fTexSamplers;
-        const SamplerHandle* fBufferSamplers;
+        const SamplerArray& fTexSamplers;
+        const SamplerArray& fBufferSamplers;
         const TransformsIn& fTransformsIn;
         TransformsOut* fTransformsOut;
     };
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 31d1de2..88ef5b9 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -27,6 +27,7 @@
     , fDesc(desc)
     , fGeometryProcessor(nullptr)
     , fXferProcessor(nullptr)
+    , fSamplerUniforms(4)
     , fNumVertexSamplers(0)
     , fNumGeometrySamplers(0)
     , fNumFragmentSamplers(0) {
@@ -96,8 +97,8 @@
     SkASSERT(!fGeometryProcessor);
     fGeometryProcessor = proc.createGLSLInstance(*this->glslCaps());
 
-    SkSTArray<4, SamplerHandle> texSamplers(proc.numTextures());
-    SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
+    SkSTArray<4, GrGLSLSampler> texSamplers(proc.numTextures());
+    SkSTArray<2, GrGLSLSampler> bufferSamplers(proc.numBuffers());
     this->emitSamplers(proc, &texSamplers, &bufferSamplers);
 
     GrGLSLGeometryProcessor::EmitArgs args(&fVS,
@@ -108,8 +109,8 @@
                                            proc,
                                            outputColor->c_str(),
                                            outputCoverage->c_str(),
-                                           texSamplers.begin(),
-                                           bufferSamplers.begin(),
+                                           texSamplers,
+                                           bufferSamplers,
                                            fCoordTransforms,
                                            &fOutCoords);
     fGeometryProcessor->emitCode(args);
@@ -149,8 +150,8 @@
 
     GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
 
-    SkSTArray<4, SamplerHandle> texSamplers(fp.numTextures());
-    SkSTArray<2, SamplerHandle> bufferSamplers(fp.numBuffers());
+    SkSTArray<4, GrGLSLSampler> texSamplers(fp.numTextures());
+    SkSTArray<2, GrGLSLSampler> bufferSamplers(fp.numBuffers());
     this->emitSamplers(fp, &texSamplers, &bufferSamplers);
 
     GrGLSLFragmentProcessor::EmitArgs args(&fFS,
@@ -160,8 +161,8 @@
                                            output->c_str(),
                                            input.isOnes() ? nullptr : input.c_str(),
                                            fOutCoords[index],
-                                           texSamplers.begin(),
-                                           bufferSamplers.begin());
+                                           texSamplers,
+                                           bufferSamplers);
     fragProc->emitCode(args);
 
     // We have to check that effects and the code they emit are consistent, ie if an effect
@@ -196,8 +197,8 @@
     openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
     fFS.codeAppend(openBrace.c_str());
 
-    SkSTArray<4, SamplerHandle> texSamplers(xp.numTextures());
-    SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
+    SkSTArray<4, GrGLSLSampler> texSamplers(xp.numTextures());
+    SkSTArray<2, GrGLSLSampler> bufferSamplers(xp.numBuffers());
     this->emitSamplers(xp, &texSamplers, &bufferSamplers);
 
     bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
@@ -208,8 +209,8 @@
                                        ignoresCoverage ? nullptr : coverageIn.c_str(),
                                        fFS.getPrimaryColorOutputName(),
                                        fFS.getSecondaryColorOutputName(),
-                                       texSamplers.begin(),
-                                       bufferSamplers.begin(),
+                                       texSamplers,
+                                       bufferSamplers,
                                        usePLSDstRead);
     fXferProcessor->emitCode(args);
 
@@ -220,8 +221,8 @@
 }
 
 void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
-                                        SkTArray<SamplerHandle>* outTexSamplers,
-                                        SkTArray<SamplerHandle>* outBufferSamplers) {
+                                        GrGLSLSampler::SamplerArray* outTexSamplers,
+                                        GrGLSLSampler::SamplerArray* outBufferSamplers) {
     SkString name;
     int numTextures = processor.numTextures();
     for (int t = 0; t < numTextures; ++t) {
@@ -264,7 +265,7 @@
                                        GrPixelConfig config,
                                        const char* name,
                                        GrShaderFlags visibility,
-                                       SkTArray<SamplerHandle>* outSamplers) {
+                                       GrGLSLSampler::SamplerArray* outSamplers) {
     if (visibility & kVertex_GrShaderFlag) {
         ++fNumVertexSamplers;
     }
@@ -276,12 +277,9 @@
         ++fNumFragmentSamplers;
     }
     GrSLPrecision precision = this->glslCaps()->samplerPrecision(config, visibility);
-    SamplerHandle handle = this->uniformHandler()->addSampler(visibility,
-                                                              config,
-                                                              samplerType,
-                                                              precision,
-                                                              name);
-    outSamplers->emplace_back(handle);
+    UniformHandle u = this->uniformHandler()->addUniform(visibility, samplerType, precision, name);
+    fSamplerUniforms.push_back(u);
+    outSamplers->emplace_back(u, config);
 }
 
 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
@@ -371,10 +369,6 @@
     this->uniformHandler()->appendUniformDecls(visibility, out);
 }
 
-const GrGLSLSampler& GrGLSLProgramBuilder::getSampler(SamplerHandle handle) const {
-    return this->uniformHandler()->getSampler(handle);
-}
-
 void GrGLSLProgramBuilder::addRTAdjustmentUniform(GrSLPrecision precision,
                                                   const char* name,
                                                   const char** outName) {
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index c175fc6..3ce7daf 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -41,10 +41,6 @@
 
     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
 
-    typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
-
-    const GrGLSLSampler& getSampler(SamplerHandle handle) const;
-
     // Handles for program uniforms (other than per-effect uniforms)
     struct BuiltinUniformHandles {
         UniformHandle       fRTAdjustmentUni;
@@ -108,6 +104,8 @@
 
     void finalizeShaders();
 
+    SkTArray<UniformHandle> fSamplerUniforms;
+
 private:
     // reset is called by program creator between each processor's emit code.  It increments the
     // stage offset for variable name mangling, and also ensures verfication variables in the
@@ -148,15 +146,14 @@
                                 const GrGLSLExpr4& coverageIn,
                                 bool ignoresCoverage,
                                 GrPixelLocalStorageState plsState);
-
     void emitSamplers(const GrProcessor& processor,
-                      SkTArray<SamplerHandle>* outTexSamplers,
-                      SkTArray<SamplerHandle>* outBufferSamplers);
+                      GrGLSLSampler::SamplerArray* outTexSamplers,
+                      GrGLSLSampler::SamplerArray* outBufferSamplers);
     void emitSampler(GrSLType samplerType,
                      GrPixelConfig,
                      const char* name,
                      GrShaderFlags visibility,
-                     SkTArray<SamplerHandle>* outSamplers);
+                     GrGLSLSampler::SamplerArray* outSamplers);
     void emitFSOutputSwizzle(bool hasSecondaryOutput);
     bool checkSamplerCounts();
 
diff --git a/src/gpu/glsl/GrGLSLSampler.h b/src/gpu/glsl/GrGLSLSampler.h
index a105009..0fc67a9 100644
--- a/src/gpu/glsl/GrGLSLSampler.h
+++ b/src/gpu/glsl/GrGLSLSampler.h
@@ -9,37 +9,27 @@
 #define GrGLSLSampler_DEFINED
 
 #include "GrTypes.h"
-#include "GrTypesPriv.h"
-#include "SkString.h"
+#include "SkTArray.h"
+#include "glsl/GrGLSLProgramDataManager.h"
 
 class GrGLSLSampler {
 public:
-    virtual ~GrGLSLSampler() {}
+    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
+    typedef SkTArray<GrGLSLSampler> SamplerArray;
 
-    explicit GrGLSLSampler(uint32_t visibility, GrPixelConfig config)
-        : fVisibility(visibility)
+    GrGLSLSampler(UniformHandle uniform, GrPixelConfig config)
+        : fSamplerUniform(uniform)
         , fConfig(config) {
         SkASSERT(kUnknown_GrPixelConfig != fConfig);
     }
 
-    uint32_t visibility() const { return fVisibility; }
     GrPixelConfig config() const { return fConfig; }
-    virtual GrSLType type() const = 0;
-
-    // Returns the string to be used for the sampler in glsl 2D texture functions (texture,
-    // texture2D, etc.)
-    const char* getSamplerNameForTexture2D() const {
-        SkASSERT(GrSLTypeIs2DTextureType(this->type()));
-        return this->onGetSamplerNameForTexture2D();
-    }
-
-    // Returns the string to be used for the sampler in glsl texelFetch.
-    virtual const char* getSamplerNameForTexelFetch() const = 0;
 
 private:
-    virtual const char* onGetSamplerNameForTexture2D() const = 0;
-    uint32_t      fVisibility;
+    UniformHandle fSamplerUniform;
     GrPixelConfig fConfig;
+
+    friend class GrGLSLShaderBuilder;
 };
 
 #endif
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 1342d1c..1031f84 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -63,68 +63,71 @@
 }
 
 void GrGLSLShaderBuilder::appendTextureLookup(SkString* out,
-                                              SamplerHandle samplerHandle,
+                                              const GrGLSLSampler& sampler,
                                               const char* coordName,
                                               GrSLType varyingType) const {
     const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps();
-    const GrGLSLSampler& sampler = fProgramBuilder->getSampler(samplerHandle);
-    GrSLType samplerType = sampler.type();
+    GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler();
+    GrSLType samplerType = uniformHandler->getUniformVariable(sampler.fSamplerUniform).getType();
     if (samplerType == kSampler2DRect_GrSLType) {
         if (varyingType == kVec2f_GrSLType) {
             out->appendf("%s(%s, textureSize(%s) * %s)",
                          GrGLSLTexture2DFunctionName(varyingType, samplerType,
                                                      glslCaps->generation()),
-                         sampler.getSamplerNameForTexture2D(),
-                         sampler.getSamplerNameForTexture2D(),
+                         uniformHandler->getUniformCStr(sampler.fSamplerUniform),
+                         uniformHandler->getUniformCStr(sampler.fSamplerUniform),
                          coordName);
         } else {
             out->appendf("%s(%s, vec3(textureSize(%s) * %s.xy, %s.z))",
                          GrGLSLTexture2DFunctionName(varyingType, samplerType,
                                                      glslCaps->generation()),
-                         sampler.getSamplerNameForTexture2D(),
-                         sampler.getSamplerNameForTexture2D(),
+                         uniformHandler->getUniformCStr(sampler.fSamplerUniform),
+                         uniformHandler->getUniformCStr(sampler.fSamplerUniform),
                          coordName,
                          coordName);
         }
     } else {
         out->appendf("%s(%s, %s)",
                      GrGLSLTexture2DFunctionName(varyingType, samplerType, glslCaps->generation()),
-                     sampler.getSamplerNameForTexture2D(),
+                     uniformHandler->getUniformCStr(sampler.fSamplerUniform),
                      coordName);
     }
 
     this->appendTextureSwizzle(out, sampler.config());
 }
 
-void GrGLSLShaderBuilder::appendTextureLookup(SamplerHandle samplerHandle,
+void GrGLSLShaderBuilder::appendTextureLookup(const GrGLSLSampler& sampler,
                                               const char* coordName,
                                               GrSLType varyingType) {
-    this->appendTextureLookup(&this->code(), samplerHandle, coordName, varyingType);
+    this->appendTextureLookup(&this->code(), sampler, coordName, varyingType);
 }
 
 void GrGLSLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
-                                                         SamplerHandle samplerHandle,
+                                                         const GrGLSLSampler& sampler,
                                                          const char* coordName,
                                                          GrSLType varyingType) {
     SkString lookup;
-    this->appendTextureLookup(&lookup, samplerHandle, coordName, varyingType);
+    this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
     this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
 }
 
 void GrGLSLShaderBuilder::appendTexelFetch(SkString* out,
-                                           SamplerHandle samplerHandle,
+                                           const GrGLSLSampler& sampler,
                                            const char* coordExpr) const {
-    const GrGLSLSampler& sampler = fProgramBuilder->getSampler(samplerHandle);
+    const GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler();
     SkASSERT(fProgramBuilder->glslCaps()->texelFetchSupport());
-    SkASSERT(GrSLTypeIsSamplerType(sampler.type()));
+    SkASSERT(GrSLTypeIsSamplerType(
+             uniformHandler->getUniformVariable(sampler.fSamplerUniform).getType()));
 
-    out->appendf("texelFetch(%s, %s)", sampler.getSamplerNameForTexelFetch(), coordExpr);
+    out->appendf("texelFetch(%s, %s)",
+                 uniformHandler->getUniformCStr(sampler.fSamplerUniform),
+                 coordExpr);
 
     this->appendTextureSwizzle(out, sampler.config());
 }
 
-void GrGLSLShaderBuilder::appendTexelFetch(SamplerHandle samplerHandle, const char* coordExpr) {
-    this->appendTexelFetch(&this->code(), samplerHandle, coordExpr);
+void GrGLSLShaderBuilder::appendTexelFetch(const GrGLSLSampler& sampler, const char* coordExpr) {
+    this->appendTexelFetch(&this->code(), sampler, coordExpr);
 }
 
 void GrGLSLShaderBuilder::appendTextureSwizzle(SkString* out, GrPixelConfig config) const {
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index ea36a56..ef7963f 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -9,12 +9,14 @@
 #define GrGLSLShaderBuilder_DEFINED
 
 #include "GrAllocator.h"
-#include "glsl/GrGLSLUniformHandler.h"
 #include "glsl/GrGLSLShaderVar.h"
 #include "SkTDArray.h"
 
 #include <stdarg.h>
 
+class GrGLSLProgramBuilder;
+class GrGLSLSampler;
+
 /**
   base class for all shaders builders
 */
@@ -23,19 +25,17 @@
     GrGLSLShaderBuilder(GrGLSLProgramBuilder* program);
     virtual ~GrGLSLShaderBuilder() {}
 
-    typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
-
     /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
         Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
         order of the result depends on the GrTextureAccess associated with the GrGLSLSampler.
         */
     void appendTextureLookup(SkString* out,
-                             SamplerHandle,
+                             const GrGLSLSampler&,
                              const char* coordName,
                              GrSLType coordType = kVec2f_GrSLType) const;
 
     /** Version of above that appends the result to the shader code instead.*/
-    void appendTextureLookup(SamplerHandle,
+    void appendTextureLookup(const GrGLSLSampler&,
                              const char* coordName,
                              GrSLType coordType = kVec2f_GrSLType);
 
@@ -45,17 +45,17 @@
         vec4 or float. If modulation is "" or nullptr it this function acts as though
         appendTextureLookup were called. */
     void appendTextureLookupAndModulate(const char* modulation,
-                                        SamplerHandle,
+                                        const GrGLSLSampler&,
                                         const char* coordName,
                                         GrSLType coordType = kVec2f_GrSLType);
 
     /** Fetches an unfiltered texel from a sampler at integer coordinates. coordExpr must match the
         dimensionality of the sampler and must be within the sampler's range. coordExpr is emitted
         exactly once, so expressions like "idx++" are acceptable. */
-    void appendTexelFetch(SkString* out, SamplerHandle, const char* coordExpr) const;
+    void appendTexelFetch(SkString* out, const GrGLSLSampler&, const char* coordExpr) const;
 
     /** Version of above that appends the result to the shader code instead.*/
-    void appendTexelFetch(SamplerHandle, const char* coordExpr);
+    void appendTexelFetch(const GrGLSLSampler&, const char* coordExpr);
 
     /**
     * Adds a #define directive to the top of the shader.
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index 56cac4a..a2f7053 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -12,14 +12,12 @@
 #include "GrGLSLShaderVar.h"
 
 class GrGLSLProgramBuilder;
-class GrGLSLSampler;
 
 class GrGLSLUniformHandler {
 public:
     virtual ~GrGLSLUniformHandler() {}
 
     typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
-    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
 
     /** Add a uniform variable to the current program, that has visibility in one or more shaders.
         visibility is a bitfield of GrShaderFlag values indicating from which shaders the uniform
@@ -32,7 +30,6 @@
                              GrSLPrecision precision,
                              const char* name,
                              const char** outName = nullptr) {
-        SkASSERT(!GrSLTypeIsSamplerType(type));
         return this->addUniformArray(visibility, type, precision, name, 0, outName);
     }
 
@@ -42,7 +39,6 @@
                                   const char* name,
                                   int arrayCount,
                                   const char** outName = nullptr) {
-        SkASSERT(!GrSLTypeIsSamplerType(type));
         return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount,
                                              outName);
     }
@@ -53,7 +49,6 @@
      * Shortcut for getUniformVariable(u).c_str()
      */
     virtual const char* getUniformCStr(UniformHandle u) const = 0;
-
 protected:
     explicit GrGLSLUniformHandler(GrGLSLProgramBuilder* program) : fProgramBuilder(program) {}
 
@@ -61,23 +56,6 @@
     GrGLSLProgramBuilder* fProgramBuilder;
 
 private:
-    virtual int numSamplers() const = 0;
-    virtual const GrGLSLSampler& getSampler(SamplerHandle handle) const = 0;
-
-    SamplerHandle addSampler(uint32_t visibility,
-                             GrPixelConfig config,
-                             GrSLType type,
-                             GrSLPrecision precision,
-                             const char* name) {
-        return this->internalAddSampler(visibility, config, type, precision, name);
-    }
-
-    virtual SamplerHandle internalAddSampler(uint32_t visibility,
-                                             GrPixelConfig config,
-                                             GrSLType type,
-                                             GrSLPrecision precision,
-                                             const char* name) = 0;
-
     virtual UniformHandle internalAddUniformArray(uint32_t visibility,
                                                   GrSLType type,
                                                   GrSLPrecision precision,
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.h b/src/gpu/glsl/GrGLSLXferProcessor.h
index f4a8ebd..adc3d41 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ b/src/gpu/glsl/GrGLSLXferProcessor.h
@@ -22,8 +22,7 @@
     GrGLSLXferProcessor() {}
     virtual ~GrGLSLXferProcessor() {}
 
-    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
-
+    typedef GrGLSLSampler::SamplerArray SamplerArray;
     struct EmitArgs {
         EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
                  GrGLSLUniformHandler* uniformHandler,
@@ -33,8 +32,8 @@
                  const char* inputCoverage,
                  const char* outputPrimary,
                  const char* outputSecondary,
-                 const SamplerHandle* texSamplers,
-                 const SamplerHandle* bufferSamplers,
+                 const SamplerArray& texSamplers,
+                 const SamplerArray& bufferSamplers,
                  const bool usePLSDstRead)
             : fXPFragBuilder(fragBuilder)
             , fUniformHandler(uniformHandler)
@@ -56,8 +55,8 @@
         const char* fInputCoverage;
         const char* fOutputPrimary;
         const char* fOutputSecondary;
-        const SamplerHandle* fTexSamplers;
-        const SamplerHandle* fBufferSamplers;
+        const SamplerArray& fTexSamplers;
+        const SamplerArray& fBufferSamplers;
         bool fUsePLSDstRead;
     };
     /**
diff --git a/src/gpu/vk/GrVkGLSLSampler.h b/src/gpu/vk/GrVkGLSLSampler.h
deleted file mode 100644
index 4bfacae..0000000
--- a/src/gpu/vk/GrVkGLSLSampler.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef GrVkGLSLSampler_DEFINED
-#define GrVkGLSLSampler_DEFINED
-
-#include "glsl/GrGLSLSampler.h"
-
-#include "glsl/GrGLSLShaderVar.h"
-
-class GrVkGLSLSampler : public GrGLSLSampler {
-public:
-    GrVkGLSLSampler(uint32_t visibility,
-                    GrPixelConfig config,
-                    GrSLType type,
-                    GrSLPrecision precision,
-                    const char* name,
-                    uint32_t binding,
-                    uint32_t set) : INHERITED(visibility, config), fBinding(binding) {
-        SkASSERT(GrSLTypeIsSamplerType(type));
-        fShaderVar.setType(type);
-        fShaderVar.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
-        fShaderVar.setPrecision(precision);
-        fShaderVar.accessName()->set(name);
-        SkString layoutQualifier;
-        layoutQualifier.appendf("set=%d, binding=%d", set, binding);
-        fShaderVar.setLayoutQualifier(layoutQualifier.c_str());
-    }
-
-    GrSLType type() const override { return fShaderVar.getType(); }
-    uint32_t binding() const { return fBinding; }
-
-    const char* onGetSamplerNameForTexture2D() const override { return fShaderVar.c_str(); }
-    const char* getSamplerNameForTexelFetch() const override { return fShaderVar.c_str(); }
-
-private:
-    GrGLSLShaderVar fShaderVar;
-    uint32_t        fBinding;
-
-    friend class GrVkUniformHandler;
-
-    typedef GrGLSLSampler INHERITED;
-};
-
-#endif
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index be30bb3..2bd8003 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -162,18 +162,20 @@
     VkShaderModule vertShaderModule;
     VkShaderModule fragShaderModule;
 
-    uint32_t numSamplers = (uint32_t)fUniformHandler.numSamplers();
+    uint32_t numSamplers = fSamplerUniforms.count();
 
     SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
                                                      new VkDescriptorSetLayoutBinding[numSamplers]);
     for (uint32_t i = 0; i < numSamplers; ++i) {
-        const GrVkGLSLSampler& sampler =
-            static_cast<const GrVkGLSLSampler&>(fUniformHandler.getSampler(i));
-        SkASSERT(sampler.binding() == i);
-        dsSamplerBindings[i].binding = sampler.binding();
+        UniformHandle uniHandle = fSamplerUniforms[i];
+        GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle);
+        SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType());
+        SkASSERT(GrVkUniformHandler::kSamplerDescSet == uniformInfo.fSetNumber);
+        SkASSERT(uniformInfo.fBinding == i);
+        dsSamplerBindings[i].binding = uniformInfo.fBinding;
         dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
         dsSamplerBindings[i].descriptorCount = 1;
-        dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility());
+        dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility);
         dsSamplerBindings[i].pImmutableSamplers = nullptr;
     }
 
@@ -182,10 +184,11 @@
     dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
     dsSamplerLayoutCreateInfo.pNext = nullptr;
     dsSamplerLayoutCreateInfo.flags = 0;
-    dsSamplerLayoutCreateInfo.bindingCount = numSamplers;
+    dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count();
     // Setting to nullptr fixes an error in the param checker validation layer. Even though
     // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
-    dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr;
+    dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() :
+                                                                     nullptr;
 
     GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
                         CreateDescriptorSetLayout(fGpu->device(),
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.cpp b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
index c72f209..60d7d7f 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.cpp
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
@@ -32,10 +32,11 @@
             uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
             uniform.fType = uniformInfo.fVariable.getType();
         );
-        uniform.fBinding =
-            (kVertex_GrShaderFlag == uniformInfo.fVisibility) ? GrVkUniformHandler::kVertexBinding
-                                                              : GrVkUniformHandler::kFragBinding;
+        uniform.fBinding = uniformInfo.fBinding;
         uniform.fOffset = uniformInfo.fUBOffset;
+        SkDEBUGCODE(
+            uniform.fSetNumber = uniformInfo.fSetNumber;
+        );
     }
 }
 
@@ -58,6 +59,7 @@
     const Uniform& uni = fUniforms[u.toIndex()];
     SkASSERT(uni.fType == kFloat_GrSLType);
     SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
     memcpy(buffer, &v0, sizeof(float));
@@ -71,6 +73,7 @@
     SkASSERT(arrayCount > 0);
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
 
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
@@ -85,6 +88,7 @@
     const Uniform& uni = fUniforms[u.toIndex()];
     SkASSERT(uni.fType == kVec2f_GrSLType);
     SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
     float v[2] = { v0, v1 };
@@ -99,6 +103,7 @@
     SkASSERT(arrayCount > 0);
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
 
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
@@ -113,6 +118,7 @@
     const Uniform& uni = fUniforms[u.toIndex()];
     SkASSERT(uni.fType == kVec3f_GrSLType);
     SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
     float v[3] = { v0, v1, v2 };
@@ -127,6 +133,7 @@
     SkASSERT(arrayCount > 0);
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
 
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
@@ -145,6 +152,7 @@
     const Uniform& uni = fUniforms[u.toIndex()];
     SkASSERT(uni.fType == kVec4f_GrSLType);
     SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
     float v[4] = { v0, v1, v2, v3 };
@@ -159,6 +167,7 @@
     SkASSERT(arrayCount > 0);
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
 
     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     SkASSERT(sizeof(float) == 4);
@@ -205,6 +214,7 @@
     SkASSERT(arrayCount > 0);
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
+    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
 
     void* buffer;
     if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.h b/src/gpu/vk/GrVkPipelineStateDataManager.h
index 0a03579..089d170 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.h
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.h
@@ -59,6 +59,7 @@
         SkDEBUGCODE(
             GrSLType    fType;
             int         fArrayCount;
+            uint32_t    fSetNumber;
         );
     };
 
diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp
index 3451d6b..4ffbcfe 100644
--- a/src/gpu/vk/GrVkUniformHandler.cpp
+++ b/src/gpu/vk/GrVkUniformHandler.cpp
@@ -136,7 +136,6 @@
     SkASSERT(0 == (~kVisibilityMask & visibility));
     SkASSERT(0 != visibility);
     SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
-    GrSLTypeIsFloatType(type);
 
     UniformInfo& uni = fUniforms.push_back();
     uni.fVariable.setType(type);
@@ -156,63 +155,58 @@
     SkASSERT(kVertex_GrShaderFlag == visibility || kFragment_GrShaderFlag == visibility);
     uni.fVisibility = visibility;
     uni.fVariable.setPrecision(precision);
-    // When outputing the GLSL, only the outer uniform block will get the Uniform modifier. Thus
-    // we set the modifier to none for all uniforms declared inside the block.
-    uni.fVariable.setTypeModifier(GrGLSLShaderVar::kNone_TypeModifier);
+    if (GrSLTypeIsFloatType(type)) {
+        // When outputing the GLSL, only the outer uniform block will get the Uniform modifier. Thus
+        // we set the modifier to none for all uniforms declared inside the block.
+        uni.fVariable.setTypeModifier(GrGLSLShaderVar::kNone_TypeModifier);
 
-    uint32_t* currentOffset = kVertex_GrShaderFlag == visibility ? &fCurrentVertexUBOOffset
-                                                                   : &fCurrentFragmentUBOOffset;
-    get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
+        uint32_t* currentOffset = kVertex_GrShaderFlag == visibility ? &fCurrentVertexUBOOffset
+                                                                     : &fCurrentFragmentUBOOffset;
+        get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
+        uni.fSetNumber = kUniformBufferDescSet;
+        uni.fBinding = kVertex_GrShaderFlag == visibility ? kVertexBinding : kFragBinding;
 
-    if (outName) {
-        *outName = uni.fVariable.c_str();
+        if (outName) {
+            *outName = uni.fVariable.c_str();
+        }
+    } else {
+        SkASSERT(type == kSampler2D_GrSLType);
+        uni.fVariable.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
+
+        uni.fSetNumber = kSamplerDescSet;
+        uni.fBinding = fCurrentSamplerBinding++;
+        uni.fUBOffset = 0; // This value will be ignored, but initializing to avoid any errors.
+        SkString layoutQualifier;
+        layoutQualifier.appendf("set=%d, binding=%d", uni.fSetNumber, uni.fBinding);
+        uni.fVariable.setLayoutQualifier(layoutQualifier.c_str());
     }
 
     return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
 }
 
-GrGLSLUniformHandler::SamplerHandle GrVkUniformHandler::internalAddSampler(uint32_t visibility,
-                                                                           GrPixelConfig config,
-                                                                           GrSLType type,
-                                                                           GrSLPrecision precision,
-                                                                           const char* name) {
-    SkASSERT(name && strlen(name));
-    SkDEBUGCODE(static const uint32_t kVisMask = kVertex_GrShaderFlag | kFragment_GrShaderFlag);
-    SkASSERT(0 == (~kVisMask & visibility));
-    SkASSERT(0 != visibility);
-    SkString mangleName;
-    char prefix = 'u';
-    fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
-    fSamplers.emplace_back(visibility, config, type, precision, mangleName.c_str(),
-                           (uint32_t)fSamplers.count(), kSamplerDescSet);
-    return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
-}
-
 void GrVkUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
-    SkASSERT(kVertex_GrShaderFlag == visibility || kFragment_GrShaderFlag == visibility);
-
-    for (int i = 0; i < fSamplers.count(); ++i) {
-        const GrVkGLSLSampler& sampler = fSamplers[i];
-        SkASSERT(sampler.type() == kSampler2D_GrSLType);
-        if (visibility == sampler.visibility()) {
-            sampler.fShaderVar.appendDecl(fProgramBuilder->glslCaps(), out);
-            out->append(";\n");
-        }
-    }
-
+    SkTArray<UniformInfo*> uniformBufferUniform;
+    // Used to collect all the variables that will be place inside the uniform buffer
     SkString uniformsString;
+    SkASSERT(kVertex_GrShaderFlag == visibility || kFragment_GrShaderFlag == visibility);
+    uint32_t uniformBinding = (visibility == kVertex_GrShaderFlag) ? kVertexBinding : kFragBinding;
     for (int i = 0; i < fUniforms.count(); ++i) {
         const UniformInfo& localUniform = fUniforms[i];
         if (visibility == localUniform.fVisibility) {
             if (GrSLTypeIsFloatType(localUniform.fVariable.getType())) {
+                SkASSERT(uniformBinding == localUniform.fBinding);
+                SkASSERT(kUniformBufferDescSet == localUniform.fSetNumber);
                 localUniform.fVariable.appendDecl(fProgramBuilder->glslCaps(), &uniformsString);
                 uniformsString.append(";\n");
+            } else {
+                SkASSERT(localUniform.fVariable.getType() == kSampler2D_GrSLType);
+                SkASSERT(kSamplerDescSet == localUniform.fSetNumber);
+                localUniform.fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
+                out->append(";\n");
             }
         }
     }
     if (!uniformsString.isEmpty()) {
-        uint32_t uniformBinding = (visibility == kVertex_GrShaderFlag) ? kVertexBinding
-                                                                       : kFragBinding;
         const char* stage = (visibility == kVertex_GrShaderFlag) ? "vertex" : "fragment";
         out->appendf("layout (set=%d, binding=%d) uniform %sUniformBuffer\n{\n",
                      kUniformBufferDescSet, uniformBinding, stage);
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index f6060b0..46d27cd 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -11,7 +11,6 @@
 #include "glsl/GrGLSLUniformHandler.h"
 
 #include "GrAllocator.h"
-#include "GrVkGLSLSampler.h"
 #include "glsl/GrGLSLShaderVar.h"
 
 class GrVkUniformHandler : public GrGLSLUniformHandler {
@@ -31,6 +30,8 @@
     struct UniformInfo {
         GrGLSLShaderVar fVariable;
         uint32_t        fVisibility;
+        uint32_t        fSetNumber;
+        uint32_t        fBinding;
         uint32_t        fUBOffset;
     };
     typedef GrTAllocator<UniformInfo> UniformInfoArray;
@@ -60,17 +61,6 @@
                                           int arrayCount,
                                           const char** outName) override;
 
-    SamplerHandle internalAddSampler(uint32_t visibility,
-                                     GrPixelConfig config,
-                                     GrSLType type,
-                                     GrSLPrecision precision,
-                                     const char* name) override;
-
-    int numSamplers() const override { return fSamplers.count(); }
-    const GrGLSLSampler& getSampler(SamplerHandle handle) const override {
-        return fSamplers[handle.toIndex()];
-    }
-
     void appendUniformDecls(GrShaderFlags, SkString*) const override;
 
     bool hasVertexUniforms() const { return fCurrentVertexUBOOffset > 0; }
@@ -83,8 +73,6 @@
 
 
     UniformInfoArray fUniforms;
-    SkTArray<GrVkGLSLSampler> fSamplers;
-
     uint32_t         fCurrentVertexUBOOffset;
     uint32_t         fCurrentFragmentUBOOffset;
     uint32_t         fCurrentSamplerBinding;