Revert "Revert "Mark wrapped textures imported into SkImages as "read only".""

This reverts commit ff4ccaa9fcfbcf29c476eda973febf4b2d6dc974.

Bug: skia:8509
Change-Id: If4a059d6e6e412ec1d6be2c70663d59c362e91d2
Reviewed-on: https://skia-review.googlesource.com/c/175249
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index 2bbfa4c..f94e274 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -1068,8 +1068,8 @@
 
     GrXferProcessor::DstProxy fakeDstProxy;
     {
-        sk_sp<GrTextureProxy> proxy =
-                proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin);
+        sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
+                backendTex, kTopLeft_GrSurfaceOrigin, kBorrow_GrWrapOwnership, kRead_GrIOType);
         fakeDstProxy.setProxy(std::move(proxy));
     }
 
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index d3cc2f4..693fc54 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -5,8 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkTypes.h"
-
 #include "GrContext.h"
 #include "GrContextPriv.h"
 #include "GrGpu.h"
@@ -14,7 +12,10 @@
 #include "GrRenderTarget.h"
 #include "GrResourceProvider.h"
 #include "GrTexture.h"
+#include "GrTexturePriv.h"
+#include "SkAutoPixmapStorage.h"
 #include "SkMipMap.h"
+#include "SkTypes.h"
 #include "Test.h"
 
 // Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
