Alter GrSurface/GrSurfaceProxy flags to prepare for GrTexture/GrTextureProxy -specific flags

This CL:
  moves GrRenderTarget::fFlags to GrSurface::fSurfaceFlags
  adds a GrInternalSurfaceFlags type and uses it for GrSurfaceProxy::fSurfaceFlags

  The goal of this is to provide a location where GrTexture/GrTextureProxy-specific flags
(i.e., isExternal & isRectangle) can be stored.

Change-Id: I8df7b79036a6853dd378ff6cf10d4b37c60dd511
Reviewed-on: https://skia-review.googlesource.com/114796
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 188e6d1..ebfa4fd 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -38,11 +38,10 @@
     GrFSAAType fsaaType() const {
         SkASSERT(fSampleCnt >= 1);
         if (fSampleCnt <= 1) {
-            SkASSERT(!(fFlags & GrRenderTargetFlags::kMixedSampled));
+            SkASSERT(!this->hasMixedSamples());
             return GrFSAAType::kNone;
         }
-        return (fFlags & GrRenderTargetFlags::kMixedSampled) ? GrFSAAType::kMixedSamples
-                                                             : GrFSAAType::kUnifiedMSAA;
+        return this->hasMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA;
     }
 
     /**
@@ -116,9 +115,7 @@
     const GrRenderTargetPriv renderTargetPriv() const;
 
 protected:
-    GrRenderTarget(GrGpu*, const GrSurfaceDesc&,
-                   GrRenderTargetFlags = GrRenderTargetFlags::kNone,
-                   GrStencilAttachment* = nullptr);
+    GrRenderTarget(GrGpu*, const GrSurfaceDesc&, GrStencilAttachment* = nullptr);
 
     // override of GrResource
     void onAbandon() override;
@@ -135,7 +132,6 @@
 
     int                  fSampleCnt;
     GrStencilAttachment* fStencilAttachment;
-    GrRenderTargetFlags  fFlags;
 
     SkIRect              fResolveRect;
 
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 1056bdd..ee17d8a 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef GrSurface_DEFINED
 #define GrSurface_DEFINED
 
@@ -64,6 +63,20 @@
                               GrMipMapped, bool useNextPow2 = false);
 
 protected:
+    void setHasMixedSamples() {
+        SkASSERT(this->asRenderTarget());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
+    }
+    bool hasMixedSamples() const { return fSurfaceFlags & GrInternalSurfaceFlags::kMixedSampled; }
+
+    void setSupportsWindowRects() {
+        SkASSERT(this->asRenderTarget());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
+    }
+    bool supportsWindowRects() const {
+        return fSurfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport;
+    }
+
     // Methods made available via GrSurfacePriv
     bool hasPendingRead() const;
     bool hasPendingWrite() const;
@@ -76,7 +89,10 @@
             : INHERITED(gpu)
             , fConfig(desc.fConfig)
             , fWidth(desc.fWidth)
-            , fHeight(desc.fHeight) {}
+            , fHeight(desc.fHeight)
+            , fSurfaceFlags(GrInternalSurfaceFlags::kNone) {
+    }
+
     ~GrSurface() override {}
 
 
@@ -84,9 +100,10 @@
     void onAbandon() override;
 
 private:
-    GrPixelConfig        fConfig;
-    int                  fWidth;
-    int                  fHeight;
+    GrPixelConfig          fConfig;
+    int                    fWidth;
+    int                    fHeight;
+    GrInternalSurfaceFlags fSurfaceFlags;
 
     typedef GrGpuResource INHERITED;
 };
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 97d6210..3fec742 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -376,9 +376,10 @@
      */
     kPerformInitialClear_GrSurfaceFlag = 0x2
 };
-
 GR_MAKE_BITFIELD_OPS(GrSurfaceFlags)
 
+typedef GrSurfaceFlags GrSurfaceDescFlags;
+
 // opaque type for 3D API object handles
 typedef intptr_t GrBackendObject;
 
@@ -409,7 +410,7 @@
             , fConfig(kUnknown_GrPixelConfig)
             , fSampleCnt(1) {}
 
