Clarify subrect semantics for GrTextureAdjuster and handle mip maps correctly.

Review URL: https://codereview.chromium.org/1410383008
diff --git a/src/gpu/GrTextureParamsAdjuster.cpp b/src/gpu/GrTextureParamsAdjuster.cpp
index b1faf14..26fb8a6 100644
--- a/src/gpu/GrTextureParamsAdjuster.cpp
+++ b/src/gpu/GrTextureParamsAdjuster.cpp
@@ -118,11 +118,11 @@
     return copy.detach();
 }
 
-GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, const SkIRect& subset)
+GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea)
     : fOriginal(original) {
-    if (subset.fLeft > 0 || subset.fTop > 0 ||
-        subset.fRight < original->width() || subset.fBottom < original->height()) {
-        fSubset.set(subset);
+    if (contentArea.fLeft > 0 || contentArea.fTop > 0 ||
+        contentArea.fRight < original->width() || contentArea.fBottom < original->height()) {
+        fContentArea.set(contentArea);
     }
 }
 
@@ -131,13 +131,19 @@
     GrTexture* texture = this->originalTexture();
     GrContext* context = texture->getContext();
     CopyParams copyParams;
-    const SkIRect* subset = this->subset();
+    const SkIRect* contentArea = this->contentArea();
 
-    if (!context->getGpu()->makeCopyForTextureParams(texture->width(), texture->height(), params,
-                                                     &copyParams)) {
+    if (contentArea && GrTextureParams::kMipMap_FilterMode == params.filterMode()) {
+        // If we generate a MIP chain for texture it will read pixel values from outside the content
+        // area.
+        copyParams.fWidth = contentArea->width();
+        copyParams.fHeight = contentArea->height();
+        copyParams.fFilter = GrTextureParams::kBilerp_FilterMode;
+    } else if (!context->getGpu()->makeCopyForTextureParams(texture->width(), texture->height(),
+                                                            params, &copyParams)) {
         if (outOffset) {
-            if (subset) {
-                outOffset->set(subset->fLeft, subset->fRight);
+            if (contentArea) {
+                outOffset->set(contentArea->fLeft, contentArea->fRight);
             } else {
                 outOffset->set(0, 0);
             }
@@ -152,7 +158,7 @@
             return result;
         }
     }
-    GrTexture* result = copy_on_gpu(texture, subset, copyParams);
+    GrTexture* result = copy_on_gpu(texture, contentArea, copyParams);
     if (result) {
         if (key.isValid()) {
             result->resourcePriv().setUniqueKey(key);
diff --git a/src/gpu/GrTextureParamsAdjuster.h b/src/gpu/GrTextureParamsAdjuster.h
index c9b90a5..f8fdc2d 100644
--- a/src/gpu/GrTextureParamsAdjuster.h
+++ b/src/gpu/GrTextureParamsAdjuster.h
@@ -69,7 +69,12 @@
     typedef SkNoncopyable INHERITED;
 };
 
-/** Base class for sources that start out as textures */
+/**
+ * Base class for sources that start out as textures. Optionally allows for a content area subrect.
+ * The intent is not to use content area for subrect rendering. Rather, the pixels outside the
+ * content area have undefined values and shouldn't be read *regardless* of filtering mode or
+ * the SkCanvas::SrcRectConstraint used for subrect draws.
+ */
 class GrTextureAdjuster : public GrTextureProducer {
 public:
     /** Makes the subset of the texture safe to use with the given texture parameters.
@@ -79,20 +84,18 @@
     GrTexture* refTextureSafeForParams(const GrTextureParams&, SkIPoint* outOffset);
 
 protected:
-    /** No subset, use the whole texture */
+    /** The whole texture is content. */
     explicit GrTextureAdjuster(GrTexture* original): fOriginal(original) {}
 
-    GrTextureAdjuster(GrTexture* original, const SkIRect& subset);
+    GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea);
 
     GrTexture* originalTexture() { return fOriginal; }
 
-    /** Returns the subset or null for the whole original texture */
-    const SkIRect* subset() { return fSubset.getMaybeNull(); }
+    /** Returns the content area or null for the whole original texture */
+    const SkIRect* contentArea() { return fContentArea.getMaybeNull(); }
 
 private:
-    GrTexture* internalRefTextureSafeForParams(GrTexture*, const SkIRect* subset,
-                                               const GrTextureParams&, SkIPoint* outOffset);
-    SkTLazy<SkIRect>    fSubset;
+    SkTLazy<SkIRect>    fContentArea;
     GrTexture*          fOriginal;
 
     typedef GrTextureProducer INHERITED;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 4685c76..469ef5b 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -346,9 +346,10 @@
         if (fBmp->isVolatile()) {
             return;
         }
-        // The texture subset must represent the whole bitmap. Texture-backed bitmaps don't support
-        // extractSubset(). Therefore, either the bitmap and the teture are the same size or the
-        // subset's dimensions are the bitmap's dimensions.
+        // The content area must represent the whole bitmap. Texture-backed bitmaps don't support
+        // extractSubset(). Therefore, either the bitmap and the texture are the same size or the
+        // content's dimensions are the bitmap's dimensions which is pinned to the upper left
+        // of the texture.
         GrUniqueKey baseKey;
         GrMakeKeyFromImageID(&baseKey, fBmp->getGenerationID(),
                              SkIRect::MakeWH(fBmp->width(), fBmp->height()));