Add texture-specific flags for External & Rectangle textures

For DDLs, Ganesh needs to know about External & Rectangle textures prior to instantiation (or PromiseImage fulfillment). These new flags allow the client to provide this information when the lazyProxy is created.

The new texture flags work analogously to the render target flags:
   GrSurface and GrSurfaceProxy get a new set of accessors for the new flags
   The new flags are set appropriately on a GrGLTexture when it is created
   For wrapped texture proxies the flags are just copied off of the GrSurface
   For lazy-proxies/promise-images the flags are computed up front and passed to the proxy
   The GrSurfaceProxy/GrSurface flags equivalence is verified in GrSurfaceProxy::assign

Change-Id: Ia8e1998aa0a36ce4481bfd9e56be21f990e83148
Reviewed-on: https://skia-review.googlesource.com/114985
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index ee17d8a..5fc365b 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -63,6 +63,20 @@
                               GrMipMapped, bool useNextPow2 = false);
 
 protected:
+    void setDoesNotSupportMipMaps() {
+        SkASSERT(this->asTexture());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
+    }
+    bool doesNotSupportMipMaps() const {
+        return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
+    }
+
+    void setIsClampOnly() {
+        SkASSERT(this->asTexture());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly;
+    }
+    bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; }
+
     void setHasMixedSamples() {
         SkASSERT(this->asRenderTarget());
         fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 0b15079..3c503fa 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -420,6 +420,20 @@
     bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil,
                          GrSurfaceDescFlags descFlags, GrMipMapped, const GrUniqueKey*);
 
+    void setDoesNotSupportMipMaps() {
+        SkASSERT(this->asTextureProxy());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
+    }
+    bool doesNotSupportMipMaps() const {
+        return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
+    }
+
+    void setIsClampOnly() {
+        SkASSERT(this->asTextureProxy());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly;
+    }
+    bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; }
+
     void setHasMixedSamples() {
         SkASSERT(this->asRenderTargetProxy());
         fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index d64c9a3..69c79ab 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -672,14 +672,24 @@
 
 // Flags shared between the GrSurface & GrSurfaceProxy class hierarchies
 enum class GrInternalSurfaceFlags {
-    kNone               = 0,
+    kNone                  = 0,
 
     // Surface-level
-    kNoPendingIO        = 1 << 0,
+    kNoPendingIO           = 1 << 0,
 
-    // Texture-only
+    // Texture-only flags
 
-    /* coming soon */
+    // This flag is set when the internal texture target doesn't support mipmaps (e.g.,
+    // external and rectangle textures). Note that Ganesh does not internally
+    // create resources with this limitation - this flag will only appear on resources passed
+    // into Ganesh.
+    kDoesNotSupportMipMaps = 1 << 1,
+
+    // This flag is set when the internal texture target only supports the clamp wrap mode (e.g.,
+    // external and rectangle textures). Note that Ganesh does not internally
+    // create resources with this limitation - this flag will only appear on resources passed
+    // into Ganesh.
+    kIsClampOnly           = 1 << 2,
 
     // RT-only
 
@@ -689,14 +699,14 @@
     //    this is disabled for FBO0
     //    but, otherwise, is enabled whenever MSAA is enabled and GrCaps reports mixed samples
     //        are supported
-    kMixedSampled       = 1 << 3,
+    kMixedSampled          = 1 << 3,
 
     // For internal resources:
     //    this is enabled whenever GrCaps reports window rect support
     // For wrapped resources1
     //    this is disabled for FBO0
     //    but, otherwise, is enabled whenever GrCaps reports window rect support
-    kWindowRectsSupport = 1 << 4
+    kWindowRectsSupport    = 1 << 4
 };
 GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags)
 
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index 1114a26..8a89068 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -93,6 +93,14 @@
     // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
     // DDL is being replayed into.
 
+    GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
+    if (fContext->caps()->usesMixedSamples() && desc.fSampleCnt > 1) {
+        surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
+    }
+    if (fContext->caps()->maxWindowRectangles() > 0) {
+        surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
+    }
+
     sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
             [lazyProxyData](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
@@ -106,7 +114,7 @@
             },
             desc,
             fCharacterization.origin(),
