Revert "Initial OpenGL Image support."

This reverts commit be34882042048db096baca32ddf4a8b472529804.

Reason for revert: Test failures and shader compilation issues on Android.

Original change's description:
> Initial OpenGL Image support.
> 
> This change along with recently landed changes is enough to make the new unit test work and not much else. imageLoad is support but not stores or any other image functions (atomics). Barriers in the shading language or the GL API are not yet hooked up.
> 
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4182
> 
> Change-Id: I5958b7c89e40ae5ee05f7bbaca3b3738162fe5ce
> Reviewed-on: https://skia-review.googlesource.com/4182
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Reviewed-by: Chris Dalton <csmartdalton@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> 

TBR=egdaniel@google.com,bsalomon@google.com,csmartdalton@google.com,reviews@skia.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: I29a2502c296ae39ed9a999957800414ae46e6f0f
Reviewed-on: https://skia-review.googlesource.com/5129
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gn/tests.gni b/gn/tests.gni
index 8473e0e..98980ec 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -106,7 +106,6 @@
   "$_tests/ImageGeneratorTest.cpp",
   "$_tests/ImageIsOpaqueTest.cpp",
   "$_tests/ImageNewShaderTest.cpp",
-  "$_tests/ImageStorageTest.cpp",
   "$_tests/ImageTest.cpp",
   "$_tests/IndexedPngOverflowTest.cpp",
   "$_tests/InfRectTest.cpp",
diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h
index a51d814..a91dcfe 100644
--- a/include/gpu/GrGpuResourceRef.h
+++ b/include/gpu/GrGpuResourceRef.h
@@ -43,10 +43,6 @@
     /** Does this object own a pending read or write on the resource it is wrapping. */
     bool ownsPendingIO() const { return fPendingIO; }
 
-    /** What type of IO does this represent? This is independent of whether a normal ref or a
-        pending IO is currently held. */
-    GrIOType ioType() const { return fIOType; }
-
     /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
         is called. */
     void reset();
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
index c2888d3..e4f59ea 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -14,7 +14,6 @@
 #include "GrProcessorUnitTest.h"
 #include "GrProgramElement.h"
 #include "GrSamplerParams.h"
-#include "GrShaderVar.h"
 #include "SkMath.h"
 #include "SkString.h"
 #include "../private/SkAtomics.h"
@@ -63,7 +62,6 @@
 public:
     class TextureSampler;
     class BufferAccess;
-    class ImageStorageAccess;
 
     virtual ~GrProcessor();
 
@@ -90,17 +88,7 @@
         numBuffers(). */
     const BufferAccess& bufferAccess(int index) const { return *fBufferAccesses[index]; }
 
-    int numImageStorages() const { return fImageStorageAccesses.count(); }
-
-    /** Returns the access object for the image at index. index must be valid according to
-        numImages(). */
-    const ImageStorageAccess& imageStorageAccess(int index) const {
-        return *fImageStorageAccesses[index];
-    }
-
-    /**
-     * Platform specific built-in features that a processor can request for the fragment shader.
-     */
+    /** Platform specific built-in features that a processor can request for the fragment shader. */
     enum RequiredFeatures {
         kNone_RequiredFeatures             = 0,
         kFragmentPosition_RequiredFeature  = 1 << 0,
@@ -130,16 +118,15 @@
     GrProcessor() : fClassID(kIllegalProcessorClassID), fRequiredFeatures(kNone_RequiredFeatures) {}
 
     /**
-     * Subclasses call these from their constructor to register sampler/image sources. The processor
+     * Subclasses call these from their constructor to register sampler sources. The processor
      * subclass manages the lifetime of the objects (these functions only store pointers). The
      * TextureSampler and/or BufferAccess instances are typically member fields of the GrProcessor
      * subclass. These must only be called from the constructor because GrProcessors are immutable.
      */
     void addTextureSampler(const TextureSampler*);
-    void addBufferAccess(const BufferAccess*);
-    void addImageStorageAccess(const ImageStorageAccess*);
+    void addBufferAccess(const BufferAccess* bufferAccess);
 
-    bool hasSameSamplersAndAccesses(const GrProcessor &) const;
+    bool hasSameSamplers(const GrProcessor&) const;
 
     /**
      * If the prcoessor will generate code that uses platform specific built-in features, then it
@@ -158,6 +145,7 @@
          fClassID = kClassID;
     }
 
+    uint32_t fClassID;
 private:
     static uint32_t GenClassID() {
         // fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The
@@ -176,11 +164,9 @@
     };
     static int32_t gCurrProcessorClassID;
 
-    uint32_t                                        fClassID;
-    RequiredFeatures                                fRequiredFeatures;
-    SkSTArray<4, const TextureSampler*, true>       fTextureSamplers;
-    SkSTArray<1, const BufferAccess*, true>         fBufferAccesses;
-    SkSTArray<1, const ImageStorageAccess*, true>   fImageStorageAccesses;
+    RequiredFeatures fRequiredFeatures;
+    SkSTArray<4, const TextureSampler*, true>   fTextureSamplers;
+    SkSTArray<2, const BufferAccess*, true>     fBufferAccesses;
 
     typedef GrProgramElement INHERITED;
 };
@@ -189,8 +175,7 @@
 
 /**
  * Used to represent a texture that is required by a GrProcessor. It holds a GrTexture along with
- * an associated GrSamplerParams. TextureSamplers don't perform any coord manipulation to account
- * for texture origin.
+ * an associated GrSamplerParams
  */
 class GrProcessor::TextureSampler : public SkNoncopyable {
 public:
@@ -272,7 +257,7 @@
     /**
      * For internal use by GrProcessor.
      */
-    const GrGpuResourceRef* programBuffer() const { return &fBuffer;}
+    const GrGpuResourceRef* getProgramBuffer() const { return &fBuffer;}
 
 private:
     GrPixelConfig                 fTexelConfig;
@@ -282,38 +267,4 @@
     typedef SkNoncopyable INHERITED;
 };
 
-/**
- * This is used by a GrProcessor to access a texture using image load/store in its shader code.
- * ImageStorageAccesses don't perform any coord manipulation to account for texture origin.
- * Currently the format of the load/store data in the shader is inferred from the texture config,
- * though it could be made explicit.
- */
-class GrProcessor::ImageStorageAccess : public SkNoncopyable {
-public:
-    ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType,
-                       GrShaderFlags visibility = kFragment_GrShaderFlag);
-
-    bool operator==(const ImageStorageAccess& that) const {
-        return this->texture() == that.texture() && fVisibility == that.fVisibility;
-    }
-
-    bool operator!=(const ImageStorageAccess& that) const { return !(*this == that); }
-
-    GrTexture* texture() const { return fTexture.get(); }
-    GrShaderFlags visibility() const { return fVisibility; }
-    GrIOType ioType() const { return fTexture.ioType(); }
-    GrImageStorageFormat format() const { return fFormat; }
-
-    /**
-     * For internal use by GrProcessor.
-     */
-    const GrGpuResourceRef* programTexture() const { return &fTexture; }
-
-private:
-    GrTGpuResourceRef<GrTexture>    fTexture;
-    GrShaderFlags                   fVisibility;
-    GrImageStorageFormat            fFormat;
-    typedef SkNoncopyable INHERITED;
-};
-
 #endif
diff --git a/include/gpu/GrShaderVar.h b/include/gpu/GrShaderVar.h
index be2677b..aaae107 100644
--- a/include/gpu/GrShaderVar.h
+++ b/include/gpu/GrShaderVar.h
@@ -284,8 +284,6 @@
         }
     }
 
-    void setImageStorageFormat(GrImageStorageFormat format);
-
     void addModifier(const char* modifier) {
         if (modifier) {
             fExtraModifiers.appendf("%s ", modifier);
@@ -312,6 +310,23 @@
     }
 
 private:
+    static const char* TypeModifierString(TypeModifier t) {
+        switch (t) {
+            case kNone_TypeModifier:
+                return "";
+            case kIn_TypeModifier:
+                return "in";
+            case kInOut_TypeModifier:
+                return "inout";
+            case kOut_TypeModifier:
+                return "out";
+            case kUniform_TypeModifier:
+                return "uniform";
+        }
+        SkFAIL("Unknown shader variable type modifier.");
+        return ""; // suppress warning
+    }
+
     GrSLType        fType;
     TypeModifier    fTypeModifier;
     int             fCount;
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index cd56e0e..4ecab9c 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -34,8 +34,6 @@
     kBufferSampler_GrSLType,
     kTexture2D_GrSLType,
     kSampler_GrSLType,
-    kImageStorage2D_GrSLType,
-    kIImageStorage2D_GrSLType,
 };
 
 enum GrShaderType {
@@ -105,8 +103,6 @@
         case kUint_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
             return false;
     }
     SkFAIL("Unexpected type");
