API changes to GrTextureAdjuster.
authorbsalomon <bsalomon@google.com>
Thu, 12 Nov 2015 17:59:44 +0000 (09:59 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 12 Nov 2015 17:59:44 +0000 (09:59 -0800)
These changes are to facilitate converting SkGpuDevice::drawTextureAdjuster to SkGpuDevice::drawTextureProducer.

Make constraint rect relative to content area

Store dimensions in GrTextureProducer

Make originalTexture() protected.

Remove getContentArea()

Provide pre-normalized texture matrix to GrTextureAdjuster::createFragmentProcessor. Define it to be be relative to content area.

Review URL: https://codereview.chromium.org/1438663004

src/gpu/GrTextureParamsAdjuster.cpp
src/gpu/GrTextureParamsAdjuster.h
src/gpu/SkGpuDevice_drawTexture.cpp

index 37f1d81..0547d95 100644 (file)
@@ -120,7 +120,9 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset,
 }
 
 GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea)
-    : fOriginal(original) {
+    : INHERITED(contentArea.width(), contentArea.height())
+    , fOriginal(original) {
+    SkASSERT(SkIRect::MakeWH(original->width(), original->height()).contains(contentArea));
     if (contentArea.fLeft > 0 || contentArea.fTop > 0 ||
         contentArea.fRight < original->width() || contentArea.fBottom < original->height()) {
         fContentArea.set(contentArea);
@@ -323,18 +325,28 @@ static DomainMode determine_domain_mode(
 }
 
 const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor(
-                                        const SkMatrix& textureMatrix,
-                                        const SkRect& constraintRect,
+                                        const SkMatrix& origTextureMatrix,
+                                        const SkRect& origConstraintRect,
                                         FilterConstraint filterConstraint,
                                         bool coordsLimitedToConstraintRect,
                                         const GrTextureParams::FilterMode* filterOrNullForBicubic) {
 
+    SkMatrix textureMatrix = origTextureMatrix;
     const SkIRect* contentArea = this->contentAreaOrNull();
+    // Convert the constraintRect to be relative to the texture rather than the content area so
+    // that both rects are in the same coordinate system.
+    SkTCopyOnFirstWrite<SkRect> constraintRect(origConstraintRect);
+    if (contentArea) {
+        SkScalar l = SkIntToScalar(contentArea->fLeft);
+        SkScalar t = SkIntToScalar(contentArea->fTop);
+        constraintRect.writable()->offset(l, t);
+        textureMatrix.postTranslate(l, t);
+    }
 
     SkRect domain;
     GrTexture* texture = this->originalTexture();
     DomainMode domainMode =
-        determine_domain_mode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
+        determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect,
                               texture->width(), texture->height(),
                               contentArea, filterOrNullForBicubic,
                               &domain);
@@ -348,13 +360,14 @@ const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor(
                  GrTextureParams::kMipMap_FilterMode == *filterOrNullForBicubic);
         static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBilerp_FilterMode;
         domainMode =
-            determine_domain_mode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
+            determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect,
                                   texture->width(), texture->height(),
                                   contentArea, &kBilerp, &domain);
         SkASSERT(kTightCopy_DomainMode != domainMode);
     }
     SkASSERT(kNoDomain_DomainMode == domainMode ||
              (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom));
+    textureMatrix.postIDiv(texture->width(), texture->height());
     if (filterOrNullForBicubic) {
         if (kDomain_DomainMode == domainMode) {
             return GrTextureDomainEffect::Create(texture, textureMatrix, domain,
index 4e1f5a7..0a3d529 100644 (file)
@@ -11,6 +11,7 @@
 #include "GrTextureParams.h"
 #include "GrResourceKey.h"
 #include "GrTexture.h"
+#include "SkFunction.h"
 #include "SkTLazy.h"
 
 class GrContext;
@@ -36,7 +37,12 @@ public:
 
     virtual ~GrTextureProducer() {}
 
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+
 protected:
+    GrTextureProducer(int width, int height) : fWidth(width), fHeight(height) {}
+
     /** Helper for creating a key for a copy from an original key. */
     static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
                                        const CopyParams& copyParams,
@@ -66,6 +72,10 @@ protected:
     */
     virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
 
+private:
+    const int fWidth;
+    const int fHeight;
+
     typedef SkNoncopyable INHERITED;
 };
 
@@ -93,10 +103,12 @@ public:
      * It attempts to avoids making a copy of the texture and avoid using a texture domain unless
      * necessary.
      *
-     * @param textureMatrix                    Matrix to transform local coords by to compute
-     *                                         texture coords.
-     * @param constraintRect                   Subrect of content area to be rendered. Must be
-     *                                         clipped to the content area already.
+     * @param textureMatrix                    Matrix to apply to local coordinates to compute
+     *                                         texel coordinates. The post-transformed coordinates
+     *                                         should be in texels (relative to this->width() and
+     *                                         this->height()) and not be normalized. 
+     * @param constraintRect                   Subrect of content area to be rendered. The
+     *                                         constraint rect is relative to the content area.
      * @param filterConstriant                 Indicates whether filtering is limited to
      *                                         constraintRect.
      * @param coordsLimitedToConstraintRect    Is it known that textureMatrix*localCoords is bound
@@ -113,22 +125,16 @@ public:
         bool coordsLimitedToConstraintRect,
         const GrTextureParams::FilterMode* filterOrNullForBicubic);
 
-    GrTexture* originalTexture() const { return fOriginal; }
-
-    void getContentArea(SkIRect* contentArea) const {
-        if (fContentArea.isValid()) {
-            *contentArea = *fContentArea.get();
-        } else {
-            *contentArea = SkIRect::MakeWH(fOriginal->width(), fOriginal->height());
-        }
-    }
-
 protected:
     /** The whole texture is content. */
-    explicit GrTextureAdjuster(GrTexture* original): fOriginal(original) {}
+    explicit GrTextureAdjuster(GrTexture* original)
+        : INHERITED(original->width(), original->height())
+        , fOriginal(original) {}
 
     GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea);
 
+    GrTexture* originalTexture() const { return fOriginal; }
+
     /** Returns the content area or null for the whole original texture */
     const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); }
 