-            GrInternalSurfaceFlags::kNone,
+            surfaceFlags,
             GrProxyProvider::Textureable(fCharacterization.isTextureable()),
             GrMipMapped::kNo,
             SkBackingFit::kExact,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 18a13de..fafce10 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -26,6 +26,7 @@
 #include "GrStencilSettings.h"
 #include "GrSurfacePriv.h"
 #include "GrTexturePriv.h"
+#include "GrTextureProxyPriv.h"
 #include "GrTracing.h"
 #include "SkJSONWriter.h"
 #include "SkMathPriv.h"
@@ -44,11 +45,25 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps,
+bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* texProxy,
                                           int width, int height,
                                           const GrSamplerState& textureParams,
                                           GrTextureProducer::CopyParams* copyParams,
                                           SkScalar scaleAdjust[2]) {
+
+    if (texProxy) {
+        // If the texture format itself doesn't support repeat wrap mode or mipmapping (and
+        // those capabilities are required) force a copy.
+        if ((textureParams.isRepeated() && texProxy->texPriv().isClampOnly()) ||
+            (GrSamplerState::Filter::kMipMap == textureParams.filter() &&
+                                                    texProxy->texPriv().doesNotSupportMipMaps())) {
+            copyParams->fFilter = GrSamplerState::Filter::kNearest;
+            copyParams->fWidth = texProxy->width();
+            copyParams->fHeight = texProxy->height();
+            return true;
+        }
+    }
+
     if (textureParams.isRepeated() && !caps->npotTextureTileSupport() &&
         (!SkIsPow2(width) || !SkIsPow2(height))) {
         SkASSERT(scaleAdjust);
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 95c5117..78b6fd4 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -506,26 +506,12 @@
     virtual void clearStencil(GrRenderTarget* target, int clearValue) = 0;
 
     // Determines whether a texture will need to be rescaled in order to be used with the
-    // GrSamplerState. This variation is called when the caller will create a new texture using the
-    // resource provider from a non-texture src (cpu-backed image, ...).
-    static bool IsACopyNeededForTextureParams(const GrCaps*, int width, int height,
+    // GrSamplerState.
+    static bool IsACopyNeededForTextureParams(const GrCaps*, GrTextureProxy* texProxy,
+                                              int width, int height,
                                               const GrSamplerState&, GrTextureProducer::CopyParams*,
                                               SkScalar scaleAdjust[2]);
 
-    // Like the above but this variation should be called when the caller is not creating the
-    // original texture but rather was handed the original texture. It adds additional checks
-    // relevant to original textures that were created external to Skia via
-    // GrResourceProvider::wrap methods.
-    bool isACopyNeededForTextureParams(GrTextureProxy* proxy, const GrSamplerState& params,
-                                       GrTextureProducer::CopyParams* copyParams,
-                                       SkScalar scaleAdjust[2]) const {
-        if (IsACopyNeededForTextureParams(this->caps(), proxy->width(), proxy->height(), params,
-                                          copyParams, scaleAdjust)) {
-            return true;
-        }
-        return this->onIsACopyNeededForTextureParams(proxy, params, copyParams, scaleAdjust);
-    }
-
     void handleDirtyContext() {
         if (fResetBits) {
             this->resetContext();
@@ -578,12 +564,6 @@
     virtual GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
                                      const void* data) = 0;
 
-    virtual bool onIsACopyNeededForTextureParams(GrTextureProxy* proxy, const GrSamplerState&,
-                                                 GrTextureProducer::CopyParams*,
-                                                 SkScalar scaleAdjust[2]) const {
-        return false;
-    }
-
     virtual bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
                                      size_t rowBytes, GrColorType, DrawPreference*,
                                      ReadPixelTempDrawInfo*) = 0;
diff --git a/src/gpu/GrSurfacePriv.h b/src/gpu/GrSurfacePriv.h
index 4d61dca..98d8fc5 100644
--- a/src/gpu/GrSurfacePriv.h
+++ b/src/gpu/GrSurfacePriv.h
@@ -40,6 +40,9 @@
 
     GrInternalSurfaceFlags flags() const { return fSurface->fSurfaceFlags; }
 
+    bool doesNotSupportMipMaps() const { return fSurface->doesNotSupportMipMaps(); }
+    bool isClampOnly() const { return fSurface->isClampOnly(); }
+
 private:
     explicit GrSurfacePriv(GrSurface* surface) : fSurface(surface) {}
     GrSurfacePriv(const GrSurfacePriv&); // unimpl
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index a49251f..2aa13c8 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -179,6 +179,11 @@
 
 void GrSurfaceProxy::assign(sk_sp<GrSurface> surface) {
     SkASSERT(!fTarget && surface);
+
+    // Check that our a priori computation matched the ultimate reality
+    SkASSERT((fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO) ==
+             surface->surfacePriv().flags());
+
     fTarget = surface.release();
 
     this->INHERITED::transferRefs();
@@ -222,10 +227,6 @@
 
     this->assign(std::move(surface));
 
-    // Check that our a priori computation matched the ultimate reality
-    SkASSERT((fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO) ==
-             fTarget->surfacePriv().flags());
-
     return true;
 }
 
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index cc7a899..306ec59 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -75,13 +75,9 @@
         return nullptr;
     }
 
-    // DDL TODO: remove the need for the GrGpu in this method
-    GrGpu* gpu = fContext->contextPriv().getGpu();
-    if (!gpu) {
-        return proxy;
-    }
-
-    if (!gpu->isACopyNeededForTextureParams(proxy.get(), params, &copyParams, scaleAdjust)) {
+    if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(),
+                                              proxy.get(), proxy->width(), proxy->height(),
+                                              params, &copyParams, scaleAdjust)) {
         return proxy;
     }
 
diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp
index 720f357..5db0b48 100644
--- a/src/gpu/GrTextureMaker.cpp
+++ b/src/gpu/GrTextureMaker.cpp
@@ -31,13 +31,14 @@
     sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
                                                                  AllowedTexGenType::kCheap));
     if (original) {
-        GrGpu* gpu = fContext->contextPriv().getGpu();
-
-        if (!gpu->isACopyNeededForTextureParams(original.get(), params, &copyParams, scaleAdjust)) {
+        if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), original.get(),
+                                                  original->width(), original->height(),
+                                                  params, &copyParams, scaleAdjust)) {
             return original;
         }
     } else {
-        if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), this->width(), this->height(),
+        if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), nullptr,
+                                                  this->width(), this->height(),
                                                   params, &copyParams, scaleAdjust)) {
             return this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
                                                  AllowedTexGenType::kAny);
