Remove option to make GrCoordTransforms apply to device positions.
authorBrian Salomon <bsalomon@google.com>
Mon, 3 Oct 2016 21:15:28 +0000 (17:15 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 3 Oct 2016 21:39:33 +0000 (21:39 +0000)
Adds a device space texture decal effect to use for clipping.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2870

Change-Id: Ifcc7617ea87f5a86e301995cba9dfc30a4b0e2c5
Reviewed-on: https://skia-review.googlesource.com/2870
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
25 files changed:
experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp
gm/dcshader.cpp [deleted file]
gm/windowrectangles.cpp
include/gpu/GrCoordTransform.h
src/effects/GrAlphaThresholdFragmentProcessor.cpp
src/effects/SkDisplacementMapEffect.cpp
src/effects/SkPerlinNoiseShader.cpp
src/effects/gradients/SkGradientShader.cpp
src/effects/gradients/SkGradientShaderPriv.h
src/gpu/GrBlurUtils.cpp
src/gpu/GrClipStackClip.cpp
src/gpu/GrCoordTransform.cpp
src/gpu/GrFragmentProcessor.cpp
src/gpu/GrPrimitiveProcessor.cpp
src/gpu/GrProcessor.cpp
src/gpu/GrSWMaskHelper.cpp
src/gpu/effects/GrSimpleTextureEffect.cpp
src/gpu/effects/GrSimpleTextureEffect.h
src/gpu/effects/GrSingleTextureEffect.cpp
src/gpu/effects/GrSingleTextureEffect.h
src/gpu/effects/GrTextureDomain.cpp
src/gpu/effects/GrTextureDomain.h
src/gpu/effects/GrYUVEffect.cpp
src/gpu/glsl/GrGLSLGeometryProcessor.cpp
src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp

index b863b2a..593fda1 100644 (file)
@@ -689,7 +689,7 @@ private:
         this->initClassID<GrPerlinNoise2Effect>();
         this->addTextureAccess(&fPermutationsAccess);
         this->addTextureAccess(&fNoiseAccess);
-        fCoordTransform.reset(kLocal_GrCoordSet, matrix);
+        fCoordTransform.reset(matrix);
         this->addCoordTransform(&fCoordTransform);
     }
 
@@ -1103,7 +1103,7 @@ private:
         this->initClassID<GrImprovedPerlinNoiseEffect>();
         this->addTextureAccess(&fPermutationsAccess);
         this->addTextureAccess(&fGradientAccess);
-        fCoordTransform.reset(kLocal_GrCoordSet, matrix);
+        fCoordTransform.reset(matrix);
         this->addCoordTransform(&fCoordTransform);
     }
 
