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,
- ©Params)) {
+ 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, ©Params)) {
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()));