diff --git a/src/gpu/GrTextureProxyPriv.h b/src/gpu/GrTextureProxyPriv.h
index 3b68374..c7582d3 100644
--- a/src/gpu/GrTextureProxyPriv.h
+++ b/src/gpu/GrTextureProxyPriv.h
@@ -31,6 +31,9 @@
     // been instantiated or not.
     GrMipMapped proxyMipMapped() const { return fTextureProxy->fMipMapped; }
 
+    bool doesNotSupportMipMaps() const { return fTextureProxy->doesNotSupportMipMaps(); }
+    bool isClampOnly() const { return fTextureProxy->isClampOnly(); }
+
 private:
     explicit GrTextureProxyPriv(GrTextureProxy* textureProxy) : fTextureProxy(textureProxy) {}
     GrTextureProxyPriv(const GrTextureProxyPriv&) {} // unimpl
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 4e1e64b..ce81adf 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4553,30 +4553,6 @@
     return attribState;
 }
 
-bool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy,
-                                              const GrSamplerState& textureParams,
-                                              GrTextureProducer::CopyParams* copyParams,
-                                              SkScalar scaleAdjust[2]) const {
-    const GrTexture* texture = proxy->priv().peekTexture();
-    if (!texture) {
-        // The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them.
-        // In that case the proxy should already be instantiated.
-        return false;
-    }
-
-    if (textureParams.isRepeated() || GrSamplerState::Filter::kMipMap == textureParams.filter()) {
-        const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture);
-        if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
-            GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
-            copyParams->fFilter = GrSamplerState::Filter::kNearest;
-            copyParams->fWidth = texture->width();
-            copyParams->fHeight = texture->height();
-            return true;
-        }
-    }
-    return false;
-}
-
 void GrGLGpu::onFinishFlush(bool insertedSemaphore) {
     // If we inserted semaphores during the flush, we need to call GLFlush.
     if (insertedSemaphore) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index c09cac6..9a03d97 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -215,10 +215,6 @@
                            GrGLTexture::TexParams* initialTexParams, const GrMipLevel texels[],
                            int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
 
-    bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerState&,
-                                         GrTextureProducer::CopyParams*,
-                                         SkScalar scaleAdjust[2]) const override;
-
     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
     // render target.
     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 5175ea8..8fe9927 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -69,6 +69,11 @@
 void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
     SkASSERT(0 != idDesc.fInfo.fID);
     SkASSERT(0 != idDesc.fInfo.fFormat);