diff --git a/gm/dcshader.cpp b/gm/dcshader.cpp
deleted file mode 100644 (file)
index 6f273c0..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "gm.h"
-#if SK_SUPPORT_GPU
-#include "GrFragmentProcessor.h"
-#include "GrCoordTransform.h"
-#include "GrInvariantOutput.h"
-#include "effects/GrXfermodeFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-#include "glsl/GrGLSLProgramBuilder.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-#include "Resources.h"
-#include "SkReadBuffer.h"
-#include "SkShader.h"
-#include "SkStream.h"
-#include "SkTypeface.h"
-#include "SkWriteBuffer.h"
-
-namespace skiagm {
-
-///////////////////////////////////////////////////////////////////////////////
-
-class DCShader : public SkShader {
-public:
-    DCShader(const SkMatrix& matrix) : fDeviceMatrix(matrix) {}
-
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DCShader)
-
-    void flatten(SkWriteBuffer& buf) const override {
-        buf.writeMatrix(fDeviceMatrix);
-    }
-
-    sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-
-#ifndef SK_IGNORE_TO_STRING
-    void toString(SkString* str) const override {
-        str->appendf("DCShader: ()");
-    }
-#endif
-
-private:
-    const SkMatrix fDeviceMatrix;
-};
-
-sk_sp<SkFlattenable> DCShader::CreateProc(SkReadBuffer& buf) {
-    SkMatrix matrix;
-    buf.readMatrix(&matrix);
-    return sk_make_sp<DCShader>(matrix);
-}
-
-class DCFP : public GrFragmentProcessor {
-public:
-    DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) {
-        this->addCoordTransform(&fDeviceTransform);
-        this->initClassID<DCFP>();
-    }
-
-    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
-        class DCGLFP : public GrGLSLFragmentProcessor {
-            void emitCode(EmitArgs& args) override {
-                GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
-                SkString coords2d = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
-                fragBuilder->codeAppendf("vec2 c = %s;", coords2d.c_str());
-                fragBuilder->codeAppend("vec2 r = mod(c, vec2(20.0));");
-                fragBuilder->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5,"
-                                                      "0.5*cos((c.x + c.y) / 15.0) + 0.5,"
-                                                      "(r.x + r.y) / 20.0,"
-                                                      "distance(r, vec2(15.0)) / 20.0 + 0.2);");
-                fragBuilder->codeAppendf("color.rgb *= color.a;"
-                                         "%s = color * %s;",
-                                         args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
-            }
-            void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {}
-        };
-        return new DCGLFP;
-    }
-
-    const char* name() const override { return "DCFP"; }
-
-    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
-        inout->mulByUnknownFourComponents();
-    }
-
-private:
-    void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
-                               GrProcessorKeyBuilder* b) const override {}
-
-    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
-
-    GrCoordTransform fDeviceTransform;
-};
-
-sk_sp<GrFragmentProcessor> DCShader::asFragmentProcessor(const AsFPArgs&) const {
-    sk_sp<GrFragmentProcessor> inner(new DCFP(fDeviceMatrix));
-    return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
-}
-
-class DCShaderGM : public GM {
-public:
-    DCShaderGM() {
-        this->setBGColor(sk_tool_utils::color_to_565(0xFFAABBCC));
-    }
-
-    ~DCShaderGM() override {
-        for (int i = 0; i < fPrims.count(); ++i) {
-            delete fPrims[i];
-        }
-    }
-
-protected:
-
-    SkString onShortName() override {
-        return SkString("dcshader");
-    }
-
-    SkISize onISize() override { return SkISize::Make(1000, 900); }
-
-    void onOnceBeforeDraw() override {
-        struct Rect : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                SkRect rect = SkRect::MakeXYWH(0, 0, 50, 50);
-                canvas->drawRect(rect, paint);
-                return rect;
-            }
-        };
-
-        struct Circle : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                constexpr SkScalar radius = 25;
-                canvas->drawCircle(radius, radius, radius, paint);
-                return SkRect::MakeXYWH(0, 0, 2 * radius, 2 * radius);
-            }
-        };
-
-        struct RRect : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                SkRRect rrect;
-                rrect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 10, 10);
-                canvas->drawRRect(rrect, paint);
-                return rrect.getBounds();
-            }
-        };
-
-        struct DRRect : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                SkRRect outerRRect;
-                outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5);
-                SkRRect innerRRect;
-                innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3);
-                canvas->drawDRRect(outerRRect, innerRRect, paint);
-                return outerRRect.getBounds();
-            }
-        };
-        struct Path : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                SkPath path;
-                path.addCircle(15, 15, 10);
-                path.addOval(SkRect::MakeXYWH(2, 2, 22, 37));
-                path.setFillType(SkPath::kEvenOdd_FillType);
-                canvas->drawPath(path, paint);
-                return path.getBounds();
-            }
-        };
-
-        struct Points : public Prim {
-            Points(SkCanvas::PointMode mode) : fMode(mode) {}
-
-            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
-                SkRandom random;
-                SkPoint points[500];
-                SkRect bounds = SkRect::MakeWH(50, 50);
-                int count = SkToInt(SK_ARRAY_COUNT(points));
-                if (SkCanvas::kPoints_PointMode != fMode) {
-                    count = SkTMin(count, 10);
-                }
-                for (int p = 0; p < count; ++p) {
-                    points[p].fX = random.nextUScalar1() * bounds.width();
-                    points[p].fY = random.nextUScalar1() * bounds.width();
-                }
-                canvas->drawPoints(fMode, count, points, paint);
-                return bounds;
-            }
-            SkCanvas::PointMode fMode;
-        };
-
-        struct Text : public Prim {
-            SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) override {
-                SkPaint paint = origPaint;
-                paint.setTextSize(30.f);
-                this->setFont(&paint);
-                const char* text = this->text();
-                const SkVector offset = SkVector::Make(10, 10);
-                canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint);
-                SkRect bounds;
-                paint.measureText(text, strlen(text), &bounds);
-                bounds.offset(offset);
-                return bounds;
-            }
-
-            virtual void setFont(SkPaint* paint) {
-                sk_tool_utils::set_portable_typeface(paint);
-            }
-
-            virtual const char* text() const { return "Hello, Skia!"; }
-        };
-
-        fPrims.push_back(new Rect);
-        fPrims.push_back(new Circle);
-        fPrims.push_back(new RRect);
-        fPrims.push_back(new DRRect);
-        fPrims.push_back(new Path);
-        fPrims.push_back(new Points(SkCanvas::kPoints_PointMode));
-        fPrims.push_back(new Points(SkCanvas::kLines_PointMode));
-        fPrims.push_back(new Points(SkCanvas::kPolygon_PointMode));
-        fPrims.push_back(new Text);
-    }
-
-    void onDraw(SkCanvas* canvas) override {
-        // This GM exists to test a specific feature of the GPU backend. It does not work with the
-        // sw rasterizer, tile modes, etc.
-        if (nullptr == canvas->getGrContext()) {
-            skiagm::GM::DrawGpuOnlyMessage(canvas);
-            return;
-        }
-        SkPaint paint;
-        SkTArray<SkMatrix> devMats;
-        devMats.push_back().reset();
-        devMats.push_back().setRotate(45, 500, 500);
-        devMats.push_back().setRotate(-30, 200, 200);
-        devMats.back().setPerspX(-SK_Scalar1 / 2000);
-        devMats.back().setPerspY(SK_Scalar1 / 1000);
-
-
-        SkTArray<SkMatrix> viewMats;
-        viewMats.push_back().setScale(0.75f, 0.75f);
-        viewMats.push_back().setRotate(45, 50, 50);
-        viewMats.back().postScale(0.5f, 1.1f);
-
-        canvas->translate(10, 20);
-        canvas->save();
-        SkScalar tx = 0, maxTy = 0;
-        constexpr SkScalar kW = 900;
-
-        for (int aa = 0; aa < 2; ++aa) {
-            for (int i = 0; i < fPrims.count(); ++i) {
-                for (int j = 0; j < devMats.count(); ++j) {
-                    for (int k = 0; k < viewMats.count(); ++k) {
-                        paint.setShader(sk_make_sp<DCShader>(devMats[j]));
-                        paint.setAntiAlias(SkToBool(aa));
-                        canvas->save();
-                        canvas->concat(viewMats[k]);
-                        SkRect bounds = fPrims[i]->draw(canvas, paint);
-                        canvas->restore();
-                        viewMats[k].mapRect(&bounds);
-                        // add margins
-                        bounds.fRight += 20;
-                        bounds.fBottom += 20;
-                        canvas->translate(bounds.fRight, 0);
-                        tx += bounds.fRight;
-                        maxTy = SkTMax(bounds.fBottom, maxTy);
-                        if (tx > kW) {
-                            tx = 0;
-                            canvas->restore();
-                            canvas->translate(0, maxTy);
-                            canvas->save();
-                            maxTy = 0;
-                        }
-                    }
-                }
-            }
-        }
-        canvas->restore();
-    }
-
-private:
-    struct Prim {
-        virtual ~Prim() {}
-        virtual SkRect draw(SkCanvas*, const SkPaint&) = 0;
-    };
-
-    SkTArray<Prim*> fPrims;
-
-    typedef GM INHERITED;
-};
-
-DEF_GM(return new DCShaderGM;)
-}
-#endif
index 3928763..5266df2 100644 (file)
@@ -155,14 +155,7 @@ class AlphaOnlyClip final : public MaskOnlyClipBase {
 public:
     AlphaOnlyClip(GrTexture* mask, int x, int y) {
         int w = mask->width(), h = mask->height();
-        SkMatrix mat = SkMatrix::MakeScale(1.f / SkIntToScalar(w), 1.f / SkIntToScalar(h));
-        mat.preTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
-        fFP = GrTextureDomainEffect::Make(
-                  mask, nullptr, mat,
-                  GrTextureDomain::MakeTexelDomain(mask, SkIRect::MakeWH(w, h)),
-                  GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode,
-                  kDevice_GrCoordSet);
-
+        fFP = GrDeviceSpaceTextureDecalFragmentProcessor::Make(mask, SkIRect::MakeWH(w, h), {x, y});
     }
 private:
     bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip* out) const override {
index 4d96cd9..3080523 100644 (file)
 #include "GrShaderVar.h"
 
 /**
- * Coordinates available to GrProcessor subclasses for requesting transformations. Transformed
- * coordinates are made available in the the portion of fragment shader emitted by the effect.
- *
- * The precision of the shader var that interpolates the transformed coordinates can be specified.
- */
-enum GrCoordSet {
-    /**
-     * The user-space coordinates that map to the fragment being rendered. This is the space in
-     * which SkShader operates. It is usually the space in which geometry passed to SkCanvas is
-     * specified (before the view matrix is applied). However, some draw calls take explicit local
-     * coords that map onto the geometry (e.g. drawVertices, drawBitmapRectToRect).
-     */
-    kLocal_GrCoordSet,
-
-    /**
-     * The device space position of the fragment being shaded.
-     */
-    kDevice_GrCoordSet,
-};
-
-/**
- * A class representing a linear transformation from one of the built-in coordinate sets (local or
- * position). GrProcessors just define these transformations, and the framework does the rest of the
- * work to make the transformed coordinates available in their fragment shader.
+ * A class representing a linear transformation of local coordinates. GrFragnentProcessors
+ * these transformations, and the GrGeometryProcessor implements the transformation.
  */
 class GrCoordTransform : SkNoncopyable {
 public:
-    GrCoordTransform() : fSourceCoords(kLocal_GrCoordSet) { SkDEBUGCODE(fInProcessor = false); }
+    GrCoordTransform() { SkDEBUGCODE(fInProcessor = false); }
 
     /**
      * Create a transformation that maps [0, 1] to a texture's boundaries. The precision is inferred
      * from the texture size and filter. The texture origin also implies whether a y-reversal should
      * be performed.
      */
-    GrCoordTransform(GrCoordSet sourceCoords,
-                     const GrTexture* texture,
-                     GrTextureParams::FilterMode filter) {
+    GrCoordTransform(const GrTexture* texture, GrTextureParams::FilterMode filter) {
         SkASSERT(texture);
         SkDEBUGCODE(fInProcessor = false);
-        this->reset(sourceCoords, texture, filter);
+        this->reset(texture, filter);
     }
 
     /**
      * Create a transformation from a matrix. The precision is inferred from the texture size and
      * filter. The texture origin also implies whether a y-reversal should be performed.
      */
-    GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m,
-                     const GrTexture* texture, GrTextureParams::FilterMode filter) {
+    GrCoordTransform(const SkMatrix& m, const GrTexture* texture,
+                     GrTextureParams::FilterMode filter) {
         SkDEBUGCODE(fInProcessor = false);
         SkASSERT(texture);
-        this->reset(sourceCoords, m, texture, filter);
+        this->reset(m, texture, filter);
     }
 
     /**
      * Create a transformation that applies the matrix to a coord set.
      */
-    GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m,
-                     GrSLPrecision precision = kDefault_GrSLPrecision) {
+    GrCoordTransform(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
         SkDEBUGCODE(fInProcessor = false);
-        this->reset(sourceCoords, m, precision);
+        this->reset(m, precision);
     }
 
-    void reset(GrCoordSet sourceCoords, const GrTexture* texture,
-               GrTextureParams::FilterMode filter) {
+    void reset(const GrTexture* texture, GrTextureParams::FilterMode filter) {
         SkASSERT(!fInProcessor);
         SkASSERT(texture);
-        this->reset(sourceCoords, MakeDivByTextureWHMatrix(texture), texture, filter);
+        this->reset(MakeDivByTextureWHMatrix(texture), texture, filter);
     }
 
-    void reset(GrCoordSet, const SkMatrix&, const GrTexture*, GrTextureParams::FilterMode filter);
-    void reset(GrCoordSet sourceCoords, const SkMatrix& m,
-               GrSLPrecision precision = kDefault_GrSLPrecision);
+    void reset(const SkMatrix&, const GrTexture*, GrTextureParams::FilterMode filter);
+    void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision);
 
     GrCoordTransform& operator= (const GrCoordTransform& that) {
         SkASSERT(!fInProcessor);
-        fSourceCoords = that.fSourceCoords;
         fMatrix = that.fMatrix;
         fReverseY = that.fReverseY;
         fPrecision = that.fPrecision;
@@ -107,15 +79,13 @@ public:
     }
 
     bool operator==(const GrCoordTransform& that) const {
-        return fSourceCoords == that.fSourceCoords &&
-               fMatrix.cheapEqualTo(that.fMatrix) &&
+        return fMatrix.cheapEqualTo(that.fMatrix) &&
                fReverseY == that.fReverseY &&
                fPrecision == that.fPrecision;
     }
 
     bool operator!=(const GrCoordTransform& that) const { return !(*this == that); }
 
-    GrCoordSet sourceCoords() const { return fSourceCoords; }
     const SkMatrix& getMatrix() const { return fMatrix; }
     bool reverseY() const { return fReverseY; }
     GrSLPrecision precision() const { return fPrecision; }
@@ -130,7 +100,6 @@ public:
     }
 
 private:
-    GrCoordSet              fSourceCoords;
     SkMatrix                fMatrix;
     bool                    fReverseY;
     GrSLPrecision           fPrecision;
index 99f0a19..442acd0 100644 (file)
@@ -47,13 +47,11 @@ GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
                                                            const SkIRect& bounds)
     : fInnerThreshold(innerThreshold)
     , fOuterThreshold(outerThreshold)
-    , fImageCoordTransform(kLocal_GrCoordSet,
-                           GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture,
+    , fImageCoordTransform(GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture,
                            GrTextureParams::kNone_FilterMode)
     , fImageTextureAccess(texture)
     , fColorSpaceXform(std::move(colorSpaceXform))
-    , fMaskCoordTransform(kLocal_GrCoordSet,
-                          make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()),
+    , fMaskCoordTransform(make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()),
                           maskTexture,
                           GrTextureParams::kNone_FilterMode)
     , fMaskTextureAccess(maskTexture) {
index 4f6386d..283372f 100644 (file)
@@ -480,10 +480,9 @@ GrDisplacementMapEffect::GrDisplacementMapEffect(
                              const SkMatrix& offsetMatrix,
                              GrTexture* color,
                              const SkISize& colorDimensions)
-    : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement,
-                             GrTextureParams::kNone_FilterMode)
+    : fDisplacementTransform(offsetMatrix, displacement, GrTextureParams::kNone_FilterMode)
     , fDisplacementAccess(displacement)
-    , fColorTransform(kLocal_GrCoordSet, color, GrTextureParams::kNone_FilterMode)
+    , fColorTransform(color, GrTextureParams::kNone_FilterMode)
     , fDomain(GrTextureDomain::MakeTexelDomain(color, SkIRect::MakeSize(colorDimensions)),
               GrTextureDomain::kDecal_Mode)
     , fColorAccess(color)
index a174bca..caff495 100644 (file)
@@ -554,7 +554,7 @@ private:
         this->initClassID<GrPerlinNoiseEffect>();
         this->addTextureAccess(&fPermutationsAccess);
         this->addTextureAccess(&fNoiseAccess);
-        fCoordTransform.reset(kLocal_GrCoordSet, matrix);
+        fCoordTransform.reset(matrix);
         this->addCoordTransform(&fCoordTransform);
     }
 
