From 2ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31b Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Mon, 3 Oct 2016 17:15:28 -0400 Subject: [PATCH] Remove option to make GrCoordTransforms apply to device positions. 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 Reviewed-by: Robert Phillips --- .../SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp | 4 +- gm/dcshader.cpp | 294 --------------------- gm/windowrectangles.cpp | 9 +- include/gpu/GrCoordTransform.h | 61 ++--- src/effects/GrAlphaThresholdFragmentProcessor.cpp | 6 +- src/effects/SkDisplacementMapEffect.cpp | 5 +- src/effects/SkPerlinNoiseShader.cpp | 2 +- src/effects/gradients/SkGradientShader.cpp | 7 +- src/effects/gradients/SkGradientShaderPriv.h | 2 - src/gpu/GrBlurUtils.cpp | 9 +- src/gpu/GrClipStackClip.cpp | 20 +- src/gpu/GrCoordTransform.cpp | 8 +- src/gpu/GrFragmentProcessor.cpp | 2 +- src/gpu/GrPrimitiveProcessor.cpp | 6 +- src/gpu/GrProcessor.cpp | 2 +- src/gpu/GrSWMaskHelper.cpp | 5 +- src/gpu/effects/GrSimpleTextureEffect.cpp | 8 +- src/gpu/effects/GrSimpleTextureEffect.h | 31 +-- src/gpu/effects/GrSingleTextureEffect.cpp | 15 +- src/gpu/effects/GrSingleTextureEffect.h | 8 +- src/gpu/effects/GrTextureDomain.cpp | 210 ++++++++++----- src/gpu/effects/GrTextureDomain.h | 55 +++- src/gpu/effects/GrYUVEffect.cpp | 6 +- src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 33 +-- src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 7 +- 25 files changed, 261 insertions(+), 554 deletions(-) delete mode 100644 gm/dcshader.cpp diff --git a/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp b/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp index b863b2a..593fda1 100644 --- a/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp +++ b/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp @@ -689,7 +689,7 @@ private: this->initClassID(); this->addTextureAccess(&fPermutationsAccess); this->addTextureAccess(&fNoiseAccess); - fCoordTransform.reset(kLocal_GrCoordSet, matrix); + fCoordTransform.reset(matrix); this->addCoordTransform(&fCoordTransform); } @@ -1103,7 +1103,7 @@ private: this->initClassID(); 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 index 6f273c0..0000000 --- a/gm/dcshader.cpp +++ /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 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 DCShader::CreateProc(SkReadBuffer& buf) { - SkMatrix matrix; - buf.readMatrix(&matrix); - return sk_make_sp(matrix); -} - -class DCFP : public GrFragmentProcessor { -public: - DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) { - this->addCoordTransform(&fDeviceTransform); - this->initClassID(); - } - - 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 DCShader::asFragmentProcessor(const AsFPArgs&) const { - sk_sp 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 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 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(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 fPrims; - - typedef GM INHERITED; -}; - -DEF_GM(return new DCShaderGM;) -} -#endif diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp index 3928763..5266df2 100644 --- a/gm/windowrectangles.cpp +++ b/gm/windowrectangles.cpp @@ -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 { diff --git a/include/gpu/GrCoordTransform.h b/include/gpu/GrCoordTransform.h index 4d96cd9..3080523 100644 --- a/include/gpu/GrCoordTransform.h +++ b/include/gpu/GrCoordTransform.h @@ -15,82 +15,54 @@ #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; diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp index 99f0a19..442acd0 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp +++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp @@ -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) { diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 4f6386d..283372f 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -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) diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp index a174bca..caff495 100644 --- a/src/effects/SkPerlinNoiseShader.cpp +++ b/src/effects/SkPerlinNoiseShader.cpp @@ -554,7 +554,7 @@ private: this->initClassID(); this->addTextureAccess(&fPermutationsAccess); this->addTextureAccess(&fNoiseAccess); - fCoordTransform.reset(kLocal_GrCoordSet, matrix); + fCoordTransform.reset(matrix); this->addCoordTransform(&fCoordTransform); } diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index df23039..4ee8203 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -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 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; } diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index df7ac78..f850994 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -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 fColors; diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp index 383652d..5f575e3 100644 --- a/src/gpu/GrBlurUtils.cpp +++ b/src/gpu/GrBlurUtils.cpp @@ -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; } diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index d85db11..7694a3f 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -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 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(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, diff --git a/src/gpu/GrCoordTransform.cpp b/src/gpu/GrCoordTransform.cpp index e7d9b1e..2da49c4 100644 --- a/src/gpu/GrCoordTransform.cpp +++ b/src/gpu/GrCoordTransform.cpp @@ -10,12 +10,11 @@ #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; diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 7233658..123792d 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -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();) } diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp index 180217e..2aaaa04 100644 --- a/src/gpu/GrPrimitiveProcessor.cpp +++ b/src/gpu/GrPrimitiveProcessor.cpp @@ -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 SkTArraysourceCoords() && - !this->hasExplicitLocalCoords()) { + if (!this->hasExplicitLocalCoords()) { key |= kPositionCoords_Flag; - } else if (kDevice_GrCoordSet == coordTransform->sourceCoords()) { - key |= kDeviceCoords_Flag; } GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits)); diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index b945b02..5ca9935 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -48,7 +48,7 @@ GrProcessorTestFactory::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; diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index a20eacb..8bb3fed 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -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 batch(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), SkMatrix::I(), diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index b05ac83..beb64d5 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -84,13 +84,7 @@ sk_sp 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); } diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index 44e5c06..8242362 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -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 Make(GrTexture* tex, sk_sp colorSpaceXform, - const SkMatrix& matrix, - GrCoordSet coordSet = kLocal_GrCoordSet) { + const SkMatrix& matrix) { return sk_sp( new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, - GrTextureParams::kNone_FilterMode, coordSet)); + GrTextureParams::kNone_FilterMode)); } /* clamp mode */ static sk_sp Make(GrTexture* tex, sk_sp colorSpaceXform, const SkMatrix& matrix, - GrTextureParams::FilterMode filterMode, - GrCoordSet coordSet = kLocal_GrCoordSet) { + GrTextureParams::FilterMode filterMode) { return sk_sp( - new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode, - coordSet)); + new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode)); } static sk_sp Make(GrTexture* tex, sk_sp colorSpaceXform, const SkMatrix& matrix, - const GrTextureParams& p, - GrCoordSet coordSet = kLocal_GrCoordSet) { + const GrTextureParams& p) { return sk_sp(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), - matrix, p, coordSet)); + matrix, p)); } virtual ~GrSimpleTextureEffect() {} @@ -58,18 +53,16 @@ private: GrSimpleTextureEffect(GrTexture* texture, sk_sp 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(GrTexture* texture, sk_sp 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(); } diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index c84e95e..2683789 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -9,9 +9,8 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, sk_sp 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 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 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); diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index a30cd03..7d110bf 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -34,16 +34,14 @@ public: protected: /** unfiltered, clamp mode */ - GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&, - GrCoordSet = kLocal_GrCoordSet); + GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&); /** clamp mode */ GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&, - GrTextureParams::FilterMode filterMode, GrCoordSet = kLocal_GrCoordSet); + GrTextureParams::FilterMode filterMode); GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&, - const GrTextureParams&, - GrCoordSet = kLocal_GrCoordSet); + const GrTextureParams&); /** * Can be used as a helper to implement subclass onComputeInvariantOutput(). It assumes that diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index e809109..55d69bf 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -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(); - 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(); - 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().textureDomain(); - b->add32(GrTextureDomain::GLDomain::DomainKey(domain)); -} - - /////////////////////////////////////////////////////////////////////////////// sk_sp GrTextureDomainEffect::Make(GrTexture* texture, @@ -223,8 +176,7 @@ sk_sp 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 GrTextureDomainEffect::Make(GrTexture* texture, } else { return sk_sp( 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() {} - 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(); + 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(); + 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(); - 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 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 GrTextureDomainEffect::TestCreate(GrProcessorTestData matrix, domain, mode, - bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode, - coords); + bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode); +} + +/////////////////////////////////////////////////////////////////////////////// + +sk_sp GrDeviceSpaceTextureDecalFragmentProcessor::Make(GrTexture* texture, + const SkIRect& subset, const SkIPoint& deviceSpaceOffset) { + return sk_sp(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(); + this->setWillReadFragmentPosition(); +} + +GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const { + class GLSLProcessor : public GrGLSLFragmentProcessor { + public: + void emitCode(EmitArgs& args) override { + const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = + args.fFp.cast(); + 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(); + 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(); + 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 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); } diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index 9edecac..82ff73c 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -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, 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 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 diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp index 5b04f21..cbe25e8 100644 --- a/src/gpu/effects/GrYUVEffect.cpp +++ b/src/gpu/effects/GrYUVEffect.cpp @@ -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); } diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp index bea49e5..0d5ed93 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -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; } diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp index 5ae28a0..24f21ff 100644 --- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp @@ -15,12 +15,7 @@ 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); -- 2.7.4