Roll external/skia a50deea95..4ba4b10ea (11 commits)

https://skia.googlesource.com/skia.git/+log/a50deea95..4ba4b10ea

2017-10-30 angle-deps-roller@chromium.org Roll skia/third_party/externals/angle2/ e7c5f4f05..163965d5c (1 commit)
2017-10-30 egdaniel@google.com Have mip status match surface when snapping image from wrapped object
2017-10-30 mtklein@chromium.org make color rotating a little less pointlessly slow
2017-10-30 egdaniel@google.com Add mip support to GrAHardwareBufferImageGenerator
2017-10-30 angle-deps-roller@chromium.org Roll skia/third_party/externals/angle2/ 55bc905f0..e7c5f4f05 (2 commits)
2017-10-30 robertphillips@google.com Revert "Revert "Fix Debian9-Clang build""
2017-10-30 robertphillips@google.com Revert "Revert "Fix GrDefaultPathRender inversely wound path bug""
2017-10-30 robertphillips@google.com Suppress Gr*PathRendererTests on Vulkan NexusPlayer and Iris 540
2017-10-30 angle-deps-roller@chromium.org Roll skia/third_party/externals/angle2/ 87c358839..55bc905f0 (1 commit)
2017-10-30 liyuqian@google.com Initialize mask to 0 during AntiRect optimization
2017-10-30 ethannicholas@google.com fix skslc splitting escape sequences in half

Test: Presubmit checks will test this change.
Change-Id: Id56fd1ec1a7105f3cbccadaa208d076b211ef792
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
diff --git a/Android.bp b/Android.bp
index eff057f..53f8a96 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1379,6 +1379,7 @@
         "tests/DFPathRendererTest.cpp",
         "tests/DashPathEffectTest.cpp",
         "tests/DataRefTest.cpp",
+        "tests/DefaultPathRendererTest.cpp",
         "tests/DequeTest.cpp",
         "tests/DetermineDomainModeTest.cpp",
         "tests/DeviceLooperTest.cpp",
diff --git a/DEPS b/DEPS
index aed9a75..14c881c 100644
--- a/DEPS
+++ b/DEPS
@@ -3,7 +3,7 @@
 deps = {
   "buildtools"                          : "https://chromium.googlesource.com/chromium/buildtools.git@e6b510a9daf822bbe9f922c200c58150803d2fd8",
   "common"                              : "https://skia.googlesource.com/common.git@9737551d7a52c3db3262db5856e6bcd62c462b92",
-  "third_party/externals/angle2"        : "https://chromium.googlesource.com/angle/angle.git@87c358839ccde050baa73185a201779a1cd73e84",
+  "third_party/externals/angle2"        : "https://chromium.googlesource.com/angle/angle.git@163965d5ce2b333f4a017e542b43d5426de96453",
   "third_party/externals/dng_sdk"       : "https://android.googlesource.com/platform/external/dng_sdk.git@96443b262250c390b0caefbf3eed8463ba35ecae",
   "third_party/externals/expat"         : "https://android.googlesource.com/platform/external/expat.git@android-6.0.1_r55",
   "third_party/externals/freetype"      : "https://skia.googlesource.com/third_party/freetype2.git@447a0b62634802d8acdb56008cff5ff4e50be244",
diff --git a/dm/DM.cpp b/dm/DM.cpp
index b43ce6f..cb5332d 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -1281,8 +1281,11 @@
     } reporter;
 
     if (!FLAGS_dryRun && !is_blacklisted("_", "tests", "_", test.name)) {
+        GrContextOptions options = grCtxOptions;
+        test.modifyGrContextOptions(&options);
+
         start("unit", "test", "", test.name);
-        GrContextFactory factory(grCtxOptions);
+        GrContextFactory factory(options);
         test.run(&reporter, &factory);
     }
     done("unit", "test", "", test.name);
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 0968aca..8e36f0c 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -2165,14 +2165,14 @@
             pixels.allocPixels(canvas->imageInfo());
             canvas->readPixels(pixels, 0, 0);
             for (int y = 0; y < pixels.height(); y++) {
+                uint32_t* row = pixels.getAddr32(0,y);
                 for (int x = 0; x < pixels.width(); x++) {
-                    uint32_t pixel = *pixels.getAddr32(x, y);
+                    uint32_t pixel = *row;
                     uint8_t r = SkGetPackedR32(pixel);
                     uint8_t g = SkGetPackedG32(pixel);
                     uint8_t b = SkGetPackedB32(pixel);
                     uint8_t a = SkGetPackedA32(pixel);
-                    *pixels.getAddr32(x, y) =
-                            SkSwizzle_RGBA_to_PMColor(b << 0 | r << 8 | g << 16 | a << 24);
+                    *row++ = SkSwizzle_RGBA_to_PMColor(b << 0 | r << 8 | g << 16 | a << 24);
                 }
             }
 
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 0e39d3b..bf1c651 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -186,8 +186,11 @@
         desc.fHeight = info.height();
         desc.fConfig = fProxy->config();
 
