Revert "Revert "Converted texture and runtime effects to use GrMatrixEffect""

This reverts commit 36a3e014e1.

Change-Id: I2bb432ec423a85478adddc6845d5d7aa59d4055b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/284918
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2020-04-28 13:55:02 -04:00 committed by Skia Commit-Bot
parent 3c411f58c4
commit afe2c90739
19 changed files with 207 additions and 74 deletions

View File

@ -20,8 +20,11 @@ class SampleMatrixVariableEffect : public GrFragmentProcessor {
public:
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 2;
SampleMatrixVariableEffect(std::unique_ptr<GrFragmentProcessor> child)
: INHERITED(CLASS_ID, kNone_OptimizationFlags) {
SampleMatrixVariableEffect(std::unique_ptr<GrFragmentProcessor> child, float xOffset,
float yOffset)
: INHERITED(CLASS_ID, kNone_OptimizationFlags)
, fXOffset(xOffset)
, fYOffset(yOffset) {
child->setSampleMatrix(SkSL::SampleMatrix(SkSL::SampleMatrix::Kind::kVariable));
this->registerChildProcessor(std::move(child));
}
@ -42,15 +45,25 @@ public:
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
float fXOffset;
float fYOffset;
typedef GrFragmentProcessor INHERITED;
friend class GLSLSampleMatrixVariableEffect;
};
class GLSLSampleMatrixVariableEffect : public GrGLSLFragmentProcessor {
void emitCode(EmitArgs& args) override {
auto& smve = args.fFp.cast<SampleMatrixVariableEffect>();
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString sample1 = this->invokeChildWithMatrix(0, args, "float3x3(1)");
SkString sample2 = this->invokeChildWithMatrix(0, args, "float3x3(1, -1, 0, 1, 0, 0, "
"-0.5, 1, 1)");
SkString sample2 = this->invokeChildWithMatrix(0, args,
SkStringPrintf("float3x3(1, -1, 0, 1, 0, 0, "
"%g, %g, 1)",
smve.fXOffset,
smve.fYOffset).c_str());
fragBuilder->codeAppendf("%s = (%s + %s) / 2;\n", args.fOutputColor, sample1.c_str(),
sample2.c_str());
}
@ -71,7 +84,7 @@ DEF_SIMPLE_GPU_GM(sample_matrix_variable, ctx, rtCtx, canvas, 512, 256) {
GrTextureEffect::Make(std::move(view), bmp.alphaType(), SkMatrix());
imgFP->setSampleMatrix(SkSL::SampleMatrix::Kind::kVariable);
auto fp = std::unique_ptr<GrFragmentProcessor>(
new SampleMatrixVariableEffect(std::move(imgFP)));
new SampleMatrixVariableEffect(std::move(imgFP), -128, 256));
GrPaint paint;
paint.addCoverageFragmentProcessor(std::move(fp));
@ -95,7 +108,7 @@ DEF_SIMPLE_GPU_GM(sample_matrix_variable, ctx, rtCtx, canvas, 512, 256) {
std::unique_ptr<GrFragmentProcessor> gradientFP = as_SB(shader)->asFragmentProcessor(args);
gradientFP->setSampleMatrix(SkSL::SampleMatrix::Kind::kVariable);
auto fp = std::unique_ptr<GrFragmentProcessor>(
new SampleMatrixVariableEffect(std::move(gradientFP)));
new SampleMatrixVariableEffect(std::move(gradientFP), -0.5, 1));
paint.addCoverageFragmentProcessor(std::move(fp));
rtCtx->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), bounds);
}

View File

@ -25,6 +25,7 @@
#include "src/gpu/GrColorInfo.h"
#include "src/gpu/GrFPArgs.h"
#include "src/gpu/effects/GrSkSLFP.h"
#include "src/gpu/effects/generated/GrMatrixEffect.h"
#endif
namespace SkSL {
@ -648,7 +649,7 @@ public:
if (!this->totalLocalMatrix(args.fPreLocalMatrix)->invert(&matrix)) {
return nullptr;
}
auto fp = GrSkSLFP::Make(args.fContext, fEffect, "runtime_shader", fInputs, &matrix);
auto fp = GrSkSLFP::Make(args.fContext, fEffect, "runtime_shader", fInputs);
for (const auto& child : fChildren) {
auto childFP = child ? as_SB(child)->asFragmentProcessor(args) : nullptr;
if (!childFP) {
@ -657,10 +658,14 @@ public:
}
fp->addChild(std::move(childFP));
}
std::unique_ptr<GrFragmentProcessor> result = std::move(fp);
if (!matrix.isIdentity()) {
result = GrMatrixEffect::Make(matrix, std::move(result));
}
if (GrColorTypeClampType(args.fDstColorInfo->colorType()) != GrClampType::kNone) {
return GrFragmentProcessor::ClampPremulOutput(std::move(fp));
return GrFragmentProcessor::ClampPremulOutput(std::move(result));
} else {
return std::move(fp);
return result;
}
}
#endif