@@ -135,8 +131,6 @@
         case kBool_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
             return false;
     }
     SkFAIL("Unexpected type");
@@ -165,38 +159,6 @@
         case kBool_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
-            return false;
-    }
-    SkFAIL("Unexpected type");
-    return false;
-}
-
-static inline bool GrSLTypeIsImageStorage(GrSLType type) {
-    switch (type) {
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
-            return true;
-
-        case kVoid_GrSLType:
-        case kFloat_GrSLType:
-        case kVec2f_GrSLType:
-        case kVec3f_GrSLType:
-        case kVec4f_GrSLType:
-        case kMat22f_GrSLType:
-        case kMat33f_GrSLType:
-        case kMat44f_GrSLType:
-        case kInt_GrSLType:
-        case kUint_GrSLType:
-        case kBool_GrSLType:
-        case kTexture2D_GrSLType:
-        case kSampler_GrSLType:
-        case kTexture2DSampler_GrSLType:
-        case kITexture2DSampler_GrSLType:
-        case kTextureExternalSampler_GrSLType:
-        case kTexture2DRectSampler_GrSLType:
-        case kBufferSampler_GrSLType:
             return false;
     }
     SkFAIL("Unexpected type");
@@ -221,8 +183,6 @@
         case kBufferSampler_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
             return true;
 
         case kVoid_GrSLType:
@@ -340,15 +300,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-enum class GrImageStorageFormat {
-    kRGBA8,
-    kRGBA8i,
-    kRGBA16f,
-    kRGBA32f,
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
 /**
 * We have coverage effects that clip rendering to the edge of some geometric primitive.
 * This enum specifies how that clipping is performed. Not all factories that take a
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index de4ab9e..820b428 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -27,7 +27,7 @@
 
 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
     if (this->classID() != that.classID() ||
-        !this->hasSameSamplersAndAccesses(that)) {
+        !this->hasSameSamplers(that)) {
         return false;
     }
     if (!this->hasSameTransforms(that)) {
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 738ff13..1e100e4 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -122,12 +122,7 @@
 
 void GrProcessor::addBufferAccess(const BufferAccess* access) {
     fBufferAccesses.push_back(access);
-    this->addGpuResource(access->programBuffer());
-}
-
-void GrProcessor::addImageStorageAccess(const ImageStorageAccess* access) {
-    fImageStorageAccesses.push_back(access);
-    this->addGpuResource(access->programTexture());
+    this->addGpuResource(access->getProgramBuffer());
 }
 
 void* GrProcessor::operator new(size_t size) {
@@ -138,10 +133,9 @@
     return MemoryPoolAccessor().pool()->release(target);
 }
 
-bool GrProcessor::hasSameSamplersAndAccesses(const GrProcessor &that) const {
+bool GrProcessor::hasSameSamplers(const GrProcessor& that) const {
     if (this->numTextureSamplers() != that.numTextureSamplers() ||
-        this->numBuffers() != that.numBuffers() ||
-        this->numImageStorages() != that.numImageStorages()) {
+        this->numBuffers() != that.numBuffers()) {
         return false;
     }
     for (int i = 0; i < this->numTextureSamplers(); ++i) {
@@ -154,11 +148,6 @@
             return false;
         }
     }
-    for (int i = 0; i < this->numImageStorages(); ++i) {
-        if (this->imageStorageAccess(i) != that.imageStorageAccess(i)) {
-            return false;
-        }
-    }
     return true;
 }
 
@@ -200,34 +189,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType,
-                                                    GrShaderFlags visibility) {
-    SkASSERT(texture);
-    fTexture.set(texture.release(), ioType);
-    fVisibility = visibility;
-    // We currently infer this from the config. However, we could allow the client to specify
-    // a format that is different but compatible with the config.
-    switch (fTexture.get()->config()) {
-        case kRGBA_8888_GrPixelConfig:
-            fFormat = GrImageStorageFormat::kRGBA8;
-            break;
-        case kRGBA_8888_sint_GrPixelConfig:
-            fFormat = GrImageStorageFormat::kRGBA8i;
-            break;
-        case kRGBA_half_GrPixelConfig:
-            fFormat = GrImageStorageFormat::kRGBA16f;
-            break;
-        case kRGBA_float_GrPixelConfig:
-            fFormat = GrImageStorageFormat::kRGBA32f;
-            break;
-        default:
-            SkFAIL("Config is not (yet) supported as image storage.");
-            break;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 // Initial static variable from GrXPFactory
 int32_t GrXPFactory::gCurrXPFClassID =
         GrXPFactory::kIllegalXPFClassID;
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index 9f3278c..cdbbc23 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -15,88 +15,48 @@
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLCaps.h"
 
-enum {
-    kSamplerOrImageTypeKeyBits = 4
-};
-
-static inline uint16_t image_storage_or_sampler_uniform_type_key(GrSLType type ) {
-    int value = UINT16_MAX;
-    switch (type) {
-        case kTexture2DSampler_GrSLType:
-            value = 0;
-            break;
-        case kITexture2DSampler_GrSLType:
-            value = 1;
-            break;
-        case kTextureExternalSampler_GrSLType:
-            value = 2;
-            break;
-        case kTexture2DRectSampler_GrSLType:
-            value = 3;
-            break;
-        case kBufferSampler_GrSLType:
-            value = 4;
-            break;
-        case kImageStorage2D_GrSLType:
-            value = 5;
-            break;
-        case kIImageStorage2D_GrSLType:
-            value = 6;
-            break;
-
-        default:
-            break;
-    }
-    SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value);
-    return value;
-}
-
 static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility,
                             const GrGLSLCaps& caps) {
-    int samplerTypeKey = image_storage_or_sampler_uniform_type_key(samplerType);
+    enum {
+        kFirstSamplerType = kTexture2DSampler_GrSLType,
+        kLastSamplerType = kBufferSampler_GrSLType,
+        kSamplerTypeKeyBits = 4
+    };
+    GR_STATIC_ASSERT(kLastSamplerType - kFirstSamplerType < (1 << kSamplerTypeKeyBits));
 
-    GR_STATIC_ASSERT(1 == sizeof(caps.configTextureSwizzle(config).asKey()));
-    return SkToU16(samplerTypeKey |
-                   caps.configTextureSwizzle(config).asKey() << kSamplerOrImageTypeKeyBits |
-                   (caps.samplerPrecision(config, visibility) << (8 + kSamplerOrImageTypeKeyBits)));
+    SkASSERT((int)samplerType >= kFirstSamplerType && (int)samplerType <= kLastSamplerType);
+    int samplerTypeKey = samplerType - kFirstSamplerType;
+
+    return SkToU16(caps.configTextureSwizzle(config).asKey() |
+                   (samplerTypeKey << 8) |
+                   (caps.samplerPrecision(config, visibility) << (8 + kSamplerTypeKeyBits)));
 }
 
-static uint16_t storage_image_key(const GrProcessor::ImageStorageAccess& imageAccess) {
-    GrSLType type = imageAccess.texture()->texturePriv().imageStorageType();
-    return image_storage_or_sampler_uniform_type_key(type) |
-           (int)imageAccess.format() << kSamplerOrImageTypeKeyBits;
-}
-
-static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc,
-                                       const GrGLSLCaps& caps) {
+static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc,
+                             const GrGLSLCaps& caps) {
     int numTextureSamplers = proc.numTextureSamplers();
-    int numBuffers = proc.numBuffers();
-    int numImageStorages = proc.numImageStorages();
-    int numUniforms = numTextureSamplers + numBuffers + numImageStorages;
-    // Need two bytes per key.
-    int word32Count = (numUniforms + 1) / 2;
+    int numSamplers = numTextureSamplers + proc.numBuffers();
+    // Need two bytes per key (swizzle, sampler type, and precision).
+    int word32Count = (numSamplers + 1) / 2;
     if (0 == word32Count) {
         return;
     }
     uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
-    int j = 0;
-    for (int i = 0; i < numTextureSamplers; ++i, ++j) {
-        const GrProcessor::TextureSampler& sampler = proc.textureSampler(i);
-        const GrTexture* tex = sampler.texture();
-        k16[j] = sampler_key(tex->texturePriv().samplerType(), tex->config(), sampler.visibility(),
-                             caps);
+    int i = 0;
+    for (; i < numTextureSamplers; ++i) {
+        const GrProcessor::TextureSampler& textureSampler = proc.textureSampler(i);
+        const GrTexture* tex = textureSampler.texture();
+        k16[i] = sampler_key(tex->texturePriv().samplerType(), tex->config(),
+                             textureSampler.visibility(), caps);
     }
-    for (int i = 0; i < numBuffers; ++i, ++j) {
-        const GrProcessor::BufferAccess& access = proc.bufferAccess(i);
-        k16[j] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(), access.visibility(),
-                             caps);
+    for (; i < numSamplers; ++i) {
+        const GrProcessor::BufferAccess& access = proc.bufferAccess(i - numTextureSamplers);
+        k16[i] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(),
+                             access.visibility(), caps);
     }
-    for (int i = 0; i < numImageStorages; ++i, ++j) {
-        k16[j] = storage_image_key(proc.imageStorageAccess(i));
-    }
-    // zero the last 16 bits if the number of uniforms for samplers and image storages is odd.
-    if (numUniforms & 0x1) {
-        k16[numUniforms] = 0;
+    // zero the last 16 bits if the number of samplers is odd.
+    if (numSamplers & 0x1) {
+        k16[numSamplers] = 0;
     }
 }
 
@@ -122,7 +82,7 @@
         return false;
     }
 
-    add_sampler_and_image_keys(b, proc, glslCaps);
+    add_sampler_keys(b, proc, glslCaps);
 
     uint32_t* key = b->add32n(2);
     key[0] = (classID << 16) | SkToU32(processorKeySize);
diff --git a/src/gpu/GrShaderVar.cpp b/src/gpu/GrShaderVar.cpp
index e1ea207..ef305cb 100644
--- a/src/gpu/GrShaderVar.cpp
+++ b/src/gpu/GrShaderVar.cpp
@@ -9,47 +9,14 @@
 #include "GrShaderVar.h"
 #include "glsl/GrGLSLCaps.h"
 
-static const char* type_modifier_string(GrShaderVar::TypeModifier t) {
-    switch (t) {
-        case GrShaderVar::kNone_TypeModifier: return "";
-        case GrShaderVar::kIn_TypeModifier: return "in";
-        case GrShaderVar::kInOut_TypeModifier: return "inout";
-        case GrShaderVar::kOut_TypeModifier: return "out";
-        case GrShaderVar::kUniform_TypeModifier: return "uniform";
-    }
-    SkFAIL("Unknown shader variable type modifier.");
-    return "";
-}
-
-void GrShaderVar::setImageStorageFormat(GrImageStorageFormat format) {
-    const char* formatStr = nullptr;
-    switch (format) {
-        case GrImageStorageFormat::kRGBA8:
-            formatStr = "rgba8";
-            break;
-        case GrImageStorageFormat::kRGBA8i:
-            formatStr = "rgba8i";
-            break;
-        case GrImageStorageFormat::kRGBA16f:
-            formatStr = "rgba16f";
-            break;
-        case GrImageStorageFormat::kRGBA32f:
-            formatStr = "rgba32f";
-            break;
-    }
-    this->addLayoutQualifier(formatStr);
-    SkASSERT(formatStr);
-}
-
 void GrShaderVar::appendDecl(const GrGLSLCaps* glslCaps, SkString* out) const {
     SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeAcceptsPrecision(fType));
-    SkString layout = fLayoutQualifier;
     if (!fLayoutQualifier.isEmpty()) {
         out->appendf("layout(%s) ", fLayoutQualifier.c_str());
     }
     out->append(fExtraModifiers);
     if (this->getTypeModifier() != kNone_TypeModifier) {
-        out->append(type_modifier_string(this->getTypeModifier()));
+        out->append(TypeModifierString(this->getTypeModifier()));
         out->append(" ");
     }
     GrSLType effectiveType = this->getType();
diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h
index 0420611..d68eb79 100644
--- a/src/gpu/GrTexturePriv.h
+++ b/src/gpu/GrTexturePriv.h
@@ -49,14 +49,6 @@
         return fTexture->fMaxMipMapLevel;
     }
 
-    GrSLType imageStorageType() const {
-        if (GrPixelConfigIsSint(fTexture->config())) {
-            return kIImageStorage2D_GrSLType;
-        } else {
-            return kImageStorage2D_GrSLType;
-        }
-    }
-
     GrSLType samplerType() const { return fTexture->fSamplerType; }
 
     /** The filter used is clamped to this value in GrProcessor::TextureSampler. */
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 0e6007b..9f24e50 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -324,21 +324,16 @@
         static constexpr int kMaxSaneImages = 4;
         GrGLint maxUnits;
         GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
-        GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
-                          &glslCaps->fMaxVertexImageStorages);
-        GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
-                          &glslCaps->fMaxGeometryImageStorages);
-        GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
-                          &glslCaps->fMaxFragmentImageStorages);
-        GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
-                          &glslCaps->fMaxCombinedImageStorages);
+        GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS, &glslCaps->fMaxVertexImages);
+        GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &glslCaps->fMaxGeometryImages);
+        GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &glslCaps->fMaxFragmentImages);
+        GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS, &glslCaps->fMaxCombinedImages);
         // We use one unit for every image uniform