+        GrMipMapped mipMapped = willBeMipped ? GrMipMapped::kYes : GrMipMapped::kNo;
+
         sk_sp<GrSurfaceContext> dstContext(fCtx->contextPriv().makeDeferredSurfaceContext(
                                                                             desc,
+                                                                            mipMapped,
                                                                             SkBackingFit::kExact,
                                                                             SkBudgeted::kYes));
         if (!dstContext) {
diff --git a/gn/tests.gni b/gn/tests.gni
index 3c42b80..b051326 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -48,6 +48,7 @@
   "$_tests/DashPathEffectTest.cpp",
   "$_tests/DataRefTest.cpp",
   "$_tests/DequeTest.cpp",
+  "$_tests/DefaultPathRendererTest.cpp",
   "$_tests/DetermineDomainModeTest.cpp",
   "$_tests/DeviceLooperTest.cpp",
   "$_tests/DeviceTest.cpp",
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index d0d0df7..e5f568c 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -231,7 +231,7 @@
                                                  GrPixelConfig config,
                                                  sk_sp<SkColorSpace> colorSpace,
                                                  int sampleCnt = 0,
-                                                 bool willNeedMipMaps = false,
+                                                 GrMipMapped = GrMipMapped::kNo,
                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
                                                  const SkSurfaceProps* surfaceProps = nullptr,
                                                  SkBudgeted = SkBudgeted::kYes);
@@ -247,7 +247,7 @@
                                                  GrPixelConfig config,
                                                  sk_sp<SkColorSpace> colorSpace,
                                                  int sampleCnt = 0,
-                                                 bool willNeedMipMaps = false,
+                                                 GrMipMapped = GrMipMapped::kNo,
                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
                                                  const SkSurfaceProps* surfaceProps = nullptr,
                                                  SkBudgeted budgeted = SkBudgeted::kYes);
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 2bbf02a..0eccdce 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -326,12 +326,12 @@
     // Helper function that creates a temporary SurfaceContext to perform the copy
     // It always returns a kExact-backed proxy bc it is used when converting an SkSpecialImage
     // to an SkImage. The copy is is not a render target and not multisampled.
-    static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src,
+    static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src, GrMipMapped,
                                       SkIRect srcRect, SkBudgeted);
 
     // Copy the entire 'src'
     // It always returns a kExact-backed proxy bc it is used in SkGpuDevice::snapSpecial
-    static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src,
+    static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src, GrMipMapped,
                                       SkBudgeted budgeted);
 
     // Test-only entry point - should decrease in use as proxies propagate
diff --git a/infra/bots/recipes/test.expected/Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan.json b/infra/bots/recipes/test.expected/Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan.json
index 30a0586..65f2bd5 100644
--- a/infra/bots/recipes/test.expected/Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan.json
+++ b/infra/bots/recipes/test.expected/Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan.json
@@ -678,7 +678,7 @@
       "--json-output",
       "/path/to/tmp/json",
       "copy",
-      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 builder Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan swarming_bot_id skia-bot-123 swarming_task_id 123456 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch x86 compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value PowerVR extra_config Android_Vulkan model NexusPlayer os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --dont_write pdf --ignoreSigInt --nocpu --config vk --src tests gm colorImage --blacklist _ test _ GrShape _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~ResourceCache ~gradients_no_texture$ ~tilemodes ~shadertext$ ~bitmapfilters ~GrContextFactory_abandon ~FullScreenClearWithLayers ~ClearOp ~ComposedImageFilterBounds_Gpu ~ImageEncode_Gpu ~ImageFilterFailAffectsTransparentBlack_Gpu ~ImageFilterZeroBlurSigma_Gpu ~ImageNewShader_GPU ~ImageReadPixels_Gpu ~ImageScalePixels_Gpu ~OverdrawSurface_Gpu ~ReadWriteAlpha ~SpecialImage_DeferredGpu ~SpecialImage_Gpu ~SurfaceSemaphores --noRAW_threading --verbose; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 builder Test-Android-Clang-NexusPlayer-GPU-PowerVR-x86-Release-All-Android_Vulkan swarming_bot_id skia-bot-123 swarming_task_id 123456 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch x86 compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value PowerVR extra_config Android_Vulkan model NexusPlayer os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --dont_write pdf --ignoreSigInt --nocpu --config vk --src tests gm colorImage --blacklist _ test _ GrShape _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~ResourceCache ~gradients_no_texture$ ~tilemodes ~shadertext$ ~bitmapfilters ~GrContextFactory_abandon ~FullScreenClearWithLayers ~GrDefaultPathRendererTest ~GrMSAAPathRendererTest ~ClearOp ~ComposedImageFilterBounds_Gpu ~ImageEncode_Gpu ~ImageFilterFailAffectsTransparentBlack_Gpu ~ImageFilterZeroBlurSigma_Gpu ~ImageNewShader_GPU ~ImageReadPixels_Gpu ~ImageScalePixels_Gpu ~OverdrawSurface_Gpu ~ReadWriteAlpha ~SpecialImage_DeferredGpu ~SpecialImage_Gpu ~SurfaceSemaphores --noRAW_threading --verbose; echo $? >/data/local/tmp/rc",
       "[START_DIR]/tmp/dm.sh"
     ],
     "env": {
diff --git a/infra/bots/recipes/test.expected/Test-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-Vulkan.json b/infra/bots/recipes/test.expected/Test-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-Vulkan.json
index 8748982..7970395 100644
--- a/infra/bots/recipes/test.expected/Test-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-Vulkan.json
+++ b/infra/bots/recipes/test.expected/Test-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-Vulkan.json
@@ -599,6 +599,8 @@
       "~WritePixels_Gpu",
       "~WritePixelsNonTexture_Gpu",
       "~XfermodeImageFilterCroppedInput_Gpu",
+      "~GrDefaultPathRendererTest",
+      "~GrMSAAPathRendererTest",
       "--verbose"
     ],
     "env": {
diff --git a/infra/bots/recipes/test.py b/infra/bots/recipes/test.py
index dbacf81..023afb7 100644
--- a/infra/bots/recipes/test.py
+++ b/infra/bots/recipes/test.py
@@ -570,6 +570,8 @@
                   '~bitmapfilters'])
     match.append('~GrContextFactory_abandon') #skia:6209
     match.append('~FullScreenClearWithLayers') #skia:7191