@@ -145,18 +151,14 @@ private:
  */
 class GrTextureMaker : public GrTextureProducer {
 public:
-
-    GrTextureMaker(int width, int height) : fWidth(width), fHeight(height) {}
-
-    int width() const { return fWidth; }
-    int height() const { return fHeight; }
-
     /** Returns a texture that is safe for use with the params. If the size of the returned texture
         does not match width()/height() then the contents of the original must be scaled to fit
         the texture. */
     GrTexture* refTextureForParams(GrContext*, const GrTextureParams&);
 
 protected:
+    GrTextureMaker(int width, int height) : INHERITED(width, height) {}
+
     /**
      *  Return the maker's "original" texture. It is the responsibility of the maker
      *  to make this efficient ... if the texture is being generated, the maker must handle
@@ -185,9 +187,6 @@ protected:
     virtual GrTexture* generateTextureForParams(GrContext*, const CopyParams&);
 
 private:
-    const int fWidth;
-    const int fHeight;
-
     typedef GrTextureProducer INHERITED;
 };
 
index 6a8f173..b41d69c 100644 (file)
@@ -65,17 +65,15 @@ void SkGpuDevice::drawTextureAdjuster(GrTextureAdjuster* adjuster,
     // the matrix that maps the src rect to the dst rect.
     SkRect clippedSrcRect;
     SkRect clippedDstRect;
-    SkIRect contentIBounds;
-    adjuster->getContentArea(&contentIBounds);
-    const SkRect contentBounds = SkRect::Make(contentIBounds);
+    const SkRect srcBounds = SkRect::MakeIWH(adjuster->width(), adjuster->height());
     SkMatrix srcToDstMatrix;
     if (srcRect) {
         if (!dstRect) {
-            dstRect = &contentBounds;
+            dstRect = &srcBounds;
         }
-        if (!contentBounds.contains(*srcRect)) {
+        if (!srcBounds.contains(*srcRect)) {
             clippedSrcRect = *srcRect;
-            if (!clippedSrcRect.intersect(contentBounds)) {
+            if (!clippedSrcRect.intersect(srcBounds)) {
                 return;
             }
             if (!srcToDstMatrix.setRectToRect(*srcRect, *dstRect, SkMatrix::kFill_ScaleToFit)) {
@@ -90,15 +88,14 @@ void SkGpuDevice::drawTextureAdjuster(GrTextureAdjuster* adjuster,
             }
         }
     } else {
-        clippedSrcRect = contentBounds;
+        clippedSrcRect = srcBounds;
         if (dstRect) {
             clippedDstRect = *dstRect;
-            if (!srcToDstMatrix.setRectToRect(contentBounds, *dstRect,
-                                              SkMatrix::kFill_ScaleToFit)) {
+            if (!srcToDstMatrix.setRectToRect(srcBounds, *dstRect, SkMatrix::kFill_ScaleToFit)) {
                 return;
             }
         } else {
-            clippedDstRect = contentBounds;
+            clippedDstRect = srcBounds;
             srcToDstMatrix.reset();
         }
     }
@@ -120,21 +117,11 @@ void SkGpuDevice::drawTextureAdjusterImpl(GrTextureAdjuster* adjuster,
     // by not baking anything about the srcRect, dstRect, or viewMatrix, into the texture FP. In
     // the future this should be an opaque optimization enabled by the combination of batch/GP and
     // FP.
-    SkMatrix textureFPMatrix;
     const SkMaskFilter* mf = paint.getMaskFilter();
-    GrTexture* texture = adjuster->originalTexture();
     // The shader expects proper local coords, so we can't replace local coords with texture coords
     // if the shader will be used. If we have a mask filter we will change the underlying geometry
     // that is rendered.
     bool canUseTextureCoordsAsLocalCoords = !use_shader(alphaTexture, paint) && !mf;
-    if (canUseTextureCoordsAsLocalCoords) {
-        textureFPMatrix.setIDiv(texture->width(), texture->height());
-    } else {
-        if (!srcToDstMatrix.invert(&textureFPMatrix)) {
-            return;
-        }
-        textureFPMatrix.postIDiv(texture->width(), texture->height());
-    }
 
     bool doBicubic;
     GrTextureParams::FilterMode fm =
@@ -154,8 +141,18 @@ void SkGpuDevice::drawTextureAdjusterImpl(GrTextureAdjuster* adjuster,
     // This is conservative as a mask filter does not have to expand the bounds rendered.
     bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf;
 
+    const SkMatrix* textureMatrix;
+    SkMatrix tempMatrix;
+    if (canUseTextureCoordsAsLocalCoords) {
+        textureMatrix = &SkMatrix::I();
+    } else {
+        if (!srcToDstMatrix.invert(&tempMatrix)) {
+            return;
+        }
+        textureMatrix = &tempMatrix;
+    }
     SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor(
-        textureFPMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect, filterMode));
+        *textureMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect, filterMode));
     if (!fp) {
         return;
     }