Remove GrCoordTransform entirely
Bug: skia:10416
Change-Id: I0ca7535a0e6507e6b2a9f4682788826972c5f3b8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/300296
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 9a40c93..8a0f765 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -71,7 +71,6 @@
"$_src/gpu/GrContextThreadSafeProxy.cpp",
"$_src/gpu/GrContextThreadSafeProxyPriv.h",
"$_src/gpu/GrContext_Base.cpp",
- "$_src/gpu/GrCoordTransform.h",
"$_src/gpu/GrCopyRenderTask.cpp",
"$_src/gpu/GrCopyRenderTask.h",
"$_src/gpu/GrCpuBuffer.h",
diff --git a/src/gpu/GrCoordTransform.h b/src/gpu/GrCoordTransform.h
deleted file mode 100644
index 85cdf2e..0000000
--- a/src/gpu/GrCoordTransform.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrCoordTransform_DEFINED
-#define GrCoordTransform_DEFINED
-
-#include "include/core/SkMatrix.h"
-
-/**
- * A class representing a linear transformation of local coordinates. GrFragnentProcessors
- * these transformations, and the GrGeometryProcessor implements the transformation.
- */
-class GrCoordTransform {
-public:
- GrCoordTransform() = default;
-};
-
-#endif
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index a37206b..c16014c 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessorAnalysis.h"
@@ -30,8 +29,7 @@
return false;
}
}
- if (this->numCoordTransforms() != that.numCoordTransforms()) {
- // FPs have either 0 or 1 coord transform, and if they have 1, it's the identity
+ if (this->usesVaryingCoordsDirectly() != that.usesVaryingCoordsDirectly()) {
return false;
}
if (!this->onIsEqual(that)) {
@@ -69,25 +67,6 @@
return this->onTextureSampler(i);
}
-int GrFragmentProcessor::numCoordTransforms() const {
- if (SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) && !this->isSampledWithExplicitCoords()) {
- // coordTransform(0) will return an implicitly defined coord transform so that varyings are
- // added for this FP in order to support uniform sample matrix lifting.
- return 1;
- } else {
- return 0;
- }
-}
-
-const GrCoordTransform& GrFragmentProcessor::coordTransform(int i) const {
- SkASSERT(i == 0 && SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) &&
- !this->isSampledWithExplicitCoords());
- // as things stand, matrices only work when there's a coord transform, so we need to add
- // an identity transform to keep the downstream code happy
- static const GrCoordTransform kImplicitIdentity;
- return kImplicitIdentity;
-}
-
void GrFragmentProcessor::addAndPushFlagToChildren(PrivateFlags flag) {
// This propagates down, so if we've already marked it, all our children should have it too
if (!(fFlags & flag)) {
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 9fe9291..7ea426d 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -14,7 +14,6 @@
#include "src/gpu/GrProcessor.h"
#include "src/gpu/ops/GrOp.h"
-class GrCoordTransform;
class GrGLSLFragmentProcessor;
class GrPaint;
class GrPipeline;
@@ -23,9 +22,7 @@
class GrSwizzle;
/** Provides custom fragment shader code. Fragment processors receive an input color (half4) and
- produce an output color. They may reference textures and uniforms. They may use
- GrCoordTransforms to receive a transformation of the local coordinates that map from local space
- to the fragment being processed.
+ produce an output color. They may reference textures and uniforms.
*/
class GrFragmentProcessor : public GrProcessor {
public:
@@ -121,8 +118,7 @@
int numTextureSamplers() const { return fTextureSamplerCnt; }
const TextureSampler& textureSampler(int i) const;
- int numCoordTransforms() const;
- const GrCoordTransform& coordTransform(int index) const;
+ int numVaryingCoordsUsed() const { return this->usesVaryingCoordsDirectly() ? 1 : 0; }
int numChildProcessors() const { return fChildProcessors.count(); }
@@ -132,16 +128,26 @@
SkDEBUGCODE(bool isInstantiated() const;)
/**
- * Do any of the FPs in this tree require local coordinates to be produced by the primitive
- * processor. This can return true even if this FP does not refer to sample coordinates, but
- * true if a descendant FP uses them. FPs that are sampled explicitly do not
- * require primitive-generated local coordinates.
+ * Does this FP require local coordinates to be produced by the primitive processor? This only
+ * returns true if this FP will directly read those local coordinates. FPs that are sampled
+ * explicitly do not require primitive-generated local coordinates (because the sample
+ * coordinates are supplied by the parent FP).
*
* If the root of an FP tree does not provide explicit coordinates, the geometry processor
* provides the original local coordinates to start. This may be implicit as part of vertex
* shader-lifted varyings, or by providing the base local coordinate to the fragment shader.
*/
- bool sampleCoordsDependOnLocalCoords() const {
+ bool usesVaryingCoordsDirectly() const {
+ return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) &&
+ !SkToBool(fFlags & kSampledWithExplicitCoords_Flag);
+ }
+
+ /**
+ * Do any of the FPs in this tree require local coordinates to be produced by the primitive
+ * processor? This can return true even if this FP does not refer to sample coordinates, but
+ * true if a descendant FP uses them.
+ */
+ bool usesVaryingCoords() const {
return (SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) ||
SkToBool(fFlags & kUsesSampleCoordsIndirectly_Flag)) &&
!SkToBool(fFlags & kSampledWithExplicitCoords_Flag);
@@ -152,9 +158,9 @@
* (e.g. uses EmitArgs::fSampleCoord in emitCode()). This also returns true if the
* coordinate reference comes from autogenerated code invoking 'sample(matrix)' expressions.
*
- * Unlike sampleCoordsDependOnLocalCoords(), this can return true whether or not the FP is
- * explicitly sampled, and does not change based on how the FP is composed. This property is
- * specific to the FP's function and not the entire program.
+ * Unlike usesVaryingCoords(), this can return true whether or not the FP is explicitly
+ * sampled, and does not change based on how the FP is composed. This property is specific to
+ * the FP's function and not the entire program.
*/
bool referencesSampleCoords() const {
return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
@@ -281,19 +287,9 @@
// gets the number of Items owned by each FP and GetFn is a member that gets them by index.
template <typename Item, CountFn Count, GetFn<Item> Get> class FPItemIter;
- // Loops over all the GrCoordTransforms owned by GrFragmentProcessors. The possible sources for
+ // Loops over all the TextureSamplers owned by GrFragmentProcessors. The possible sources for
// the iteration are the same as those for Iter and the FPs are walked in the same order as
- // Iter. This provides access to the coord transform and the FP that owns it. Example usage:
- // for (GrFragmentProcessor::CoordTransformIter iter(pipeline); iter; ++iter) {
- // // transform is const GrCoordTransform& and owningFP is const GrFragmentProcessor&.
- // auto [transform, owningFP] = *iter;
- // ...
- // }
- // See the ranges below to make this simpler a la range-for loops.
- using CoordTransformIter = FPItemIter<const GrCoordTransform,
- &GrFragmentProcessor::numCoordTransforms,
- &GrFragmentProcessor::coordTransform>;
- // Same as CoordTransformIter but for TextureSamplers:
+ // Iter. This provides access to the texture sampler and the FP that owns it. Example usage:
// for (GrFragmentProcessor::TextureSamplerIter iter(pipeline); iter; ++iter) {
// // TextureSamplerIter is const GrFragmentProcessor::TextureSampler& and
// // owningFP is const GrFragmentProcessor&.
@@ -305,7 +301,7 @@
&GrFragmentProcessor::numTextureSamplers,
&GrFragmentProcessor::textureSampler>;
- // Implementation detail for using CoordTransformIter and TextureSamplerIter in range-for loops.
+ // Implementation detail for using TextureSamplerIter in range-for loops.
template <typename Src, typename ItemIter> class FPItemRange;
// These allow iteration over texture samplers for various FP sources via range-for loops.
@@ -459,8 +455,7 @@
/**
* Subclass implements this to support isEqual(). It will only be called if it is known that
* the two processors are of the same subclass (i.e. they return the same object from
- * getFactory()). The processor subclass should not compare its coord transforms as that will
- * be performed automatically in the non-virtual isEqual().
+ * getFactory()).
*/
virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp
index 2fdd97b..8371117 100644
--- a/src/gpu/GrPathProcessor.cpp
+++ b/src/gpu/GrPathProcessor.cpp
@@ -58,25 +58,17 @@
GrGLSLUniformHandler* uniformHandler,
FPCoordTransformHandler* transformHandler) {
for (int i = 0; *transformHandler; ++*transformHandler, ++i) {
- const auto& fp = transformHandler->get();
-
- GrShaderVar fragmentVar;
- GrShaderVar transformVar;
- if (fp.isSampledWithExplicitCoords()) {
- transformHandler->omitCoordsForCurrCoordTransform();
- } else {
- SkString strVaryingName;
- strVaryingName.printf("TransformedCoord_%d", i);
- GrGLSLVarying v(kFloat2_GrSLType);
+ SkString strVaryingName;
+ strVaryingName.printf("TransformedCoord_%d", i);
+ GrGLSLVarying v(kFloat2_GrSLType);
#ifdef SK_GL
- GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*)varyingHandler;
- fVaryingTransform.push_back().fHandle =
- glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), &v)
- .toIndex();
+ GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*)varyingHandler;
+ fVaryingTransform.push_back().fHandle =
+ glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), &v)
+ .toIndex();
#endif
- fragmentVar = {SkString(v.fsIn()), kFloat2_GrSLType};
- transformHandler->specifyCoordsForCurrCoordTransform(transformVar, fragmentVar);
- }
+ GrShaderVar fragmentVar = {SkString(v.fsIn()), kFloat2_GrSLType};
+ transformHandler->specifyCoordsForCurrCoordTransform(fragmentVar);
}
}
@@ -104,7 +96,7 @@
// Varying transforms are used for non-explicitly sampled FPs. We provide a matrix
// to GL as fixed function state and it uses it to compute a varying that we pick up
- // in the FS as the output of the coord transform.
+ // in the FS as the transformed local coords.
struct TransformVarying {
VaryingHandle fHandle;
SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp
index 60ecb50..fcbc753 100644
--- a/src/gpu/GrPrimitiveProcessor.cpp
+++ b/src/gpu/GrPrimitiveProcessor.cpp
@@ -34,8 +34,6 @@
uint32_t GrPrimitiveProcessor::computeCoordTransformsKey(const GrFragmentProcessor& fp) const {
// This is highly coupled with the code in GrGLSLGeometryProcessor::collectTransforms().
- // At this point, all effects do not use really coord transforms; they may implicitly report
- // a noop coord transform but this does not impact the key.
uint32_t key = 0;
if (fp.isSampledWithExplicitCoords()) {
diff --git a/src/gpu/GrProcessorAnalysis.cpp b/src/gpu/GrProcessorAnalysis.cpp
index 0395236..df3f426 100644
--- a/src/gpu/GrProcessorAnalysis.cpp
+++ b/src/gpu/GrProcessorAnalysis.cpp
@@ -40,7 +40,7 @@
if (fCompatibleWithCoverageAsAlpha && !fp->compatibleWithCoverageAsAlpha()) {
fCompatibleWithCoverageAsAlpha = false;
}
- if (fp->sampleCoordsDependOnLocalCoords()) {
+ if (fp->usesVaryingCoords()) {
fUsesLocalCoords = true;
}
}
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index cc10424..48fb9af 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -183,14 +183,14 @@
if (!fps[i]->compatibleWithCoverageAsAlpha()) {
analysis.fCompatibleWithCoverageAsAlpha = false;
}
- coverageUsesLocalCoords |= fps[i]->sampleCoordsDependOnLocalCoords();
+ coverageUsesLocalCoords |= fps[i]->usesVaryingCoords();
}
if (clip) {
hasCoverageFP = hasCoverageFP || clip->numClipCoverageFragmentProcessors();
for (int i = 0; i < clip->numClipCoverageFragmentProcessors(); ++i) {
const GrFragmentProcessor* clipFP = clip->clipCoverageFragmentProcessor(i);
analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
- coverageUsesLocalCoords |= clipFP->sampleCoordsDependOnLocalCoords();
+ coverageUsesLocalCoords |= clipFP->usesVaryingCoords();
}
}
int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
index c17de84..c436f14 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
@@ -16,9 +16,9 @@
#include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h"
#include "src/gpu/ccpr/GrOctoBounds.h"
-static bool has_coord_transforms(const GrPaint& paint) {
+static bool uses_varying_coords(const GrPaint& paint) {
for (const auto& fp : GrFragmentProcessor::PaintCRange(paint)) {
- if (fp.numCoordTransforms() > 0) {
+ if (fp.usesVaryingCoordsDirectly()) {
return true;
}
}
@@ -102,7 +102,7 @@
const SkIRect& maskDevIBounds, const SkRect& conservativeDevBounds,
GrPaint&& paint)
: GrDrawOp(ClassID())
- , fViewMatrixIfUsingLocalCoords(has_coord_transforms(paint) ? m : SkMatrix::I())
+ , fViewMatrixIfUsingLocalCoords(uses_varying_coords(paint) ? m : SkMatrix::I())
, fDraws(m, shape, strokeDevWidth, shapeConservativeIBounds, maskDevIBounds,
paint.getColor4f())
, fProcessors(std::move(paint)) { // Paint must be moved after fetching its color above.
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 3408809..5eb265d 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -71,8 +71,8 @@
};
public:
- using TransformedCoordVars = BuilderInputProvider<GrGLSLPrimitiveProcessor::TransformVar,
- &GrFragmentProcessor::numCoordTransforms>;
+ using TransformedCoordVars =
+ BuilderInputProvider<GrShaderVar, &GrFragmentProcessor::numVaryingCoordsUsed>;
using TextureSamplers =
BuilderInputProvider<SamplerHandle, &GrFragmentProcessor::numTextureSamplers>;
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index c57735d..b276969 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -167,7 +167,7 @@
paramCount = 1;
if (args.fFp.referencesSampleCoords()) {
- const GrShaderVar& varying = args.fTransformedCoords[0].fVaryingPoint;
+ const GrShaderVar& varying = args.fTransformedCoords[0];
switch(varying.getType()) {
case kFloat2_GrSLType:
// Just point the local coords to the varying
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index 77c846a..a741fd1 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -95,83 +95,67 @@
for (int i = 0; *handler; ++*handler, ++i) {
const auto& fp = handler->get();
- // FIXME: GrCoordTransform is used solely as a vehicle for iterating over all FPs that
- // require sample coordinates directly. We should make this iteration lighter weight.
+
+ SkASSERT(fp.referencesSampleCoords());
+ SkASSERT(!fp.isSampledWithExplicitCoords());
// FPs that use local coordinates need a varying to convey the coordinate. This may be the
// base GP's local coord if transforms have to be computed in the FS, or it may be a unique
// varying that computes the equivalent transformation hierarchy in the VS.
GrShaderVar varyingVar;
- // If the FP references local coords, we need to make sure the vertex shader sets up the
- // right transforms or pass-through variables for the FP to evaluate in the fragment shader
- if (fp.referencesSampleCoords()) {
- if (fp.isSampledWithExplicitCoords()) {
- // If the FP local coords are evaluated in the fragment shader, we only need to
- // produce the original local coordinate to pass into the root; any other situation,
- // the FP will have a 2nd parameter to its function and the caller sends the coords
- if (!fp.parent()) {
- varyingVar = getBaseLocalCoord();
+ // The FP's local coordinates are determined by the uniform transform hierarchy
+ // from this FP to the root, and can be computed in the vertex shader.
+ // If this hierarchy would be the identity transform, then we should use the
+ // original local coordinate.
+ // NOTE: The actual transform logic is handled in emitTransformCode(), this just
+ // needs to determine if a unique varying should be added for the FP.
+ GrShaderVar transformedLocalCoord;
+ const GrFragmentProcessor* coordOwner = nullptr;
+
+ const GrFragmentProcessor* node = &fp;
+ while(node) {
+ SkASSERT(!node->isSampledWithExplicitCoords() &&
+ !node->sampleUsage().hasVariableMatrix());
+
+ if (node->sampleUsage().hasUniformMatrix()) {
+ // We can stop once we hit an FP that adds transforms; this FP can reuse
+ // that FPs varying (possibly vivifying it if this was the first use).
+ transformedLocalCoord = localCoordsMap[node];
+ coordOwner = node;
+ break;
+ } // else intervening FP is an identity transform so skip past it
+
+ node = node->parent();
+ }
+
+ if (coordOwner) {
+ // The FP will use coordOwner's varying; add varying if this was the first use
+ if (transformedLocalCoord.getType() == kVoid_GrSLType) {
+ GrGLSLVarying v(kFloat2_GrSLType);
+ if (GrSLTypeVecLength(localCoordsVar.getType()) == 3 ||
+ coordOwner->hasPerspectiveTransform()) {
+ v = GrGLSLVarying(kFloat3_GrSLType);
}
- } else {
- // The FP's local coordinates are determined by the uniform transform hierarchy
- // from this FP to the root, and can be computed in the vertex shader.
- // If this hierarchy would be the identity transform, then we should use the
- // original local coordinate.
- // NOTE: The actual transform logic is handled in emitTransformCode(), this just
- // needs to determine if a unique varying should be added for the FP.
- GrShaderVar transformedLocalCoord;
- const GrFragmentProcessor* coordOwner = nullptr;
+ SkString strVaryingName;
+ strVaryingName.printf("TransformedCoords_%d", i);
+ varyingHandler->addVarying(strVaryingName.c_str(), &v);
- const GrFragmentProcessor* node = &fp;
- while(node) {
- SkASSERT(!node->isSampledWithExplicitCoords() &&
- !node->sampleUsage().hasVariableMatrix());
-
- if (node->sampleUsage().hasUniformMatrix()) {
- // We can stop once we hit an FP that adds transforms; this FP can reuse
- // that FPs varying (possibly vivifying it if this was the first use).
- transformedLocalCoord = localCoordsMap[node];
- coordOwner = node;
- break;
- } // else intervening FP is an identity transform so skip past it
-
- node = node->parent();
- }
-
- if (coordOwner) {
- // The FP will use coordOwner's varying; add varying if this was the first use
- if (transformedLocalCoord.getType() == kVoid_GrSLType) {
- GrGLSLVarying v(kFloat2_GrSLType);
- if (GrSLTypeVecLength(localCoordsVar.getType()) == 3 ||
- coordOwner->hasPerspectiveTransform()) {
- v = GrGLSLVarying(kFloat3_GrSLType);
- }
- SkString strVaryingName;
- strVaryingName.printf("TransformedCoords_%d", i);
- varyingHandler->addVarying(strVaryingName.c_str(), &v);
-
- fTransformInfos.push_back({GrShaderVar(v.vsOut(), v.type()),
- localCoordsVar,
- coordOwner});
- transformedLocalCoord = GrShaderVar(SkString(v.fsIn()), v.type(),
- GrShaderVar::TypeModifier::In);
- localCoordsMap[coordOwner] = transformedLocalCoord;
- }
-
- varyingVar = transformedLocalCoord;
- } else {
- // The FP transform hierarchy is the identity, so use the original local coord
- varyingVar = getBaseLocalCoord();
- }
+ fTransformInfos.push_back(
+ {GrShaderVar(v.vsOut(), v.type()), localCoordsVar, coordOwner});
+ transformedLocalCoord =
+ GrShaderVar(SkString(v.fsIn()), v.type(), GrShaderVar::TypeModifier::In);
+ localCoordsMap[coordOwner] = transformedLocalCoord;
}
+
+ varyingVar = transformedLocalCoord;
+ } else {
+ // The FP transform hierarchy is the identity, so use the original local coord
+ varyingVar = getBaseLocalCoord();
}
- if (varyingVar.getType() != kVoid_GrSLType) {
- handler->specifyCoordsForCurrCoordTransform(GrShaderVar(), varyingVar);
- } else {
- handler->omitCoordsForCurrCoordTransform();
- }
+ SkASSERT(varyingVar.getType() != kVoid_GrSLType);
+ handler->specifyCoordsForCurrCoordTransform(varyingVar);
}
}
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
index 7b1264c..d8bdb2b 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
@@ -33,17 +33,23 @@
//////////////////////////////////////////////////////////////////////////////
GrGLSLPrimitiveProcessor::FPCoordTransformHandler::FPCoordTransformHandler(
- const GrPipeline& pipeline, SkTArray<TransformVar>* transformedCoordVars)
- : fIter(pipeline), fTransformedCoordVars(transformedCoordVars) {}
+ const GrPipeline& pipeline, SkTArray<GrShaderVar>* transformedCoordVars)
+ : fIter(pipeline), fTransformedCoordVars(transformedCoordVars) {
+ while (fIter && !fIter->usesVaryingCoordsDirectly()) {
+ ++fIter;
+ }
+}
const GrFragmentProcessor& GrGLSLPrimitiveProcessor::FPCoordTransformHandler::get() const {
- return (*fIter).second;
+ return *fIter;
}
GrGLSLPrimitiveProcessor::FPCoordTransformHandler&
GrGLSLPrimitiveProcessor::FPCoordTransformHandler::operator++() {
SkASSERT(fAddedCoord);
- ++fIter;
+ do {
+ ++fIter;
+ } while (fIter && !fIter->usesVaryingCoordsDirectly());
SkDEBUGCODE(fAddedCoord = false;)
return *this;
}
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index e429d64..2db52cb 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -26,55 +26,38 @@
using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
- struct TransformVar {
- // The transform as a variable. This may be a kFloat3x3 matrix or a kFloat4 representing
- // {scaleX, transX, scaleY, transY}. For explicitly sampled FPs this is visible in the
- // FS. This is not available for NV_path_rendering with non-explicitly sampled FPs.
- GrShaderVar fTransform;
- // The transformed coordinate output by the vertex shader and consumed by the fragment
- // shader. Only valid for non-explicitly sampled FPs.
- GrShaderVar fVaryingPoint;
- };
-
-
virtual ~GrGLSLPrimitiveProcessor() {}
/**
- * 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.
+ * This class provides access to each GrFragmentProcessor in a GrPipeline that requires varying
+ * local coords to be produced by the primitive processor. It is also used by the primitive
+ * processor to specify the fragment shader variable that will hold the transformed coords for
+ * each of those GrFragmentProcessors. It is required that the primitive processor iterate over
+ * each fragment processor 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&, SkTArray<TransformVar>*);
+ FPCoordTransformHandler(const GrPipeline&, SkTArray<GrShaderVar>*);
~FPCoordTransformHandler() { SkASSERT(!fIter); }
operator bool() const { return (bool)fIter; }
- // Gets the current coord transform and its owning GrFragmentProcessor.
+ // Gets the current GrFragmentProcessor
const GrFragmentProcessor& get() const;
FPCoordTransformHandler& operator++();
- // 'args' are constructor params to GrShaderVar.
- void specifyCoordsForCurrCoordTransform(GrShaderVar transformVar, GrShaderVar varyingVar) {
+ void specifyCoordsForCurrCoordTransform(GrShaderVar varyingVar) {
SkASSERT(!fAddedCoord);
- fTransformedCoordVars->push_back({transformVar, varyingVar});
- SkDEBUGCODE(fAddedCoord = true;)
- }
-
- void omitCoordsForCurrCoordTransform() {
- SkASSERT(!fAddedCoord);
- fTransformedCoordVars->push_back();
+ fTransformedCoordVars->push_back(varyingVar);
SkDEBUGCODE(fAddedCoord = true;)
}
private:
- GrFragmentProcessor::CoordTransformIter fIter;
- SkDEBUGCODE(bool fAddedCoord = false;)
- SkTArray<TransformVar>* fTransformedCoordVars;
+ GrFragmentProcessor::CIter fIter;
+ SkDEBUGCODE(bool fAddedCoord = false;)
+ SkTArray<GrShaderVar>* fTransformedCoordVars;
};
struct EmitArgs {
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 5965514..627f380 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -140,7 +140,7 @@
output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output,
&glslFragmentProcessors);
for (const auto& subFP : GrFragmentProcessor::FPCRange(fp)) {
- transformedCoordVarsIdx += subFP.numCoordTransforms();
+ transformedCoordVarsIdx += subFP.numVaryingCoordsUsed();
}
**inOut = output;
}
@@ -185,8 +185,7 @@
name.c_str()));
}
}
- const GrGLSLPrimitiveProcessor::TransformVar* coordVars = fTransformedCoordVars.begin() +
- transformedCoordVarsIdx;
+ const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, texSamplers.begin());
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
@@ -200,11 +199,11 @@
textureSamplers);
if (fp.referencesSampleCoords()) {
- // The fp's generated code expects a _coords variable, but we're a the root so _coords
+ // The fp's generated code expects a _coords variable, but we're at the root so _coords
// is just the local coordinates produced by the primitive processor.
- SkASSERT(coords.count() > 0);
+ SkASSERT(fp.usesVaryingCoordsDirectly());
- const GrShaderVar& varying = coordVars[0].fVaryingPoint;
+ const GrShaderVar& varying = coordVars[0];
switch(varying.getType()) {
case kFloat2_GrSLType:
fFS.codeAppendf("float2 %s = %s.xy;\n",
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 4129975..3fe7816 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -173,7 +173,7 @@
// These are used to check that we don't excede the allowable number of resources in a shader.
int fNumFragmentSamplers;
- SkSTArray<4, GrGLSLPrimitiveProcessor::TransformVar> fTransformedCoordVars;
+ SkSTArray<4, GrShaderVar> fTransformedCoordVars;
};
#endif
diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h
index 8324130..8151c9c 100644
--- a/src/sksl/SkSLContext.h
+++ b/src/sksl/SkSLContext.h
@@ -395,7 +395,6 @@
Modifiers mods(Layout(), Modifiers::kConst_Flag);
std::vector<Type::Field> fields = {
Type::Field(mods, "numTextureSamplers", intType),
- Type::Field(mods, "numCoordTransforms", intType),
Type::Field(mods, "numChildProcessors", intType),
Type::Field(mods, "usesLocalCoords", boolType),
Type::Field(mods, "compatibleWithCoverageAsAlpha", boolType),
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index 33ab5ba..192c9c6 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -787,8 +787,7 @@
"%s\n", describe_fp(*fp).c_str());
REPORTER_ASSERT(reporter, fp->numChildProcessors() == clone->numChildProcessors(),
"%s\n", describe_fp(*fp).c_str());
- REPORTER_ASSERT(reporter, fp->sampleCoordsDependOnLocalCoords() ==
- clone->sampleCoordsDependOnLocalCoords(),
+ REPORTER_ASSERT(reporter, fp->usesVaryingCoords() == clone->usesVaryingCoords(),
"%s\n", describe_fp(*fp).c_str());
REPORTER_ASSERT(reporter, fp->referencesSampleCoords() ==
clone->referencesSampleCoords(),