+    match.append('~GrDefaultPathRendererTest') #skia:7244
+    match.append('~GrMSAAPathRendererTest') #skia:7244
     # skia:7018
     match.extend(['~ClearOp',
                   '~ComposedImageFilterBounds_Gpu',
@@ -660,6 +662,8 @@
     match.append('~WritePixels_Gpu')
     match.append('~WritePixelsNonTexture_Gpu')
     match.append('~XfermodeImageFilterCroppedInput_Gpu')
+    match.append('~GrDefaultPathRendererTest') #skia:7244
+    match.append('~GrMSAAPathRendererTest') #skia:7244
 
   if 'AlphaR2' in bot and 'ANGLE' in bot:
     # skia:7096
diff --git a/src/core/SkColorSpaceXformImageGenerator.cpp b/src/core/SkColorSpaceXformImageGenerator.cpp
index 0ca6ab1..8121cf9 100644
--- a/src/core/SkColorSpaceXformImageGenerator.cpp
+++ b/src/core/SkColorSpaceXformImageGenerator.cpp
@@ -85,9 +85,11 @@
         return nullptr;
     }
 
+    GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
+
     sk_sp<GrRenderTargetContext> renderTargetContext = ctx->makeDeferredRenderTargetContext(
             SkBackingFit::kExact, info.width(), info.height(), kRGBA_8888_GrPixelConfig, nullptr,
-            0, willNeedMipMaps, kTopLeft_GrSurfaceOrigin);
+            0, mipMapped, kTopLeft_GrSurfaceOrigin);
     if (!renderTargetContext) {
         return nullptr;
     }
diff --git a/src/core/SkCoverageDelta.cpp b/src/core/SkCoverageDelta.cpp
index b168c21..a6bb1dd 100644
--- a/src/core/SkCoverageDelta.cpp
+++ b/src/core/SkCoverageDelta.cpp
@@ -86,6 +86,7 @@
             // Blit the mask
             int L = fAntiRect.fX - fBounds.fLeft;
             for(int i = 0; i < fAntiRect.fHeight; ++i) {
+                sk_bzero(maskRow, fBounds.width());
                 SkAlpha* tMask = maskRow + L;
                 if (fAntiRect.fLeftAlpha) {
                     tMask[0] = fAntiRect.fLeftAlpha;
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index db4fadc..df56afd 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -464,7 +464,8 @@
             }
 
             sk_sp<GrTextureProxy> subsetProxy(GrSurfaceProxy::Copy(fContext, fTextureProxy.get(),
-                                                                   *subset, SkBudgeted::kYes));
+                                                                   GrMipMapped::kNo, *subset,
+                                                                   SkBudgeted::kYes));
             if (!subsetProxy) {
                 return nullptr;
             }
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 164e3d6..bdfdbd0 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -104,17 +104,44 @@
         return nullptr;
     }
 
+    bool makingASubset = true;
     if (0 == origin.fX && 0 == origin.fY &&
             info.width() == getInfo().width() && info.height() == getInfo().height()) {
-        // If the caller wants the entire texture, we're done
-        return proxy;
-    } else {
-        // Otherwise, make a copy of the requested subset.
-        return GrSurfaceProxy::Copy(context, proxy.get(),
-                                    SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(),
-                                                      info.height()),
-                                    SkBudgeted::kYes);
+        makingASubset = false;
+        if (!willNeedMipMaps || GrMipMapped::kYes == proxy->mipMapped()) {
+            // If the caller wants the full texture and we have the correct mip support, we're done
+            return proxy;
+        }
     }
+    // Otherwise, make a copy for the requested subset or for mip maps.
+    SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
+
+    GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
+
+    sk_sp<GrTextureProxy> texProxy = GrSurfaceProxy::Copy(context, proxy.get(), mipMapped,
+                                                          subset, SkBudgeted::kYes);
+    if (!makingASubset && texProxy) {
+        // We are in this case if we wanted the full texture, but we will be mip mapping the
+        // texture. Therefore we want to update the cached texture so that we point to the
+        // mipped version instead of the old one.
+        SkASSERT(willNeedMipMaps);
+        SkASSERT(GrMipMapped::kYes == texProxy->mipMapped());
+
+        // The only way we should get into here is if we just made a new texture in makeProxy or
+        // we found a cached texture in the same context. Thus the current and cached contexts
+        // should match.
+        SkASSERT(context->uniqueID() == fOwningContextID);
+
+        // Clear out the old cached texture.
+        this->clear();
+
+        // We need to get the actual GrTexture so force instantiation of the GrTextureProxy
+        texProxy->instantiate(context->resourceProvider());
+        GrTexture* texture = texProxy->priv().peekTexture();
+        SkASSERT(texture);
+        fOriginalTexture = texture;
+    }
+    return texProxy;
 }
 #endif
 
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 7240c79..58dacf6 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -183,9 +183,11 @@
         // Otherwise, make a copy of the requested subset. Make sure our temporary is renderable,
         // because Vulkan will want to do the copy as a draw. All other copies would require a
         // layout change in Vulkan and we do not change the layout of borrowed images.