+    if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE ||
+        idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
+        this->setDoesNotSupportMipMaps();
+        this->setIsClampOnly();
+    }
     fTexParams.invalidate();
     fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
     fInfo = idDesc.fInfo;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9c62c34..6342512 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -28,6 +28,7 @@
 #include "GrTexture.h"
 #include "GrTexturePriv.h"
 #include "GrTextureProxy.h"
+#include "gl/GrGLDefines.h"
 #include "effects/GrNonlinearColorSpaceXformEffect.h"
 #include "effects/GrYUVtoRGBEffect.h"
 #include "SkCanvas.h"
@@ -617,6 +618,17 @@
     sk_sp<GrReleaseProcHelper> fDoneHelper;
 };
 
+static GrInternalSurfaceFlags get_flags_from_format(const GrBackendFormat& backendFormat) {
+    if (const GrGLenum* target = backendFormat.getGLTarget()) {
+        if (GR_GL_TEXTURE_RECTANGLE == *target || GR_GL_TEXTURE_EXTERNAL == *target) {
+            return GrInternalSurfaceFlags::kDoesNotSupportMipMaps |
+                   GrInternalSurfaceFlags::kIsClampOnly;
+        }
+    }
+
+    return GrInternalSurfaceFlags::kNone;
+}
+
 sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
                                                const GrBackendFormat& backendFormat,
                                                int width,
@@ -661,6 +673,8 @@
     PromiseImageHelper promiseHelper(textureFulfillProc, textureReleaseProc, promiseDoneProc,
                                      textureContext);
 
+    GrInternalSurfaceFlags formatFlags = get_flags_from_format(backendFormat);
+
     sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
             [promiseHelper, config] (GrResourceProvider* resourceProvider) mutable {
                 if (!resourceProvider) {
@@ -669,7 +683,7 @@
                 }
 
                 return promiseHelper.getTexture(resourceProvider, config);
-            }, desc, origin, mipMapped, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
+            }, desc, origin, mipMapped, formatFlags, SkBackingFit::kExact,
                SkBudgeted::kNo, GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
 
     if (!proxy) {
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index 9abe5f9..d9aa522 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -11,9 +11,12 @@
 
 #include "GrBackendSurface.h"
 #include "GrGpu.h"
+#include "GrTextureProxyPriv.h"
+
 #include "SkCanvas.h"
 #include "SkDeferredDisplayListRecorder.h"
 #include "SkGpuDevice.h"
+#include "SkImage_Gpu.h"
 #include "SkSurface.h"
 #include "SkSurface_Gpu.h"
 #include "SkSurfaceCharacterization.h"
@@ -406,7 +409,7 @@
 
 static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); }
 static void dummy_release_proc(void*) { SkASSERT(0); }
-static void dummy_done_proc(void*) { SkASSERT(0); }
+static void dummy_done_proc(void*) { }
 
 // Test out the behavior of an invalid DDLRecorder
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
@@ -433,7 +436,7 @@
         REPORTER_ASSERT(reporter, !recorder.getCanvas());
         REPORTER_ASSERT(reporter, !recorder.detach());
 