View File

@ -137,6 +137,7 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrRecordingContext* context,
canDrawArgs.fClipConservativeBounds = &scissorRect;
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fShape = &shape;
canDrawArgs.fPaint = nullptr;
canDrawArgs.fAAType = aaType;
SkASSERT(!renderTargetContext->wrapsVkSecondaryCB());
canDrawArgs.fTargetIsWrappedVkSecondaryCB = false;

View File

@ -64,7 +64,6 @@ public:
for (int i = 0; *transformHandler; ++*transformHandler, ++i) {
auto [coordTransform, fp] = transformHandler->get();
SkString matrix;
GrShaderVar fragmentVar;
GrShaderVar transformVar;
if (fp.isSampledWithExplicitCoords()) {
@ -89,7 +88,6 @@ public:
&name)
.toIndex();
transformVar = uniformHandler->getUniformVariable(uni.fHandle);
matrix = name;
}
} else {
SkString strVaryingName;
@ -104,10 +102,9 @@ public:
.toIndex();
#endif
fVaryingTransform.back().fType = varyingType;
matrix = matrix_to_sksl(coordTransform.matrix());
fragmentVar = {SkString(v.fsIn()), varyingType};
}
transformHandler->specifyCoordsForCurrCoordTransform(matrix, transformVar, fragmentVar);
transformHandler->specifyCoordsForCurrCoordTransform(transformVar, fragmentVar);
}
}

View File