-        glslCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(glslCaps->fMaxCombinedImageStorages,
-                                                            maxUnits), kMaxSaneImages);
-        glslCaps->fMaxVertexImageStorages = SkTMin(maxUnits, glslCaps->fMaxVertexImageStorages);
-        glslCaps->fMaxGeometryImageStorages = SkTMin(maxUnits, glslCaps->fMaxGeometryImageStorages);
-        glslCaps->fMaxFragmentImageStorages =  SkTMin(maxUnits,
-                                                      glslCaps->fMaxFragmentImageStorages);
+        glslCaps->fMaxCombinedImages = SkTMin(SkTMin(glslCaps->fMaxCombinedImages, maxUnits),
+                                                     kMaxSaneImages);
+        glslCaps->fMaxVertexImages = SkTMin(maxUnits, glslCaps->fMaxVertexImages);
+        glslCaps->fMaxGeometryImages = SkTMin(maxUnits, glslCaps->fMaxGeometryImages);
+        glslCaps->fMaxFragmentImages =  SkTMin(maxUnits, glslCaps->fMaxFragmentImages);
     }
 
     /**************************************************************************
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index c96275f..496635d 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -159,11 +159,6 @@
 
     bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
 
-    /** The format to use read/write a texture as an image in a shader */
-    GrGLenum getImageFormat(GrPixelConfig config) const {
-        return fConfigTable[config].fFormats.fSizedInternalFormat;
-    }
-
     /**
     * Gets an array of legal stencil formats. These formats are not guaranteed
     * to be supported by the driver but are legal GLenum names given the GL
@@ -456,6 +451,7 @@
         GrGLenum fExternalFormat[kExternalFormatUsageCnt];
         GrGLenum fExternalType;
 
+
         // Either the base or sized internal format depending on the GL and config.
         GrGLenum fInternalFormatTexImage;
         GrGLenum fInternalFormatRenderbuffer;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 7764052..9c25602 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -217,7 +217,6 @@
     fCaps.reset(SkRef(ctx->caps()));
 
     fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSamplers());
-    fHWBoundImageStorages.reset(this->glCaps().glslCaps()->maxCombinedImageStorages());
 
     fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
     fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
@@ -558,10 +557,6 @@
             SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
             fHWBufferTextures[b].fKnownBound = false;
         }
-        for (int i = 0; i < fHWBoundImageStorages.count(); ++i) {
-            SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport());
-            fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid();
-        }
     }
 
     if (resetBits & kBlend_GrGLBackendState) {
@@ -3347,27 +3342,6 @@
     }
 }
 
-void GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) {
-    SkASSERT(texture);
-    if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID ||
-        ioType != fHWBoundImageStorages[unitIdx].fIOType) {
-        GrGLenum access;
-        switch (ioType) {
-            case kRead_GrIOType:
-                access = GR_GL_READ_ONLY;
-                break;
-            case kWrite_GrIOType:
-                access = GR_GL_WRITE_ONLY;
-                break;
-            case kRW_GrIOType:
-                access = GR_GL_READ_WRITE;
-                break;
-        }
-        GrGLenum format = this->glCaps().getImageFormat(texture->config());
-        GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format));
-    }
-}
-
 void GrGLGpu::generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs,
                               GrGLTexture* texture) {
     SkASSERT(texture);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index c6e7935..dff342d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -62,8 +62,6 @@
 
     void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*);
 
-    void bindImageStorage(int unitIdx, GrIOType, GrGLTexture *);
-
     void generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs, GrGLTexture* texture);
 
     bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
@@ -571,12 +569,6 @@
     TriState                                fHWSRGBFramebuffer;
     SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
 
-    struct Image {
-        GrGpuResource::UniqueID fTextureUniqueID;
-        GrIOType                fIOType;
-    };
-    SkTArray<Image, true>                   fHWBoundImageStorages;
-
     struct BufferTexture {
         BufferTexture() : fTextureID(0), fKnownBound(false),
                           fAttachedBufferUniqueID(SK_InvalidUniqueID),
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 8a61eca..1f2e1c8 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -32,7 +32,6 @@
                          GrGLuint programID,
                          const UniformInfoArray& uniforms,
                          const UniformInfoArray& samplers,
-                         const UniformInfoArray& imageStorages,
                          const VaryingInfoArray& pathProcVaryings,
                          GrGLSLPrimitiveProcessor* geometryProcessor,
                          GrGLSLXferProcessor* xferProcessor,
@@ -48,7 +47,6 @@
     // Assign texture units to sampler uniforms one time up front.
     GL_CALL(UseProgram(fProgramID));
     fProgramDataManager.setSamplers(samplers);
-    fProgramDataManager.setImageStorages(imageStorages);
 }
 
 GrGLProgram::~GrGLProgram() {
@@ -164,11 +162,6 @@
         fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.texelConfig(),
                               static_cast<GrGLBuffer*>(access.buffer()));
     }
-    for (int i = 0; i < processor.numImageStorages(); ++i) {
-        const GrProcessor::ImageStorageAccess& access = processor.imageStorageAccess(i);
-        fGpu->bindImageStorage((*nextSamplerIdx)++, access.ioType(),
-                               static_cast<GrGLTexture *>(access.texture()));
-    }
 }
 
 void GrGLProgram::generateMipmaps(const GrProcessor& processor,
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index ea00df2..3b0940e 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -103,9 +103,9 @@
     void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&);
 
 protected:
-    using UniformHandle    = GrGLSLProgramDataManager::UniformHandle ;
-    using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
-    using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
+    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
+    typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
+    typedef GrGLProgramDataManager::VaryingInfoArray VaryingInfoArray;
 
     GrGLProgram(GrGLGpu*,
                 const GrProgramDesc&,
@@ -113,7 +113,6 @@
                 GrGLuint programID,
                 const UniformInfoArray& uniforms,
                 const UniformInfoArray& samplers,
-                const UniformInfoArray& imageStorages,
                 const VaryingInfoArray&, // used for NVPR only currently
                 GrGLSLPrimitiveProcessor* geometryProcessor,
                 GrGLSLXferProcessor* xferProcessor,
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index 863eab7..3245bd7 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -65,16 +65,6 @@
     }
 }
 
-void GrGLProgramDataManager::setImageStorages(const UniformInfoArray& images) const {
-    for (int i = 0; i < images.count(); ++i) {
-        const UniformInfo& image = images[i];
-        SkASSERT(image.fVisibility);
-        if (kUnusedUniform != image.fLocation) {
-            GR_GL_CALL(fGpu->glInterface(), Uniform1i(image.fLocation, i));
-        }
-    }
-}
-
 void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
     const Uniform& uni = fUniforms[u.toIndex()];
     SkASSERT(uni.fType == kInt_GrSLType);
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 62af4b8..0ef902c 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -47,7 +47,6 @@
 
 
     void setSamplers(const UniformInfoArray& samplers) const;
-    void setImageStorages(const UniformInfoArray &images) 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.
diff --git a/src/gpu/gl/GrGLUniformHandler.cpp b/src/gpu/gl/GrGLUniformHandler.cpp
index 6a2e21f..2def001 100644
--- a/src/gpu/gl/GrGLUniformHandler.cpp
+++ b/src/gpu/gl/GrGLUniformHandler.cpp
@@ -80,33 +80,11 @@
     return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
 }
 
-GrGLSLUniformHandler::ImageStorageHandle GrGLUniformHandler::addImageStorage(
-        uint32_t visibility, GrSLType type, GrImageStorageFormat format, 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);
-
-    UniformInfo& imageStorage = fImageStorages.push_back();
-    imageStorage.fVariable.setName(mangleName);
-
-    SkASSERT(GrSLTypeIsImageStorage(type));
-    imageStorage.fVariable.setType(type);
-    imageStorage.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
-    imageStorage.fVariable.setImageStorageFormat(format);
-    imageStorage.fLocation = -1;
-    imageStorage.fVisibility = visibility;
-    return GrGLSLUniformHandler::ImageStorageHandle(fImageStorages.count() - 1);
-}
-
 void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
     for (int i = 0; i < fUniforms.count(); ++i) {
         if (fUniforms[i].fVisibility & visibility) {
             fUniforms[i].fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
-            out->append(";");
+            out->append(";\n");
         }
     }
     for (int i = 0; i < fSamplers.count(); ++i) {
@@ -115,29 +93,19 @@
             out->append(";\n");
         }
     }
-    for (int i = 0; i < fImageStorages.count(); ++i) {
-        if (fImageStorages[i].fVisibility & visibility) {
-            fImageStorages[i].fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
-            out->append(";");
-        }
-    }
 }
 
 void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) {
     if (caps.bindUniformLocationSupport()) {
-        int currUniform = 0;
-        for (int i = 0; i < fUniforms.count(); ++i, ++currUniform) {
-            GL_CALL(BindUniformLocation(programID, currUniform, fUniforms[i].fVariable.c_str()));
-            fUniforms[i].fLocation = currUniform;
+        int uniformCnt = fUniforms.count();
+        for (int i = 0; i < uniformCnt; ++i) {
+            GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
+            fUniforms[i].fLocation = i;
         }
-        for (int i = 0; i < fSamplers.count(); ++i, ++currUniform) {
-            GL_CALL(BindUniformLocation(programID, currUniform, fSamplers[i].fVariable.c_str()));
-            fSamplers[i].fLocation = currUniform;
-        }
-        for (int i = 0; i < fImageStorages.count(); ++i) {
-            GL_CALL(BindUniformLocation(programID, currUniform,
-                                        fImageStorages[i].fVariable.c_str()));
-            fImageStorages[i].fLocation = currUniform;
+        for (int i = 0; i < fSamplers.count(); ++i) {
+            GrGLint location = i + uniformCnt;
+            GL_CALL(BindUniformLocation(programID, location, fSamplers[i].fVariable.c_str()));
+            fSamplers[i].fLocation = location;
         }
     }
 }
@@ -155,12 +123,6 @@
             GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fVariable.c_str()));
             fSamplers[i].fLocation = location;
         }
-        for (int i = 0; i < fImageStorages.count(); ++i) {
-            GrGLint location;
-            GL_CALL_RET(location, GetUniformLocation(programID,
-                                                     fImageStorages[i].fVariable.c_str()));
-            fImageStorages[i].fLocation = location;
-        }
     }
 }
 
diff --git a/src/gpu/gl/GrGLUniformHandler.h b/src/gpu/gl/GrGLUniformHandler.h
index 32663a4..d3aa2f8 100644
--- a/src/gpu/gl/GrGLUniformHandler.h
+++ b/src/gpu/gl/GrGLUniformHandler.h
@@ -29,8 +29,7 @@
     explicit GrGLUniformHandler(GrGLSLProgramBuilder* program)
         : INHERITED(program)
         , fUniforms(kUniformsPerBlock)
-        , fSamplers(kUniformsPerBlock)
-        , fImageStorages(kUniformsPerBlock) {}
+        , fSamplers(kUniformsPerBlock) {}
 
     UniformHandle internalAddUniformArray(uint32_t visibility,
                                           GrSLType type,
@@ -47,19 +46,10 @@
         return fSamplers[handle.toIndex()].fVariable;
     }
 
-    ImageStorageHandle addImageStorage(uint32_t visibility,
-                                       GrSLType,
-                                       GrImageStorageFormat,
-                                       const char* name) override;
-
     GrSwizzle samplerSwizzle(SamplerHandle handle) const override {
         return fSamplerSwizzles[handle.toIndex()];
     }
 
-    const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
-        return fImageStorages[handle.toIndex()].fVariable;
-    }
-
     void appendUniformDecls(GrShaderFlags visibility, SkString*) const override;
 
     // Manually set uniform locations for all our uniforms.
@@ -76,7 +66,6 @@
     UniformInfoArray    fUniforms;
     UniformInfoArray    fSamplers;
     SkTArray<GrSwizzle> fSamplerSwizzles;
-    UniformInfoArray    fImageStorages;
 
     friend class GrGLProgramBuilder;
 
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index a774570..a1ad572 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -237,7 +237,6 @@
                            programID,
                            fUniformHandler.fUniforms,
                            fUniformHandler.fSamplers,
-                           fUniformHandler.fImageStorages,
                            fVaryingHandler.fPathProcVaryingInfos,
                            fGeometryProcessor,
                            fXferProcessor,
diff --git a/src/gpu/glsl/GrGLSL.h b/src/gpu/glsl/GrGLSL.h
index bc5b319..4461f4c 100644
--- a/src/gpu/glsl/GrGLSL.h
+++ b/src/gpu/glsl/GrGLSL.h
@@ -146,10 +146,6 @@
             return "texture2D";
         case kSampler_GrSLType:
             return "sampler";
-        case kImageStorage2D_GrSLType:
-            return "image2D";
-        case kIImageStorage2D_GrSLType:
-            return "iimage2D";
     }
     SkFAIL("Unknown shader var type.");
     return ""; // suppress warning
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp
index 57e5a0c..5bb22b3 100644
--- a/src/gpu/glsl/GrGLSLCaps.cpp
+++ b/src/gpu/glsl/GrGLSLCaps.cpp
@@ -47,10 +47,10 @@
     fMaxGeometrySamplers = 0;
     fMaxFragmentSamplers = 0;
     fMaxCombinedSamplers = 0;
-    fMaxVertexImageStorages = 0;
-    fMaxGeometryImageStorages = 0;
-    fMaxFragmentImageStorages = 0;
-    fMaxCombinedImageStorages   = 0;
+    fMaxVertexImages = 0;
+    fMaxGeometryImages = 0;
+    fMaxFragmentImages = 0;
+    fMaxCombinedImages   = 0;
     fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
 }
 
@@ -95,10 +95,10 @@
     r.appendf("Max GS Samplers: %d\n", fMaxGeometrySamplers);
     r.appendf("Max FS Samplers: %d\n", fMaxFragmentSamplers);
     r.appendf("Max Combined Samplers: %d\n", fMaxFragmentSamplers);
-    r.appendf("Max VS Image Storages: %d\n", fMaxVertexImageStorages);
-    r.appendf("Max GS Image Storages: %d\n", fMaxGeometryImageStorages);
-    r.appendf("Max FS Image Storages: %d\n", fMaxFragmentImageStorages);
-    r.appendf("Max Combined Image Storages: %d\n", fMaxFragmentImageStorages);
+    r.appendf("Max VS Images: %d\n", fMaxVertexImages);
+    r.appendf("Max GS Images: %d\n", fMaxGeometryImages);
+    r.appendf("Max FS Images: %d\n", fMaxFragmentImages);
+    r.appendf("Max Combined Images: %d\n", fMaxFragmentImages);
     r.appendf("Advanced blend equation interaction: %s\n",
               kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
     return r;
diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h
index 11ce754..4c53ad0 100644
--- a/src/gpu/glsl/GrGLSLCaps.h
+++ b/src/gpu/glsl/GrGLSLCaps.h
@@ -157,13 +157,13 @@
 
     int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
 
-    int maxVertexImageStorages() const { return fMaxVertexImageStorages; }
+    int maxVertexImages() const { return fMaxVertexImages; }
 
-    int maxGeometryImageStorages() const { return fMaxGeometryImageStorages; }
+    int maxGeometryImages() const { return fMaxGeometryImages; }
 
-    int maxFragmentImageStorages() const { return fMaxFragmentImageStorages; }
+    int maxFragmentImages() const { return fMaxFragmentImages; }
 
-    int maxCombinedImageStorages() const { return fMaxCombinedImageStorages; }
+    int maxCombinedImages() const { return fMaxCombinedImages; }
 
     /**
      * Given a texture's config, this determines what swizzle must be appended to accesses to the
@@ -238,10 +238,10 @@
     int fMaxFragmentSamplers;
     int fMaxCombinedSamplers;
 
-    int fMaxVertexImageStorages;
-    int fMaxGeometryImageStorages;
-    int fMaxFragmentImageStorages;
-    int fMaxCombinedImageStorages;
+    int fMaxVertexImages;
+    int fMaxGeometryImages;
+    int fMaxFragmentImages;
+    int fMaxCombinedImages;
 
     AdvBlendEqInteraction fAdvBlendEqInteraction;
 
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 8c32482..5ae7fee 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -49,7 +49,6 @@
     TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
     TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
     BufferSamplers bufferSamplers = args.fBufferSamplers.childInputs(childIndex);
-    ImageStorages imageStorages = args.fImageStorages.childInputs(childIndex);
     EmitArgs childArgs(fragBuilder,
                        args.fUniformHandler,
                        args.fGLSLCaps,
@@ -59,7 +58,6 @@
                        coordVars,
                        textureSamplers,
                        bufferSamplers,
-                       imageStorages,
                        args.fGpImplementsDistanceVector);
     this->childProcessor(childIndex)->emitCode(childArgs);
     fragBuilder->codeAppend("}\n");
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index c815423..aba68b7 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -11,13 +11,13 @@
 #include "GrFragmentProcessor.h"
 #include "GrShaderVar.h"
 #include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
 
 class GrProcessor;
 class GrProcessorKeyBuilder;
 class GrGLSLCaps;
 class GrGLSLFPBuilder;
 class GrGLSLFPFragmentBuilder;
+class GrGLSLUniformHandler;
 
 class GrGLSLFragmentProcessor {
 public:
@@ -29,9 +29,8 @@
         }
     }
 
-    using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
-    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
-    using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
+    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
+    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
 
 private:
     /**
@@ -75,8 +74,6 @@
                                                  &GrProcessor::numTextureSamplers>;
     using BufferSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
                                                 &GrProcessor::numBuffers>;
-    using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrProcessor,
-                                               &GrProcessor::numImageStorages>;
 
     /** 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
@@ -102,12 +99,6 @@
         @param bufferSamplers    Contains one entry for each BufferAccess of the GrProcessor. These
                                  can be passed to the builder to emit buffer reads in the generated
                                  code.
-        @param imageStorages     Contains one entry for each ImageStorageAccess of the GrProcessor.
-                                 These can be passed to the builder to emit image loads and stores
-                                 in the generated code.
-        @param gpImplementsDistanceVector
-                                 Does the GrGeometryProcessor implement the feature where it
-                                 provides a vector to the nearest edge of the shape being rendered.
      */
     struct EmitArgs {
         EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
@@ -119,7 +110,6 @@
                  const TransformedCoordVars& transformedCoordVars,
                  const TextureSamplers& textureSamplers,
                  const BufferSamplers& bufferSamplers,
-                 const ImageStorages& imageStorages,
                  bool gpImplementsDistanceVector)
             : fFragBuilder(fragBuilder)
             , fUniformHandler(uniformHandler)