-        GrBackendFormat format;
+        GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType);
         sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo,
                                                            kTopLeft_GrSurfaceOrigin,
                                                            kRGBA_8888_SkColorType,
@@ -464,4 +467,42 @@
     canvas->getGrContext()->flush();
 }
 
+// Check that the texture-specific flags (i.e., for external & rectangle textures) work
+// for promise images. As such, this is a GL-only test.
+DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
+    GrContext* context = ctxInfo.grContext();
+
+    SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
+    sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
+
+    SkSurfaceCharacterization characterization;
+    SkAssertResult(s->characterize(&characterization));
+
+    SkDeferredDisplayListRecorder recorder(characterization);
+
+    for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
+        GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
+
+        sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo,
+                                                           kTopLeft_GrSurfaceOrigin,
+                                                           kRGBA_8888_SkColorType,
+                                                           kPremul_SkAlphaType, nullptr,
+                                                           dummy_fulfill_proc,
+                                                           dummy_release_proc,
+                                                           dummy_done_proc,
+                                                           nullptr);
+        REPORTER_ASSERT(reporter, image);
+
+        GrTextureProxy* backingProxy = ((SkImage_Gpu*) image.get())->peekProxy();
+
+        if (GR_GL_TEXTURE_2D == target) {
+            REPORTER_ASSERT(reporter, !backingProxy->texPriv().doesNotSupportMipMaps());
+            REPORTER_ASSERT(reporter, !backingProxy->texPriv().isClampOnly());
+        } else {
+            REPORTER_ASSERT(reporter, backingProxy->texPriv().doesNotSupportMipMaps());
+            REPORTER_ASSERT(reporter, backingProxy->texPriv().isClampOnly());
+        }
+    }
+
+}
 #endif
diff --git a/tests/EGLImageTest.cpp b/tests/EGLImageTest.cpp
index e65954a..b44f5b2 100644
--- a/tests/EGLImageTest.cpp
+++ b/tests/EGLImageTest.cpp
@@ -13,8 +13,11 @@
 #include "GrContextPriv.h"
 #include "GrRenderTargetContext.h"
 #include "GrShaderCaps.h"
+#include "GrSurfacePriv.h"
 #include "GrTest.h"
+#include "GrTexture.h"
 #include "GrTextureContext.h"
+#include "GrTextureProxyPriv.h"
 #include "gl/GLTestContext.h"
 #include "gl/GrGLGpu.h"
 #include "gl/GrGLUtil.h"
@@ -159,6 +162,13 @@
         return;
     }
 
+    GrTextureProxy* proxy = surfaceContext->asTextureProxy();
+    REPORTER_ASSERT(reporter, proxy->texPriv().doesNotSupportMipMaps());
+    REPORTER_ASSERT(reporter, proxy->priv().peekTexture()->surfacePriv().doesNotSupportMipMaps());
+
+    REPORTER_ASSERT(reporter, proxy->texPriv().isClampOnly());
+    REPORTER_ASSERT(reporter, proxy->priv().peekTexture()->surfacePriv().isClampOnly());
+
     // Should not be able to wrap as a RT
     {
         sk_sp<GrRenderTargetContext> temp =
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index e7512fb..6087aab 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -14,7 +14,9 @@
 #include "GrContextPriv.h"
 #include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
+#include "GrSurfacePriv.h"
 #include "GrTest.h"
+#include "GrTextureProxyPriv.h"
 #include "gl/GLTestContext.h"
 #include "gl/GrGLGpu.h"
 #include "gl/GrGLUtil.h"
@@ -135,6 +137,12 @@
             continue;
         }
 
+        SkASSERT(rectProxy->texPriv().doesNotSupportMipMaps());
+        SkASSERT(rectProxy->priv().peekTexture()->surfacePriv().doesNotSupportMipMaps());
+
+        SkASSERT(rectProxy->texPriv().isClampOnly());
+        SkASSERT(rectProxy->priv().peekTexture()->surfacePriv().isClampOnly());
+
         test_basic_draw_as_src(reporter, context, rectProxy, refPixels);
 
         // Test copy to both a texture and RT