@ -49,6 +49,7 @@ bool GrPathRenderer::drawPath(const DrawPathArgs& args) {
canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
canArgs.fViewMatrix = args.fViewMatrix;
canArgs.fShape = args.fShape;
canArgs.fPaint = &args.fPaint;
canArgs.fAAType = args.fAAType;
canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB();
canArgs.validate();

View File

@ -83,6 +83,7 @@ public:
const SkIRect* fClipConservativeBounds;
const SkMatrix* fViewMatrix;
const GrStyledShape* fShape;
const GrPaint* fPaint;
GrAAType fAAType;
bool fTargetIsWrappedVkSecondaryCB;

View File

@ -868,6 +868,7 @@ bool GrReducedClip::drawStencilClipMask(GrRecordingContext* context,
canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
canDrawArgs.fViewMatrix = &SkMatrix::I();
canDrawArgs.fShape = &shape;
canDrawArgs.fPaint = nullptr;
canDrawArgs.fAAType = pathAAType;
canDrawArgs.fHasUserStencilSettings = false;
canDrawArgs.fTargetIsWrappedVkSecondaryCB = renderTargetContext->wrapsVkSecondaryCB();

View File

@ -2306,12 +2306,16 @@ bool GrRenderTargetContextPriv::drawAndStencilPath(const GrHardClip& clip,
clip.getConservativeBounds(fRenderTargetContext->width(), fRenderTargetContext->height(),
&clipConservativeBounds, nullptr);
GrPaint paint;
paint.setCoverageSetOpXPFactory(op, invert);
GrStyledShape shape(path, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fCaps = fRenderTargetContext->caps();
canDrawArgs.fProxy = fRenderTargetContext->asRenderTargetProxy();
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fShape = &shape;
canDrawArgs.fPaint = &paint;
canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
canDrawArgs.fAAType = aaType;
SkASSERT(!fRenderTargetContext->wrapsVkSecondaryCB());
@ -2325,9 +2329,6 @@ bool GrRenderTargetContextPriv::drawAndStencilPath(const GrHardClip& clip,
return false;
}
GrPaint paint;
paint.setCoverageSetOpXPFactory(op, invert);
GrPathRenderer::DrawPathArgs args{fRenderTargetContext->drawingManager()->getContext(),
std::move(paint),
ss,
@ -2378,6 +2379,7 @@ void GrRenderTargetContext::drawShapeUsingPathRenderer(const GrClip& clip,
canDrawArgs.fProxy = this->asRenderTargetProxy();
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fShape = &originalShape;
canDrawArgs.fPaint = &paint;
canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
canDrawArgs.fTargetIsWrappedVkSecondaryCB = this->wrapsVkSecondaryCB();
canDrawArgs.fHasUserStencilSettings = false;

View File

@ -163,28 +163,23 @@ public:
};
std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, sk_sp<SkRuntimeEffect> effect,
const char* name, sk_sp<SkData> inputs,
const SkMatrix* matrix) {
const char* name, sk_sp<SkData> inputs) {
if (inputs->size() != effect->inputSize()) {
return nullptr;
}
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(
context->priv().caps()->refShaderCaps(), context->priv().getShaderErrorHandler(),
std::move(effect), name, std::move(inputs), matrix));
std::move(effect), name, std::move(inputs)));
}
GrSkSLFP::GrSkSLFP(sk_sp<const GrShaderCaps> shaderCaps, ShaderErrorHandler* shaderErrorHandler,
sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> inputs,
const SkMatrix* matrix)
sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> inputs)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
, fShaderCaps(std::move(shaderCaps))
, fShaderErrorHandler(shaderErrorHandler)
, fEffect(std::move(effect))
, fName(name)
, fInputs(std::move(inputs)) {
if (matrix) {
fCoordTransform = GrCoordTransform(*matrix);
}
this->addCoordTransform(&fCoordTransform);
}
@ -195,8 +190,6 @@ GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
, fEffect(other.fEffect)
, fName(other.fName)
, fInputs(other.fInputs) {
SkASSERT(other.numCoordTransforms() == 1);
fCoordTransform = other.fCoordTransform;
this->addCoordTransform(&fCoordTransform);
}
@ -291,7 +284,7 @@ std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d
auto result = GrSkSLFP::Make(d->context(), effect, "Arithmetic",
SkData::MakeWithCopy(&inputs, sizeof(inputs)));
result->addChild(GrConstColorProcessor::Make(
SK_PMColor4fWHITE, GrConstColorProcessor::InputMode::kIgnore));
SK_PMColor4fWHITE, GrConstColorProcessor::InputMode::kIgnore));
return std::unique_ptr<GrFragmentProcessor>(result.release());
}
case 2: {

View File

@ -69,8 +69,7 @@ public:
static std::unique_ptr<GrSkSLFP> Make(GrContext_Base* context,
sk_sp<SkRuntimeEffect> effect,
const char* name,
sk_sp<SkData> inputs,
const SkMatrix* matrix = nullptr);
sk_sp<SkData> inputs);
const char* name() const override;
@ -82,8 +81,7 @@ private:
using ShaderErrorHandler = GrContextOptions::ShaderErrorHandler;
GrSkSLFP(sk_sp<const GrShaderCaps> shaderCaps, ShaderErrorHandler* shaderErrorHandler,
sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> inputs,
const SkMatrix* matrix);
sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> inputs);
GrSkSLFP(const GrSkSLFP& other);

View File

