Stop flattening GrCoordTransforms in parent GrFragmentProcessors.
This changes moves to a model that iterates over GrCTs in a GrFP hierarchy when inserting transformations by GrGLSLPrimitiveProcessors. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2339203002 Committed: https://skia.googlesource.com/skia/+/d91237ee051523f439238042674ade99207fe4a6 Review-Url: https://codereview.chromium.org/2339203002
This commit is contained in:
parent
be9d82161d
commit
a624bf3d1c
@ -14,6 +14,7 @@ class GrCoordTransform;
|
||||
class GrGLSLCaps;
|
||||
class GrGLSLFragmentProcessor;
|
||||
class GrInvariantOutput;
|
||||
class GrPipeline;
|
||||
class GrProcessorKeyBuilder;
|
||||
|
||||
/** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and
|
||||
@ -68,8 +69,7 @@ public:
|
||||
, fUsesDistanceVectorField(false)
|
||||
, fUsesLocalCoords(false)
|
||||
, fNumTexturesExclChildren(0)
|
||||
, fNumBuffersExclChildren(0)
|
||||
, fNumTransformsExclChildren(0) {}
|
||||
, fNumBuffersExclChildren(0) {}
|
||||
|
||||
~GrFragmentProcessor() override;
|
||||
|
||||
@ -86,9 +86,7 @@ public:
|
||||
|
||||
int numBuffersExclChildren() const { return fNumBuffersExclChildren; }
|
||||
|
||||
int numTransformsExclChildren() const { return fNumTransformsExclChildren; }
|
||||
|
||||
int numTransforms() const { return fCoordTransforms.count(); }
|
||||
int numCoordTransforms() const { return fCoordTransforms.count(); }
|
||||
|
||||
/** Returns the coordinate transformation at index. index must be valid according to
|
||||
numTransforms(). */
|
||||
@ -135,6 +133,40 @@ public:
|
||||
this->onComputeInvariantOutput(inout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-order traversal of a FP hierarchy, or of the forest of FPs in a GrPipeline. In the latter
|
||||
* case the tree rooted at each FP in the GrPipeline is visited successively.
|
||||
* */
|
||||
class Iter : public SkNoncopyable {
|
||||
public:
|
||||
explicit Iter(const GrFragmentProcessor* fp) { fFPStack.push_back(fp); }
|
||||
explicit Iter(const GrPipeline& pipeline);
|
||||
const GrFragmentProcessor* next();
|
||||
|
||||
private:
|
||||
SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates over all the GrCoordTransforms in a GrPipeline's GrFragmentProcessors. FPs are
|
||||
* visited in the same order as Iter and each of an FP's coord transforms are visited linearly.
|
||||
*/
|
||||
class CoordTransformIter : public SkNoncopyable {
|
||||
public:
|
||||
explicit CoordTransformIter(const GrPipeline& pipeline)
|
||||
: fCurrFP(nullptr)
|
||||
, fCTIdx(0)
|
||||
, fFPIter(pipeline) {
|
||||
fCurrFP = fFPIter.next();
|
||||
}
|
||||
const GrCoordTransform* next();
|
||||
|
||||
private:
|
||||
const GrFragmentProcessor* fCurrFP;
|
||||
int fCTIdx;
|
||||
GrFragmentProcessor::Iter fFPIter;
|
||||
};
|
||||
|
||||
protected:
|
||||
void addTextureAccess(const GrTextureAccess* textureAccess) override;
|
||||
void addBufferAccess(const GrBufferAccess*) override;
|
||||
@ -206,15 +238,18 @@ private:
|
||||
|
||||
bool fUsesLocalCoords;
|
||||
|
||||
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
|
||||
|
||||
/**
|
||||
* fCoordTransforms stores the transforms of this proc, followed by all the transforms of this
|
||||
* proc's children. In other words, each proc stores all the transforms of its subtree as if
|
||||
* A processor stores the texture accesses of this proc, followed by all the accesses of this
|
||||
* proc's children. In other words, each proc stores all the accesses of its subtree as if
|
||||
* they were collected using preorder traversal.
|
||||
*
|
||||
* Example:
|
||||
* Suppose we have frag proc A, who has two children B and D. B has a child C, and D has
|
||||
* two children E and F. Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms
|
||||
* respectively. The following shows what the fCoordTransforms array of each proc would contain:
|
||||
* two children E and F. Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 accesses
|
||||
* respectively. The following shows what the array of each proc's texture accesses would
|
||||
* contain:
|
||||
*
|
||||
* (A)
|
||||
* [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2]
|
||||
@ -227,12 +262,10 @@ private:
|
||||
* (C) (E) (F)
|
||||
* [c1] [e1,e2,e3] [f1,f2]
|
||||
*
|
||||
* The same goes for fTextureAccesses with textures.
|
||||
* The same goes for buffer accesses.
|
||||
*/
|
||||
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
|
||||
int fNumTexturesExclChildren;
|
||||
int fNumBuffersExclChildren;
|
||||
int fNumTransformsExclChildren;
|
||||
|
||||
/**
|
||||
* This is not SkSTArray<1, sk_sp<GrFragmentProcessor>> because this class holds strong
|
||||
|
@ -99,8 +99,7 @@ public:
|
||||
gpArgs->fPositionVar,
|
||||
gp.inLocalCoords()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
} else {
|
||||
// emit transforms with position
|
||||
this->emitTransforms(vertBuilder,
|
||||
@ -109,8 +108,7 @@ public:
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
}
|
||||
|
||||
// Setup coverage as pass through
|
||||
@ -150,7 +148,8 @@ public:
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
|
||||
|
||||
if (!dgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dgp.viewMatrix())) {
|
||||
@ -172,14 +171,7 @@ public:
|
||||
pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage()));
|
||||
fCoverage = dgp.coverage();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<DefaultGeoProc>().fLocalMatrix, pdman, index,
|
||||
transforms);
|
||||
this->setTransformDataHelper(dgp.fLocalMatrix, pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrPipeline.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
@ -81,16 +82,10 @@ void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
|
||||
fCoordTransforms.push_back(transform);
|
||||
fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet;
|
||||
SkDEBUGCODE(transform->setInProcessor();)
|
||||
fNumTransformsExclChildren++;
|
||||
}
|
||||
|
||||
int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) {
|
||||
// Append the child's transforms to our transforms array and the child's textures array to our
|
||||
// textures array
|
||||
if (!child->fCoordTransforms.empty()) {
|
||||
fCoordTransforms.push_back_n(child->fCoordTransforms.count(),
|
||||
child->fCoordTransforms.begin());
|
||||
}
|
||||
// Append the child's textures array to our textures array
|
||||
if (!child->fTextureAccesses.empty()) {
|
||||
fTextureAccesses.push_back_n(child->fTextureAccesses.count(),
|
||||
child->fTextureAccesses.begin());
|
||||
@ -120,10 +115,10 @@ void GrFragmentProcessor::notifyRefCntIsZero() const {
|
||||
}
|
||||
|
||||
bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
|
||||
if (this->numTransforms() != that.numTransforms()) {
|
||||
if (this->numCoordTransforms() != that.numCoordTransforms()) {
|
||||
return false;
|
||||
}
|
||||
int count = this->numTransforms();
|
||||
int count = this->numCoordTransforms();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (this->coordTransform(i) != that.coordTransform(i)) {
|
||||
return false;
|
||||
@ -408,3 +403,39 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
|
||||
}
|
||||
return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
|
||||
for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
|
||||
fFPStack.push_back(&pipeline.getFragmentProcessor(i));
|
||||
}
|
||||
}
|
||||
|
||||
const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
|
||||
if (fFPStack.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
const GrFragmentProcessor* back = fFPStack.back();
|
||||
fFPStack.pop_back();
|
||||
for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
|
||||
fFPStack.push_back(&back->childProcessor(i));
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const GrCoordTransform* GrFragmentProcessor::CoordTransformIter::next() {
|
||||
if (!fCurrFP) {
|
||||
return nullptr;
|
||||
}
|
||||
while (fCTIdx == fCurrFP->numCoordTransforms()) {
|
||||
fCTIdx = 0;
|
||||
fCurrFP = fFPIter.next();
|
||||
if (!fCurrFP) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &fCurrFP->coordTransform(fCTIdx++);
|
||||
}
|
||||
|
@ -161,8 +161,7 @@ private:
|
||||
gpArgs->fPositionVar,
|
||||
cgp.fInPosition->fName,
|
||||
cgp.fLocalMatrix,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
fragBuilder->codeAppend("float d = length(circleEdge.xy);");
|
||||
fragBuilder->codeAppend("float distanceToOuterEdge = circleEdge.z * (1.0 - d);");
|
||||
@ -210,14 +209,10 @@ private:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
this->setTransformDataHelper(primProc.cast<CircleGeometryProcessor>().fLocalMatrix,
|
||||
pdman, index, transforms);
|
||||
pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -319,8 +314,7 @@ private:
|
||||
gpArgs->fPositionVar,
|
||||
egp.fInPosition->fName,
|
||||
egp.fLocalMatrix,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// for outer curve
|
||||
fragBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||
@ -357,15 +351,10 @@ private:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override {
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<EllipseGeometryProcessor>().fLocalMatrix,
|
||||
pdman, index, transforms);
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const EllipseGeometryProcessor& egp = primProc.cast<EllipseGeometryProcessor>();
|
||||
this->setTransformDataHelper(egp.fLocalMatrix, pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -472,8 +461,7 @@ private:
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
diegp.fInPosition->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
@ -525,8 +513,8 @@ private:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>();
|
||||
|
||||
if (!diegp.fViewMatrix.isIdentity() && !fViewMatrix.cheapEqualTo(diegp.fViewMatrix)) {
|
||||
@ -535,6 +523,7 @@ private:
|
||||
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
}
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler);
|
||||
|
||||
// Setup uniform color
|
||||
if (pathProc.overrides().readsColor()) {
|
||||
@ -54,34 +54,30 @@ public:
|
||||
}
|
||||
|
||||
void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
tout->push_back_n(tin.count());
|
||||
fInstalledTransforms.push_back_n(tin.count());
|
||||
for (int i = 0; i < tin.count(); i++) {
|
||||
const ProcCoords& coordTransforms = tin[i];
|
||||
fInstalledTransforms[i].push_back_n(coordTransforms.count());
|
||||
for (int t = 0; t < coordTransforms.count(); t++) {
|
||||
GrSLType varyingType =
|
||||
coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
|
||||
kVec2f_GrSLType;
|
||||
FPCoordTransformHandler* transformHandler) {
|
||||
int i = 0;
|
||||
while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
|
||||
GrSLType varyingType =
|
||||
coordTransform->getMatrix().hasPerspective() ? kVec3f_GrSLType
|
||||
: kVec2f_GrSLType;
|
||||
|
||||
SkString strVaryingName("MatrixCoord");
|
||||
strVaryingName.appendf("_%i_%i", i, t);
|
||||
GrGLSLVertToFrag v(varyingType);
|
||||
GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
|
||||
fInstalledTransforms[i][t].fHandle =
|
||||
glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
|
||||
&v).toIndex();
|
||||
fInstalledTransforms[i][t].fType = varyingType;
|
||||
SkString strVaryingName;
|
||||
strVaryingName.printf("TransformedCoord_%d", i);
|
||||
GrGLSLVertToFrag v(varyingType);
|
||||
GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
|
||||
fInstalledTransforms.push_back().fHandle =
|
||||
glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
|
||||
&v).toIndex();
|
||||
fInstalledTransforms.back().fType = varyingType;
|
||||
|
||||
(*tout)[i].emplace_back(SkString(v.fsIn()), varyingType);
|
||||
}
|
||||
transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pd,
|
||||
const GrPrimitiveProcessor& primProc) override {
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
if (pathProc.overrides().readsColor() && pathProc.color() != fColor) {
|
||||
float c[4];
|
||||
@ -89,28 +85,21 @@ public:
|
||||
pd.set4fv(fColorUniform, 1, c);
|
||||
fColor = pathProc.color();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& coordTransforms) override {
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
SkTArray<TransformVarying, true>& transforms = fInstalledTransforms[index];
|
||||
int numTransforms = transforms.count();
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
SkASSERT(transforms[t].fHandle.isValid());
|
||||
const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(),
|
||||
*coordTransforms[t]);
|
||||
if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
|
||||
int t = 0;
|
||||
while (const GrCoordTransform* coordTransform = transformIter.next()) {
|
||||
SkASSERT(fInstalledTransforms[t].fHandle.isValid());
|
||||
const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
|
||||
if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
|
||||
continue;
|
||||
}
|
||||
transforms[t].fCurrentValue = transform;
|
||||
fInstalledTransforms[t].fCurrentValue = m;
|
||||
|
||||
SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
|
||||
transforms[t].fType == kVec3f_GrSLType);
|
||||
unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
|
||||
pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform);
|
||||
SkASSERT(fInstalledTransforms[t].fType == kVec2f_GrSLType ||
|
||||
fInstalledTransforms[t].fType == kVec3f_GrSLType);
|
||||
unsigned components = fInstalledTransforms[t].fType == kVec2f_GrSLType ? 2 : 3;
|
||||
pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m);
|
||||
++t;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +111,7 @@ private:
|
||||
GrSLType fType = kVoid_GrSLType;
|
||||
};
|
||||
|
||||
SkSTArray<8, SkSTArray<2, TransformVarying, true> > fInstalledTransforms;
|
||||
SkTArray<TransformVarying, true> fInstalledTransforms;
|
||||
|
||||
UniformHandle fColorUniform;
|
||||
GrColor fColor;
|
||||
|
@ -101,7 +101,7 @@ static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
|
||||
fp.getGLSLProcessorKey(glslCaps, b);
|
||||
|
||||
return gen_meta_key(fp, glslCaps, primProc.getTransformKey(fp.coordTransforms(),
|
||||
fp.numTransformsExclChildren()), b);
|
||||
fp.numCoordTransforms()), b);
|
||||
}
|
||||
|
||||
bool GrProgramDesc::Build(GrProgramDesc* desc,
|
||||
|
@ -577,8 +577,7 @@ public:
|
||||
gpArgs->fPositionVar,
|
||||
qe.inPosition()->fName,
|
||||
qe.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
@ -614,7 +613,8 @@ public:
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const QuadEdgeEffect& qe = gp.cast<QuadEdgeEffect>();
|
||||
if (qe.color() != fColor) {
|
||||
float c[4];
|
||||
@ -622,14 +622,7 @@ public:
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = qe.color();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<QuadEdgeEffect>().fLocalMatrix, pdman, index,
|
||||
transforms);
|
||||
this->setTransformDataHelper(qe.fLocalMatrix, pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "batches/GrVertexBatch.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "glsl/GrGLSLGeometryProcessor.h"
|
||||
#include "glsl/GrGLSLGeometryProcessor.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLVarying.h"
|
||||
#include "glsl/GrGLSLVertexShaderBuilder.h"
|
||||
@ -120,8 +121,7 @@ public:
|
||||
gpArgs->fPositionVar,
|
||||
rgp.inPosition()->fName,
|
||||
rgp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// TODO: compute all these offsets, spans, and scales in the VS
|
||||
fragBuilder->codeAppendf("float insetW = min(1.0, %s.x) - 0.5;",
|
||||
@ -194,15 +194,10 @@ public:
|
||||
b->add32(0x0);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<RectGeometryProcessor>().fLocalMatrix, pdman,
|
||||
index, transforms);
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const RectGeometryProcessor& rgp = primProc.cast<RectGeometryProcessor>();
|
||||
this->setTransformDataHelper(rgp.fLocalMatrix, pdman,&transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -148,8 +148,8 @@ public:
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
|
||||
qp.inPosition()->fName, SkMatrix::I(), args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
qp.inPosition()->fName, SkMatrix::I(),
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn(), uv.fsIn(),
|
||||
@ -167,14 +167,15 @@ public:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
virtual void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>();
|
||||
if (!qp.viewMatrix().isIdentity()) {
|
||||
float viewMatrix[3 * 3];
|
||||
GrGLSLGetMatrix<3>(viewMatrix, qp.viewMatrix());
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -333,8 +333,8 @@ public:
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
|
||||
te.inPosition()->fName, te.localMatrix(), args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
te.inPosition()->fName, te.localMatrix(),
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
@ -391,16 +391,10 @@ public:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
virtual void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<PLSAATriangleEffect>().fLocalMatrix, pdman,
|
||||
index, transforms);
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
this->setTransformDataHelper(gp.cast<PLSAATriangleEffect>().fLocalMatrix, pdman,
|
||||
&transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -522,8 +516,8 @@ public:
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
|
||||
qe.inPosition()->fName, qe.localMatrix(), args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
qe.inPosition()->fName, qe.localMatrix(),
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
@ -581,16 +575,10 @@ public:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
virtual void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<PLSQuadEdgeEffect>().fLocalMatrix, pdman,
|
||||
index, transforms);
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
this->setTransformDataHelper(gp.cast<PLSQuadEdgeEffect>().fLocalMatrix, pdman,
|
||||
&transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -680,8 +668,8 @@ public:
|
||||
varyingHandler->emitAttributes(fe);
|
||||
this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName);
|
||||
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
|
||||
fe.inPosition()->fName, fe.localMatrix(), args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
fe.inPosition()->fName, fe.localMatrix(),
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
@ -716,8 +704,8 @@ public:
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
virtual void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& gp) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const PLSFinishEffect& fe = gp.cast<PLSFinishEffect>();
|
||||
pdman.set1f(fUseEvenOdd, fe.fUseEvenOdd);
|
||||
if (fe.color() != fColor && !fe.colorIgnored()) {
|
||||
@ -726,14 +714,7 @@ public:
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = fe.color();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<PLSFinishEffect>().fLocalMatrix, pdman,
|
||||
index, transforms);
|
||||
this->setTransformDataHelper(fe.fLocalMatrix, pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder*);
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& primProc) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrConicEffect& ce = primProc.cast<GrConicEffect>();
|
||||
|
||||
if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
|
||||
@ -47,14 +47,7 @@ public:
|
||||
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
|
||||
fCoverageScale = ce.coverageScale();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<GrConicEffect>().localMatrix(), pdman, index,
|
||||
transforms);
|
||||
this->setTransformDataHelper(ce.localMatrix(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -109,8 +102,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// TODO: this precision check should actually be a check on the number of bits
|
||||
// high and medium provide and the selection of the lowest level that suffices.
|
||||
@ -299,8 +291,8 @@ public:
|
||||
const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder*);
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& primProc) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
|
||||
|
||||
if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) {
|
||||
@ -321,14 +313,7 @@ public:
|
||||
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
|
||||
fCoverageScale = qe.coverageScale();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<GrQuadEffect>().localMatrix(), pdman, index,
|
||||
transforms);
|
||||
this->setTransformDataHelper(qe.localMatrix(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -383,8 +368,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
fragBuilder->codeAppendf("float edgeAlpha;");
|
||||
|
||||
@ -516,8 +500,8 @@ public:
|
||||
const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder*);
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& primProc) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrCubicEffect& ce = primProc.cast<GrCubicEffect>();
|
||||
|
||||
if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
|
||||
@ -533,6 +517,7 @@ public:
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = ce.color();
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -584,8 +569,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
|
||||
GrGLSLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
|
||||
|
@ -60,8 +60,7 @@ public:
|
||||
gpArgs->fPositionVar,
|
||||
cte.inPosition()->fName,
|
||||
cte.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
if (cte.maskFormat() == kARGB_GrMaskFormat) {
|
||||
fragBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
@ -84,7 +83,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
|
||||
if (btgp.color() != fColor && !btgp.hasVertexColor()) {
|
||||
float c[4];
|
||||
@ -92,14 +92,7 @@ public:
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = btgp.color();
|
||||
}
|
||||
}
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<GrBitmapTextGeoProc>().localMatrix(), pdman,
|
||||
index, transforms);
|
||||
this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& proc,
|
||||
|
@ -817,16 +817,8 @@ public:
|
||||
const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder*);
|
||||
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override;
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<DashingCircleEffect>().localMatrix(), pdman,
|
||||
index, transforms);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
|
||||
FPCoordTransformIter&& transformIter) override;
|
||||
private:
|
||||
UniformHandle fParamUniform;
|
||||
UniformHandle fColorUniform;
|
||||
@ -879,8 +871,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
gpArgs->fPositionVar,
|
||||
dce.inPosition()->fName,
|
||||
dce.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// transforms all points so that we can compare them to our test circle
|
||||
fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
@ -901,7 +892,8 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
|
||||
void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& processor) {
|
||||
const GrPrimitiveProcessor& processor,
|
||||
FPCoordTransformIter&& transformIter) {
|
||||
const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
|
||||
if (dce.color() != fColor) {
|
||||
float c[4];
|
||||
@ -909,6 +901,7 @@ void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = dce.color();
|
||||
}
|
||||
this->setTransformDataHelper(dce.localMatrix(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp,
|
||||
@ -1037,15 +1030,8 @@ public:
|
||||
const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder*);
|
||||
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override;
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(primProc.cast<DashingLineEffect>().localMatrix(), pdman, index,
|
||||
transforms);
|
||||
}
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
|
||||
FPCoordTransformIter&& iter) override;
|
||||
|
||||
private:
|
||||
GrColor fColor;
|
||||
@ -1094,8 +1080,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
gpArgs->fPositionVar,
|
||||
de.inPosition()->fName,
|
||||
de.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// transforms all points so that we can compare them to our test rect
|
||||
fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
@ -1134,7 +1119,8 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
|
||||
void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& processor) {
|
||||
const GrPrimitiveProcessor& processor,
|
||||
FPCoordTransformIter&& transformIter) {
|
||||
const DashingLineEffect& de = processor.cast<DashingLineEffect>();
|
||||
if (de.color() != fColor) {
|
||||
float c[4];
|
||||
@ -1142,6 +1128,7 @@ void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
pdman.set4fv(fColorUniform, 1, c);
|
||||
fColor = de.color();
|
||||
}
|
||||
this->setTransformDataHelper(de.localMatrix(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp,
|
||||
|
@ -73,8 +73,7 @@ public:
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// add varyings
|
||||
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
|
||||
@ -179,7 +178,8 @@ public:
|
||||
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
#ifdef SK_GAMMA_APPLY_TO_A8
|
||||
const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>();
|
||||
float distanceAdjust = dfTexEffect.getDistanceAdjust();
|
||||
@ -196,6 +196,7 @@ public:
|
||||
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& gp,
|
||||
@ -345,8 +346,7 @@ public:
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
const char* textureSizeUniName = nullptr;
|
||||
fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||
@ -433,7 +433,8 @@ public:
|
||||
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
SkASSERT(fTextureSizeUni.isValid());
|
||||
|
||||
GrTexture* texture = proc.texture(0);
|
||||
@ -453,6 +454,7 @@ public:
|
||||
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& gp,
|
||||
@ -582,8 +584,7 @@ public:
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
|
||||
// set up varyings
|
||||
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
|
||||
@ -732,8 +733,8 @@ public:
|
||||
fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& processor) override {
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& processor,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
SkASSERT(fDistanceAdjustUni.isValid());
|
||||
|
||||
const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFieldLCDTextGeoProc>();
|
||||
@ -752,6 +753,7 @@ public:
|
||||
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
}
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& gp,
|
||||
|
@ -70,7 +70,8 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
|
||||
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
|
||||
// of GLProgram determine how to set coord transforms
|
||||
int nextSamplerIdx = 0;
|
||||
fGeometryProcessor->setData(fProgramDataManager, primProc);
|
||||
fGeometryProcessor->setData(fProgramDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
|
||||
|
||||
this->setFragmentData(primProc, pipeline, &nextSamplerIdx);
|
||||
@ -107,16 +108,10 @@ void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
|
||||
for (int i = 0; i < numProcessors; ++i) {
|
||||
const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
|
||||
fFragmentProcessors[i]->setData(fProgramDataManager, processor);
|
||||
this->setTransformData(primProc, processor, i);
|
||||
this->bindTextures(processor, pipeline.getAllowSRGBInputs(), nextSamplerIdx);
|
||||
}
|
||||
}
|
||||
void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrFragmentProcessor& processor,
|
||||
int index) {
|
||||
fGeometryProcessor->setTransformData(primProc, fProgramDataManager, index,
|
||||
processor.coordTransforms());
|
||||
}
|
||||
|
||||
|
||||
void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline) {
|
||||
|
@ -120,7 +120,6 @@ protected:
|
||||
|
||||
// A helper to loop over effects, set the transforms (via subclass) and bind textures
|
||||
void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx);
|
||||
void setTransformData(const GrPrimitiveProcessor&, const GrFragmentProcessor&, int index);
|
||||
|
||||
// Helper for setData() that sets the view matrix and loads the render target height uniform
|
||||
void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
|
||||
|
@ -43,16 +43,16 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
|
||||
|
||||
/*
|
||||
* We now want to find the subset of coords and samplers that belong to the child and its
|
||||
* descendants and put that into childCoords and childSamplers. To do so, we'll do a forwards
|
||||
* linear search.
|
||||
* TODO: Move textures and buffers to the iterator model used by coords.
|
||||
* We now want to find the subset of samplers that belong to the child and its descendants and
|
||||
* put that into childSamplers. To do so, we'll do a forwards linear search.
|
||||
*
|
||||
* Explanation:
|
||||
* Each GrFragmentProcessor has a copy of all the transforms and textures of itself and
|
||||
* all procs in its subtree. For example, suppose we have frag proc A, who has two children B
|
||||
* and D. B has a child C, and D has two children E and F. Each frag proc's transforms array
|
||||
* contains its own transforms, followed by the transforms of all its descendants (i.e. preorder
|
||||
* traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms respectively.
|
||||
* Each GrFragmentProcessor has a copy of all the textures of itself and all procs in its
|
||||
* subtree. For example, suppose we have frag proc A, who has two children B and D. B has a
|
||||
* child C, and D has two children E and F. Each frag proc's textures array contains its own
|
||||
* textures, followed by the textures of all its descendants (i.e. preorder traversal). Suppose
|
||||
* procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 textures respectively.
|
||||
*
|
||||
* (A)
|
||||
* [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2]
|
||||
@ -66,28 +66,22 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
* [c1] [e1,e2,e3] [f1,f2]
|
||||
*
|
||||
* So if we're inside proc A's emitCode, and A is about to call emitCode on proc D, we want the
|
||||
* EmitArgs that's passed onto D to only contain its and its descendants' coords. The
|
||||
* EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want
|
||||
* EmitArgs that's passed onto D to only contain its and its descendants' textures. The
|
||||
* EmitArgs given to A would contain the textures [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want
|
||||
* to extract the subset [d1,e1,e2,e3,f1,f2] to pass on to D. We can do this with a linear
|
||||
* search since we know that A has 1 transform (using A.numTransformsExclChildren()), and B's
|
||||
* subtree has 3 transforms (using B.numTransforms()), so we know the start of D's transforms is
|
||||
* 4 after the start of A's transforms.
|
||||
* Textures work the same way as transforms.
|
||||
* search since we know that A has 1 texture (using A.numTexturesExclChildren()), and B's
|
||||
* subtree has 3 textures (using B.numTextures()), so we know the start of D's textures is
|
||||
* 4 after the start of A's textures.
|
||||
* Textures work the same way as textures.
|
||||
*/
|
||||
int firstCoordAt = args.fFp.numTransformsExclChildren();
|
||||
int firstTextureAt = args.fFp.numTexturesExclChildren();
|
||||
int firstBufferAt = args.fFp.numBuffersExclChildren();
|
||||
for (int i = 0; i < childIndex; ++i) {
|
||||
firstCoordAt += args.fFp.childProcessor(i).numTransforms();
|
||||
firstTextureAt += args.fFp.childProcessor(i).numTextures();
|
||||
firstBufferAt += args.fFp.childProcessor(i).numBuffers();
|
||||
}
|
||||
SkTArray<GrShaderVar> childCoords;
|
||||
const SamplerHandle* childTexSamplers = nullptr;
|
||||
const SamplerHandle* childBufferSamplers = nullptr;
|
||||
if (childProc.numTransforms() > 0) {
|
||||
childCoords.push_back_n(childProc.numTransforms(), &args.fTransformedCoords[firstCoordAt]);
|
||||
}
|
||||
if (childProc.numTextures() > 0) {
|
||||
childTexSamplers = &args.fTexSamplers[firstTextureAt];
|
||||
}
|
||||
@ -99,13 +93,14 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
fragBuilder->codeAppend("{\n");
|
||||
fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
|
||||
fragBuilder->getMangleString().c_str(), childProc.name());
|
||||
TransformedCoordVars coordVars = args.fTransformedCoords.childTransforms(childIndex);
|
||||
EmitArgs childArgs(fragBuilder,
|
||||
args.fUniformHandler,
|
||||
args.fGLSLCaps,
|
||||
childProc,
|
||||
outputColor,
|
||||
inputColor,
|
||||
childCoords,
|
||||
coordVars,
|
||||
childTexSamplers,
|
||||
childBufferSamplers,
|
||||
args.fGpImplementsDistanceVector);
|
||||
@ -114,3 +109,19 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
|
||||
fragBuilder->onAfterChildProcEmitCode();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using TransformedCoordVars = GrGLSLFragmentProcessor::TransformedCoordVars;
|
||||
TransformedCoordVars TransformedCoordVars::childTransforms(int childIdx) const {
|
||||
const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
|
||||
GrFragmentProcessor::Iter iter(fFP);
|
||||
int numToSkip = 0;
|
||||
while (true) {
|
||||
const GrFragmentProcessor* fp = iter.next();
|
||||
if (fp == child) {
|
||||
return TransformedCoordVars(child, fTransformedVars + numToSkip);
|
||||
}
|
||||
numToSkip += fp->numCoordTransforms();
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,30 @@ public:
|
||||
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
|
||||
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
|
||||
|
||||
/**
|
||||
* When building a program from a GrPipeline this is used to provide the GrShaderVars that
|
||||
* contain the resulting transformed coords from each of a GrFragmentProcessor's
|
||||
* GrCoordTransforms. This allows the GrFragmentProcessor subclasses to refer to the transformed
|
||||
* coords in fragment code.
|
||||
*/
|
||||
class TransformedCoordVars {
|
||||
public:
|
||||
TransformedCoordVars(const GrFragmentProcessor* fp, const GrShaderVar* vars)
|
||||
: fFP(fp)
|
||||
, fTransformedVars(vars) {}
|
||||
|
||||
const GrShaderVar& operator[] (int i) const {
|
||||
SkASSERT(i >= 0 && i < fFP->numCoordTransforms());
|
||||
return fTransformedVars[i];
|
||||
}
|
||||
|
||||
TransformedCoordVars childTransforms(int childIdx) const;
|
||||
|
||||
private:
|
||||
const GrFragmentProcessor* fFP;
|
||||
const GrShaderVar* fTransformedVars;
|
||||
};
|
||||
|
||||
/** Called when the program stage should insert its code into the shaders. The code in each
|
||||
shader will be in its own block ({}) and so locally scoped names will not collide across
|
||||
stages.
|
||||
@ -50,7 +74,7 @@ public:
|
||||
etc.) that allows the processor to communicate back similar known
|
||||
info about its output.
|
||||
@param transformedCoords Fragment shader variables containing the coords computed using
|
||||
each of the GrFragmentProcessor's Coord Transforms.
|
||||
each of the GrFragmentProcessor's GrCoordTransforms.
|
||||
@param texSamplers Contains one entry for each GrTextureAccess of the GrProcessor.
|
||||
These can be passed to the builder to emit texture reads in the
|
||||
generated code.
|
||||
@ -65,7 +89,7 @@ public:
|
||||
const GrFragmentProcessor& fp,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const SkTArray<GrShaderVar>& transformedCoords,
|
||||
const TransformedCoordVars& transformedCoordVars,
|
||||
const SamplerHandle* texSamplers,
|
||||
const SamplerHandle* bufferSamplers,
|
||||
bool gpImplementsDistanceVector)
|
||||
@ -75,7 +99,7 @@ public:
|
||||
, fFp(fp)
|
||||
, fOutputColor(outputColor)
|
||||
, fInputColor(inputColor)
|
||||
, fTransformedCoords(transformedCoords)
|
||||
, fTransformedCoords(transformedCoordVars)
|
||||
, fTexSamplers(texSamplers)
|
||||
, fBufferSamplers(bufferSamplers)
|
||||
, fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
|
||||
@ -85,7 +109,7 @@ public:
|
||||
const GrFragmentProcessor& fFp;
|
||||
const char* fOutputColor;
|
||||
const char* fInputColor;
|
||||
const SkTArray<GrShaderVar>& fTransformedCoords;
|
||||
const TransformedCoordVars& fTransformedCoords;
|
||||
const SamplerHandle* fTexSamplers;
|
||||
const SamplerHandle* fBufferSamplers;
|
||||
bool fGpImplementsDistanceVector;
|
||||
|
@ -29,73 +29,84 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const SkMatrix& localMatrix,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
tout->push_back_n(tin.count());
|
||||
fInstalledTransforms.push_back_n(tin.count());
|
||||
for (int i = 0; i < tin.count(); i++) {
|
||||
const ProcCoords& coordTransforms = tin[i];
|
||||
fInstalledTransforms[i].push_back_n(coordTransforms.count());
|
||||
for (int t = 0; t < coordTransforms.count(); t++) {
|
||||
SkString strUniName("StageMatrix");
|
||||
strUniName.appendf("_%i_%i", i, t);
|
||||
GrSLType varyingType;
|
||||
FPCoordTransformHandler* handler) {
|
||||
int i = 0;
|
||||
while (const GrCoordTransform* coordTransform = handler->nextCoordTransform()) {
|
||||
SkString strUniName;
|
||||
strUniName.printf("CoordTransformMatrix_%d", i);
|
||||
GrSLType varyingType;
|
||||
|
||||
GrCoordSet coordType = coordTransforms[t]->sourceCoords();
|
||||
uint32_t type = coordTransforms[t]->getMatrix().getType();
|
||||
if (kLocal_GrCoordSet == coordType) {
|
||||
type |= localMatrix.getType();
|
||||
}
|
||||
varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
|
||||
kVec2f_GrSLType;
|
||||
GrSLPrecision precision = coordTransforms[t]->precision();
|
||||
GrCoordSet coordType = coordTransform->sourceCoords();
|
||||
uint32_t type = coordTransform->getMatrix().getType();
|
||||
if (kLocal_GrCoordSet == coordType) {
|
||||
type |= localMatrix.getType();
|
||||
}
|
||||
varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
|
||||
kVec2f_GrSLType;
|
||||
GrSLPrecision precision = coordTransform->precision();
|
||||
|
||||
const char* uniName;
|
||||
fInstalledTransforms[i][t].fHandle =
|
||||
uniformHandler->addUniform(kVertex_GrShaderFlag,
|
||||
kMat33f_GrSLType, precision,
|
||||
strUniName.c_str(),
|
||||
&uniName).toIndex();
|
||||
const char* uniName;
|
||||
|
||||
SkString strVaryingName("MatrixCoord");
|
||||
strVaryingName.appendf("_%i_%i", i, t);
|
||||
|
||||
GrGLSLVertToFrag v(varyingType);
|
||||
varyingHandler->addVarying(strVaryingName.c_str(), &v, precision);
|
||||
fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag,
|
||||
kMat33f_GrSLType,
|
||||
precision,
|
||||
strUniName.c_str(),
|
||||
&uniName).toIndex();
|
||||
SkString strVaryingName;
|
||||
strVaryingName.printf("TransformedCoords_%d", i);
|
||||
|
||||
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
|
||||
(*tout)[i].emplace_back(SkString(v.fsIn()), varyingType);
|
||||
GrGLSLVertToFrag v(varyingType);
|
||||
varyingHandler->addVarying(strVaryingName.c_str(), &v, precision);
|
||||
|
||||
// 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());
|
||||
}
|
||||
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 {
|
||||
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());
|
||||
}
|
||||
// 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 == varyingType) {
|
||||
vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
|
||||
if (kVec2f_GrSLType == posVar.getType()) {
|
||||
vb->codeAppendf("%s = %s * vec3(%s, 1);",
|
||||
v.vsOut(), uniName, posVar.c_str());
|
||||
} else {
|
||||
vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
|
||||
vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
FPCoordTransformIter* transformIter) {
|
||||
int i = 0;
|
||||
while (const GrCoordTransform* coordTransform = transformIter->next()) {
|
||||
const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform);
|
||||
if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) {
|
||||
pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m);
|
||||
fInstalledTransforms[i].fCurrentValue = m;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
SkASSERT(i == fInstalledTransforms.count());
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder,
|
||||
GrGPArgs* gpArgs,
|
||||
const char* posName) {
|
||||
|
@ -22,31 +22,11 @@ public:
|
||||
/* Any general emit code goes in the base class emitCode. Subclasses override onEmitCode */
|
||||
void emitCode(EmitArgs&) override;
|
||||
|
||||
// By default we use the identity matrix
|
||||
void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) override {
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, index, transforms);
|
||||
}
|
||||
|
||||
protected:
|
||||
// A helper which subclasses can use if needed and used above in the default setTransformData().
|
||||
void setTransformDataHelper(const SkMatrix& localMatrix,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) {
|
||||
SkTArray<TransformUniform, true>& procTransforms = fInstalledTransforms[index];
|
||||
int numTransforms = transforms.count();
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
SkASSERT(procTransforms[t].fHandle.isValid());
|
||||
const SkMatrix& transform = GetTransformMatrix(localMatrix, *transforms[t]);
|
||||
if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) {
|
||||
pdman.setSkMatrix(procTransforms[t].fHandle.toIndex(), transform);
|
||||
procTransforms[t].fCurrentValue = transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
FPCoordTransformIter*);
|
||||
|
||||
// Emit a uniform matrix for each coord transform.
|
||||
void emitTransforms(GrGLSLVertexBuilder* vb,
|
||||
@ -54,10 +34,9 @@ protected:
|
||||
GrGLSLUniformHandler* uniformHandler,
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
FPCoordTransformHandler* handler) {
|
||||
this->emitTransforms(vb, varyingHandler, uniformHandler,
|
||||
posVar, localCoords, SkMatrix::I(), tin, tout);
|
||||
posVar, localCoords, SkMatrix::I(), handler);
|
||||
}
|
||||
|
||||
// Emit pre-transformed coords as a vertex attribute per coord-transform.
|
||||
@ -67,8 +46,7 @@ protected:
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const SkMatrix& localMatrix,
|
||||
const TransformsIn&,
|
||||
TransformsOut*);
|
||||
FPCoordTransformHandler*);
|
||||
|
||||
struct GrGPArgs {
|
||||
// The variable used by a GP to store its position. It can be
|
||||
@ -103,7 +81,7 @@ private:
|
||||
SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
|
||||
};
|
||||
|
||||
SkSTArray<8, SkSTArray<2, TransformUniform, true> > fInstalledTransforms;
|
||||
SkTArray<TransformUniform, true> fInstalledTransforms;
|
||||
|
||||
typedef GrGLSLPrimitiveProcessor INHERITED;
|
||||
};
|
||||
|
@ -47,3 +47,16 @@ void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLPPFragmentBuilder* fragBu
|
||||
&stagedLocalVarName);
|
||||
fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const GrCoordTransform* GrGLSLPrimitiveProcessor::FPCoordTransformHandler::nextCoordTransform() {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(nullptr == fCurr || fAddedCoord);
|
||||
fAddedCoord = false;
|
||||
fCurr = fIter.next();
|
||||
return fCurr;
|
||||
#else
|
||||
return fIter.next();
|
||||
#endif
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef GrGLSLPrimitiveProcessor_DEFINED
|
||||
#define GrGLSLPrimitiveProcessor_DEFINED
|
||||
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrPrimitiveProcessor.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLSampler.h"
|
||||
@ -23,14 +24,45 @@ class GrGLSLVertexBuilder;
|
||||
|
||||
class GrGLSLPrimitiveProcessor {
|
||||
public:
|
||||
using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;
|
||||
|
||||
virtual ~GrGLSLPrimitiveProcessor() {}
|
||||
|
||||
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
|
||||
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
|
||||
|
||||
typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
|
||||
typedef SkSTArray<8, ProcCoords> TransformsIn;
|
||||
typedef SkSTArray<8, SkTArray<GrShaderVar>> TransformsOut;
|
||||
/**
|
||||
* This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
|
||||
* GrPipeline. It is also used by the primitive processor to specify the fragment shader
|
||||
* variable that will hold the transformed coords for each GrCoordTransform. It is required that
|
||||
* the primitive processor iterate over each coord transform and insert a shader var result for
|
||||
* each. The GrGLSLFragmentProcessors will reference these variables in their fragment code.
|
||||
*/
|
||||
class FPCoordTransformHandler : public SkNoncopyable {
|
||||
public:
|
||||
FPCoordTransformHandler(const GrPipeline& pipeline,
|
||||
SkTArray<GrShaderVar>* transformedCoordVars)
|
||||
: fIter(pipeline)
|
||||
, fTransformedCoordVars(transformedCoordVars) {}
|
||||
|
||||
~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());}
|
||||
|
||||
const GrCoordTransform* nextCoordTransform();
|
||||
|
||||
// 'args' are constructor params to GrShaderVar.
|
||||
template<typename... Args>
|
||||
void specifyCoordsForCurrCoordTransform(Args&&... args) {
|
||||
SkASSERT(!fAddedCoord);
|
||||
fTransformedCoordVars->emplace_back(std::forward<Args>(args)...);
|
||||
SkDEBUGCODE(fAddedCoord = true;)
|
||||
}
|
||||
|
||||
private:
|
||||
GrFragmentProcessor::CoordTransformIter fIter;
|
||||
SkDEBUGCODE(bool fAddedCoord = false;)
|
||||
SkDEBUGCODE(const GrCoordTransform* fCurr = nullptr;)
|
||||
SkTArray<GrShaderVar>* fTransformedCoordVars;
|
||||
};
|
||||
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLVertexBuilder* vertBuilder,
|
||||
@ -44,8 +76,7 @@ public:
|
||||
const char* distanceVectorName,
|
||||
const SamplerHandle* texSamplers,
|
||||
const SamplerHandle* bufferSamplers,
|
||||
const TransformsIn& transformsIn,
|
||||
TransformsOut* transformsOut)
|
||||
FPCoordTransformHandler* transformHandler)
|
||||
: fVertBuilder(vertBuilder)
|
||||
, fFragBuilder(fragBuilder)
|
||||
, fVaryingHandler(varyingHandler)
|
||||
@ -57,8 +88,7 @@ public:
|
||||
, fDistanceVectorName(distanceVectorName)
|
||||
, fTexSamplers(texSamplers)
|
||||
, fBufferSamplers(bufferSamplers)
|
||||
, fTransformsIn(transformsIn)
|
||||
, fTransformsOut(transformsOut) {}
|
||||
, fFPCoordTransformHandler(transformHandler) {}
|
||||
GrGLSLVertexBuilder* fVertBuilder;
|
||||
GrGLSLPPFragmentBuilder* fFragBuilder;
|
||||
GrGLSLVaryingHandler* fVaryingHandler;
|
||||
@ -70,8 +100,7 @@ public:
|
||||
const char* fDistanceVectorName;
|
||||
const SamplerHandle* fTexSamplers;
|
||||
const SamplerHandle* fBufferSamplers;
|
||||
const TransformsIn& fTransformsIn;
|
||||
TransformsOut* fTransformsOut;
|
||||
FPCoordTransformHandler* fFPCoordTransformHandler;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -80,21 +109,22 @@ public:
|
||||
*/
|
||||
virtual void emitCode(EmitArgs&) = 0;
|
||||
|
||||
/** A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
|
||||
produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
|
||||
uploads any uniform variables required by the shaders created in emitCode(). The
|
||||
GrPrimitiveProcessor parameter is guaranteed to be of the same type that created this
|
||||
GrGLSLPrimitiveProcessor and to have an identical processor key as the one that created this
|
||||
GrGLSLPrimitiveProcessor. */
|
||||
virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) = 0;
|
||||
/**
|
||||
* A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
|
||||
* produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
|
||||
* uploads any uniform variables required by the shaders created in emitCode(). The
|
||||
* GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
|
||||
* identical processor key as the GrPrimitiveProcessor that created this
|
||||
* GrGLSLPrimitiveProcessor.
|
||||
* The subclass may use the transform iterator to perform any setup required for the particular
|
||||
* set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over
|
||||
* the transforms in the same order as the TransformHandler passed to emitCode.
|
||||
*/
|
||||
virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
|
||||
FPCoordTransformIter&&) = 0;
|
||||
|
||||
static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&);
|
||||
|
||||
virtual void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrGLSLProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms) = 0;
|
||||
|
||||
protected:
|
||||
void setupUniformColor(GrGLSLPPFragmentBuilder* fragBuilder,
|
||||
GrGLSLUniformHandler* uniformHandler,
|
||||
|
@ -53,19 +53,9 @@ bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
|
||||
// be sent to the GrGLSLPrimitiveProcessor in its emitCode function
|
||||
const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
|
||||
|
||||
for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) {
|
||||
const GrFragmentProcessor& processor = this->pipeline().getFragmentProcessor(i);
|
||||
|
||||
SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back();
|
||||
processor.gatherCoordTransforms(&procCoords);
|
||||
}
|
||||
|
||||
this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage);
|
||||
|
||||
int numProcs = this->pipeline().numFragmentProcessors();
|
||||
this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors(), inputColor);
|
||||
this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(), numProcs,
|
||||
inputCoverage);
|
||||
this->emitAndInstallFragProcs(inputColor, inputCoverage);
|
||||
if (primProc.getPixelLocalStorageState() !=
|
||||
GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
|
||||
this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor,
|
||||
@ -109,6 +99,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
||||
SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
|
||||
this->emitSamplers(proc, &texSamplers, &bufferSamplers);
|
||||
|
||||
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
|
||||
&fTransformedCoordVars);
|
||||
GrGLSLGeometryProcessor::EmitArgs args(&fVS,
|
||||
&fFS,
|
||||
this->varyingHandler(),
|
||||
@ -120,8 +112,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
||||
distanceVectorName,
|
||||
texSamplers.begin(),
|
||||
bufferSamplers.begin(),
|
||||
fCoordTransforms,
|
||||
&fOutCoords);
|
||||
&transformHandler);
|
||||
fGeometryProcessor->emitCode(args);
|
||||
|
||||
// We have to check that effects and the code they emit are consistent, ie if an effect
|
||||
@ -131,14 +122,21 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
||||
fFS.codeAppend("}");
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::emitAndInstallFragProcs(int procOffset,
|
||||
int numProcs,
|
||||
GrGLSLExpr4* inOut) {
|
||||
for (int i = procOffset; i < numProcs; ++i) {
|
||||
void GrGLSLProgramBuilder::emitAndInstallFragProcs(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
|
||||
int transformedCoordVarsIdx = 0;
|
||||
GrGLSLExpr4** inOut = &color;
|
||||
for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) {
|
||||
if (i == this->pipeline().numColorFragmentProcessors()) {
|
||||
inOut = &coverage;
|
||||
}
|
||||
GrGLSLExpr4 output;
|
||||
const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i);
|
||||
this->emitAndInstallFragProc(fp, i, *inOut, &output);
|
||||
*inOut = output;
|
||||
this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, &output);
|
||||
GrFragmentProcessor::Iter iter(&fp);
|
||||
while (const GrFragmentProcessor* fp = iter.next()) {
|
||||
transformedCoordVarsIdx += fp->numCoordTransforms();
|
||||
}
|
||||
**inOut = output;
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +144,7 @@ void GrGLSLProgramBuilder::emitAndInstallFragProcs(int procOffset,
|
||||
// the fix is to allow effects to take the GrGLSLExpr4 directly
|
||||
void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
|
||||
int index,
|
||||
int transformedCoordVarsIdx,
|
||||
const GrGLSLExpr4& input,
|
||||
GrGLSLExpr4* output) {
|
||||
// Program builders have a bit of state we need to clear with each effect
|
||||
@ -163,13 +162,15 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
|
||||
SkSTArray<2, SamplerHandle> bufferSamplers(fp.numBuffers());
|
||||
this->emitSamplers(fp, &texSamplers, &bufferSamplers);
|
||||
|
||||
const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
|
||||
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
|
||||
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
|
||||
this->uniformHandler(),
|
||||
this->glslCaps(),
|
||||
fp,
|
||||
output->c_str(),
|
||||
input.isOnes() ? nullptr : input.c_str(),
|
||||
fOutCoords[index],
|
||||
coords,
|
||||
texSamplers.begin(),
|
||||
bufferSamplers.begin(),
|
||||
this->primitiveProcessor().implementsDistanceVector());
|
||||
@ -418,5 +419,4 @@ void GrGLSLProgramBuilder::finalizeShaders() {
|
||||
this->varyingHandler()->finalize();
|
||||
fVS.finalize(kVertex_GrShaderFlag);
|
||||
fFS.finalize(kFragment_GrShaderFlag);
|
||||
|
||||
}
|
||||
|
@ -139,9 +139,10 @@ private:
|
||||
void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
|
||||
GrGLSLExpr4* outputColor,
|
||||
GrGLSLExpr4* outputCoverage);
|
||||
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
|
||||
void emitAndInstallFragProcs(GrGLSLExpr4* colorInOut, GrGLSLExpr4* coverageInOut);
|
||||
void emitAndInstallFragProc(const GrFragmentProcessor&,
|
||||
int index,
|
||||
int transformedCoordVarsIdx,
|
||||
const GrGLSLExpr4& input,
|
||||
GrGLSLExpr4* output);
|
||||
void emitAndInstallXferProc(const GrXferProcessor&,
|
||||
@ -167,11 +168,10 @@ private:
|
||||
void verify(const GrFragmentProcessor&);
|
||||
#endif
|
||||
|
||||
GrGLSLPrimitiveProcessor::TransformsIn fCoordTransforms;
|
||||
GrGLSLPrimitiveProcessor::TransformsOut fOutCoords;
|
||||
int fNumVertexSamplers;
|
||||
int fNumGeometrySamplers;
|
||||
int fNumFragmentSamplers;
|
||||
int fNumVertexSamplers;
|
||||
int fNumGeometrySamplers;
|
||||
int fNumFragmentSamplers;
|
||||
SkSTArray<4, GrShaderVar> fTransformedCoordVars;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -80,7 +80,10 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;
|
||||
|
||||
private:
|
||||
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {}
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
}
|
||||
|
||||
class VertexInputs;
|
||||
class Backend;
|
||||
@ -388,7 +391,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
gpArgs->fPositionVar.set(positionType, "deviceCoords");
|
||||
|
||||
this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
args.fFPCoordTransformHandler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -194,14 +194,13 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
|
||||
|
||||
SkSTArray<8, const GrTextureAccess*> textureBindings;
|
||||
|
||||
fGeometryProcessor->setData(fDataManager, primProc);
|
||||
fGeometryProcessor->setData(fDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
append_texture_bindings(primProc, &textureBindings);
|
||||
|
||||
for (int i = 0; i < fFragmentProcessors.count(); ++i) {
|
||||
const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
|
||||
fFragmentProcessors[i]->setData(fDataManager, processor);
|
||||
fGeometryProcessor->setTransformData(primProc, fDataManager, i,
|
||||
processor.coordTransforms());
|
||||
append_texture_bindings(processor, &textureBindings);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,8 @@ private:
|
||||
this->setupPosition(args.fVertBuilder, gpArgs, gp.fAttribs[0].fName);
|
||||
}
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrPrimitiveProcessor& primProc) override {}
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&&) override {}
|
||||
};
|
||||
return new GLSLGP();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user