-    GrSurfaceFlags         fFlags;  //!< bitfield of TextureFlags
+    GrSurfaceDescFlags     fFlags;  //!< bitfield of TextureFlags
     int                    fWidth;  //!< Width of the texture
     int                    fHeight; //!< Height of the texture
 
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index 2468df3..f1e1b7d 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -27,12 +27,10 @@
 
     GrFSAAType fsaaType() const {
         if (fSampleCnt <= 1) {
-            SkASSERT(!(fRenderTargetFlags & GrRenderTargetFlags::kMixedSampled));
+            SkASSERT(!this->hasMixedSamples());
             return GrFSAAType::kNone;
         }
-        return (fRenderTargetFlags & GrRenderTargetFlags::kMixedSampled)
-                                                             ? GrFSAAType::kMixedSamples
-                                                             : GrFSAAType::kUnifiedMSAA;
+        return this->hasMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA;
     }
 
     /*
@@ -55,8 +53,6 @@
 
     int maxWindowRectangles(const GrCaps& caps) const;
 
-    GrRenderTargetFlags testingOnly_getFlags() const;
-
     // TODO: move this to a priv class!
     bool refsWrappedObjects() const;
 
@@ -65,7 +61,7 @@
 
     // Deferred version
     GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit,
-                        SkBudgeted, uint32_t flags);
+                        SkBudgeted, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -79,7 +75,7 @@
     // know the final size until flush time.
     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
                         const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit, SkBudgeted,
-                        uint32_t flags, GrRenderTargetFlags renderTargetFlags);
+                        GrInternalSurfaceFlags);
 
     // Wrapped version
     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
@@ -97,13 +93,6 @@
     // For deferred proxies that pointer is filled in when we need to instantiate the
     // deferred resource.
 
-    // These don't usually get computed until the render target is instantiated, but the render
-    // target proxy may need to answer queries about it before then. And since in the deferred case
-    // we know the newly created render target will be internal, we are able to precompute what the
-    // flags will ultimately end up being. In the wrapped case we just copy the wrapped
-    // rendertarget's info here.
-    GrRenderTargetFlags fRenderTargetFlags;
-
     typedef GrSurfaceProxy INHERITED;
 };
 
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index deac900..0b15079 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -375,24 +375,26 @@
     inline GrSurfaceProxyPriv priv();
     inline const GrSurfaceProxyPriv priv() const;
 
+    GrInternalSurfaceFlags testingOnly_getFlags() const;
+
 protected:
     // Deferred version
     GrSurfaceProxy(const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
-                   SkBudgeted budgeted, uint32_t flags)
+                   SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
             : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse, desc, origin, fit,
-                             budgeted, flags) {
+                             budgeted, surfaceFlags) {
         // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
     }
 
     using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*)>;
 
     // Lazy-callback version
-    GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                   const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
-                   SkBudgeted budgeted, uint32_t flags);
+    GrSurfaceProxy(LazyInstantiateCallback&&, LazyInstantiationType,
+                   const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit,
+                   SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
-    GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit);
+    GrSurfaceProxy(sk_sp<GrSurface>, GrSurfaceOrigin, SkBackingFit);
 
     virtual ~GrSurfaceProxy();
 
@@ -413,26 +415,47 @@
     void assign(sk_sp<GrSurface> surface);
 
     sk_sp<GrSurface> createSurfaceImpl(GrResourceProvider*, int sampleCnt, bool needsStencil,
-                                       GrSurfaceFlags flags, GrMipMapped mipMapped) const;
+                                       GrSurfaceDescFlags descFlags, GrMipMapped) const;
 
     bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil,
-                         GrSurfaceFlags flags, GrMipMapped mipMapped, const GrUniqueKey*);
+                         GrSurfaceDescFlags descFlags, GrMipMapped, const GrUniqueKey*);
+
+    void setHasMixedSamples() {
+        SkASSERT(this->asRenderTargetProxy());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
+    }
+    bool hasMixedSamples() const { return fSurfaceFlags & GrInternalSurfaceFlags::kMixedSampled; }
+
+    void setSupportsWindowRects() {
+        SkASSERT(this->asRenderTargetProxy());
+        fSurfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
+    }
+    bool supportsWindowRects() const {
+        return fSurfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport;
+    }
 
 private:
     // For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in
     // from the wrapped resource.
-    GrPixelConfig        fConfig;
-    int                  fWidth;
-    int                  fHeight;
-    GrSurfaceOrigin      fOrigin;
-    SkBackingFit         fFit;      // always kApprox for lazy-callback resources
-                                    // always kExact for wrapped resources
-    mutable SkBudgeted   fBudgeted; // always kYes for lazy-callback resources
-                                    // set from the backing resource for wrapped resources
-                                    // mutable bc of SkSurface/SkImage wishy-washiness
-    const uint32_t       fFlags;
+    GrPixelConfig          fConfig;
+    int                    fWidth;
+    int                    fHeight;
+    GrSurfaceOrigin        fOrigin;
+    SkBackingFit           fFit;      // always kApprox for lazy-callback resources
+                                      // always kExact for wrapped resources
+    mutable SkBudgeted     fBudgeted; // always kYes for lazy-callback resources
+                                      // set from the backing resource for wrapped resources
+                                      // mutable bc of SkSurface/SkImage wishy-washiness
 
-    const UniqueID       fUniqueID; // set from the backing resource for wrapped resources
+    // In many cases these flags aren't actually known until the proxy has been instantiated.
+    // However, Ganesh frequently needs to change its behavior based on these settings. For
+    // internally create proxies we will know these properties ahead of time. For wrapped
+    // proxies we will copy the properties off of the GrSurface. For lazy proxies we force the
+    // call sites to provide the required information ahead of time. At instantiation time
+    // we verify that the assumed properties match the actual properties.
+    GrInternalSurfaceFlags fSurfaceFlags;
+
+    const UniqueID         fUniqueID; // set from the backing resource for wrapped resources
 
     LazyInstantiateCallback fLazyInstantiateCallback;
     // If this is set to kSingleuse, then after one call to fLazyInstantiateCallback we will cleanup
@@ -440,7 +463,7 @@
     // by the standard function to be released. This is specifically useful in non-dll cases where
     // we make lazy proxies and instantiate them immediately.
     // Note: This is ignored if fLazyInstantiateCallback is null.
-    LazyInstantiationType fLazyInstantiationType;
+    LazyInstantiationType  fLazyInstantiationType;
     SkDEBUGCODE(virtual void validateLazySurface(const GrSurface*) = 0;)
 
     static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
@@ -448,13 +471,13 @@
 
     virtual size_t onUninstantiatedGpuMemorySize() const = 0;
 
-    bool                 fNeedsClear;
+    bool                   fNeedsClear;
 
     // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
     // will be called but, when the proxy is deferred, it will compute the answer itself.
     // If the proxy computes its own answer that answer is checked (in debug mode) in
     // the instantiation method.
-    mutable size_t      fGpuMemorySize;
+    mutable size_t         fGpuMemorySize;
 
     // The last opList that wrote to or is currently going to write to this surface
     // The opList can be closed (e.g., no surface context is currently bound
@@ -463,7 +486,7 @@
     // the opList used to create the current contents of this surface
     // and the opList of a destination surface to which this one is being drawn or copied.
     // This pointer is unreffed. OpLists own a ref on their surface proxies.
-    GrOpList* fLastOpList;
+    GrOpList*              fLastOpList;
 
     typedef GrIORefProxy INHERITED;
 };
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index e8bb87c..2ded566 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -73,11 +73,11 @@
 
     // Deferred version - when constructed with data the origin is always kTopLeft.
     GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped, SkBackingFit, SkBudgeted,
-                   const void* srcData, size_t srcRowBytes, uint32_t flags);
+                   const void* srcData, size_t srcRowBytes, GrInternalSurfaceFlags);
 
     // Deferred version - no data.
     GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin, GrMipMapped, SkBackingFit,
-                   SkBudgeted, uint32_t flags);
+                   SkBudgeted, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -90,8 +90,8 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrSurfaceDesc& desc,
-                   GrSurfaceOrigin, GrMipMapped, SkBackingFit fit, SkBudgeted budgeted,
-                   uint32_t flags);
+                   GrSurfaceOrigin, GrMipMapped, SkBackingFit, SkBudgeted,
+                   GrInternalSurfaceFlags);
 
     // Wrapped version
     GrTextureProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
@@ -101,7 +101,7 @@
     sk_sp<GrSurface> createSurface(GrResourceProvider*) const override;
 
 private:
-    GrMipMapped fMipMapped;
+    GrMipMapped      fMipMapped;
 
     GrUniqueKey      fUniqueKey;
     GrProxyProvider* fProxyProvider; // only set when fUniqueKey is valid
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 5c6d102..d64c9a3 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -670,26 +670,35 @@
     kLast_GrAccessPattern = kStream_GrAccessPattern
 };
 
-// Flags shared between GrRenderTarget and GrRenderTargetProxy
-enum class GrRenderTargetFlags {
+// Flags shared between the GrSurface & GrSurfaceProxy class hierarchies
+enum class GrInternalSurfaceFlags {
     kNone               = 0,
 
+    // Surface-level
+    kNoPendingIO        = 1 << 0,
+
+    // Texture-only
+
+    /* coming soon */
+
+    // RT-only
+
     // For internal resources:
     //    this is enabled whenever MSAA is enabled and GrCaps reports mixed samples are supported
     // For wrapped resources:
     //    this is disabled for FBO0
     //    but, otherwise, is enabled whenever MSAA is enabled and GrCaps reports mixed samples
     //        are supported