+        GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
+
         sk_sp<GrRenderTargetContext> rtContext(context->makeDeferredRenderTargetContext(
                 SkBackingFit::kExact, info.width(), info.height(), proxy->config(), nullptr,
-                0, willNeedMipMaps, proxy->origin(), nullptr, SkBudgeted::kYes));
+                0, mipMapped, proxy->origin(), nullptr, SkBudgeted::kYes));
 
         if (!rtContext) {
             return nullptr;
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 68fd9f3..9760205d 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -85,6 +85,7 @@
 
     sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
                                                         desc,
+                                                        GrMipMapped::kNo,
                                                         SkBackingFit::kApprox,
                                                         SkBudgeted::kYes);
     if (!sContext) {
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f4f1d6c..2d9f011 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -617,7 +617,7 @@
                                                            tempDrawInfo.fTempSurfaceDesc.fConfig,
                                                            nullptr,
                                                            tempDrawInfo.fTempSurfaceDesc.fSampleCnt,
-                                                           false,
+                                                           GrMipMapped::kNo,
                                                            tempDrawInfo.fTempSurfaceDesc.fOrigin);
         if (tempRTC) {
             SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top));
@@ -750,11 +750,19 @@
 }
 
 sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+                                                                  GrMipMapped mipMapped,
                                                                   SkBackingFit fit,
                                                                   SkBudgeted isDstBudgeted) {
 
-    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(),
-                                                               dstDesc, fit, isDstBudgeted);
+    sk_sp<GrTextureProxy> proxy;
+    if (GrMipMapped::kNo == mipMapped) {
+        proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(), dstDesc, fit,
+                                             isDstBudgeted);
+    } else {
+        SkASSERT(SkBackingFit::kExact == fit);
+        proxy = GrSurfaceProxy::MakeDeferredMipMap(fContext->resourceProvider(), dstDesc,
+                                                   isDstBudgeted);
+    }
     if (!proxy) {
         return nullptr;
     }
@@ -877,7 +885,7 @@
                                                                  GrPixelConfig config,
                                                                  sk_sp<SkColorSpace> colorSpace,
                                                                  int sampleCnt,
-                                                                 bool willNeedMipMaps,
+                                                                 GrMipMapped mipMapped,
                                                                  GrSurfaceOrigin origin,
                                                                  const SkSurfaceProps* surfaceProps,
                                                                  SkBudgeted budgeted) {
@@ -886,7 +894,7 @@
     }
 
     return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace),
-                                                 sampleCnt, willNeedMipMaps, origin, surfaceProps,
+                                                 sampleCnt, mipMapped, origin, surfaceProps,
                                                  budgeted);
 }
 
@@ -896,7 +904,7 @@
                                                         GrPixelConfig config,
                                                         sk_sp<SkColorSpace> colorSpace,
                                                         int sampleCnt,
-                                                        bool willNeedMipMaps,
+                                                        GrMipMapped mipMapped,
                                                         GrSurfaceOrigin origin,
                                                         const SkSurfaceProps* surfaceProps,
                                                         SkBudgeted budgeted) {
@@ -913,7 +921,7 @@
     desc.fSampleCnt = sampleCnt;
 
     sk_sp<GrTextureProxy> rtp;
-    if (!willNeedMipMaps) {
+    if (GrMipMapped::kNo == mipMapped) {
         rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(), desc, fit, budgeted);
     } else {
         rtp = GrSurfaceProxy::MakeDeferredMipMap(this->resourceProvider(), desc, budgeted);
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index e1773c8..cdd04b4 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -27,6 +27,7 @@
     sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>);
 
     sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc&,
+                                                       GrMipMapped,
                                                        SkBackingFit,
                                                        SkBudgeted);
 
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 5f071e8..44550e1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1890,6 +1890,7 @@
 
     sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext(
                                                                                 desc,
+                                                                                GrMipMapped::kNo,
                                                                                 fit,
                                                                                 SkBudgeted::kYes);
     if (!sContext) {
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index d45847a..1005758 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -100,6 +100,7 @@
 
     sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
                                                                                 desc,
+                                                                                GrMipMapped::kNo,
                                                                                 fit,
                                                                                 SkBudgeted::kYes);
     if (!sContext || !sContext->asTextureProxy()) {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index da5bb17..3e188b8 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -411,6 +411,7 @@
 
 sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context,
                                            GrSurfaceProxy* src,
+                                           GrMipMapped mipMapped,
                                            SkIRect srcRect,
                                            SkBudgeted budgeted) {
     if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
@@ -425,6 +426,7 @@
 
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
                                                                             dstDesc,
+                                                                            mipMapped,
                                                                             SkBackingFit::kExact,
                                                                             budgeted));
     if (!dstContext) {
@@ -439,8 +441,8 @@
 }
 
 sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context, GrSurfaceProxy* src,
-                                           SkBudgeted budgeted) {
-    return Copy(context, src, SkIRect::MakeWH(src->width(), src->height()), budgeted);
+                                           GrMipMapped mipMapped, SkBudgeted budgeted) {
+    return Copy(context, src, mipMapped, SkIRect::MakeWH(src->width(), src->height()), budgeted);
 }
 
 sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