@@ -130,7 +120,6 @@
             , fTransformedCoords(transformedCoordVars)
             , fTexSamplers(textureSamplers)
             , fBufferSamplers(bufferSamplers)
-            , fImageStorages(imageStorages)
             , fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
         GrGLSLFPFragmentBuilder* fFragBuilder;
         GrGLSLUniformHandler* fUniformHandler;
@@ -141,7 +130,6 @@
         const TransformedCoordVars& fTransformedCoords;
         const TextureSamplers& fTexSamplers;
         const BufferSamplers& fBufferSamplers;
-        const ImageStorages& fImageStorages;
         bool fGpImplementsDistanceVector;
     };
 
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index b398cfd..1991639 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -11,7 +11,6 @@
 #include "GrFragmentProcessor.h"
 #include "GrPrimitiveProcessor.h"
 #include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
 
 class GrBatchTracker;
 class GrPrimitiveProcessor;
@@ -19,6 +18,7 @@
 class GrGLSLPPFragmentBuilder;
 class GrGLSLGeometryBuilder;
 class GrGLSLGPBuilder;
+class GrGLSLUniformHandler;
 class GrGLSLVaryingHandler;
 class GrGLSLVertexBuilder;
 
@@ -28,9 +28,8 @@
 
     virtual ~GrGLSLPrimitiveProcessor() {}
 
