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 <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Brian Salomon 2016-10-03 17:15:28 -04:00 committed by Skia Commit-Bot
parent 2cbcd12281
commit 2ebd0c80a2
25 changed files with 261 additions and 554 deletions

View 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);
}

View File

@ -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

View 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 {

View File

@ -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;

View 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) {

View 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)

View 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);
}

View 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;
}

View 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;

View 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;
}

View 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,

View File

@ -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;

View 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();)
}

View 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));

View 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;

View 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(),

View 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);
}

View 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>();
}

View 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);

View 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

View 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);
}

View 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

View 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);
}

View 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;
}

View File

@ -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);