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:
parent
2cbcd12281
commit
2ebd0c80a2
@ -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);
|
||||
}
|
||||
|
||||
|
294
gm/dcshader.cpp
294
gm/dcshader.cpp
@ -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
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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();)
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user