Use varyings to implement MatrixEffects applied to DeviceCoord FPs.
Modify GrGLSLGP's logic to add a varying for a series of matrix sample usages below a DeviceSpace FP in the FP hierarchy. The varying is based off the GPs position output variable in the VS. Adds a new sample usage type for the DeviceSpace FP. Bug: skia:12198 Change-Id: Ic39f3296c60a073656ad0c72a431a462d5714e92 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/435717 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
0dd5f62310
commit
9eca2ca0c6
@ -140,15 +140,21 @@ SkBitmap make_test_bitmap() {
|
|||||||
enum EffectType {
|
enum EffectType {
|
||||||
kUniform,
|
kUniform,
|
||||||
kExplicit,
|
kExplicit,
|
||||||
|
kDevice,
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<GrFragmentProcessor> wrap(std::unique_ptr<GrFragmentProcessor> fp,
|
static std::unique_ptr<GrFragmentProcessor> wrap(std::unique_ptr<GrFragmentProcessor> fp,
|
||||||
EffectType effectType) {
|
EffectType effectType,
|
||||||
|
int drawX, int drawY) {
|
||||||
switch (effectType) {
|
switch (effectType) {
|
||||||
case kUniform:
|
case kUniform:
|
||||||
return std::make_unique<UniformMatrixEffect>(std::move(fp));
|
return std::make_unique<UniformMatrixEffect>(std::move(fp));
|
||||||
case kExplicit:
|
case kExplicit:
|
||||||
return std::make_unique<ExplicitCoordEffect>(std::move(fp));
|
return std::make_unique<ExplicitCoordEffect>(std::move(fp));
|
||||||
|
case kDevice:
|
||||||
|
// Subtract out upper-left corner of draw so that device is effectively identity.
|
||||||
|
fp = GrMatrixEffect::Make(SkMatrix::Translate(-drawX, -drawY), std::move(fp));
|
||||||
|
return GrFragmentProcessor::DeviceSpace(std::move(fp));
|
||||||
}
|
}
|
||||||
SkUNREACHABLE;
|
SkUNREACHABLE;
|
||||||
}
|
}
|
||||||
@ -157,7 +163,7 @@ static std::unique_ptr<GrFragmentProcessor> wrap(std::unique_ptr<GrFragmentProce
|
|||||||
|
|
||||||
namespace skiagm {
|
namespace skiagm {
|
||||||
|
|
||||||
DEF_SIMPLE_GPU_GM_CAN_FAIL(fp_sample_chaining, rContext, canvas, errorMsg, 232, 232) {
|
DEF_SIMPLE_GPU_GM_CAN_FAIL(fp_sample_chaining, rContext, canvas, errorMsg, 232, 306) {
|
||||||
auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas);
|
auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas);
|
||||||
if (!sdc) {
|
if (!sdc) {
|
||||||
*errorMsg = GM::kErrorMsg_DrawSkippedGpuOnly;
|
*errorMsg = GM::kErrorMsg_DrawSkippedGpuOnly;
|
||||||
@ -182,7 +188,7 @@ DEF_SIMPLE_GPU_GM_CAN_FAIL(fp_sample_chaining, rContext, canvas, errorMsg, 232,
|
|||||||
auto fp = GrTextureEffect::Make(std::move(view), bmp.alphaType());
|
auto fp = GrTextureEffect::Make(std::move(view), bmp.alphaType());
|
||||||
#endif
|
#endif
|
||||||
for (EffectType effectType : effects) {
|
for (EffectType effectType : effects) {
|
||||||
fp = wrap(std::move(fp), effectType);
|
fp = wrap(std::move(fp), effectType, x, y);
|
||||||
}
|
}
|
||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
paint.setColorFragmentProcessor(std::move(fp));
|
paint.setColorFragmentProcessor(std::move(fp));
|
||||||
@ -206,9 +212,16 @@ DEF_SIMPLE_GPU_GM_CAN_FAIL(fp_sample_chaining, rContext, canvas, errorMsg, 232,
|
|||||||
draw({ kExplicit, kExplicit }); // Translate up by 16px
|
draw({ kExplicit, kExplicit }); // Translate up by 16px
|
||||||
nextRow();
|
nextRow();
|
||||||
|
|
||||||
// Remember, these are applied inside out:
|
// Third row: Remember, these are applied inside out:
|
||||||
draw({ kUniform, kExplicit }); // Scale Y by 2x and translate up by 8px
|
draw({ kUniform, kExplicit }); // Scale Y by 2x and translate up by 8px
|
||||||
draw({ kExplicit, kUniform }); // Scale Y by 2x and translate up by 16px
|
draw({ kExplicit, kUniform }); // Scale Y by 2x and translate up by 16px
|
||||||
|
nextRow();
|
||||||
|
|
||||||
|
// Fourth row: device space.
|
||||||
|
draw({ kDevice, kUniform }); // Same as identity (uniform applied *before*
|
||||||
|
// device so ignored).
|
||||||
|
draw({ kExplicit, kUniform, kDevice }); // Scale Y by 2x and translate up by 16px
|
||||||
|
draw({ kDevice, kExplicit, kUniform, kDevice }); // Identity, again.
|
||||||
|
|
||||||
return DrawResult::kOk;
|
return DrawResult::kOk;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
kPassThrough,
|
kPassThrough,
|
||||||
// Child is sampled with a matrix whose value is uniform
|
// Child is sampled with a matrix whose value is uniform
|
||||||
kUniformMatrix,
|
kUniformMatrix,
|
||||||
|
// Child is sampled with sk_FragCoord.xy
|
||||||
|
kFragCoord,
|
||||||
// Child is sampled using explicit coordinates
|
// Child is sampled using explicit coordinates
|
||||||
kExplicit,
|
kExplicit,
|
||||||
};
|
};
|
||||||
@ -52,6 +54,8 @@ public:
|
|||||||
return SampleUsage(Kind::kPassThrough, false);
|
return SampleUsage(Kind::kPassThrough, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SampleUsage FragCoord() { return SampleUsage(Kind::kFragCoord, false); }
|
||||||
|
|
||||||
bool operator==(const SampleUsage& that) const {
|
bool operator==(const SampleUsage& that) const {
|
||||||
return fKind == that.fKind && fHasPerspective == that.fHasPerspective;
|
return fKind == that.fKind && fHasPerspective == that.fHasPerspective;
|
||||||
}
|
}
|
||||||
@ -71,6 +75,7 @@ public:
|
|||||||
bool isPassThrough() const { return fKind == Kind::kPassThrough; }
|
bool isPassThrough() const { return fKind == Kind::kPassThrough; }
|
||||||
bool isExplicit() const { return fKind == Kind::kExplicit; }
|
bool isExplicit() const { return fKind == Kind::kExplicit; }
|
||||||
bool isUniformMatrix() const { return fKind == Kind::kUniformMatrix; }
|
bool isUniformMatrix() const { return fKind == Kind::kUniformMatrix; }
|
||||||
|
bool isFragCoord() const { return fKind == Kind::kFragCoord; }
|
||||||
|
|
||||||
std::string constructor() const;
|
std::string constructor() const;
|
||||||
|
|
||||||
|
@ -652,7 +652,8 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::DeviceSpace(
|
|||||||
private:
|
private:
|
||||||
DeviceSpace(std::unique_ptr<GrFragmentProcessor> fp)
|
DeviceSpace(std::unique_ptr<GrFragmentProcessor> fp)
|
||||||
: GrFragmentProcessor(kDeviceSpace_ClassID, fp->optimizationFlags()) {
|
: GrFragmentProcessor(kDeviceSpace_ClassID, fp->optimizationFlags()) {
|
||||||
this->registerChild(std::move(fp), SkSL::SampleUsage::Explicit());
|
// Passing FragCoord here is the reason this is a subclass and not a runtime-FP.
|
||||||
|
this->registerChild(std::move(fp), SkSL::SampleUsage::FragCoord());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> clone() const override {
|
std::unique_ptr<GrFragmentProcessor> clone() const override {
|
||||||
|
@ -70,6 +70,7 @@ SkString GrGLSLFragmentProcessor::invokeChild(int childIndex,
|
|||||||
SkASSERT(!childProc->sampleUsage().isUniformMatrix());
|
SkASSERT(!childProc->sampleUsage().isUniformMatrix());
|
||||||
|
|
||||||
if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
|
if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
|
||||||
|
SkASSERT(!childProc->sampleUsage().isFragCoord() || skslCoords == "sk_FragCoord.xy");
|
||||||
// The child's function takes a half4 color and a float2 coordinate
|
// The child's function takes a half4 color and a float2 coordinate
|
||||||
invocation.appendf(", %s", skslCoords.empty() ? args.fSampleCoord : skslCoords.c_str());
|
invocation.appendf(", %s", skslCoords.empty() ? args.fSampleCoord : skslCoords.c_str());
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::emitCode(EmitArgs&
|
|||||||
args.fVaryingHandler,
|
args.fVaryingHandler,
|
||||||
args.fUniformHandler,
|
args.fUniformHandler,
|
||||||
gpArgs.fLocalCoordVar,
|
gpArgs.fLocalCoordVar,
|
||||||
|
gpArgs.fPositionVar,
|
||||||
pipeline);
|
pipeline);
|
||||||
|
|
||||||
if (args.fGeomProc.willUseTessellationShaders()) {
|
if (args.fGeomProc.willUseTessellationShaders()) {
|
||||||
@ -76,18 +77,22 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::collectTransforms(
|
|||||||
GrGLSLVaryingHandler* varyingHandler,
|
GrGLSLVaryingHandler* varyingHandler,
|
||||||
GrGLSLUniformHandler* uniformHandler,
|
GrGLSLUniformHandler* uniformHandler,
|
||||||
const GrShaderVar& localCoordsVar,
|
const GrShaderVar& localCoordsVar,
|
||||||
|
const GrShaderVar& positionVar,
|
||||||
const GrPipeline& pipeline) {
|
const GrPipeline& pipeline) {
|
||||||
SkASSERT(localCoordsVar.getType() == kFloat2_GrSLType ||
|
SkASSERT(localCoordsVar.getType() == kFloat2_GrSLType ||
|
||||||
localCoordsVar.getType() == kFloat3_GrSLType ||
|
localCoordsVar.getType() == kFloat3_GrSLType ||
|
||||||
localCoordsVar.getType() == kVoid_GrSLType);
|
localCoordsVar.getType() == kVoid_GrSLType);
|
||||||
|
SkASSERT(positionVar.getType() == kFloat2_GrSLType ||
|
||||||
|
positionVar.getType() == kFloat3_GrSLType);
|
||||||
|
|
||||||
|
enum class BaseCoord { kNone, kLocal, kPosition };
|
||||||
|
|
||||||
auto baseLocalCoordFSVar = [&, baseLocalCoord = GrGLSLVarying()]() mutable {
|
auto baseLocalCoordFSVar = [&, baseLocalCoord = GrGLSLVarying()]() mutable {
|
||||||
SkASSERT(GrSLTypeIsFloatType(localCoordsVar.getType()));
|
SkASSERT(GrSLTypeIsFloatType(localCoordsVar.getType()));
|
||||||
if (baseLocalCoord.type() == kVoid_GrSLType) {
|
if (baseLocalCoord.type() == kVoid_GrSLType) {
|
||||||
// Initialize to the GP provided coordinate
|
// Initialize to the GP provided coordinate
|
||||||
SkString baseLocalCoordName = SkStringPrintf("LocalCoord");
|
|
||||||
baseLocalCoord = GrGLSLVarying(localCoordsVar.getType());
|
baseLocalCoord = GrGLSLVarying(localCoordsVar.getType());
|
||||||
varyingHandler->addVarying(baseLocalCoordName.c_str(), &baseLocalCoord);
|
varyingHandler->addVarying("LocalCoord", &baseLocalCoord);
|
||||||
vb->codeAppendf("%s = %s;\n", baseLocalCoord.vsOut(), localCoordsVar.getName().c_str());
|
vb->codeAppendf("%s = %s;\n", baseLocalCoord.vsOut(), localCoordsVar.getName().c_str());
|
||||||
}
|
}
|
||||||
return baseLocalCoord.fsInVar();
|
return baseLocalCoord.fsInVar();
|
||||||
@ -97,12 +102,13 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::collectTransforms(
|
|||||||
// Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
|
// Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
|
||||||
// sampled with a series of matrices applied to local coords. For each such FP a varying is
|
// sampled with a series of matrices applied to local coords. For each such FP a varying is
|
||||||
// added to the varying handler and added to 'result'.
|
// added to the varying handler and added to 'result'.
|
||||||
auto liftTransforms = [&, traversalIndex = 0](auto& self,
|
auto liftTransforms = [&, traversalIndex = 0](
|
||||||
const GrFragmentProcessor& fp,
|
auto& self,
|
||||||
bool hasPerspective,
|
const GrFragmentProcessor& fp,
|
||||||
const GrFragmentProcessor* lastMatrixFP = nullptr,
|
bool hasPerspective,
|
||||||
int lastMatrixTraversalIndex = -1,
|
const GrFragmentProcessor* lastMatrixFP = nullptr,
|
||||||
bool inExplicitSubtree = false) mutable -> void {
|
int lastMatrixTraversalIndex = -1,
|
||||||
|
BaseCoord baseCoord = BaseCoord::kLocal) mutable -> void {
|
||||||
++traversalIndex;
|
++traversalIndex;
|
||||||
switch (fp.sampleUsage().kind()) {
|
switch (fp.sampleUsage().kind()) {
|
||||||
case SkSL::SampleUsage::Kind::kNone:
|
case SkSL::SampleUsage::Kind::kNone:
|
||||||
@ -117,15 +123,27 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::collectTransforms(
|
|||||||
lastMatrixFP = &fp;
|
lastMatrixFP = &fp;
|
||||||
lastMatrixTraversalIndex = traversalIndex;
|
lastMatrixTraversalIndex = traversalIndex;
|
||||||
break;
|
break;
|
||||||
|
case SkSL::SampleUsage::Kind::kFragCoord:
|
||||||
|
hasPerspective = positionVar.getType() == kFloat3_GrSLType;
|
||||||
|
lastMatrixFP = nullptr;
|
||||||
|
lastMatrixTraversalIndex = -1;
|
||||||
|
baseCoord = BaseCoord::kPosition;
|
||||||
|
break;
|
||||||
case SkSL::SampleUsage::Kind::kExplicit:
|
case SkSL::SampleUsage::Kind::kExplicit:
|
||||||
inExplicitSubtree = true;
|
baseCoord = BaseCoord::kNone;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& [varyingFSVar, hasCoordsParam] = result[&fp];
|
auto& [varyingFSVar, hasCoordsParam] = result[&fp];
|
||||||
hasCoordsParam = fp.usesSampleCoordsDirectly();
|
hasCoordsParam = fp.usesSampleCoordsDirectly();
|
||||||
|
|
||||||
if (fp.usesSampleCoordsDirectly() && !inExplicitSubtree) {
|
// We add a varying if we're in a chain of matrices multiplied by local or device coords.
|
||||||
|
// If the coord is the untransformed local coord we add a varying. We don't if it is
|
||||||
|
// untransformed device coords since it doesn't save us anything over "sk_FragCoord.xy". Of
|
||||||
|
// course, if the FP doesn't directly use its coords then we don't add a varying.
|
||||||
|
if (fp.usesSampleCoordsDirectly() &&
|
||||||
|
(baseCoord == BaseCoord::kLocal ||
|
||||||
|
(baseCoord == BaseCoord::kPosition && lastMatrixFP))) {
|
||||||
// Associate the varying with the highest possible node in the FP tree that shares the
|
// Associate the varying with the highest possible node in the FP tree that shares the
|
||||||
// same coordinates so that multiple FPs in a subtree can share. If there are no matrix
|
// same coordinates so that multiple FPs in a subtree can share. If there are no matrix
|
||||||
// sample nodes on the way up the tree then directly use the local coord.
|
// sample nodes on the way up the tree then directly use the local coord.
|
||||||
@ -134,13 +152,13 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::collectTransforms(
|
|||||||
} else {
|
} else {
|
||||||
// If there is an already a varying that incorporates all matrices from the root to
|
// If there is an already a varying that incorporates all matrices from the root to
|
||||||
// lastMatrixFP just use it. Otherwise, we add it.
|
// lastMatrixFP just use it. Otherwise, we add it.
|
||||||
auto& [varying, localCoord, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
|
auto& [varying, inputCoords, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
|
||||||
if (varying.type() == kVoid_GrSLType) {
|
if (varying.type() == kVoid_GrSLType) {
|
||||||
varying = GrGLSLVarying(hasPerspective ? kFloat3_GrSLType : kFloat2_GrSLType);
|
varying = GrGLSLVarying(hasPerspective ? kFloat3_GrSLType : kFloat2_GrSLType);
|
||||||
SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
|
SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
|
||||||
lastMatrixTraversalIndex);
|
lastMatrixTraversalIndex);
|
||||||
varyingHandler->addVarying(strVaryingName.c_str(), &varying);
|
varyingHandler->addVarying(strVaryingName.c_str(), &varying);
|
||||||
localCoord = localCoordsVar;
|
inputCoords = baseCoord == BaseCoord::kLocal ? localCoordsVar : positionVar;
|
||||||
varyingIdx = lastMatrixTraversalIndex;
|
varyingIdx = lastMatrixTraversalIndex;
|
||||||
}
|
}
|
||||||
SkASSERT(varyingIdx == lastMatrixTraversalIndex);
|
SkASSERT(varyingIdx == lastMatrixTraversalIndex);
|
||||||
@ -157,11 +175,12 @@ GrGLSLGeometryProcessor::FPCoordsMap GrGLSLGeometryProcessor::collectTransforms(
|
|||||||
hasPerspective,
|
hasPerspective,
|
||||||
lastMatrixFP,
|
lastMatrixFP,
|
||||||
lastMatrixTraversalIndex,
|
lastMatrixTraversalIndex,
|
||||||
inExplicitSubtree);
|
baseCoord);
|
||||||
// If we have a varying then we never need a param. Otherwise, if one of our
|
// If we have a varying then we never need a param. Otherwise, if one of our
|
||||||
// children takes a non-explicit coord then we'll need our coord.
|
// children takes a non-explicit coord then we'll need our coord.
|
||||||
hasCoordsParam |= varyingFSVar.getType() == kVoid_GrSLType &&
|
hasCoordsParam |= varyingFSVar.getType() == kVoid_GrSLType &&
|
||||||
!child->sampleUsage().isExplicit() &&
|
!child->sampleUsage().isExplicit() &&
|
||||||
|
!child->sampleUsage().isFragCoord() &&
|
||||||
result[child].hasCoordsParam;
|
result[child].hasCoordsParam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +218,7 @@ void GrGLSLGeometryProcessor::emitTransformCode(GrGLSLVertexBuilder* vb,
|
|||||||
|
|
||||||
// If we hit an ancestor with a varying on our walk up then save off the varying as the
|
// If we hit an ancestor with a varying on our walk up then save off the varying as the
|
||||||
// input to our accumulated transformExpression. Start off assuming we'll reach the root.
|
// input to our accumulated transformExpression. Start off assuming we'll reach the root.
|
||||||
GrShaderVar inputCoords = info.localCoords;
|
GrShaderVar inputCoords = info.inputCoords;
|
||||||
|
|
||||||
for (const auto* base = fp->parent(); base; base = base->parent()) {
|
for (const auto* base = fp->parent(); base; base = base->parent()) {
|
||||||
if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
|
if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
|
||||||
@ -209,13 +228,16 @@ void GrGLSLGeometryProcessor::emitTransformCode(GrGLSLVertexBuilder* vb,
|
|||||||
inputCoords = iter->second.varying.vsOutVar();
|
inputCoords = iter->second.varying.vsOutVar();
|
||||||
break;
|
break;
|
||||||
} else if (base->sampleUsage().isUniformMatrix()) {
|
} else if (base->sampleUsage().isUniformMatrix()) {
|
||||||
// Accumulate any matrices along the path to either the original local coords or
|
// Accumulate any matrices along the path to either the original local/device coords
|
||||||
// a parent varying. Getting here means this FP was sampled with a uniform matrix
|
// or a parent varying. Getting here means this FP was sampled with a uniform matrix
|
||||||
// but all uses of coords below here in the FP hierarchy are beneath additional
|
// but all uses of coords below here in the FP hierarchy are beneath additional
|
||||||
// matrix samples and thus this node wasn't assigned a varying.
|
// matrix samples and thus this node wasn't assigned a varying.
|
||||||
GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
|
GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
|
||||||
*base->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
|
*base->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
|
||||||
transformExpression.appendf(" * %s", uniform.getName().c_str());
|
transformExpression.appendf(" * %s", uniform.getName().c_str());
|
||||||
|
} else if (base->sampleUsage().isFragCoord()) {
|
||||||
|
// Our chain of matrices starts here and is based on the device space position.
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
// This intermediate FP is just a pass through and doesn't need to be built
|
// This intermediate FP is just a pass through and doesn't need to be built
|
||||||
// in to the expression, but we must visit its parents in case they add transforms.
|
// in to the expression, but we must visit its parents in case they add transforms.
|
||||||
|
@ -216,18 +216,19 @@ private:
|
|||||||
//
|
//
|
||||||
// This must happen before FP code emission so that the FPs can find the appropriate varying
|
// This must happen before FP code emission so that the FPs can find the appropriate varying
|
||||||
// handles they use in place of explicit coord sampling; it is automatically called after
|
// handles they use in place of explicit coord sampling; it is automatically called after
|
||||||
// onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar.
|
// onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar and
|
||||||
|
// GpArgs::fPositionVar.
|
||||||
FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
|
FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
|
||||||
GrGLSLVaryingHandler* varyingHandler,
|
GrGLSLVaryingHandler* varyingHandler,
|
||||||
GrGLSLUniformHandler* uniformHandler,
|
GrGLSLUniformHandler* uniformHandler,
|
||||||
const GrShaderVar& localCoordsVar,
|
const GrShaderVar& localCoordsVar,
|
||||||
|
const GrShaderVar& positionVar,
|
||||||
const GrPipeline& pipeline);
|
const GrPipeline& pipeline);
|
||||||
|
|
||||||
struct TransformInfo {
|
struct TransformInfo {
|
||||||
// The varying that conveys the coordinates to one or more FPs in the FS.
|
// The varying that conveys the coordinates to one or more FPs in the FS.
|
||||||
GrGLSLVarying varying;
|
GrGLSLVarying varying;
|
||||||
// The coordinate to be transformed. varying is computed from this.
|
// The coordinate to be transformed. varying is computed from this.
|
||||||
GrShaderVar localCoords;
|
GrShaderVar inputCoords;
|
||||||
// Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
|
// Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
|
||||||
int traversalOrder;
|
int traversalOrder;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user