@ -9,6 +9,7 @@
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/effects/generated/GrMatrixEffect.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
@ -148,12 +149,58 @@ bool GrTextureEffect::Sampling::hasBorderAlpha() const {
return false;
}
static void get_matrix(const SkMatrix& preMatrix, const GrSurfaceProxyView& view,
SkMatrix* outMatrix, bool* outLazyProxyNormalization) {
SkMatrix combined = preMatrix;
bool normalize = view.proxy()->backendFormat().textureType() != GrTextureType::kRectangle;
if (normalize) {
if (view.proxy()->isFullyLazy()) {
*outLazyProxyNormalization = true;
} else {
SkMatrixPriv::PostIDiv(&combined, view.proxy()->backingStoreDimensions().fWidth,
view.proxy()->backingStoreDimensions().fHeight);
*outLazyProxyNormalization = false;
}
} else {
*outLazyProxyNormalization = false;
}
if (view.origin() == kBottomLeft_GrSurfaceOrigin) {
if (normalize) {
// combined.postScale(1,-1);
// combined.postTranslate(0,1);
combined.set(SkMatrix::kMSkewY,
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
combined.set(SkMatrix::kMScaleY,
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
combined.set(SkMatrix::kMTransY,
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
} else {
// combined.postScale(1, -1);
// combined.postTranslate(0,1);
SkScalar h = view.proxy()->backingStoreDimensions().fHeight;
combined.set(SkMatrix::kMSkewY,
h * combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
combined.set(SkMatrix::kMScaleY,
h * combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
combined.set(SkMatrix::kMTransY,
h * combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
}
}
*outMatrix = combined;
}
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
SkAlphaType alphaType,
const SkMatrix& matrix,
Filter filter) {
return std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view), alphaType, matrix, Sampling(filter)));
SkMatrix final;
bool lazyProxyNormalization;
get_matrix(matrix, view, &final, &lazyProxyNormalization);
return GrMatrixEffect::Apply(final, std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view),
alphaType,
Sampling(filter),
lazyProxyNormalization)));
}
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
@ -164,8 +211,14 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView vi
const float border[4]) {
Sampling sampling(*view.proxy(), sampler, SkRect::Make(view.proxy()->dimensions()), nullptr,
border, caps);
return std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view), alphaType, matrix, sampling));
SkMatrix final;
bool lazyProxyNormalization;
get_matrix(matrix, view, &final, &lazyProxyNormalization);
return GrMatrixEffect::Apply(final, std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view),
alphaType,
sampling,
lazyProxyNormalization)));
}
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
@ -176,8 +229,14 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyV
const GrCaps& caps,
const float border[4]) {
Sampling sampling(*view.proxy(), sampler, subset, nullptr, border, caps);
return std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view), alphaType, matrix, sampling));
SkMatrix final;
bool lazyProxyNormalization;
get_matrix(matrix, view, &final, &lazyProxyNormalization);
return GrMatrixEffect::Apply(final, std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view),
alphaType,
sampling,
lazyProxyNormalization)));
}
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
@ -189,8 +248,14 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyV
const GrCaps& caps,
const float border[4]) {
Sampling sampling(*view.proxy(), sampler, subset, &domain, border, caps);
return std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view), alphaType, matrix, sampling));
SkMatrix final;
bool lazyProxyNormalization;
get_matrix(matrix, view, &final, &lazyProxyNormalization);
return GrMatrixEffect::Apply(final, std::unique_ptr<GrFragmentProcessor>(
new GrTextureEffect(std::move(view),
alphaType,
sampling,
lazyProxyNormalization)));
}
GrTextureEffect::FilterLogic GrTextureEffect::GetFilterLogic(ShaderMode mode,
@ -227,28 +292,41 @@ GrGLSLFragmentProcessor* GrTextureEffect::onCreateGLSLInstance() const {
public:
void emitCode(EmitArgs& args) override {
auto& te = args.fFp.cast<GrTextureEffect>();
SkString coords;
if (args.fFp.isSampledWithExplicitCoords()) {
coords = "_coords";
} else {
coords = args.fTransformedCoords[0].fVaryingPoint.c_str();
}
auto* fb = args.fFragBuilder;
if (te.sampleMatrix().fKind == SkSL::SampleMatrix::Kind::kMixed) {
args.fUniformHandler->writeUniformMappings(te.sampleMatrix().fOwner, fb);
coords = SkStringPrintf("(%s * _matrix * float3(%s, 1)).xy",
te.sampleMatrix().fExpression.c_str(),
coords.c_str());
}
if (te.fShaderModes[0] == ShaderMode::kNone &&
te.fShaderModes[1] == ShaderMode::kNone) {
SkString coords;
if (args.fFp.isSampledWithExplicitCoords()) {
coords = "_coords";
} else {
coords = args.fTransformedCoords[0].fVaryingPoint.c_str();
}
switch (te.sampleMatrix().fKind) {
case SkSL::SampleMatrix::Kind::kMixed:
case SkSL::SampleMatrix::Kind::kVariable:
coords = SkStringPrintf("(_matrix * float3(%s, 1)).xy", coords.c_str());
break;
default:
break;
}
fb->codeAppendf("%s = ", args.fOutputColor);
fb->appendTextureLookupAndBlend(args.fInputColor, SkBlendMode::kModulate,
args.fTexSamplers[0], coords.c_str());
if (te.fLazyProxyNormalization) {
const char* norm = nullptr;
fNormUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
kFloat4_GrSLType, "norm", &norm);
fb->appendTextureLookupAndBlend(args.fInputColor, SkBlendMode::kModulate,
args.fTexSamplers[0],
SkStringPrintf("%s * %s.zw", coords.c_str(),
norm).c_str());
} else {
fb->appendTextureLookupAndBlend(args.fInputColor, SkBlendMode::kModulate,
args.fTexSamplers[0], coords.c_str());
}
fb->codeAppendf(";");
} else {
// Tripping this assert means we have a normalized fully lazy proxy with a
// non-default ShaderMode. There's nothing fundamentally wrong with doing that, but
// it hasn't been tested and this code path probably won't handle normalization
// properly in that case.
SkASSERT(!te.fLazyProxyNormalization);
// Here is the basic flow of the various ShaderModes are implemented in a series of
// steps. Not all the steps apply to all the modes. We try to emit only the steps
// that are necessary for the given x/y shader modes.
@ -653,14 +731,15 @@ bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
}
GrTextureEffect::GrTextureEffect(GrSurfaceProxyView view, SkAlphaType alphaType,
const SkMatrix& matrix, const Sampling& sampling)
const Sampling& sampling, bool lazyProxyNormalization)
: GrFragmentProcessor(kGrTextureEffect_ClassID,
ModulateForSamplerOptFlags(alphaType, sampling.hasBorderAlpha()))
, fCoordTransform(matrix, view.proxy(), view.origin())
, fCoordTransform(SkMatrix::I())
, fSampler(std::move(view), sampling.fHWSampler)
, fSubset(sampling.fShaderSubset)
, fClamp(sampling.fShaderClamp)
, fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]} {
, fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]}
, fLazyProxyNormalization(lazyProxyNormalization) {
// We always compare the range even when it isn't used so assert we have canonical don't care
// values.
SkASSERT(fShaderModes[0] != ShaderMode::kNone || (fSubset.fLeft == 0 && fSubset.fRight == 0));
@ -676,7 +755,8 @@ GrTextureEffect::GrTextureEffect(const GrTextureEffect& src)
, fSampler(src.fSampler)
, fSubset(src.fSubset)
, fClamp(src.fClamp)
, fShaderModes{src.fShaderModes[0], src.fShaderModes[1]} {
, fShaderModes{src.fShaderModes[0], src.fShaderModes[1]}
, fLazyProxyNormalization(src.fLazyProxyNormalization) {
std::copy_n(src.fBorder, 4, fBorder);
this->setTextureSamplerCnt(1);
this->addCoordTransform(&fCoordTransform);

View File

@ -100,8 +100,10 @@ private:
SkRect fSubset;
SkRect fClamp;
ShaderMode fShaderModes[2];
// true if we are dealing with a fully lazy proxy which can't be normalized until runtime
bool fLazyProxyNormalization;
inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const SkMatrix&, const Sampling&);
inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const Sampling&, bool);
explicit GrTextureEffect(const GrTextureEffect& src);

View File

@ -41,6 +41,8 @@ private:
: INHERITED(kGrMatrixEffect_ClassID, kNone_OptimizationFlags), matrix(matrix) {
SkASSERT(child);
child_index = this->numChildProcessors();
child->setSampleMatrix(
SkSL::SampleMatrix(SkSL::SampleMatrix::Kind::kConstantOrUniform, this, "matrix"));
this->registerChildProcessor(std::move(child));
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;

View File

@ -131,14 +131,9 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
vb->codeAppendf("%s = %s * %s;", v.vsOut(), matrix.c_str(), localCoordsStr.c_str());
}
fsVar = GrShaderVar(SkString(v.fsIn()), v.type(), GrShaderVar::TypeModifier::In);
fTransformInfos.push_back({ v.vsOut(), v.type(), matrix.c_str(), localCoordsStr, &fp });
} else {
SkASSERT(fp.sampleMatrix().fKind != SkSL::SampleMatrix::Kind::kVariable);
if (fp.sampleMatrix().fKind == SkSL::SampleMatrix::Kind::kConstantOrUniform) {
matrix += " * " + fp.sampleMatrix().fExpression;
}
fTransformInfos.push_back({ v.vsOut(), v.type(), matrix, localCoordsStr, &fp });
}
handler->specifyCoordsForCurrCoordTransform(matrix, transformVar, fsVar);
handler->specifyCoordsForCurrCoordTransform(transformVar, fsVar);
}
}
@ -151,13 +146,13 @@ void GrGLSLGeometryProcessor::emitTransformCode(GrGLSLVertexBuilder* vb,
uniformHandler->writeUniformMappings(tr.fFP->sampleMatrix().fOwner, vb);
if (tr.fType == kFloat2_GrSLType) {
vb->codeAppendf("%s = (%s * %s * %s).xy", tr.fName,
tr.fFP->sampleMatrix().fExpression.c_str(), tr.fMatrix,
tr.fFP->sampleMatrix().fExpression.c_str(), tr.fMatrix.c_str(),
tr.fLocalCoords.c_str());
} else {
SkASSERT(tr.fType == kFloat3_GrSLType);
vb->codeAppendf("%s = %s * %s * %s", tr.fName,
tr.fFP->sampleMatrix().fExpression.c_str(), tr.fMatrix,
tr.fName);
tr.fFP->sampleMatrix().fExpression.c_str(), tr.fMatrix.c_str(),
tr.fLocalCoords.c_str());
}
vb->codeAppend(";\n");
vb->codeAppend("}\n");