-    kMixedSampled       = 1 << 0,
+    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 << 1
+    kWindowRectsSupport = 1 << 4
 };
-GR_MAKE_BITFIELD_CLASS_OPS(GrRenderTargetFlags)
+GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags)
 
 #ifdef SK_DEBUG
 // Takes a pointer to a GrCaps, and will suppress prints if required
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index a0f6c01..1114a26 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -106,7 +106,7 @@
             },
             desc,
             fCharacterization.origin(),
-            GrRenderTargetFlags::kNone,
+            GrInternalSurfaceFlags::kNone,
             GrProxyProvider::Textureable(fCharacterization.isTextureable()),
             GrMipMapped::kNo,
             SkBackingFit::kExact,
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 28bf34b..fe8d100 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -466,7 +466,7 @@
         // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
         // to ops), so it can't have any pending IO.
         proxy = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
-                                           SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
+                                           SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
 
         auto uploader = skstd::make_unique<GrTDeferredProxyUploader<ClipMaskData>>(reducedClip);
         GrTDeferredProxyUploader<ClipMaskData>* uploaderRaw = uploader.get();
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 629d91b..429ad6a 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -522,7 +522,7 @@
 
     for (uint32_t i = 0; i < this->maxPages(); ++i) {
         fProxies[i] = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin,
-                SkBackingFit::kExact, SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
+                SkBackingFit::kExact, SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
         if (!fProxies[i]) {
             return false;
         }
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index c33bc51..d892dee 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -28,7 +28,7 @@
     // TODO: fold the kNoPendingIO_Flag into GrSurfaceFlags?
     sk_sp<GrSurfaceProxy> proxy =
             proxyProvider->createProxy(tmpDesc, origin, SkBackingFit::kExact, SkBudgeted::kYes,
-                                       GrResourceProvider::kNoPendingIO_Flag);
+                                       GrInternalSurfaceFlags::kNoPendingIO);
     if (!proxy->asRenderTargetProxy()) {
         return nullptr;
     }
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 7c82544..33a2b0f 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -160,13 +160,13 @@
                                                                GrSurfaceOrigin origin,
                                                                SkBackingFit fit,
                                                                SkBudgeted budgeted,
-                                                               uint32_t flags) {
+                                                               GrSurfaceDescFlags descFlags) {
     sk_sp<GrTexture> tex;
 
     if (SkBackingFit::kApprox == fit) {
-        tex = fResourceProvider->createApproxTexture(desc, flags);
+        tex = fResourceProvider->createApproxTexture(desc, descFlags);
     } else {
-        tex = fResourceProvider->createTexture(desc, budgeted, flags);
+        tex = fResourceProvider->createTexture(desc, budgeted, descFlags);
     }
     if (!tex) {
         return nullptr;
@@ -200,7 +200,7 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(sk_sp<SkImage> srcImage,
-                                                          GrSurfaceFlags flags,
+                                                          GrSurfaceDescFlags descFlags,
                                                           int sampleCnt,
                                                           SkBudgeted budgeted,
                                                           SkBackingFit fit) {
@@ -218,27 +218,27 @@
         return nullptr;
     }
 
-    if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) {
+    if (SkToBool(descFlags & kRenderTarget_GrSurfaceFlag)) {
         sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config);
         if (!sampleCnt) {
             return nullptr;
         }
     }
 
-    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
-    if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) {
+    GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
+    if (SkToBool(descFlags & kRenderTarget_GrSurfaceFlag)) {
         if (fCaps->usesMixedSamples() && sampleCnt > 1) {
-            renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
+            surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
         }
         if (fCaps->maxWindowRectangles() > 0) {
-            renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+            surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
         }
     }
 
     GrSurfaceDesc desc;
     desc.fWidth = srcImage->width();
     desc.fHeight = srcImage->height();
-    desc.fFlags = flags;
+    desc.fFlags = descFlags;
     desc.fSampleCnt = sampleCnt;
     desc.fConfig = config;
 
@@ -255,7 +255,7 @@
 
                 return resourceProvider->createTexture(desc, budgeted, fit, mipLevel);
             },