@@ -236,3 +237,94 @@
         }
     }
 }
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadOnlyTexture, reporter, context_info) {
+    auto fillPixels = [](const SkPixmap* p, const std::function<uint32_t(int x, int y)>& f) {
+        for (int y = 0; y < p->height(); ++y) {
+            for (int x = 0; x < p->width(); ++x) {
+                *p->writable_addr32(x, y) = f(x, y);
+            }
+        }
+    };
+
+    auto comparePixels = [](const SkPixmap& p1, const SkPixmap& p2, skiatest::Reporter* reporter) {
+        SkASSERT(p1.info() == p2.info());
+        for (int y = 0; y < p1.height(); ++y) {
+            for (int x = 0; x < p1.width(); ++x) {
+                REPORTER_ASSERT(reporter, p1.getColor(x, y) == p2.getColor(x, y));
+                if (p1.getColor(x, y) != p2.getColor(x, y)) {
+                    return;
+                }
+            }
+        }
+    };
+
+    static constexpr int kSize = 100;
+    SkAutoPixmapStorage pixels;
+    pixels.alloc(SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
+    fillPixels(&pixels,
+               [](int x, int y) { return (0xFFU << 24) | (x << 16) | (y << 8) | uint8_t(x * y); });
+
+    GrContext* context = context_info.grContext();
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+
+    // We test both kRW in addition to kRead mostly to ensure that the calls are structured such
+    // that they'd succeed if the texture wasn't kRead. We want to be sure we're failing with
+    // kRead for the right reason.
+    for (auto ioType : {kRead_GrIOType, kRW_GrIOType}) {
+        auto backendTex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
+                pixels.addr(), kSize, kSize, kRGBA_8888_SkColorType, true, GrMipMapped::kNo);
+        auto proxy = proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin,
+                                                       kBorrow_GrWrapOwnership, ioType);
+        auto surfContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
+
+        // Read pixels should work with a read-only texture.
+        SkAutoPixmapStorage read;
+        read.alloc(pixels.info());
+        auto readResult = surfContext->readPixels(pixels.info(), read.writable_addr(), 0, 0, 0);
+        REPORTER_ASSERT(reporter, readResult);
+        if (readResult) {
+            comparePixels(pixels, read, reporter);
+        }
+
+        // Write pixels should not work with a read-only texture.
+        SkAutoPixmapStorage write;
+        write.alloc(pixels.info());
+        fillPixels(&write, [&pixels](int x, int y) { return ~*pixels.addr32(); });
+        auto writeResult = surfContext->writePixels(pixels.info(), pixels.addr(), 0, 0, 0);
+        REPORTER_ASSERT(reporter, writeResult == (ioType == kRW_GrIOType));
+        // Try the low level write.
+        context->flush();
+        auto gpuWriteResult = context->contextPriv().getGpu()->writePixels(
+                proxy->peekTexture(), 0, 0, kSize, kSize, GrColorType::kRGBA_8888, write.addr32(),
+                0);
+        REPORTER_ASSERT(reporter, gpuWriteResult == (ioType == kRW_GrIOType));
+
+        // Copies should not work with a read-only texture
+        auto copySrc = proxyProvider->createTextureProxy(
+                SkImage::MakeFromRaster(write, nullptr, nullptr), kNone_GrSurfaceFlags, 1,
+                SkBudgeted::kYes, SkBackingFit::kExact);
+        REPORTER_ASSERT(reporter, copySrc);
+        auto copyResult = surfContext->copy(copySrc.get());
+        REPORTER_ASSERT(reporter, copyResult == (ioType == kRW_GrIOType));
+        // Try the low level copy.
+        context->flush();
+        auto gpuCopyResult = context->contextPriv().getGpu()->copySurface(
+                proxy->peekTexture(), kTopLeft_GrSurfaceOrigin, copySrc->peekTexture(),
+                kTopLeft_GrSurfaceOrigin, SkIRect::MakeWH(kSize, kSize), {0, 0});
+        REPORTER_ASSERT(reporter, gpuCopyResult == (ioType == kRW_GrIOType));
+
+        // Mip regen should not work with a read only texture.
+        if (context->contextPriv().caps()->mipMapSupport()) {
+            backendTex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
+                    nullptr, kSize, kSize, kRGBA_8888_SkColorType, true, GrMipMapped::kYes);
+            proxy = proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin,
+                                                      kBorrow_GrWrapOwnership, ioType);
+            context->flush();
+            proxy->peekTexture()->texturePriv().markMipMapsDirty();  // avoids assert in GrGpu.
+            auto regenResult =
+                    context->contextPriv().getGpu()->regenerateMipMapLevels(proxy->peekTexture());
+            REPORTER_ASSERT(reporter, regenResult == (ioType == kRW_GrIOType));
+        }
+    }
+}
diff --git a/tests/GrTestingBackendTextureUploadTest.cpp b/tests/GrTestingBackendTextureUploadTest.cpp
index 979d05e..9ff0e50 100644
--- a/tests/GrTestingBackendTextureUploadTest.cpp
+++ b/tests/GrTestingBackendTextureUploadTest.cpp
@@ -50,9 +50,8 @@
         wrappedTex = gpu->wrapRenderableBackendTexture(backendTex, 1,
                                                        GrWrapOwnership::kAdopt_GrWrapOwnership);
     } else {
-        wrappedTex = gpu->wrapBackendTexture(backendTex,
-                                             GrWrapOwnership::kAdopt_GrWrapOwnership,
-                                             false);
+        wrappedTex = gpu->wrapBackendTexture(backendTex, GrWrapOwnership::kAdopt_GrWrapOwnership,
+                                             kRead_GrIOType, false);
     }
     REPORTER_ASSERT(reporter, wrappedTex);
 
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index 8b106f0..e3fea66 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -469,7 +469,8 @@
                         return sk_sp<GrTexture>();
                     }
 
-                    sk_sp<GrTexture> texture = rp->wrapBackendTexture(backendTex);
+                    sk_sp<GrTexture> texture = rp->wrapBackendTexture(
+                            backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType);
                     if (!texture) {
                         return sk_sp<GrTexture>();
                     }
@@ -478,7 +479,7 @@
                     return texture;
                 },
                 format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
-                GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
+                GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
 
         REPORTER_ASSERT(reporter, lazyProxy.get());
 
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 9a5a0d1..a52ed8e 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -317,7 +317,7 @@
                                                                  false, GrMipMapped::kNo);
 
                     sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTexture(
-                            backendTex, origin, kBorrow_GrWrapOwnership, nullptr, nullptr);
+                            backendTex, origin, kBorrow_GrWrapOwnership, kRead_GrIOType);
                     if (!sProxy) {
                         gpu->deleteTestingOnlyBackendTexture(backendTex);
                         continue;
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index 21a9e19..dc1d3b7 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -135,7 +135,8 @@
             }
         }
 