index df23039..4ee8203 100644 (file)
@@ -1605,7 +1605,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
                 fPremulType = kAfterInterp_PremulType;
             }
 
-            fCoordTransform.reset(kCoordSet, *args.fMatrix);
+            fCoordTransform.reset(*args.fMatrix);
 
             break;
         case kTexture_ColorType:
@@ -1648,8 +1648,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
             fRow = fAtlas->lockRow(bitmap);
             if (-1 != fRow) {
                 fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
-                fCoordTransform.reset(kCoordSet, *args.fMatrix, fAtlas->getTexture(),
-                                      params.filterMode());
+                fCoordTransform.reset(*args.fMatrix, fAtlas->getTexture(), params.filterMode());
                 fTextureAccess.reset(fAtlas->getTexture(), params);
             } else {
                 SkAutoTUnref<GrTexture> texture(
@@ -1658,7 +1657,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
                 if (!texture) {
                     return;
                 }
-                fCoordTransform.reset(kCoordSet, *args.fMatrix, texture, params.filterMode());
+                fCoordTransform.reset(*args.fMatrix, texture, params.filterMode());
                 fTextureAccess.reset(texture, params);
                 fYCoord = SK_ScalarHalf;
             }
index df7ac78..f850994 100644 (file)
@@ -409,8 +409,6 @@ protected:
     const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
 
 private:
-    static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
-
     // If we're in legacy mode, then fColors will be populated. If we're gamma-correct, then
     // fColors4f and fColorSpaceXform will be populated.
     SkTDArray<SkColor>       fColors;
index 383652d..5f575e3 100644 (file)
@@ -36,16 +36,15 @@ static bool draw_mask(GrDrawContext* drawContext,
     SkMatrix matrix;
     matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
     matrix.postIDiv(mask->width(), mask->height());
-
-    grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix,
-                                                                  kDevice_GrCoordSet));
+    matrix.preConcat(viewMatrix);
+    grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix));
 
     SkMatrix inverse;
     if (!viewMatrix.invert(&inverse)) {
         return false;
     }