-            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, renderTargetFlags, fit, budgeted);
+            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, surfaceFlags, fit, budgeted);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
@@ -276,7 +276,8 @@
         return nullptr;
     }
 
-    return this->createProxy(desc, origin, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0);
+    return this->createProxy(desc, origin, GrMipMapped::kYes, SkBackingFit::kExact, budgeted,
+                             GrInternalSurfaceFlags::kNone);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap,
@@ -368,9 +369,7 @@
                                                    GrMipMapped mipMapped,
                                                    SkBackingFit fit,
                                                    SkBudgeted budgeted,
-                                                   uint32_t flags) {
-    SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags);
-
+                                                   GrInternalSurfaceFlags surfaceFlags) {
     if (GrMipMapped::kYes == mipMapped) {
         // SkMipMap doesn't include the base level in the level count so we have to add 1
         int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
@@ -392,11 +391,11 @@
         // We know anything we instantiate later from this deferred path will be
         // both texturable and renderable
         return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(
-                *this->caps(), copyDesc, origin, mipMapped, fit, budgeted, flags));
+                *this->caps(), copyDesc, origin, mipMapped, fit, budgeted, surfaceFlags));
     }
 
     return sk_sp<GrTextureProxy>(
-            new GrTextureProxy(copyDesc, origin, mipMapped, fit, budgeted, flags));
+            new GrTextureProxy(copyDesc, origin, mipMapped, fit, budgeted, surfaceFlags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::wrapBackendTexture(const GrBackendTexture& backendTex,
@@ -515,19 +514,19 @@
                                                        GrMipMapped mipMapped, SkBackingFit fit,
                                                        SkBudgeted budgeted) {
     return this->createLazyProxy(std::move(callback), desc, origin, mipMapped,
-                                 GrRenderTargetFlags::kNone, fit, budgeted);
+                                 GrInternalSurfaceFlags::kNone, fit, budgeted);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrRenderTargetFlags renderTargetFlags,
+                                                       GrInternalSurfaceFlags surfaceFlags,
                                                        SkBackingFit fit, SkBudgeted budgeted) {
     // For non-ddl draws always make lazy proxy's single use.
     LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
                                                        : LazyInstantiationType::kMultipleUse;
-    return this->createLazyProxy(std::move(callback), desc, origin, mipMapped, renderTargetFlags,
+    return this->createLazyProxy(std::move(callback), desc, origin, mipMapped, surfaceFlags,
                                  fit, budgeted, lazyType);
 }
 
@@ -535,19 +534,19 @@
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrRenderTargetFlags renderTargetFlags,
+                                                       GrInternalSurfaceFlags surfaceFlags,
                                                        SkBackingFit fit, SkBudgeted budgeted,
                                                        LazyInstantiationType lazyType) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
-    uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
+    surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO;
 
 #ifdef SK_DEBUG
     if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) {
-        if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) {
+        if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) {
             SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
         }
-        if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) {
+        if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport)) {
             SkASSERT(fCaps->maxWindowRectangles() > 0);
         }
     }
@@ -556,26 +555,25 @@
     return sk_sp<GrTextureProxy>(
             SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)
                     ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, origin,
-                                                     mipMapped, fit, budgeted, flags,
-                                                     renderTargetFlags)
+                                                     mipMapped, fit, budgeted, surfaceFlags)
                     : new GrTextureProxy(std::move(callback), lazyType, desc, origin, mipMapped,
-                                         fit, budgeted, flags));
+                                         fit, budgeted, surfaceFlags));
 }
 
 sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
         LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-        GrRenderTargetFlags renderTargetFlags, Textureable textureable, GrMipMapped mipMapped,
+        GrInternalSurfaceFlags surfaceFlags, Textureable textureable, GrMipMapped mipMapped,
         SkBackingFit fit, SkBudgeted budgeted) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
-    uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
+    surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO;
 
 #ifdef SK_DEBUG
-    if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) {
+    if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) {
         SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
     }
-    if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) {
+    if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport)) {
         SkASSERT(fCaps->maxWindowRectangles() > 0);
     }
 #endif
@@ -588,11 +586,11 @@
     if (Textureable::kYes == textureable) {
         return sk_sp<GrRenderTargetProxy>(
                 new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, origin,
-                                               mipMapped, fit, budgeted, flags, renderTargetFlags));
+                                               mipMapped, fit, budgeted, surfaceFlags));
     }
 
     return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(
-            std::move(callback), lazyType, desc, origin, fit, budgeted, flags, renderTargetFlags));
+            std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback,
@@ -600,11 +598,11 @@
                                                             GrSurfaceOrigin origin,
                                                             GrPixelConfig config) {
     GrSurfaceDesc desc;
-    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
+    GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
     if (Renderable::kYes == renderable) {
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
         if (fCaps->maxWindowRectangles() > 0) {
-            renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+            surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
         }
     }
     desc.fWidth = -1;
@@ -613,7 +611,7 @@
     desc.fSampleCnt = 1;
 
     return this->createLazyProxy(std::move(callback), desc, origin, GrMipMapped::kNo,
-                                 renderTargetFlags, SkBackingFit::kApprox, SkBudgeted::kYes);
+                                 surfaceFlags, SkBackingFit::kApprox, SkBudgeted::kYes);
 }
 
 bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index e1ddf5c..2f452b4 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -66,7 +66,8 @@
      * testing-only.
      */
     sk_sp<GrTextureProxy> createInstantiatedProxy(const GrSurfaceDesc&, GrSurfaceOrigin,
-                                                  SkBackingFit, SkBudgeted, uint32_t flags = 0);
+                                                  SkBackingFit, SkBudgeted,
+                                                  GrSurfaceDescFlags = kNone_GrSurfaceFlags);
 
     /*
      * Create an un-mipmapped texture proxy with data.
@@ -82,7 +83,7 @@
      * actually upload the data to the gpu.
      */
     sk_sp<GrTextureProxy> createTextureProxy(sk_sp<SkImage> srcImage,
-                                             GrSurfaceFlags flags,
+                                             GrSurfaceDescFlags descFlags,
                                              int sampleCnt,
                                              SkBudgeted budgeted,
                                              SkBackingFit fit);