View File

@ -97,7 +97,7 @@ private:
struct TransformInfo {
const char* fName;
GrSLType fType;
const char* fMatrix;
SkString fMatrix;
SkString fLocalCoords;
const GrFragmentProcessor* fFP;
};

View File

@ -60,8 +60,7 @@ public:
FPCoordTransformHandler& operator++();
// 'args' are constructor params to GrShaderVar.
void specifyCoordsForCurrCoordTransform(/* FIXME name and doc this properly */const SkString& name, GrShaderVar transformVar,
GrShaderVar varyingVar) {
void specifyCoordsForCurrCoordTransform(GrShaderVar transformVar, GrShaderVar varyingVar) {
SkASSERT(!fAddedCoord);
fTransformedCoordVars->push_back({transformVar, varyingVar});
SkDEBUGCODE(fAddedCoord = true;)

View File

@ -32,6 +32,18 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
: fResourceProvider(resourceProvider) {
}
static bool has_matrix(const GrFragmentProcessor& fp) {
if (fp.sampleMatrix().fKind != SkSL::SampleMatrix::Kind::kNone) {
return true;
}
for (int i = fp.numChildProcessors() - 1; i >= 0; --i) {
if (has_matrix(fp.childProcessor(i))) {
return true;
}
}
return false;
}
GrPathRenderer::CanDrawPath
GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
SkASSERT(!args.fTargetIsWrappedVkSecondaryCB);
@ -46,6 +58,16 @@ GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const
// We rely on a mixed sampled stencil buffer to implement coverage AA.
return CanDrawPath::kNo;
}
// The lack of vertex shaders means we can't move transform matrices into the vertex shader. We
// could do the transform in the fragment processor, but that would be very slow, so instead we
// just avoid using this path renderer in the face of transformed FPs.
if (args.fPaint) {
for (int i = args.fPaint->numColorFragmentProcessors() - 1; i >= 0; --i) {
if (has_matrix(*args.fPaint->getColorFragmentProcessor(i))) {
return CanDrawPath::kNo;
}
}
}
return CanDrawPath::kYes;
}