-    drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(),
-                                         SkRect::Make(maskRect), inverse);
+    drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), SkRect::Make(maskRect),
+                                         inverse);
     return true;
 }
 
index d85db11..7694a3f 100644 (file)
@@ -79,26 +79,12 @@ void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devR
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// set up the draw state to enable the aa clipping mask. Besides setting up the
-// stage matrix this also alters the vertex layout
+// set up the draw state to enable the aa clipping mask.
 static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result,
                                                      const SkIRect &devBound) {
-    SkMatrix mat;
-    // We use device coords to compute the texture coordinates. We set our matrix to be a
-    // translation to the devBound, and then a scaling matrix to normalized coords.
-    mat.setIDiv(result->width(), result->height());
-    mat.preTranslate(SkIntToScalar(-devBound.fLeft),
-                     SkIntToScalar(-devBound.fTop));
-
     SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
-    return sk_sp<GrFragmentProcessor>(GrTextureDomainEffect::Make(
-                                         result,
-                                         nullptr,
-                                         mat,
-                                         GrTextureDomain::MakeTexelDomain(result, domainTexels),
-                                         GrTextureDomain::kDecal_Mode,
-                                         GrTextureParams::kNone_FilterMode,
-                                         kDevice_GrCoordSet));
+    return GrDeviceSpaceTextureDecalFragmentProcessor::Make(result, domainTexels,
+                                                            {devBound.fLeft, devBound.fTop});
 }
 
 // Does the path in 'element' require SW rendering? If so, return true (and,
index e7d9b1e..2da49c4 100644 (file)
 #include "GrContext.h"
 #include "GrGpu.h"
 
-void GrCoordTransform::reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture,
+void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
                              GrTextureParams::FilterMode filter) {
     SkASSERT(texture);
     SkASSERT(!fInProcessor);
 
-    fSourceCoords = sourceCoords;
     fMatrix = m;
     fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
 
@@ -53,11 +52,8 @@ void GrCoordTransform::reset(GrCoordSet sourceCoords, const SkMatrix& m, const G
     }
 }
 
-void GrCoordTransform::reset(GrCoordSet sourceCoords,
-                             const SkMatrix& m,
-                             GrSLPrecision precision) {
+void GrCoordTransform::reset(const SkMatrix& m, GrSLPrecision precision) {
     SkASSERT(!fInProcessor);
-    fSourceCoords = sourceCoords;
     fMatrix = m;
     fReverseY = false;
     fPrecision = precision;
index 7233658..123792d 100644 (file)
@@ -66,7 +66,7 @@ void GrFragmentProcessor::addBufferAccess(const GrBufferAccess* bufferAccess) {
 
 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
     fCoordTransforms.push_back(transform);
-    fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet;
+    fUsesLocalCoords = true;
     SkDEBUGCODE(transform->setInProcessor();)
 }
 
index 180217e..2aaaa04 100644 (file)
@@ -21,7 +21,6 @@ enum {
     kPrecisionShift      = kMatrixTypeKeyBits,
 
     kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)),
-    kDeviceCoords_Flag   = kPositionCoords_Flag + kPositionCoords_Flag,
 
     kTransformKeyBits    = kMatrixTypeKeyBits + kPrecisionBits + 2,
 };