-    using UniformHandle      = GrGLSLProgramDataManager::UniformHandle;
-    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
-    using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
+    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
+    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
 
     /**
      * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
@@ -78,7 +77,6 @@
                  const char* distanceVectorName,
                  const SamplerHandle* texSamplers,
                  const SamplerHandle* bufferSamplers,
-                 const ImageStorageHandle* imageStorages,
                  FPCoordTransformHandler* transformHandler)
             : fVertBuilder(vertBuilder)
             , fGeomBuilder(geomBuilder)
@@ -92,7 +90,6 @@
             , fDistanceVectorName(distanceVectorName)
             , fTexSamplers(texSamplers)
             , fBufferSamplers(bufferSamplers)
-            , fImageStorages(imageStorages)
             , fFPCoordTransformHandler(transformHandler) {}
         GrGLSLVertexBuilder* fVertBuilder;
         GrGLSLGeometryBuilder* fGeomBuilder;
@@ -106,7 +103,6 @@
         const char* fDistanceVectorName;
         const SamplerHandle* fTexSamplers;
         const SamplerHandle* fBufferSamplers;
-        const ImageStorageHandle* fImageStorages;
         FPCoordTransformHandler* fFPCoordTransformHandler;
     };
 
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 03a9c21..e8097c7 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -31,10 +31,7 @@
     , fXferProcessor(nullptr)
     , fNumVertexSamplers(0)
     , fNumGeometrySamplers(0)
-    , fNumFragmentSamplers(0)
-    , fNumVertexImageStorages(0)
-    , fNumGeometryImageStorages(0)
-    , fNumFragmentImageStorages(0) {
+    , fNumFragmentSamplers(0) {
 }
 
 void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders,
@@ -69,7 +66,7 @@
         this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
     }
 
-    return this->checkSamplerCounts() && this->checkImageStorageCounts();
+    return this->checkSamplerCounts();
 }
 
 void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& proc,
@@ -100,10 +97,9 @@
     SkASSERT(!fGeometryProcessor);
     fGeometryProcessor = proc.createGLSLInstance(*this->glslCaps());
 
-    SkSTArray<4, SamplerHandle>      texSamplers(proc.numTextureSamplers());
-    SkSTArray<2, SamplerHandle>      bufferSamplers(proc.numBuffers());
-    SkSTArray<2, ImageStorageHandle> imageStorages(proc.numImageStorages());
-    this->emitSamplersAndImageStorages(proc, &texSamplers, &bufferSamplers, &imageStorages);
+    SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
+    SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
+    this->emitSamplers(proc, &texSamplers, &bufferSamplers);
 
     GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
                                                                        &fTransformedCoordVars);
@@ -119,7 +115,6 @@
                                            distanceVectorName,
                                            texSamplers.begin(),
                                            bufferSamplers.begin(),
-                                           imageStorages.begin(),
                                            &transformHandler);
     fGeometryProcessor->emitCode(args);
 
@@ -168,18 +163,15 @@
 
     SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers());
     SkSTArray<2, SamplerHandle> bufferSamplerArray(fp.numBuffers());
-    SkSTArray<2, ImageStorageHandle> imageStorageArray(fp.numImageStorages());
     GrFragmentProcessor::Iter iter(&fp);
     while (const GrFragmentProcessor* subFP = iter.next()) {
-        this->emitSamplersAndImageStorages(*subFP, &textureSamplerArray, &bufferSamplerArray,
-                                           &imageStorageArray);
+        this->emitSamplers(*subFP, &textureSamplerArray, &bufferSamplerArray);
     }
 
     const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
     GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
     GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin());
     GrGLSLFragmentProcessor::BufferSamplers bufferSamplers(&fp, bufferSamplerArray.begin());
-    GrGLSLFragmentProcessor::ImageStorages imageStorages(&fp, imageStorageArray.begin());
     GrGLSLFragmentProcessor::EmitArgs args(&fFS,
                                            this->uniformHandler(),
                                            this->glslCaps(),
@@ -189,7 +181,6 @@
                                            coords,
                                            textureSamplers,
                                            bufferSamplers,
-                                           imageStorages,
                                            this->primitiveProcessor().implementsDistanceVector());
 
     fragProc->emitCode(args);
@@ -226,10 +217,9 @@
     openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
     fFS.codeAppend(openBrace.c_str());
 
-    SkSTArray<4, SamplerHandle>      texSamplers(xp.numTextureSamplers());
-    SkSTArray<2, SamplerHandle>      bufferSamplers(xp.numBuffers());
-    SkSTArray<2, ImageStorageHandle> imageStorageArray(xp.numImageStorages());
-    this->emitSamplersAndImageStorages(xp, &texSamplers, &bufferSamplers, &imageStorageArray);
+    SkSTArray<4, SamplerHandle> texSamplers(xp.numTextureSamplers());
+    SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
+    this->emitSamplers(xp, &texSamplers, &bufferSamplers);
 
     bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
     GrGLSLXferProcessor::EmitArgs args(&fFS,
@@ -241,7 +231,6 @@
                                        fFS.getSecondaryColorOutputName(),
                                        texSamplers.begin(),
                                        bufferSamplers.begin(),
-                                       imageStorageArray.begin(),
                                        usePLSDstRead);
     fXferProcessor->emitCode(args);
 
@@ -251,16 +240,13 @@
     fFS.codeAppend("}");
 }
 
-void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
-        const GrProcessor& processor,
-        SkTArray<SamplerHandle>* outTexSamplerHandles,
-        SkTArray<SamplerHandle>* outBufferSamplerHandles,
-        SkTArray<ImageStorageHandle>* outImageStorageHandles) {
+void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
+                                        SkTArray<SamplerHandle>* outTexSamplers,
+                                        SkTArray<SamplerHandle>* outBufferSamplers) {
     SkString name;
     int numTextureSamplers = processor.numTextureSamplers();
     for (int t = 0; t < numTextureSamplers; ++t) {
         const GrProcessor::TextureSampler& sampler = processor.textureSampler(t);
-        name.printf("TextureSampler_%d", outTexSamplerHandles->count());
         GrSLType samplerType = sampler.texture()->texturePriv().samplerType();
         if (kTextureExternalSampler_GrSLType == samplerType) {
             const char* externalFeatureString = this->glslCaps()->externalTextureExtensionString();
@@ -270,9 +256,9 @@
                              1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
                              externalFeatureString);
         }
-        this->emitSampler(samplerType, sampler.texture()->config(), name.c_str(),
-                          sampler.visibility(), outTexSamplerHandles);
-
+        name.printf("TextureSampler_%d", outTexSamplers->count());
+        this->emitSampler(samplerType, sampler.texture()->config(),
+                          name.c_str(), sampler.visibility(), outTexSamplers);
     }
 
     if (int numBuffers = processor.numBuffers()) {
@@ -281,9 +267,9 @@
 
         for (int b = 0; b < numBuffers; ++b) {
             const GrProcessor::BufferAccess& access = processor.bufferAccess(b);
-            name.printf("BufferSampler_%d", outBufferSamplerHandles->count());
+            name.printf("BufferSampler_%d", outBufferSamplers->count());
             this->emitSampler(kBufferSampler_GrSLType, access.texelConfig(), name.c_str(),
-                              access.visibility(), outBufferSamplerHandles);
+                              access.visibility(), outBufferSamplers);
             texelBufferVisibility |= access.visibility();
         }
 
@@ -293,19 +279,13 @@
                              extension);
         }
     }
-    int numImageStorages = processor.numImageStorages();
-    for (int i = 0; i < numImageStorages; ++i) {
-        const GrProcessor::ImageStorageAccess& imageStorageAccess = processor.imageStorageAccess(i);
-        name.printf("Image_%d", outImageStorageHandles->count());
-        this->emitImageStorage(imageStorageAccess, name.c_str(), outImageStorageHandles);
-    }
 }
 
 void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
                                        GrPixelConfig config,
                                        const char* name,
                                        GrShaderFlags visibility,
-                                       SkTArray<SamplerHandle>* outSamplerHandles) {
+                                       SkTArray<SamplerHandle>* outSamplers) {
     if (visibility & kVertex_GrShaderFlag) {
         ++fNumVertexSamplers;
     }
@@ -318,30 +298,12 @@
     }
     GrSLPrecision precision = this->glslCaps()->samplerPrecision(config, visibility);
     GrSwizzle swizzle = this->glslCaps()->configTextureSwizzle(config);
-    outSamplerHandles->emplace_back(this->uniformHandler()->addSampler(visibility,
-                                                                       swizzle,
-                                                                       samplerType,
-                                                                       precision,
-                                                                       name));
-}
-
-void GrGLSLProgramBuilder::emitImageStorage(const GrProcessor::ImageStorageAccess& access,
-                                            const char* name,
-                                            SkTArray<ImageStorageHandle>* outImageStorageHandles) {
-    if (access.visibility() & kVertex_GrShaderFlag) {
-        ++fNumVertexImageStorages;
-    }
-    if (access.visibility() & kGeometry_GrShaderFlag) {
-        SkASSERT(this->primitiveProcessor().willUseGeoShader());
-        ++fNumGeometryImageStorages;
-    }
-    if (access.visibility() & kFragment_GrShaderFlag) {
-        ++fNumFragmentImageStorages;
-    }
-    GrSLType uniformType = access.texture()->texturePriv().imageStorageType();
-    ImageStorageHandle handle = this->uniformHandler()->addImageStorage(access.visibility(),
-         uniformType, access.format(), name);
-    outImageStorageHandles->emplace_back(handle);
+    SamplerHandle handle = this->uniformHandler()->addSampler(visibility,
+                                                              swizzle,
+                                                              samplerType,
+                                                              precision,
+                                                              name);
+    outSamplers->emplace_back(handle);
 }
 
 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
@@ -383,30 +345,6 @@
     return true;
 }
 
-bool GrGLSLProgramBuilder::checkImageStorageCounts() {
-    const GrGLSLCaps& glslCaps = *this->glslCaps();
-    if (fNumVertexImageStorages > glslCaps.maxVertexImageStorages()) {
-        GrCapsDebugf(this->caps(), "Program would use too many vertex images\n");
-        return false;
-    }
-    if (fNumGeometryImageStorages > glslCaps.maxGeometryImageStorages()) {
-        GrCapsDebugf(this->caps(), "Program would use too many geometry images\n");
-        return false;
-    }
-    if (fNumFragmentImageStorages > glslCaps.maxFragmentImageStorages()) {
-        GrCapsDebugf(this->caps(), "Program would use too many fragment images\n");
-        return false;
-    }
-    // If the same image is used in two different shaders, it counts as two combined images.
-    int numCombinedImages = fNumVertexImageStorages + fNumGeometryImageStorages +
-        fNumFragmentImageStorages;
-    if (numCombinedImages > glslCaps.maxCombinedImageStorages()) {
-        GrCapsDebugf(this->caps(), "Program would use too many combined images\n");
-        return false;
-    }
-    return true;
-}
-
 #ifdef SK_DEBUG
 void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
     SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures());
@@ -455,6 +393,7 @@
     this->uniformHandler()->appendUniformDecls(visibility, out);
 }
 
+
 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 5543537..6c1eb3b 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -28,9 +28,7 @@
 
 class GrGLSLProgramBuilder {
 public:
-    using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
-    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
-    using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
+    typedef GrGLSLUniformHandler::UniformHandle UniformHandle;
 
     virtual ~GrGLSLProgramBuilder() {}
 
@@ -44,6 +42,8 @@
 
     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
 
+    typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
+
     const GrShaderVar& samplerVariable(SamplerHandle handle) const {
         return this->uniformHandler()->samplerVariable(handle);
     }
@@ -52,10 +52,6 @@
         return this->uniformHandler()->samplerSwizzle(handle);
     }
 
-    const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
-        return this->uniformHandler()->imageStorageVariable(handle);
-    }
-
     // Handles for program uniforms (other than per-effect uniforms)
     struct BuiltinUniformHandles {
         UniformHandle       fRTAdjustmentUni;
@@ -160,18 +156,17 @@
                                 const GrGLSLExpr4& coverageIn,
                                 bool ignoresCoverage,
                                 GrPixelLocalStorageState plsState);
-    void emitSamplersAndImageStorages(const GrProcessor& processor,
-                                      SkTArray<SamplerHandle>* outTexSamplerHandles,
-                                      SkTArray<SamplerHandle>* outBufferSamplerHandles,
-                                      SkTArray<ImageStorageHandle>* outImageStorageHandles);
-    void emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
-                     GrShaderFlags visibility, SkTArray<SamplerHandle >* outSamplerHandles);
-    void emitImageStorage(const GrProcessor::ImageStorageAccess&,
-                          const char* name,
-                          SkTArray<ImageStorageHandle>* outImageStorageHandles);
+
+    void emitSamplers(const GrProcessor& processor,
+                      SkTArray<SamplerHandle>* outTexSamplers,
+                      SkTArray<SamplerHandle>* outBufferSamplers);
+    void emitSampler(GrSLType samplerType,
+                     GrPixelConfig,
+                     const char* name,
+                     GrShaderFlags visibility,
+                     SkTArray<SamplerHandle>* outSamplers);
     void emitFSOutputSwizzle(bool hasSecondaryOutput);
     bool checkSamplerCounts();
-    bool checkImageStorageCounts();
 
 #ifdef SK_DEBUG
     void verify(const GrPrimitiveProcessor&);
@@ -182,9 +177,6 @@
     int                         fNumVertexSamplers;
     int                         fNumGeometrySamplers;
     int                         fNumFragmentSamplers;
-    int                         fNumVertexImageStorages;
-    int                         fNumGeometryImageStorages;
-    int                         fNumFragmentImageStorages;
     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
 };
 
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 1647eef..28578dd 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -169,16 +169,6 @@
     this->appendTexelFetch(&this->code(), samplerHandle, coordExpr);
 }
 
-void GrGLSLShaderBuilder::appendImageStorageLoad(SkString* out, ImageStorageHandle handle,
-                                                 const char* coordExpr) {
-    const GrShaderVar& imageStorage = fProgramBuilder->imageStorageVariable(handle);
-    out->appendf("imageLoad(%s, %s)", imageStorage.c_str(), coordExpr);
-}
-
-void GrGLSLShaderBuilder::appendImageStorageLoad(ImageStorageHandle handle, const char* coordExpr) {
-    this->appendImageStorageLoad(&this->code(), handle, coordExpr);
-}
-
 bool GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
     if (featureBit & fFeaturesAddedMask) {
         return false;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index 983d50b..b568369 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -25,8 +25,7 @@
     GrGLSLShaderBuilder(GrGLSLProgramBuilder* program);
     virtual ~GrGLSLShaderBuilder() {}
 
-    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
-    using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
+    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
@@ -73,11 +72,6 @@
     /** Version of above that appends the result to the shader code instead.*/
     void appendTexelFetch(SamplerHandle, const char* coordExpr);
 