View File

@ -287,6 +287,28 @@ void HCodeGenerator::writeConstructor() {
this->writef(" %s->setSampledWithExplicitCoords();",
String(param->fName).c_str());
}
SampleMatrix matrix = fSectionAndParameterHelper.getMatrix(*param);
switch (matrix.fKind) {
case SampleMatrix::Kind::kVariable:
this->writef(" %s->setSampleMatrix(this, "
"SkSL::SampleMatrix::Kind::kVariable);",
String(param->fName).c_str());
break;
case SampleMatrix::Kind::kConstantOrUniform:
this->writef(" %s->setSampleMatrix(SkSL::SampleMatrix("
"SkSL::SampleMatrix::Kind::kConstantOrUniform, this, \"%s\"));",
String(param->fName).c_str(),
matrix.fExpression.c_str());
break;
case SampleMatrix::Kind::kMixed:
this->writef(" %s->setSampleMatrix(SkSL::SampleMatrix("
"SkSL::SampleMatrix::Kind::kMixed, this, \"%s\"));",
String(param->fName).c_str(),
matrix.fExpression.c_str());
break;
case SampleMatrix::Kind::kNone:
break;
}
this->writef(" this->registerChildProcessor(std::move(%s));",
String(param->fName).c_str());
if (param->fType.kind() == Type::kNullable_Kind) {

View File

@ -59,7 +59,6 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
SkASSERT(c.fArguments.size() == 2);
SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
"fragmentProcessor?" == c.fArguments[0]->fType.name());
SkASSERT("float2" == c.fArguments[1]->fType.name());
SkASSERT(Expression::kVariableReference_Kind == c.fArguments[0]->fKind);
int index = 0;
bool found = false;