@@ -49,11 +48,8 @@ GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, tr
             key |= kNoPersp_MatrixType;
         }
 
-        if (kLocal_GrCoordSet == coordTransform->sourceCoords() &&
-            !this->hasExplicitLocalCoords()) {
+        if (!this->hasExplicitLocalCoords()) {
             key |= kPositionCoords_Flag;
-        } else if (kDevice_GrCoordSet == coordTransform->sourceCoords()) {
-            key |= kDeviceCoords_Flag;
         }
 
         GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits));
index b945b02..5ca9935 100644 (file)
@@ -48,7 +48,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
  * we verify the count is as expected.  If a new factory is added, then these numbers must be
  * manually adjusted.
  */
-static const int kFPFactoryCount = 40;
+static const int kFPFactoryCount = 41;
 static const int kGPFactoryCount = 14;
 static const int kXPFactoryCount = 6;
 
index a20eacb..8bb3fed 100644 (file)
@@ -184,7 +184,7 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
     maskMatrix.setIDiv(texture->width(), texture->height());
     maskMatrix.preTranslate(SkIntToScalar(-textureOriginInDeviceSpace.fX),
                             SkIntToScalar(-textureOriginInDeviceSpace.fY));
-
+    maskMatrix.preConcat(viewMatrix);
     GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(paint));
     pipelineBuilder.setUserStencil(&userStencilSettings);
 
@@ -192,8 +192,7 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
                          GrSimpleTextureEffect::Make(texture,
                                                      nullptr,
                                                      maskMatrix,
-                                                     GrTextureParams::kNone_FilterMode,
-                                                     kDevice_GrCoordSet));
+                                                     GrTextureParams::kNone_FilterMode));
 
     SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(paint.getColor(),
                                                                         SkMatrix::I(),
index b05ac83..beb64d5 100644 (file)
@@ -84,13 +84,7 @@ sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData
     GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
                                                                GrTextureParams::kNone_FilterMode);
 
-    static const GrCoordSet kCoordSets[] = {
-        kLocal_GrCoordSet,
-        kDevice_GrCoordSet
-    };
-    GrCoordSet coordSet = kCoordSets[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kCoordSets))];
-
     const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
     auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
-    return GrSimpleTextureEffect::Make(d->fTextures[texIdx], colorSpaceXform, matrix, coordSet);
+    return GrSimpleTextureEffect::Make(d->fTextures[texIdx], colorSpaceXform, matrix);
 }
index 44e5c06..8242362 100644 (file)
@@ -14,40 +14,35 @@ class GrInvariantOutput;
 
 /**
  * The output color of this effect is a modulation of the input color and a sample from a texture.
- * It allows explicit specification of the filtering and wrap modes (GrTextureParams). It can use
- * local coords or device space coords as input texture coords. The input coords may be transformed
- * by a matrix.
+ * It allows explicit specification of the filtering and wrap modes (GrTextureParams) and accepts
+ * a matrix that is used to compute texture coordinates from local coordinates.
  */
 class GrSimpleTextureEffect : public GrSingleTextureEffect {
 public:
     /* unfiltered, clamp mode */
     static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
                                            sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                           const SkMatrix& matrix,
-                                           GrCoordSet coordSet = kLocal_GrCoordSet) {
+                                           const SkMatrix& matrix) {
         return sk_sp<GrFragmentProcessor>(
             new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix,
-                                      GrTextureParams::kNone_FilterMode, coordSet));
+                                      GrTextureParams::kNone_FilterMode));
     }
 
     /* clamp mode */
     static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
                                            sk_sp<GrColorSpaceXform> colorSpaceXform,
                                             const SkMatrix& matrix,
-                                            GrTextureParams::FilterMode filterMode,
-                                            GrCoordSet coordSet = kLocal_GrCoordSet) {
+                                            GrTextureParams::FilterMode filterMode) {
         return sk_sp<GrFragmentProcessor>(
-            new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode,
-                                      coordSet));
+            new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode));
     }
 
     static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
                                            sk_sp<GrColorSpaceXform> colorSpaceXform,
                                            const SkMatrix& matrix,
-                                           const GrTextureParams& p,
-                                           GrCoordSet coordSet = kLocal_GrCoordSet) {
+                                           const GrTextureParams& p) {
         return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform),
-                                                                    matrix, p, coordSet));
+                                                                    matrix, p));
     }
 
     virtual ~GrSimpleTextureEffect() {}
@@ -58,18 +53,16 @@ private:
     GrSimpleTextureEffect(GrTexture* texture,
                           sk_sp<GrColorSpaceXform> colorSpaceXform,
                           const SkMatrix& matrix,
-                          GrTextureParams::FilterMode filterMode,
-                          GrCoordSet coordSet)
-        : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode, coordSet) {
+                          GrTextureParams::FilterMode filterMode)
+        : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode) {
         this->initClassID<GrSimpleTextureEffect>();
     }
 
     GrSimpleTextureEffect(GrTexture* texture,
                           sk_sp<GrColorSpaceXform> colorSpaceXform,
                           const SkMatrix& matrix,
-                          const GrTextureParams& params,
-                          GrCoordSet coordSet)
-        : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params, coordSet) {
+                          const GrTextureParams& params)
+        : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params) {
         this->initClassID<GrSimpleTextureEffect>();
     }
 
index c84e95e..2683789 100644 (file)
@@ -9,9 +9,8 @@
 
 GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
                                              sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                             const SkMatrix& m,