@@ -448,6 +450,7 @@
 
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
                                                                             dstDesc,
+                                                                            GrMipMapped::kNo,
                                                                             SkBackingFit::kExact,
                                                                             SkBudgeted::kYes));
     if (!dstContext) {
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index cf7ee7c..f5ae0ad 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -23,10 +23,11 @@
     SkASSERT(context);
 
     const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
+    GrMipMapped mipMapped = dstWillRequireMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
 
     sk_sp<GrRenderTargetContext> copyRTC = context->makeDeferredRenderTargetContextWithFallback(
         SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(), nullptr,
-        0, dstWillRequireMipMaps, inputProxy->origin());
+        0, mipMapped, inputProxy->origin());
     if (!copyRTC) {
         return nullptr;
     }
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 085e5be..930a33e 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -109,7 +109,9 @@
                 (yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight)
                     ? SkBackingFit::kExact : SkBackingFit::kApprox;
 
-        yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc, fit,
+        yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc,
+                                                                              GrMipMapped::kNo,
+                                                                              fit,
                                                                               SkBudgeted::kYes);
         if (!yuvTextureContexts[i]) {
             return nullptr;
@@ -129,7 +131,7 @@
                                                                     desc.fWidth, desc.fHeight,
                                                                     desc.fConfig, nullptr,
                                                                     desc.fSampleCnt,
-                                                                    false, // always non mipped
+                                                                    GrMipMapped::kNo,
                                                                     kTopLeft_GrSurfaceOrigin));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 93414ed..df81d04 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -164,7 +164,7 @@
                                     SkBackingFit::kExact,
                                     origInfo.width(), origInfo.height(),
                                     config, origInfo.refColorSpace(), sampleCount,
-                                    false, origin, surfaceProps, budgeted);
+                                    mipMapped, origin, surfaceProps, budgeted);
 }
 
 sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg,
@@ -1238,6 +1238,7 @@
         // filter
         proxy = GrSurfaceProxy::Copy(fContext.get(),
                                      this->accessRenderTargetContext()->asSurfaceProxy(),
+                                     GrMipMapped::kNo,
                                      SkBudgeted::kYes);
         if (!proxy) {
             return nullptr;
@@ -1702,7 +1703,8 @@
             fit, cinfo.fInfo.width(), cinfo.fInfo.height(),
             fRenderTargetContext->colorSpaceInfo().config(),
             fRenderTargetContext->colorSpaceInfo().refColorSpace(),
-            fRenderTargetContext->numStencilSamples(), false, kBottomLeft_GrSurfaceOrigin, &props));
+            fRenderTargetContext->numStencilSamples(), GrMipMapped::kNo,
+            kBottomLeft_GrSurfaceOrigin, &props));
     if (!rtc) {
         return nullptr;
     }
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 1bee548..d3bd6e3 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4415,7 +4415,7 @@
     int width = w;
     int height = h;
     for (int i = 0; i < mipLevels; ++i) {
-        GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, width, height, 0, externalFormat,
+        GL_CALL(TexImage2D(info->fTarget, i, internalFormat, width, height, 0, externalFormat,
                            externalType, pixels));
         width = SkTMax(1, width / 2);
         height = SkTMax(1, height / 2);
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 40631a7..4a9f0c2 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -568,8 +568,10 @@
     SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());
 
     SkRect devBounds;
-    GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix,
-                     &devBounds);
+    GetPathDevBounds(path,
+                     renderTargetContext->asRenderTargetProxy()->worstCaseWidth(),
+                     renderTargetContext->asRenderTargetProxy()->worstCaseHeight(),
+                     viewMatrix, &devBounds);
 
     for (int p = 0; p < passCount; ++p) {
         if (lastPassIsBounds && (p == passCount-1)) {
diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp
index 27d78a7..50741bc 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.cpp
+++ b/src/gpu/ops/GrMSAAPathRenderer.cpp
@@ -637,8 +637,10 @@
     }
 
     SkRect devBounds;
-    GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix,
-                     &devBounds);
+    GetPathDevBounds(path,
+                     renderTargetContext->asRenderTargetProxy()->worstCaseWidth(),
+                     renderTargetContext->asRenderTargetProxy()->worstCaseHeight(),
+                     viewMatrix, &devBounds);
 
     SkASSERT(passes[0]);
     {  // First pass
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9f1586c..856b3b8 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -249,6 +249,7 @@
 
     sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
                                                                         desc,
+                                                                        GrMipMapped::kNo,
                                                                         SkBackingFit::kExact,
                                                                         fBudgeted));
     if (!sContext) {
@@ -389,7 +390,7 @@
                                                                          kRGBA_8888_GrPixelConfig,
                                                                          std::move(imageColorSpace),
                                                                          0,
-                                                                         false,
+                                                                         GrMipMapped::kNo,
                                                                          origin));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 6e9bc3f..891f037 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -110,7 +110,7 @@
     if (!srcProxy || rtc->priv().refsWrappedObjects()) {
         SkASSERT(rtc->origin() == rtc->asSurfaceProxy()->origin());
 
-        srcProxy = GrSurfaceProxy::Copy(ctx, rtc->asSurfaceProxy(), budgeted);
+        srcProxy = GrSurfaceProxy::Copy(ctx, rtc->asSurfaceProxy(), rtc->mipMapped(), budgeted);
     }
 
     const SkImageInfo info = fDevice->imageInfo();
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 3f1d156..506daa8 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -475,6 +475,9 @@
                 if (code[index + 1] != '%') {
                     ++argCount;
                 }