@@ -106,11 +107,13 @@
      * Create a GrSurfaceProxy without any data.
      */
     sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
-                                      SkBackingFit, SkBudgeted, uint32_t flags);
+                                      SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
-    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-                                      SkBackingFit fit, SkBudgeted budgeted, uint32_t flags = 0) {
-        return this->createProxy(desc, origin, GrMipMapped::kNo, fit, budgeted, flags);
+    sk_sp<GrTextureProxy> createProxy(
+                            const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
+                            SkBackingFit fit, SkBudgeted budgeted,
+                            GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) {
+        return this->createProxy(desc, origin, GrMipMapped::kNo, fit, budgeted, surfaceFlags);
     }
 
     // These match the definitions in SkImage & GrTexture.h, for whence they came
@@ -167,11 +170,11 @@
      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
      */
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrSurfaceOrigin, GrMipMapped, GrRenderTargetFlags,
+                                          GrSurfaceOrigin, GrMipMapped, GrInternalSurfaceFlags,
                                           SkBackingFit, SkBudgeted, LazyInstantiationType);
 
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrSurfaceOrigin, GrMipMapped, GrRenderTargetFlags,
+                                          GrSurfaceOrigin, GrMipMapped, GrInternalSurfaceFlags,
                                           SkBackingFit, SkBudgeted);
 
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
@@ -187,7 +190,7 @@
     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
                                                            const GrSurfaceDesc&,
                                                            GrSurfaceOrigin origin,
-                                                           GrRenderTargetFlags, Textureable,
+                                                           GrInternalSurfaceFlags, Textureable,
                                                            GrMipMapped, SkBackingFit, SkBudgeted);
 
     // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index 1b8d05e..c397235 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -19,16 +19,13 @@
 #include "SkRectPriv.h"
 
 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
-                               GrRenderTargetFlags flags,
                                GrStencilAttachment* stencil)
         : INHERITED(gpu, desc)
         , fSampleCnt(desc.fSampleCnt)
-        , fStencilAttachment(stencil)
-        , fFlags(flags) {
+        , fStencilAttachment(stencil) {
     SkASSERT(desc.fFlags & kRenderTarget_GrSurfaceFlag);
-    SkASSERT(!(fFlags & GrRenderTargetFlags::kMixedSampled) || fSampleCnt > 1);
-    SkASSERT(!(fFlags & GrRenderTargetFlags::kWindowRectsSupport) ||
-             gpu->caps()->maxWindowRectangles() > 0);
+    SkASSERT(!this->hasMixedSamples() || fSampleCnt > 1);
+    SkASSERT(!this->supportsWindowRects() || gpu->caps()->maxWindowRectangles() > 0);
     fResolveRect = SkRectPriv::MakeILargestInverted();
 }
 
diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h
index 9822e7a..71ef809 100644
--- a/src/gpu/GrRenderTargetPriv.h
+++ b/src/gpu/GrRenderTargetPriv.h
@@ -32,8 +32,6 @@
 
     int numStencilBits() const;
 
-    GrRenderTargetFlags flags() const { return fRenderTarget->fFlags; }
-
 private:
     explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
     GrRenderTargetPriv(const GrRenderTargetPriv&) {} // unimpl
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index e97900c..2526de8 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -20,18 +20,17 @@
 // cases to make the sampleConfig/numSamples stuff more rational.
 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
                                          GrSurfaceOrigin origin, SkBackingFit fit,
-                                         SkBudgeted budgeted, uint32_t flags)
-        : INHERITED(desc, origin, fit, budgeted, flags)
+                                         SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(desc, origin, fit, budgeted, surfaceFlags)
         , fSampleCnt(desc.fSampleCnt)
-        , fNeedsStencil(false)
-        , fRenderTargetFlags(GrRenderTargetFlags::kNone) {
+        , fNeedsStencil(false) {
     // Since we know the newly created render target will be internal, we are able to precompute
     // what the flags will ultimately end up being.
     if (caps.usesMixedSamples() && fSampleCnt > 1) {
-        fRenderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
+        this->setHasMixedSamples();
     }
     if (caps.maxWindowRectangles() > 0) {
-        fRenderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+        this->setSupportsWindowRects();
     }
 }
 
@@ -39,12 +38,10 @@
 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
                                          LazyInstantiationType lazyType, const GrSurfaceDesc& desc,
                                          GrSurfaceOrigin origin, SkBackingFit fit,
-                                         SkBudgeted budgeted, uint32_t flags,
-                                         GrRenderTargetFlags renderTargetFlags)
-        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
+                                         SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
         , fSampleCnt(desc.fSampleCnt)
-        , fNeedsStencil(false)
-        , fRenderTargetFlags(renderTargetFlags) {
+        , fNeedsStencil(false) {
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
 }
 
@@ -52,47 +49,38 @@
 GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
         , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples())
-        , fNeedsStencil(false)
-        , fRenderTargetFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) {
+        , fNeedsStencil(false) {
 }
 
 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
-    return (fRenderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)
-                   ? caps.maxWindowRectangles()
-                   : 0;
+    return this->supportsWindowRects() ? caps.maxWindowRectangles() : 0;
 }
 
 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
     if (LazyState::kNot != this->lazyInstantiationState()) {
         return false;
     }
-    static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
+    static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
 
-    if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kFlags,
+    if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kDescFlags,
                                GrMipMapped::kNo, nullptr)) {
         return false;
     }
     SkASSERT(fTarget->asRenderTarget());
     SkASSERT(!fTarget->asTexture());