-                                             GrCoordSet coordSet)
-    : fCoordTransform(coordSet, m, texture, GrTextureParams::kNone_FilterMode)
+                                             const SkMatrix& m)
+    : fCoordTransform(m, texture, GrTextureParams::kNone_FilterMode)
     , fTextureAccess(texture)
     , fColorSpaceXform(std::move(colorSpaceXform)) {
     this->addCoordTransform(&fCoordTransform);
@@ -21,9 +20,8 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
 GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
                                              sk_sp<GrColorSpaceXform> colorSpaceXform,
                                              const SkMatrix& m,
-                                             GrTextureParams::FilterMode filterMode,
-                                             GrCoordSet coordSet)
-    : fCoordTransform(coordSet, m, texture, filterMode)
+                                             GrTextureParams::FilterMode filterMode)
+    : fCoordTransform(m, texture, filterMode)
     , fTextureAccess(texture, filterMode)
     , fColorSpaceXform(std::move(colorSpaceXform)) {
     this->addCoordTransform(&fCoordTransform);
@@ -33,9 +31,8 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
 GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
                                              sk_sp<GrColorSpaceXform> colorSpaceXform,
                                              const SkMatrix& m,
-                                             const GrTextureParams& params,
-                                             GrCoordSet coordSet)
-    : fCoordTransform(coordSet, m, texture, params.filterMode())
+                                             const GrTextureParams& params)
+    : fCoordTransform(m, texture, params.filterMode())
     , fTextureAccess(texture, params)
     , fColorSpaceXform(std::move(colorSpaceXform)) {
     this->addCoordTransform(&fCoordTransform);
index a30cd03..7d110bf 100644 (file)
@@ -34,16 +34,14 @@ public:
 
 protected:
     /** unfiltered, clamp mode */
-    GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&,
-                          GrCoordSet = kLocal_GrCoordSet);
+    GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&);
     /** clamp mode */
     GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&,