+            } else if ('\\' == code[index] && index == start + maxChunkSize - 1) {
+                // avoid splitting an escape sequence that happens to fall across a chunk boundary
+                break;
             }
             ++index;
         }
diff --git a/tests/DefaultPathRendererTest.cpp b/tests/DefaultPathRendererTest.cpp
new file mode 100644
index 0000000..d1e102b
--- /dev/null
+++ b/tests/DefaultPathRendererTest.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+
+#if SK_SUPPORT_GPU
+#include "GrClip.h"
+#include "GrRenderTargetContext.h"
+#include "GrStyle.h"
+#include "GrTypesPriv.h"
+
+#include "effects/GrConstColorProcessor.h"
+
+static void allow_default_and_msaa(GrContextOptions* options) {
+    options->fGpuPathRenderers = GpuPathRenderers::kMSAA;
+}
+
+static void only_allow_default(GrContextOptions* options) {
+    options->fGpuPathRenderers = GpuPathRenderers::kNone;
+}
+
+static SkBitmap read_back(GrRenderTargetContext* rtc, int width, int height) {
+
+    SkImageInfo dstII = SkImageInfo::MakeN32Premul(width, height);
+
+    SkBitmap bm;
+    bm.allocPixels(dstII);
+
+    rtc->readPixels(dstII, bm.getAddr(0, 0), bm.rowBytes(), 0, 0, 0);
+
+    return bm;
+}
+
+static SkPath make_path(const SkRect& outer, int inset, SkPath::FillType fill) {
+    SkPath p;
+
+    p.addRect(outer, SkPath::kCW_Direction);
+    p.addRect(outer.makeInset(inset, inset), SkPath::kCCW_Direction);
+    p.setFillType(fill);
+    return p;
+}
+
+
+static const int kBigSize = 64; // This should be a power of 2
+static const int kPad = 3;
+
+// From crbug.com/769898:
+//   create an approx fit render target context that will have extra space (i.e., npot)
+//   draw an inverse wound concave path into it - forcing use of the stencil-using path renderer
+//   throw the RTC away so the backing GrSurface/GrStencilBuffer can be reused
+//   create a new render target context that will reuse the prior GrSurface
+//   draw a normally wound concave path that touches outside of the approx fit RTC's content rect
+//
+// When the bug manifests the GrDefaultPathRenderer/GrMSAAPathRenderer is/was leaving the stencil
+// buffer outside of the first content rect in a bad state and the second draw would be incorrect.
+
+static void run_test(GrContext* ctx, skiatest::Reporter* reporter) {
+    SkPath invPath = make_path(SkRect::MakeXYWH(0, 0, kBigSize, kBigSize),
+                               kBigSize/2-1, SkPath::kInverseWinding_FillType);
+    SkPath path = make_path(SkRect::MakeXYWH(0, 0, kBigSize, kBigSize),
+                            kPad, SkPath::kWinding_FillType);
+
+    GrStyle style(SkStrokeRec::kFill_InitStyle);
+
+    {
+        auto rtc =  ctx->makeDeferredRenderTargetContext(SkBackingFit::kApprox,
+                                                         kBigSize/2+1, kBigSize/2+1,
+                                                         kRGBA_8888_GrPixelConfig, nullptr);
+
+        rtc->clear(nullptr, GrColorPackRGBA(0x0, 0x0, 0x0, 0xFF), true);
+
+        GrPaint paint;
+
+        const GrColor4f color = { 1.0f, 0.0f, 0.0f, 1.0f };
+        auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::kIgnore_InputMode);
+        paint.addColorFragmentProcessor(std::move(fp));
+
+        rtc->drawPath(GrNoClip(), std::move(paint), GrAA::kNo,
+                      SkMatrix::I(), invPath, style);
+
+        rtc->prepareForExternalIO(0, nullptr);
+    }
+
+    {
+        auto rtc = ctx->makeDeferredRenderTargetContext(SkBackingFit::kExact, kBigSize, kBigSize,
+                                                        kRGBA_8888_GrPixelConfig, nullptr);
+
+        rtc->clear(nullptr, GrColorPackRGBA(0x0, 0x0, 0x0, 0xFF), true);
+
+        GrPaint paint;
+
+        const GrColor4f color = { 0.0f, 1.0f, 0.0f, 1.0f };
+        auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::kIgnore_InputMode);
+        paint.addColorFragmentProcessor(std::move(fp));
+
+        rtc->drawPath(GrNoClip(), std::move(paint), GrAA::kNo,
+                      SkMatrix::I(), path, style);
+
+        SkBitmap bm = read_back(rtc.get(), kBigSize, kBigSize);
+
+        bool correct = true;
+        for (int y = kBigSize/2+1; y < kBigSize-kPad-1 && correct; ++y) {
+            for (int x = kPad+1; x < kBigSize-kPad-1 && correct; ++x) {
+                correct = bm.getColor(x, y) == SK_ColorBLACK;
+                REPORTER_ASSERT(reporter, correct);
+            }
+        }
+    }
+
+}
+
+DEF_GPUTEST_FOR_CONTEXTS(GrDefaultPathRendererTest,
+                         sk_gpu_test::GrContextFactory::IsRenderingContext,
+                         reporter, ctxInfo, only_allow_default) {
+    GrContext* ctx = ctxInfo.grContext();
+
+    run_test(ctx, reporter);
+}
+
+DEF_GPUTEST_FOR_CONTEXTS(GrMSAAPathRendererTest,
+                         sk_gpu_test::GrContextFactory::IsRenderingContext,
+                         reporter, ctxInfo, allow_default_and_msaa) {
+    GrContext* ctx = ctxInfo.grContext();
+
+    if (!ctx->caps()->sampleShadingSupport()) {   // The MSAAPathRenderer requires this
+        return;
+    }
+
+    run_test(ctx, reporter);
+}
+
+#endif
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 55ffca9..e0ac272 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -159,7 +159,7 @@
                                                                            kRGBA_8888_GrPixelConfig,
                                                                            nullptr,
                                                                            sampleCnt,