-    // Check that our a priori computation matched the ultimate reality
-    SkASSERT(fRenderTargetFlags == fTarget->asRenderTarget()->renderTargetPriv().flags());
-
     return true;
 }
 
 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
-    static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
+    static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
 
     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, fNeedsStencil,
-                                                       kFlags, GrMipMapped::kNo);
+                                                       kDescFlags, GrMipMapped::kNo);
     if (!surface) {
         return nullptr;
     }
     SkASSERT(surface->asRenderTarget());
     SkASSERT(!surface->asTexture());
-    // Check that our a priori computation matched the ultimate reality
-    SkASSERT(fRenderTargetFlags == surface->asRenderTarget()->renderTargetPriv().flags());
-
     return surface;
 }
 
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 68bcf45..1e7cff2 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -172,6 +172,8 @@
 
     /** These flags govern which scratch resources we are allowed to return */
     enum Flags {
+        kNone_Flag            = 0x0,
+
         /** If the caller intends to do direct reads/writes to/from the CPU then this flag must be
          *  set when accessing resources during a GrOpList flush. This includes the execution of
          *  GrOp objects. The reason is that these memory operations are done immediately and
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 2ac4b5e..228625f 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -179,7 +179,7 @@
     // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt to
     // ops), so it can't have any pending IO.
     return proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
-                                      GrResourceProvider::kNoPendingIO_Flag);
+                                      GrInternalSurfaceFlags::kNoPendingIO);
 }
 
 namespace {
diff --git a/src/gpu/GrSurfacePriv.h b/src/gpu/GrSurfacePriv.h
index d655dfe..4d61dca 100644
--- a/src/gpu/GrSurfacePriv.h
+++ b/src/gpu/GrSurfacePriv.h
@@ -38,6 +38,8 @@
     bool hasPendingIO() const { return fSurface->hasPendingIO(); }
     bool hasUniqueRef() const { return fSurface->internalHasUniqueRef(); }
 
+    GrInternalSurfaceFlags flags() const { return fSurface->fSurfaceFlags; }
+
 private:
     explicit GrSurfacePriv(GrSurface* surface) : fSurface(surface) {}
     GrSurfacePriv(const GrSurfacePriv&); // unimpl
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 76414b5..a49251f 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -15,6 +15,7 @@
 #include "GrOpList.h"
 #include "GrProxyProvider.h"
 #include "GrSurfaceContext.h"
+#include "GrSurfacePriv.h"
 #include "GrTexturePriv.h"
 #include "GrTextureRenderTargetProxy.h"
 
@@ -49,14 +50,14 @@
 // Lazy-callback version
 GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
                                const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
-                               SkBudgeted budgeted, uint32_t flags)
+                               SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
         : fConfig(desc.fConfig)
         , fWidth(desc.fWidth)
         , fHeight(desc.fHeight)
         , fOrigin(origin)
         , fFit(fit)
         , fBudgeted(budgeted)
-        , fFlags(flags)
+        , fSurfaceFlags(surfaceFlags)
         , fLazyInstantiateCallback(std::move(callback))
         , fLazyInstantiationType(lazyType)
         , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag))
@@ -79,7 +80,7 @@
         , fOrigin(origin)
         , fFit(fit)
         , fBudgeted(fTarget->resourcePriv().isBudgeted())
-        , fFlags(0)
+        , fSurfaceFlags(fTarget->surfacePriv().flags())
         , fUniqueID(fTarget->uniqueID())  // Note: converting from unique resource ID to a proxy ID!
         , fNeedsClear(false)
         , fGpuMemorySize(kInvalidGpuMemorySize)
@@ -117,11 +118,11 @@
 sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(
                                                 GrResourceProvider* resourceProvider,
                                                 int sampleCnt, bool needsStencil,
-                                                GrSurfaceFlags flags, GrMipMapped mipMapped) const {
+                                                GrSurfaceDescFlags descFlags, GrMipMapped mipMapped) const {
     SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState());
     SkASSERT(!fTarget);
     GrSurfaceDesc desc;
-    desc.fFlags = flags;
+    desc.fFlags = descFlags;
     if (fNeedsClear) {
         desc.fFlags |= kPerformInitialClear_GrSurfaceFlag;
     }
@@ -130,6 +131,11 @@
     desc.fConfig = fConfig;
     desc.fSampleCnt = sampleCnt;
 
+    GrResourceProvider::Flags resourceProviderFlags = GrResourceProvider::kNone_Flag;
+    if (fSurfaceFlags & GrInternalSurfaceFlags::kNoPendingIO) {
+        resourceProviderFlags = GrResourceProvider::kNoPendingIO_Flag;
+    }
+
     sk_sp<GrSurface> surface;
     if (GrMipMapped::kYes == mipMapped) {
         SkASSERT(SkBackingFit::kExact == fFit);
@@ -155,9 +161,9 @@
         }
     } else {
         if (SkBackingFit::kApprox == fFit) {
-            surface = resourceProvider->createApproxTexture(desc, fFlags);
+            surface = resourceProvider->createApproxTexture(desc, resourceProviderFlags);
         } else {
-            surface = resourceProvider->createTexture(desc, fBudgeted, fFlags);
+            surface = resourceProvider->createTexture(desc, fBudgeted, resourceProviderFlags);
         }
     }
     if (!surface) {
@@ -192,8 +198,8 @@
 }
 
 bool GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
-                                     bool needsStencil, GrSurfaceFlags flags, GrMipMapped mipMapped,
-                                     const GrUniqueKey* uniqueKey) {
+                                     bool needsStencil, GrSurfaceDescFlags descFlags,
+                                     GrMipMapped mipMapped, const GrUniqueKey* uniqueKey) {
     SkASSERT(LazyState::kNot == this->lazyInstantiationState());
     if (fTarget) {
         if (uniqueKey) {
@@ -203,7 +209,7 @@
     }
 
     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, sampleCnt, needsStencil,
-                                                       flags, mipMapped);
+                                                       descFlags, mipMapped);
     if (!surface) {
         return false;
     }
@@ -215,6 +221,11 @@
     }
 
     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/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h
index 00b3868..8d7d8d0 100644
--- a/src/gpu/GrSurfaceProxyPriv.h
+++ b/src/gpu/GrSurfaceProxyPriv.h
@@ -59,7 +59,7 @@
     void assign(sk_sp<GrSurface> surface) { fProxy->assign(std::move(surface)); }
 
     bool requiresNoPendingIO() const {
-        return fProxy->fFlags & GrResourceProvider::kNoPendingIO_Flag;
+        return fProxy->fSurfaceFlags & GrInternalSurfaceFlags::kNoPendingIO;
     }
 
     // Don't abuse this call!!!!!!!
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index a19a803..03acd7c 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -17,8 +17,8 @@
 // Deferred version - with data
 GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped,
                                SkBackingFit fit, SkBudgeted budgeted, const void* srcData,
-                               size_t /*rowBytes*/, uint32_t flags)
-        : INHERITED(srcDesc, kTopLeft_GrSurfaceOrigin, fit, budgeted, flags)
+                               size_t /*rowBytes*/, GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(srcDesc, kTopLeft_GrSurfaceOrigin, fit, budgeted, surfaceFlags)
         , fMipMapped(mipMapped)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