-    /** Creates a string of shader code that performs an image load. */
-    void appendImageStorageLoad(SkString* out, ImageStorageHandle, const char* coordExpr);
-    /** Version of above that appends the result to the shader code instead. */
-    void appendImageStorageLoad(ImageStorageHandle, const char* coordExpr);
-
     /**
     * Adds a constant declaration to the top of the shader.
     */
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index 11ba2f7..d49fbd4 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -18,9 +18,8 @@
 public:
     virtual ~GrGLSLUniformHandler() {}
 
-    using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
-    GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle);
-    GR_DEFINE_RESOURCE_HANDLE_CLASS(ImageStorageHandle);
+    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
@@ -68,10 +67,6 @@
     virtual SamplerHandle addSampler(uint32_t visibility, GrSwizzle, GrSLType, GrSLPrecision,
                                      const char* name) = 0;
 
-    virtual const GrShaderVar& imageStorageVariable(ImageStorageHandle) const = 0;
-    virtual ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType type,
-                                               GrImageStorageFormat, 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 69e0072..bf6ee64 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ b/src/gpu/glsl/GrGLSLXferProcessor.h
@@ -9,10 +9,10 @@
 #define GrGLSLXferProcessor_DEFINED
 
 #include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
 
 class GrXferProcessor;
 class GrGLSLCaps;