-                                                                           false,
+                                                                           GrMipMapped::kNo,
                                                                            origin));
     return renderTargetContext;
 }
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index fa99a9a..36b5181 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -119,11 +119,11 @@
         GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples));
         bottomUps[i] = ctx->makeDeferredRenderTargetContext(
                            SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
-                           rand.nextRangeU(1 + numSamples / 2, numSamples),
+                           rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo,
                            kBottomLeft_GrSurfaceOrigin);
         topDowns[i] = ctx->makeDeferredRenderTargetContext(
                           SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
-                          rand.nextRangeU(1 + numSamples / 2, numSamples),
+                          rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo,
                           kTopLeft_GrSurfaceOrigin);
     }
 
diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp
index aad3b60..f023018 100644
--- a/tests/GrMipMappedTest.cpp
+++ b/tests/GrMipMappedTest.cpp
@@ -28,6 +28,8 @@
 #include "SkSurface_Gpu.h"
 #include "Test.h"
 
+static constexpr int kSize = 8;
+
 // Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in
 // SkImages and SkSurfaces
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) {
@@ -45,8 +47,8 @@
 
             GrBackend backend = context->contextPriv().getBackend();
             GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend,
-                                                                       8,
-                                                                       8,
+                                                                       kSize,
+                                                                       kSize,
                                                                        kRGBA_8888_GrPixelConfig,
                                                                        mipMapped,
                                                                        backendHandle);
@@ -103,8 +105,6 @@
 // Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
 // based on if we will use mips in the draw and the mip status of the GrBackendTexture.
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) {
-    static const int kSize = 8;
-
     GrContext* context = ctxInfo.grContext();
     if (!context->caps()->mipMapSupport()) {
         return;
@@ -218,5 +218,72 @@
     }
 }
 
+// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
+// resource we took the snapshot of.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) {
+    GrContext* context = ctxInfo.grContext();
+    if (!context->caps()->mipMapSupport()) {
+        return;
+    }
+
+    for (auto willUseMips : {false, true}) {
+        for (auto isWrapped : {false, true}) {
+            GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo;
+            sk_sp<SkSurface> surface;
+            GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture(
+                    nullptr, 8, 8, kRGBA_8888_GrPixelConfig, true, mipMapped);
+            if (isWrapped) {
+                GrBackend backend = context->contextPriv().getBackend();
+                GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend,
+                                                                           kSize,
+                                                                           kSize,
+                                                                           kRGBA_8888_GrPixelConfig,
+                                                                           mipMapped,
+                                                                           backendHandle);
+
+                surface = SkSurface::MakeFromBackendTexture(context,
+                                                            backendTex,
+                                                            kTopLeft_GrSurfaceOrigin,
+                                                            0,
+                                                            nullptr,
+                                                            nullptr);
+            } else {
+                SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
+                                                     kPremul_SkAlphaType);
+                surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
+                                                      kTopLeft_GrSurfaceOrigin, nullptr,
+                                                      willUseMips);
+            }
+            REPORTER_ASSERT(reporter, surface);
+            if (!surface) {
+                context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle);
+            }
+            SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
+            GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy();
+            REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
+
+            texProxy->instantiate(context->resourceProvider());
+            GrTexture* texture = texProxy->priv().peekTexture();
+            REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
+
+            sk_sp<SkImage> image = surface->makeImageSnapshot();
+            REPORTER_ASSERT(reporter, image);
+            if (!image) {
+                context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle);
+            }
+            texProxy = as_IB(image)->peekProxy();
+            REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
+
+            texProxy->instantiate(context->resourceProvider());
+            texture = texProxy->priv().peekTexture();
+            REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
+
+            // Must flush the context to make sure all the cmds (copies, etc.) from above are sent
+            // to the gpu before we delete the backendHandle.
+            context->flush();
+            context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle);
+        }
+    }
+}
 
 #endif
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index e5dc6ae..eff8c25 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -212,7 +212,8 @@
                     // Try creating the texture as a deferred proxy.
                     for (int i = 0; i < 2; ++i) {
                         auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
-                                desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
+                                desc, GrMipMapped::kNo,
+                                approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
                                 SkBudgeted::kYes);
                         if (!surfCtx) {
                             continue;
diff --git a/tests/PathRendererCacheTests.cpp b/tests/PathRendererCacheTests.cpp
index 33a02ca..dbf01ab 100644
--- a/tests/PathRendererCacheTests.cpp
+++ b/tests/PathRendererCacheTests.cpp
@@ -81,7 +81,7 @@
 
     sk_sp<GrRenderTargetContext> rtc(ctx->makeDeferredRenderTargetContext(
             SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 0,
-            kTopLeft_GrSurfaceOrigin));
+            GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
     if (!rtc) {
         return;
     }
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 0cb1d2b..863830a 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -120,7 +120,7 @@
 
 // This currently fails on ES3 ANGLE contexts
 DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter,
-                         ctxInfo) {
+                         ctxInfo, nullptr) {
     GrContext* context = ctxInfo.grContext();
     if (context->caps()->avoidStencilBuffers()) {
         return;
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index a52e961..6ebdcf7 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -176,8 +176,9 @@
         context->caps()->isConfigTexturable(desc.fConfig)) {
 
         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
-                                                                    desc, SkBackingFit::kExact,
-                                                                    SkBudgeted::kNo);
+                                                                             desc, GrMipMapped::kNo,
+                                                                             SkBackingFit::kExact,
+                                                                             SkBudgeted::kNo);
         if (!sContext) {
             ERRORF(reporter, "Could not create SRGBA surface context.");
             return;
@@ -215,7 +216,9 @@
         }
 
         desc.fConfig = kRGBA_8888_GrPixelConfig;