@@ -28,8 +28,8 @@
 // Deferred version - no data
 GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin origin,
                                GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
-                               uint32_t flags)
-        : INHERITED(srcDesc, origin, fit, budgeted, flags)
+                               GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(srcDesc, origin, fit, budgeted, surfaceFlags)
         , fMipMapped(mipMapped)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {}
@@ -38,11 +38,12 @@
 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
                                const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
                                GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
-                               uint32_t flags)
-        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
+                               GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
         , fMipMapped(mipMapped)
         , fProxyProvider(nullptr)
-        , fDeferredUploader(nullptr) {}
+        , fDeferredUploader(nullptr) {
+}
 
 // Wrapped version
 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index e753b8d..61bec05 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -23,11 +23,11 @@
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
-                                                       uint32_t flags)
-        : GrSurfaceProxy(desc, origin, fit, budgeted, flags)
+                                                       GrInternalSurfaceFlags surfaceFlags)
+        : GrSurfaceProxy(desc, origin, fit, budgeted, surfaceFlags)
         // for now textures w/ data are always wrapped
-        , GrTextureProxy(desc, origin, mipMapped, fit, budgeted, flags)
-        , GrRenderTargetProxy(caps, desc, origin, fit, budgeted, flags) {}
+        , GrTextureProxy(desc, origin, mipMapped, fit, budgeted, surfaceFlags)
+        , GrRenderTargetProxy(caps, desc, origin, fit, budgeted, surfaceFlags) {}
 
 // Lazy-callback version
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(LazyInstantiateCallback&& callback,
@@ -37,15 +37,14 @@
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
-                                                       uint32_t flags,
-                                                       GrRenderTargetFlags renderTargetFlags)
-        : GrSurfaceProxy(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
+                                                       GrInternalSurfaceFlags surfaceFlags)
+        : GrSurfaceProxy(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
         , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, origin, mipMapped, fit,
-                         budgeted, flags)
+                         budgeted, surfaceFlags)
         , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, origin, fit, budgeted,
-                              flags, renderTargetFlags) {}
+                              surfaceFlags) {}
 
 // Wrapped version
 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
@@ -76,12 +75,12 @@
     if (LazyState::kNot != this->lazyInstantiationState()) {
         return false;
     }
-    static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
+    static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
 
     const GrUniqueKey& key = this->getUniqueKey();
 
     if (!this->instantiateImpl(resourceProvider, this->numStencilSamples(), this->needsStencil(),
-                               kFlags, this->mipMapped(), key.isValid() ? &key : nullptr)) {
+                               kDescFlags, this->mipMapped(), key.isValid() ? &key : nullptr)) {
         return false;
     }
     if (key.isValid()) {
@@ -96,10 +95,10 @@
 
 sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface(
                                                     GrResourceProvider* resourceProvider) const {
-    static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
+    static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
 
     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, this->numStencilSamples(),
-                                                       this->needsStencil(), kFlags,
+                                                       this->needsStencil(), kDescFlags,
                                                        this->mipMapped());
     if (!surface) {
         return nullptr;
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index 9dd0400..193d8a7 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -29,12 +29,12 @@
 
     // Deferred version
     GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
-                               SkBackingFit, SkBudgeted, uint32_t flags);
+                               SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
                                const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped,
-                               SkBackingFit, SkBudgeted, uint32_t flags, GrRenderTargetFlags);
+                               SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
     GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 4159d39..cd102fe 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -219,7 +219,7 @@
         texDesc.fConfig = fDesc.fConfig;
 
         proxy = proxyProvider->createProxy(texDesc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
-                                           SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
+                                           SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
         if (!proxy) {
             return;
         }
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index de7399b..e1a4eb0 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -24,7 +24,8 @@
                                    const IDDesc& idDesc,
                                    GrGLStencilAttachment* stencil)
     : GrSurface(gpu, desc)
-    , INHERITED(gpu, desc, ComputeFlags(gpu->glCaps(), idDesc), stencil) {
+    , INHERITED(gpu, desc, stencil) {
+    this->setFlags(gpu->glCaps(), idDesc);
     this->init(desc, idDesc);
     this->registerWithCacheWrapped();
 }
@@ -32,21 +33,19 @@
 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc,
                                    const IDDesc& idDesc)
     : GrSurface(gpu, desc)