+class GrGLSLUniformHandler;
 class GrGLSLXPBuilder;
 class GrGLSLXPFragmentBuilder;
 
@@ -21,8 +21,7 @@
     GrGLSLXferProcessor() {}
     virtual ~GrGLSLXferProcessor() {}
 
-    using SamplerHandle        = GrGLSLUniformHandler::SamplerHandle;
-    using ImageStorageHandle   = GrGLSLUniformHandler::ImageStorageHandle;
+    typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
 
     struct EmitArgs {
         EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
@@ -35,7 +34,6 @@
                  const char* outputSecondary,
                  const SamplerHandle* texSamplers,
                  const SamplerHandle* bufferSamplers,
-                 const ImageStorageHandle* imageStorages,
                  const bool usePLSDstRead)
             : fXPFragBuilder(fragBuilder)
             , fUniformHandler(uniformHandler)
@@ -47,7 +45,6 @@
             , fOutputSecondary(outputSecondary)
             , fTexSamplers(texSamplers)
             , fBufferSamplers(bufferSamplers)
-            , fImageStorages(imageStorages)
             , fUsePLSDstRead(usePLSDstRead) {}
 
         GrGLSLXPFragmentBuilder* fXPFragBuilder;
@@ -60,7 +57,6 @@
         const char* fOutputSecondary;
         const SamplerHandle* fTexSamplers;
         const SamplerHandle* fBufferSamplers;