-                          GrTextureParams::FilterMode filterMode, GrCoordSet = kLocal_GrCoordSet);
+                          GrTextureParams::FilterMode filterMode);
     GrSingleTextureEffect(GrTexture*,
                           sk_sp<GrColorSpaceXform>,
                           const SkMatrix&,
-                          const GrTextureParams&,
-                          GrCoordSet = kLocal_GrCoordSet);
+                          const GrTextureParams&);
 
     /**
      * Can be used as a helper to implement subclass onComputeInvariantOutput(). It assumes that
index e809109..55d69bf 100644 (file)
@@ -169,53 +169,6 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
     }
 }
 
-
-//////////////////////////////////////////////////////////////////////////////
-
-class GrGLTextureDomainEffect : public GrGLSLFragmentProcessor {
-public:
-    void emitCode(EmitArgs&) override;
-
-    static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
-
-protected:
-    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
-
-private:
-    GrTextureDomain::GLDomain         fGLDomain;
-    typedef GrGLSLFragmentProcessor INHERITED;
-};
-
-void GrGLTextureDomainEffect::emitCode(EmitArgs& args) {
-    const GrTextureDomainEffect& textureDomainEffect = args.fFp.cast<GrTextureDomainEffect>();
-    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
-
-    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-    SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
-    fGLDomain.sampleTexture(fragBuilder,
-                            args.fUniformHandler,
-                            args.fGLSLCaps,
-                            domain,
-                            args.fOutputColor,
-                            coords2D,
-                            args.fTexSamplers[0],
-                            args.fInputColor);
-}
-
-void GrGLTextureDomainEffect::onSetData(const GrGLSLProgramDataManager& pdman,
-                                        const GrProcessor& processor) {
-    const GrTextureDomainEffect& textureDomainEffect = processor.cast<GrTextureDomainEffect>();
-    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
-    fGLDomain.setData(pdman, domain, processor.texture(0)->origin());
-}
-
-void GrGLTextureDomainEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
-                                     GrProcessorKeyBuilder* b) {
-    const GrTextureDomain& domain = processor.cast<GrTextureDomainEffect>().textureDomain();
-    b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
-}
-
-
 ///////////////////////////////////////////////////////////////////////////////
 
 sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
@@ -223,8 +176,7 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
                                                        const SkMatrix& matrix,
                                                        const SkRect& domain,
                                                        GrTextureDomain::Mode mode,
-                                                       GrTextureParams::FilterMode filterMode,
-                                                       GrCoordSet coordSet) {
+                                                       GrTextureParams::FilterMode filterMode) {
     static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
     if (GrTextureDomain::kIgnore_Mode == mode ||
         (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) {
@@ -232,7 +184,7 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
     } else {
         return sk_sp<GrFragmentProcessor>(
             new GrTextureDomainEffect(texture, std::move(colorSpaceXform), matrix, domain, mode,
-                                      filterMode, coordSet));
+                                      filterMode));
     }
 }
 
@@ -241,33 +193,62 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
                                              const SkMatrix& matrix,
                                              const SkRect& domain,
                                              GrTextureDomain::Mode mode,
-                                             GrTextureParams::FilterMode filterMode,
-                                             GrCoordSet coordSet)
-    : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode, coordSet)
+                                             GrTextureParams::FilterMode filterMode)
+    : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode)
     , fTextureDomain(domain, mode) {
     SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
             filterMode == GrTextureParams::kNone_FilterMode);
     this->initClassID<GrTextureDomainEffect>();
 }
 
-GrTextureDomainEffect::~GrTextureDomainEffect() {}
-
 void GrTextureDomainEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
                                                   GrProcessorKeyBuilder* b) const {
-    GrGLTextureDomainEffect::GenKey(*this, caps, b);
+    b->add32(GrTextureDomain::GLDomain::DomainKey(fTextureDomain));
 }
 
 GrGLSLFragmentProcessor* GrTextureDomainEffect::onCreateGLSLInstance() const  {
-    return new GrGLTextureDomainEffect;
+    class GLSLProcessor : public GrGLSLFragmentProcessor {
+    public:
+        void emitCode(EmitArgs& args) override {
+            const GrTextureDomainEffect& tde = args.fFp.cast<GrTextureDomainEffect>();
+            const GrTextureDomain& domain = tde.fTextureDomain;
+
+            GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+            SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+            fGLDomain.sampleTexture(fragBuilder,
+                                    args.fUniformHandler,
+                                    args.fGLSLCaps,
+                                    domain,
+                                    args.fOutputColor,
+                                    coords2D,
+                                    args.fTexSamplers[0],
+                                    args.fInputColor);
+        }
+
+    protected:
+        void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& fp) override {
+            const GrTextureDomainEffect& tde = fp.cast<GrTextureDomainEffect>();
+            const GrTextureDomain& domain = tde.fTextureDomain;
+            fGLDomain.setData(pdman, domain, tde.texture(0)->origin());
+        }
+
+    private:
+        GrTextureDomain::GLDomain         fGLDomain;
+
+    };
+
+    return new GLSLProcessor;
 }
 
 bool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
     const GrTextureDomainEffect& s = sBase.cast<GrTextureDomainEffect>();
-    return this->fTextureDomain == s.fTextureDomain;
+    return this->fTextureDomain == s.fTextureDomain && s.texture(0) == this->texture(0) &&
+           s.textureAccess(0).getParams().filterMode() ==
+                this->textureAccess(0).getParams().filterMode();
 }
 
 void GrTextureDomainEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
+    if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) {
         if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
             inout->mulByUnknownSingleComponent();
         } else {
@@ -294,7 +275,6 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData
         (GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount);
     const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
     bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? d->fRandom->nextBool() : false;
-    GrCoordSet coords = d->fRandom->nextBool() ? kLocal_GrCoordSet : kDevice_GrCoordSet;
     auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
     return GrTextureDomainEffect::Make(
         d->fTextures[texIdx],
@@ -302,6 +282,112 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData
         matrix,
         domain,
         mode,
-        bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode,
-        coords);
+        bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(GrTexture* texture,
+        const SkIRect& subset, const SkIPoint& deviceSpaceOffset) {
+    return sk_sp<GrFragmentProcessor>(new GrDeviceSpaceTextureDecalFragmentProcessor(
+            texture, subset, deviceSpaceOffset));
+}
+
+GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
+        GrTexture* texture, const SkIRect& subset, const SkIPoint& deviceSpaceOffset)
+        : fTextureAccess(texture, GrTextureParams::ClampNoFilter())
+        , fTextureDomain(GrTextureDomain::MakeTexelDomain(texture, subset),
+                         GrTextureDomain::kDecal_Mode) {
+    this->addTextureAccess(&fTextureAccess);
+    fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
+    fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
+    this->initClassID<GrDeviceSpaceTextureDecalFragmentProcessor>();
+    this->setWillReadFragmentPosition();
+}
+
+GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const  {
+    class GLSLProcessor : public GrGLSLFragmentProcessor {
+    public:
+        void emitCode(EmitArgs& args) override {
+            const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
+                    args.fFp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
+            const char* scaleAndTranslateName;
+            fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                                     kVec4f_GrSLType,
+                                                                     kDefault_GrSLPrecision,
+                                                                     "scaleAndTranslate",
+                                                                     &scaleAndTranslateName);
+            args.fFragBuilder->codeAppendf("vec2 coords = %s.xy * %s.xy + %s.zw;",
+                                           args.fFragBuilder->fragmentPosition(),
+                                           scaleAndTranslateName, scaleAndTranslateName);
+            fGLDomain.sampleTexture(args.fFragBuilder,
+                                    args.fUniformHandler,
+                                    args.fGLSLCaps,
+                                    dstdfp.fTextureDomain,
+                                    args.fOutputColor,
+                                    SkString("coords"),
+                                    args.fTexSamplers[0],
+                                    args.fInputColor);
+        }
+
+    protected:
+        void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& fp) override {
+            const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
+                    fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
+            fGLDomain.setData(pdman, dstdfp.fTextureDomain, dstdfp.texture(0)->origin());
+            float iw = 1.f / dstdfp.texture(0)->width();
+            float ih = 1.f / dstdfp.texture(0)->height();
+            float scaleAndTransData[4] = {
+                iw, ih,
+                -dstdfp.fDeviceSpaceOffset.fX * iw, -dstdfp.fDeviceSpaceOffset.fY * ih
+            };
+            if (dstdfp.texture(0)->origin() == kBottomLeft_GrSurfaceOrigin) {
+                scaleAndTransData[1] = -scaleAndTransData[1];
+                scaleAndTransData[3] = 1 - scaleAndTransData[3];
+            }
+            pdman.set4fv(fScaleAndTranslateUni, 1, scaleAndTransData);
+        }
+
+    private:
+        GrTextureDomain::GLDomain   fGLDomain;
+        UniformHandle               fScaleAndTranslateUni;
+    };
+
+    return new GLSLProcessor;
+}
+
+bool GrDeviceSpaceTextureDecalFragmentProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
+    const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
+            fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
+    return dstdfp.fTextureAccess.getTexture() == fTextureAccess.getTexture() &&
+           dstdfp.fDeviceSpaceOffset == fDeviceSpaceOffset &&
+           dstdfp.fTextureDomain == fTextureDomain;
+}
+
+void GrDeviceSpaceTextureDecalFragmentProcessor::onComputeInvariantOutput(
+        GrInvariantOutput* inout) const {
+    if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
+        inout->mulByUnknownSingleComponent();
+    } else {
+        inout->mulByUnknownFourComponents();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceTextureDecalFragmentProcessor);
+
+sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::TestCreate(
+        GrProcessorTestData* d) {
+    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
+                                        : GrProcessorUnitTest::kAlphaTextureIdx;
+    SkIRect subset;
+    subset.fLeft = d->fRandom->nextULessThan(d->fTextures[texIdx]->width() - 1);
+    subset.fRight = d->fRandom->nextRangeU(subset.fLeft, d->fTextures[texIdx]->width());
+    subset.fTop = d->fRandom->nextULessThan(d->fTextures[texIdx]->height() - 1);
+    subset.fBottom = d->fRandom->nextRangeU(subset.fTop, d->fTextures[texIdx]->height());
+    SkIPoint pt;
+    pt.fX = d->fRandom->nextULessThan(2048);
+    pt.fY = d->fRandom->nextULessThan(2048);
+    return GrDeviceSpaceTextureDecalFragmentProcessor::Make(d->fTextures[texIdx], subset, pt);
 }
index 9edecac..82ff73c 100644 (file)
@@ -85,7 +85,7 @@ public:
         );
     }
 
-    bool operator== (const GrTextureDomain& that) const {
+    bool operator==(const GrTextureDomain& that) const {
         return fMode == that.fMode && (kIgnore_Mode == fMode || fDomain == that.fDomain);
     }
 
@@ -140,7 +140,7 @@ public:
          * computed key. The returned will be limited to the lower kDomainKeyBits bits.
          */
         static uint32_t DomainKey(const GrTextureDomain& domain) {
-            GR_STATIC_ASSERT(kModeCount <= 4);
+            GR_STATIC_ASSERT(kModeCount <= (1 << kDomainKeyBits));
             return domain.mode();
         }
 