-        sContext = context->contextPriv().makeDeferredSurfaceContext(desc, SkBackingFit::kExact,
+        sContext = context->contextPriv().makeDeferredSurfaceContext(desc,
+                                                                     GrMipMapped::kNo,
+                                                                     SkBackingFit::kExact,
                                                                      SkBudgeted::kNo);
         if (!sContext) {
             ERRORF(reporter, "Could not create RGBA surface context.");
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 6c414df..b622f37 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -425,6 +425,7 @@
                                                                   kRGBA_8888_GrPixelConfig,
                                                                   nullptr,
                                                                   0,
+                                                                  GrMipMapped::kNo,
                                                                   kTopLeft_GrSurfaceOrigin));
     if (!rtc) {
         return;
diff --git a/tests/Test.h b/tests/Test.h
index c9a381e..3e34474 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -22,6 +22,7 @@
 class GLTestContext;
 }  // namespace sk_gpu_test
 class GrContext;
+struct GrContextOptions;
 #endif
 
 namespace skiatest {
@@ -89,12 +90,21 @@
 };
 
 typedef void (*TestProc)(skiatest::Reporter*, sk_gpu_test::GrContextFactory*);
+typedef void (*ContextOptionsProc)(GrContextOptions*);
 
 struct Test {
-    Test(const char* n, bool g, TestProc p) : name(n), needsGpu(g), proc(p) {}
+    Test(const char* n, bool g, TestProc p, ContextOptionsProc optionsProc = nullptr)
+        : name(n), needsGpu(g), proc(p), fContextOptionsProc(optionsProc) {}
     const char* name;
     bool needsGpu;
     TestProc proc;
+    ContextOptionsProc fContextOptionsProc;
+
+    void modifyGrContextOptions(GrContextOptions* options) {
+        if (fContextOptionsProc) {
+            (*fContextOptionsProc)(options);
+        }
+    }
 
     void run(skiatest::Reporter* r, sk_gpu_test::GrContextFactory* factory) const {
         TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/);
@@ -200,31 +210,36 @@
             skiatest::Test(#name, true, test_##name));                                       \
     void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory* factory)
 
-#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info)            \
-    static void test_##name(skiatest::Reporter*,                                          \
-                            const sk_gpu_test::ContextInfo& context_info);                \
-    static void test_gpu_contexts_##name(skiatest::Reporter* reporter,                    \
-                                         sk_gpu_test::GrContextFactory* factory) {        \
-        skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory); \
-    }                                                                                     \
-    skiatest::TestRegistry name##TestRegistry(                                            \
-            skiatest::Test(#name, true, test_gpu_contexts_##name));                       \
-    void test_##name(skiatest::Reporter* reporter,                                        \
+#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter)  \
+    static void test_##name(skiatest::Reporter*,                                                \
+                            const sk_gpu_test::ContextInfo& context_info);                      \
+    static void test_gpu_contexts_##name(skiatest::Reporter* reporter,                          \
+                                         sk_gpu_test::GrContextFactory* factory) {              \
+        skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory);       \
+    }                                                                                           \
+    skiatest::TestRegistry name##TestRegistry(                                                  \
+            skiatest::Test(#name, true, test_gpu_contexts_##name, options_filter));             \
+    void test_##name(skiatest::Reporter* reporter,                                              \
                      const sk_gpu_test::ContextInfo& context_info)
 
 #define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info)                          \
-        DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info)
+        DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr)
+
 #define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info)                    \
         DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext,   \
-                                 reporter, context_info)
+                                 reporter, context_info, nullptr)
 #define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info)                       \
-        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, reporter, context_info)
+        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType,                          \
+                                 reporter, context_info, nullptr)
 #define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info)                 \
-        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, reporter, context_info)
+        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType,                 \
+                                 reporter, context_info, nullptr)
 #define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info)                        \
-        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, reporter, context_info)
+        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType,                      \
+                                 reporter, context_info, nullptr)
 #define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info)                        \
-        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, reporter, context_info)
+        DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType,                      \
+                                 reporter, context_info, nullptr)
 
 #define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER)                          \
     do {                                                                   \