-    , INHERITED(gpu, desc, ComputeFlags(gpu->glCaps(), idDesc)) {
+    , INHERITED(gpu, desc) {
+    this->setFlags(gpu->glCaps(), idDesc);
     this->init(desc, idDesc);
 }
 
-inline GrRenderTargetFlags GrGLRenderTarget::ComputeFlags(const GrGLCaps& glCaps,
-                                                          const IDDesc& idDesc) {
-    GrRenderTargetFlags flags = GrRenderTargetFlags::kNone;
+inline void GrGLRenderTarget::setFlags(const GrGLCaps& glCaps, const IDDesc& idDesc) {
     if (idDesc.fIsMixedSampled) {
         SkASSERT(glCaps.usesMixedSamples() && idDesc.fRTFBOID); // FBO 0 can't be mixed sampled.
-        flags |= GrRenderTargetFlags::kMixedSampled;
+        this->setHasMixedSamples();
     }
     if (glCaps.maxWindowRectangles() > 0 && idDesc.fRTFBOID) {
-        flags |= GrRenderTargetFlags::kWindowRectsSupport;
+        this->setSupportsWindowRects();
     }
-    return flags;
 }
 
 void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index a448848..3da4812 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -86,7 +86,7 @@
     // Constructor for instances wrapping backend objects.
     GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*);
 
-    static GrRenderTargetFlags ComputeFlags(const GrGLCaps&, const IDDesc&);
+    void setFlags(const GrGLCaps&, const IDDesc&);
 
     GrGLGpu* getGLGpu() const;
     bool completeStencilAttachment() override;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 5a2b251..83c9409 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -708,7 +708,7 @@
                 }
 
                 return promiseHelper.getTexture(resourceProvider, config);
-            }, desc, origin, mipMapped, GrRenderTargetFlags::kNone, SkBackingFit::kExact,
+            }, desc, origin, mipMapped, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
                SkBudgeted::kNo, GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
 
     if (!proxy) {
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index e21031a..2b2b716 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -230,7 +230,7 @@
                         *testCountPtr = 1;
                         return sk_sp<GrTexture>();
                     },
-                    desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrRenderTargetFlags::kNone,
+                    desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
                     SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
 
             REPORTER_ASSERT(reporter, 0 == testCount);
@@ -422,7 +422,7 @@
                     texture->setRelease(UninstantiateReleaseProc, releasePtr);
                     return texture;
                 },
-                desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrRenderTargetFlags::kNone,
+                desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
                 SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
 
         rtc->priv().testingOnly_addDrawOp(skstd::make_unique<LazyUninstantiateTestOp>(lazyProxy));
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp
index e564397c..30cc449 100644
--- a/tests/ProxyRefTest.cpp
+++ b/tests/ProxyRefTest.cpp
@@ -74,7 +74,7 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
     return proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
-                                      SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
+                                      SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
 }
 
 static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider) {
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 4970e43..fa53a7a 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -17,6 +17,7 @@
 #include "GrRenderTargetPriv.h"
 #include "GrRenderTargetProxy.h"
 #include "GrResourceProvider.h"
+#include "GrSurfacePriv.h"
 #include "GrSurfaceProxyPriv.h"
 #include "GrTexture.h"
 #include "GrTextureProxy.h"
@@ -72,7 +73,7 @@
     REPORTER_ASSERT(reporter, rt->fsaaType() == rtProxy->fsaaType());
     REPORTER_ASSERT(reporter, rt->numColorSamples() == rtProxy->numColorSamples());
     REPORTER_ASSERT(reporter, rt->numStencilSamples() == rtProxy->numStencilSamples());
-    REPORTER_ASSERT(reporter, rt->renderTargetPriv().flags() == rtProxy->testingOnly_getFlags());
+    REPORTER_ASSERT(reporter, rt->surfacePriv().flags() == rtProxy->testingOnly_getFlags());
 }
 
 static void check_texture(skiatest::Reporter* reporter,
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 1844f18..7b0abc1 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -1644,11 +1644,11 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 static sk_sp<GrTexture> make_normal_texture(GrResourceProvider* provider,
-                                            GrSurfaceFlags flags,
+                                            GrSurfaceDescFlags descFlags,
                                             int width, int height,
                                             int sampleCnt) {
     GrSurfaceDesc desc;
-    desc.fFlags = flags;
+    desc.fFlags = descFlags;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -1658,18 +1658,18 @@
 }
 
 static sk_sp<GrTextureProxy> make_mipmap_proxy(GrProxyProvider* proxyProvider,
-                                               GrSurfaceFlags flags,
+                                               GrSurfaceDescFlags descFlags,
                                                int width, int height,
                                                int sampleCnt) {
     GrSurfaceDesc desc;
-    desc.fFlags = flags;
+    desc.fFlags = descFlags;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
     desc.fSampleCnt = sampleCnt;
 
-    auto origin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
-                                                        : kTopLeft_GrSurfaceOrigin;
+    auto origin = (descFlags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
+                                                            : kTopLeft_GrSurfaceOrigin;
 
     return proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kYes);
 }
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index 5745e4e..8727bef 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -27,9 +27,9 @@
     return fUniquelyKeyedProxies.count();
 }
 
-static GrSurfaceDesc make_desc(GrSurfaceFlags flags) {
+static GrSurfaceDesc make_desc(GrSurfaceDescFlags descFlags) {
     GrSurfaceDesc desc;
-    desc.fFlags = flags;
+    desc.fFlags = descFlags;
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -89,7 +89,7 @@
 
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
-            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes, 0);
+            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
     SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
     REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
     return proxy;
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 132f8a5..cff99a1 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -294,8 +294,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrRenderTargetFlags GrRenderTargetProxy::testingOnly_getFlags() const {
-    return fRenderTargetFlags;
+GrInternalSurfaceFlags GrSurfaceProxy::testingOnly_getFlags() const {
+    return fSurfaceFlags;
 }
 
 //////////////////////////////////////////////////////////////////////////////