-        sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture(rectangleTex, origin);
+        sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture(
+                rectangleTex, origin, kBorrow_GrWrapOwnership, kRW_GrIOType);
 
         if (!rectProxy) {
             ERRORF(reporter, "Error creating proxy for rectangle texture.");
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index 58af84e..07d82b1 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -69,7 +69,8 @@
         return nullptr;
     }
 
-    auto tmp = proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin);
+    auto tmp = proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin, kBorrow_GrWrapOwnership,
+                                                 kRead_GrIOType);
     if (!tmp) {
         return nullptr;
     }
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 03ba4d1..1748125 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -223,10 +223,10 @@
     context->resetContext();
 
     sk_sp<GrTexture> borrowed(resourceProvider->wrapBackendTexture(
-            backendTextures[0], kBorrow_GrWrapOwnership));
+            backendTextures[0], kBorrow_GrWrapOwnership, kRead_GrIOType));
 
     sk_sp<GrTexture> adopted(resourceProvider->wrapBackendTexture(
-            backendTextures[1], kAdopt_GrWrapOwnership));
+            backendTextures[1], kAdopt_GrWrapOwnership, kRead_GrIOType));
 
     REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr);
     if (!borrowed || !adopted) {
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index 03ded09..5260a0e 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -112,7 +112,8 @@
     GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
     backendTex.setPixelConfig(desc.fConfig);
 
-    return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin);
+    return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin,
+                                             kBorrow_GrWrapOwnership, kRead_GrIOType);
 }
 
 
diff --git a/tests/TraceMemoryDumpTest.cpp b/tests/TraceMemoryDumpTest.cpp
index 32eab62..c58e915 100644
--- a/tests/TraceMemoryDumpTest.cpp
+++ b/tests/TraceMemoryDumpTest.cpp
@@ -128,7 +128,7 @@
     idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
 
     auto texture = GrGLTexture::MakeWrapped(gpu, desc, GrMipMapsStatus::kNotAllocated, idDesc,
-                                            false);
+                                            kRead_GrIOType, false);
 
     ValidateMemoryDumps(reporter, context, texture->gpuMemorySize(), false /* isOwned */);
 }
diff --git a/tests/VkWrapTests.cpp b/tests/VkWrapTests.cpp
index 1553334..7c846ad 100644
--- a/tests/VkWrapTests.cpp
+++ b/tests/VkWrapTests.cpp
@@ -42,7 +42,8 @@
     GrVkImageInfo imageInfo;
     SkAssertResult(origBackendTex.getVkImageInfo(&imageInfo));
 
-    sk_sp<GrTexture> tex = gpu->wrapBackendTexture(origBackendTex, kBorrow_GrWrapOwnership, false);
+    sk_sp<GrTexture> tex =
+            gpu->wrapBackendTexture(origBackendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
     REPORTER_ASSERT(reporter, tex);
 
     // image is null
@@ -51,9 +52,9 @@
         backendCopy.fImage = VK_NULL_HANDLE;
         GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
         backendTex.setPixelConfig(kPixelConfig);
-        tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, false);
+        tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
         REPORTER_ASSERT(reporter, !tex);
-        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
+        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
         REPORTER_ASSERT(reporter, !tex);
     }
 
@@ -63,9 +64,9 @@
         backendCopy.fAlloc = GrVkAlloc();
         GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
         backendTex.setPixelConfig(kPixelConfig);
-        tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, false);
+        tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
         REPORTER_ASSERT(reporter, !tex);
-        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
+        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
         REPORTER_ASSERT(reporter, !tex);
     }
 
@@ -74,7 +75,7 @@
         GrVkImageInfo backendCopy = imageInfo;
         GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
         backendTex.setPixelConfig(kPixelConfig);
-        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
+        tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
 
         REPORTER_ASSERT(reporter, tex);
     }