@@ -171,35 +171,28 @@ public:
                                            const SkMatrix&,
                                            const SkRect& domain,
                                            GrTextureDomain::Mode,
-                                           GrTextureParams::FilterMode filterMode,
-                                           GrCoordSet = kLocal_GrCoordSet);
-
-    virtual ~GrTextureDomainEffect();
+                                           GrTextureParams::FilterMode filterMode);
 
     const char* name() const override { return "TextureDomain"; }
 
     SkString dumpInfo() const override {
         SkString str;
-        str.appendf("Domain: [L: %.2f, T: %.2f, R: %.2f, B: %.2f] ",
+        str.appendf("Domain: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]",
                     fTextureDomain.domain().fLeft, fTextureDomain.domain().fTop,
                     fTextureDomain.domain().fRight, fTextureDomain.domain().fBottom);
         str.append(INHERITED::dumpInfo());
         return str;
     }
 
-    const GrTextureDomain& textureDomain() const { return fTextureDomain; }
-
-protected:
+private:
     GrTextureDomain fTextureDomain;
 
-private:
     GrTextureDomainEffect(GrTexture*,
                           sk_sp<GrColorSpaceXform>,
                           const SkMatrix&,
                           const SkRect& domain,
                           GrTextureDomain::Mode,
-                          GrTextureParams::FilterMode,
-                          GrCoordSet);
+                          GrTextureParams::FilterMode);
 
     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
 
@@ -214,4 +207,40 @@ private:
     typedef GrSingleTextureEffect INHERITED;
 };
 
+class GrDeviceSpaceTextureDecalFragmentProcessor : public GrFragmentProcessor {
+public:
+    static sk_sp<GrFragmentProcessor> Make(GrTexture*, const SkIRect& subset,
+                                           const SkIPoint& deviceSpaceOffset);
+
+    const char* name() const override { return "GrDeviceSpaceTextureDecalFragmentProcessor"; }
+
+    SkString dumpInfo() const override {
+        SkString str;
+        str.appendf("Domain: [L: %.2f, T: %.2f, R: %.2f, B: %.2f] Offset: [%d %d]",
+                    fTextureDomain.domain().fLeft, fTextureDomain.domain().fTop,
+                    fTextureDomain.domain().fRight, fTextureDomain.domain().fBottom,
+                    fDeviceSpaceOffset.fX, fDeviceSpaceOffset.fY);
+        str.append(INHERITED::dumpInfo());
+        return str;
+    }
+
+private:
+    GrTextureAccess fTextureAccess;
+    GrTextureDomain fTextureDomain;
+    SkIPoint fDeviceSpaceOffset;
+
+    GrDeviceSpaceTextureDecalFragmentProcessor(GrTexture*, const SkIRect&, const SkIPoint&);
+
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+
+    // Since we always use decal mode, there is no need for key data.
+    void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {}
+
+    bool onIsEqual(const GrFragmentProcessor& fp) const override;
+    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
+
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
+
+    typedef GrFragmentProcessor INHERITED;
+};
 #endif
index 5b04f21..cbe25e8 100644 (file)
@@ -154,9 +154,9 @@ private:
     YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
                    const SkMatrix yuvMatrix[3], GrTextureParams::FilterMode uvFilterMode,
                    SkYUVColorSpace colorSpace, bool nv12)
-        : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode)
+        : fYTransform(yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode)
         , fYAccess(yTexture)
-        , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode)
+        , fUTransform(yuvMatrix[1], uTexture, uvFilterMode)
         , fUAccess(uTexture, uvFilterMode)
         , fVAccess(vTexture, uvFilterMode)
         , fColorSpace(colorSpace)
@@ -167,7 +167,7 @@ private:
         this->addCoordTransform(&fUTransform);
         this->addTextureAccess(&fUAccess);
         if (!fNV12) {
-            fVTransform = GrCoordTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode);
+            fVTransform = GrCoordTransform(yuvMatrix[2], vTexture, uvFilterMode);
             this->addCoordTransform(&fVTransform);
             this->addTextureAccess(&fVAccess);
         }
index bea49e5..0d5ed93 100644 (file)
@@ -36,11 +36,9 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
         strUniName.printf("CoordTransformMatrix_%d", i);
         GrSLType varyingType;
 
-        GrCoordSet coordType = coordTransform->sourceCoords();
         uint32_t type = coordTransform->getMatrix().getType();
-        if (kLocal_GrCoordSet == coordType) {
-            type |= localMatrix.getType();
-        }
+        type |= localMatrix.getType();
+
         varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
                                                                      kVec2f_GrSLType;
         GrSLPrecision precision = coordTransform->precision();
@@ -62,31 +60,10 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
         SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
         handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
 
-        // varying = matrix * coords (logically)
-        if (kDevice_GrCoordSet == coordType) {
-            if (kVec2f_GrSLType == varyingType) {
-                if (kVec2f_GrSLType == posVar.getType()) {
-                    vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
-                                    v.vsOut(), uniName, posVar.c_str());
-                } else {
-                    // The brackets here are just to scope the temp variable
-                    vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str());
-                    vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut());
-                }
-            } else {
-                if (kVec2f_GrSLType == posVar.getType()) {
-                    vb->codeAppendf("%s = %s * vec3(%s, 1);",
-                                    v.vsOut(), uniName, posVar.c_str());
-                } else {
-                    vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
-                }
-            }
+        if (kVec2f_GrSLType == varyingType) {
+            vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
         } else {
-            if (kVec2f_GrSLType == varyingType) {
-                vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
-            } else {
-                vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
-            }
+            vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
         }
         ++i;
     }
index 5ae28a0..24f21ff 100644 (file)
 SkMatrix GrGLSLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix,
                                                       const GrCoordTransform& coordTransform) {
     SkMatrix combined;
-    // We only apply the localmatrix to localcoords
-    if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
-        combined.setConcat(coordTransform.getMatrix(), localMatrix);
-    } else {
-        combined = coordTransform.getMatrix();
-    }
+    combined.setConcat(coordTransform.getMatrix(), localMatrix);
     if (coordTransform.reverseY()) {
         // combined.postScale(1,-1);
         // combined.postTranslate(0,1);