-        const ImageStorageHandle* fImageStorages;
         bool fUsePLSDstRead;
     };
     /**
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 75b8baa..2d53cd8 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -174,8 +174,6 @@
 
 static void append_texture_bindings(const GrProcessor& processor,
                                     SkTArray<const GrProcessor::TextureSampler*>* textureBindings) {
-    // We don't support image storages in VK.
-    SkASSERT(!processor.numImageStorages());
     if (int numTextureSamplers = processor.numTextureSamplers()) {
         const GrProcessor::TextureSampler** bindings =
                 textureBindings->push_back_n(numTextureSamplers);
diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp
index 8c4f851..3998c0f 100644
--- a/src/gpu/vk/GrVkUniformHandler.cpp
+++ b/src/gpu/vk/GrVkUniformHandler.cpp
@@ -45,8 +45,6 @@
         case kBufferSampler_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
             break;
     }
     SkFAIL("Unexpected type");
@@ -88,8 +86,6 @@
         case kBufferSampler_GrSLType:
         case kTexture2D_GrSLType:
         case kSampler_GrSLType:
-        case kImageStorage2D_GrSLType:
-        case kIImageStorage2D_GrSLType:
             break;
     }
     SkFAIL("Unexpected type");
@@ -162,7 +158,7 @@
     uni.fVariable.setTypeModifier(GrShaderVar::kNone_TypeModifier);
 
     uint32_t* currentOffset = kVertex_GrShaderFlag == visibility ? &fCurrentVertexUBOOffset
-                                                                 : &fCurrentFragmentUBOOffset;
+                                                                   : &fCurrentFragmentUBOOffset;
     get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
 
     if (outName) {
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index d8e8c68..e5d4a4c 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -76,18 +76,6 @@
         return fSamplers[handle.toIndex()].fVisibility;
     }
 
-    ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType,  GrImageStorageFormat,
-                                       const char* name) override {
-        SkFAIL("Image storages not implemented for Vulkan.");
-        return 0;
-    }
-
-    const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
-        SkFAIL("Image storages not implemented for Vulkan.");
-        GrShaderVar* gVar = nullptr;
-        return *gVar;
-    }
-
     void appendUniformDecls(GrShaderFlags, SkString*) const override;
 
     bool hasVertexUniforms() const { return fCurrentVertexUBOOffset > 0; }
diff --git a/src/gpu/vk/GrVkVaryingHandler.cpp b/src/gpu/vk/GrVkVaryingHandler.cpp
index d7d08c9..9bab292 100644
--- a/src/gpu/vk/GrVkVaryingHandler.cpp
+++ b/src/gpu/vk/GrVkVaryingHandler.cpp
@@ -47,10 +47,6 @@
              return 0;
         case kSampler_GrSLType:
              return 0;
-        case kImageStorage2D_GrSLType:
-            return 0;
-        case kIImageStorage2D_GrSLType:
-            return 0;
     }
     SkFAIL("Unexpected type");
     return -1;
diff --git a/tests/ImageStorageTest.cpp b/tests/ImageStorageTest.cpp
deleted file mode 100644
index 99949d0..0000000
--- a/tests/ImageStorageTest.cpp
+++ /dev/null
@@ -1,149 +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.
- */
-
-#include "Test.h"
-
-#if SK_SUPPORT_GPU
-
-#include "GrFragmentProcessor.h"
-#include "GrInvariantOutput.h"
-#include "GrRenderTargetContext.h"
-#include "GrTexture.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-
-DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageStorageLoad, reporter, ctxInfo) {
-    class TestFP : public GrFragmentProcessor {
-    public:
-        static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTexture> texture) {
-            return sk_sp<GrFragmentProcessor>(new TestFP(std::move(texture)));
-        }
-
-        const char* name() const override { return "Image Load Test FP"; }
-
-    private:
-        TestFP(sk_sp<GrTexture> texture) : fImageStorageAccess(std::move(texture), kRead_GrIOType) {
-            this->initClassID<TestFP>();
-            this->setWillReadFragmentPosition();
-            this->addImageStorageAccess(&fImageStorageAccess);
-        }
-
-        void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {}
-
-        void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
-            inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
-        }
-
-        bool onIsEqual(const GrFragmentProcessor& that) const override { return true; }
-
-        GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
-            class GLSLProcessor : public GrGLSLFragmentProcessor {
-            public:
-                GLSLProcessor() = default;
-                void emitCode(EmitArgs& args) override {
-                    const TestFP& tfp = args.fFp.cast<TestFP>();
-                    GrGLSLFPFragmentBuilder* fb = args.fFragBuilder;
-                    SkString imageLoadStr;
-                    fb->codeAppendf("vec2 coord = %s.xy;", args.fFragBuilder->fragmentPosition());
-                    fb->appendImageStorageLoad(&imageLoadStr, args.fImageStorages[0],
-                                               "ivec2(coord)");
-                    if (GrPixelConfigIsSint(tfp.fImageStorageAccess.texture()->config())) {
-                        // Map the signed bytes so that when then get read back as unorm values they
-                        // will have their original bit pattern.
-                        fb->codeAppendf("ivec4 ivals = %s;", imageLoadStr.c_str());
-                        // NV gives a linker error for this:
-                        // fb->codeAppend("ivals +=
-                        //                "mix(ivec4(0), ivec4(256), lessThan(ivals, ivec4(0)));");
-                        fb->codeAppend("if (ivals.r < 0) { ivals.r += 256; }");
-                        fb->codeAppend("if (ivals.g < 0) { ivals.g += 256; }");
-                        fb->codeAppend("if (ivals.b < 0) { ivals.b += 256; }");
-                        fb->codeAppend("if (ivals.a < 0) { ivals.a += 256; }");
-                        fb->codeAppendf("%s = (vec4(ivals) + vec4(0.5))/255;", args.fOutputColor);
-                    } else {
-                        fb->codeAppendf("%s = %s;", args.fOutputColor, imageLoadStr.c_str());
-                    }
-                }
-            };
-            return new GLSLProcessor;
-        }
-
-        ImageStorageAccess fImageStorageAccess;
-    };
-
-    static constexpr int kS = 256;
-    GrContext* context = ctxInfo.grContext();
-    if (!context->caps()->shaderCaps()->imageLoadStoreSupport()) {
-        return;
-    }
-
-    std::unique_ptr<uint32_t[]> data(new uint32_t[kS * kS]);
-    for (int j = 0; j < kS; ++j) {
-        for (int i = 0; i < kS; ++i) {
-            data[i + kS * j] = GrColorPackRGBA(i, j, 0, 0);
-        }
-    }
-
-    std::unique_ptr<uint32_t[]> idata(new uint32_t[kS * kS]);
-    for (int j = 0; j < kS; ++j) {
-        for (int i = 0; i < kS; ++i) {
-            int8_t r = i - 128;
-            int8_t g = j - 128;
-            int8_t b = -128;
-            int8_t a = -128;
-            idata[i + kS * j] = ((uint8_t)a << 24) | ((uint8_t)b << 16) |
-                                ((uint8_t)g << 8)  |  (uint8_t)r;
-        }
-    }
-
-    // Currently image accesses always have "top left" semantics.
-    GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
-    desc.fWidth = kS;
-    desc.fHeight = kS;
-    struct {
-        GrPixelConfig fConfig;
-        std::unique_ptr<uint32_t[]> fData;
-    } tests[] = {
-        {
-           kRGBA_8888_GrPixelConfig,
-           std::move(data)
-        },
-        {
-           kRGBA_8888_sint_GrPixelConfig,
-           std::move(idata)
-        },
-    };
-    for (const auto& test : tests) {
-        desc.fConfig = test.fConfig;
-        sk_sp<GrTexture> imageStorageTexture(context->textureProvider()->createTexture(desc,
-            SkBudgeted::kYes, test.fData.get(), 0));
-
-        sk_sp<GrRenderTargetContext> rtContext =
-            context->makeRenderTargetContext(SkBackingFit::kExact, kS, kS, kRGBA_8888_GrPixelConfig,
-                                             nullptr);
-        GrPaint paint;
-        paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-        paint.addColorFragmentProcessor(TestFP::Make(imageStorageTexture));
-        rtContext->drawPaint(GrNoClip(), paint, SkMatrix::I());
-        std::unique_ptr<uint32_t[]> readData(new uint32_t[kS * kS]);
-        SkImageInfo info = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
-        rtContext->readPixels(info, readData.get(), 0, 0, 0);
-        int failed = false;
-        for (int j = 0; j < kS && !failed; ++j) {
-            for (int i = 0; i < kS && !failed; ++i) {
-                uint32_t d = test.fData[j * kS + i];
-                uint32_t rd = readData[j * kS + i];
-                if (d != rd) {
-                    failed = true;
-                    ERRORF(reporter, "Expected 0x%08x, got 0x%08x at %d, %d.", d, rd, i, j);
-                }
-            }
-        }
-    }
-}
-
-#endif