Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2019 Google LLC.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "gm/gm.h"
|
|
|
|
#include "include/core/SkFont.h"
|
2020-06-18 17:40:26 +00:00
|
|
|
#include "include/effects/SkRuntimeEffect.h"
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
#include "src/gpu/GrBitmapTextureMaker.h"
|
2020-10-14 15:23:11 +00:00
|
|
|
#include "src/gpu/GrDirectContextPriv.h"
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
|
|
|
#include "src/gpu/ops/GrFillRectOp.h"
|
|
|
|
#include "tools/ToolUtils.h"
|
|
|
|
|
|
|
|
// Samples child with a constant (literal) matrix
|
|
|
|
// Scales along X
|
|
|
|
class ConstantMatrixEffect : public GrFragmentProcessor {
|
|
|
|
public:
|
|
|
|
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 3;
|
|
|
|
|
|
|
|
ConstantMatrixEffect(std::unique_ptr<GrFragmentProcessor> child)
|
|
|
|
: GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
|
|
|
|
this->registerChild(std::move(child),
|
2020-06-30 17:39:35 +00:00
|
|
|
SkSL::SampleUsage::UniformMatrix(
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
"float3x3(float3(0.5, 0.0, 0.0), "
|
|
|
|
"float3(0.0, 1.0, 0.0), "
|
|
|
|
"float3(0.0, 0.0, 1.0))"));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* name() const override { return "ConstantMatrixEffect"; }
|
|
|
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
|
|
|
bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
|
|
|
|
std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }
|
|
|
|
|
|
|
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
|
|
|
class Impl : public GrGLSLFragmentProcessor {
|
|
|
|
void emitCode(EmitArgs& args) override {
|
|
|
|
SkString sample = this->invokeChildWithMatrix(0, args);
|
2020-12-14 23:04:13 +00:00
|
|
|
args.fFragBuilder->codeAppendf("return %s;\n", sample.c_str());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return new Impl;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Samples child with a uniform matrix (functionally identical to GrMatrixEffect)
|
|
|
|
// Scales along Y
|
|
|
|
class UniformMatrixEffect : public GrFragmentProcessor {
|
|
|
|
public:
|
|
|
|
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 4;
|
|
|
|
|
|
|
|
UniformMatrixEffect(std::unique_ptr<GrFragmentProcessor> child)
|
|
|
|
: GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
|
2020-06-30 17:39:35 +00:00
|
|
|
this->registerChild(std::move(child), SkSL::SampleUsage::UniformMatrix("matrix"));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* name() const override { return "UniformMatrixEffect"; }
|
|
|
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
|
|
|
bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
|
|
|
|
std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }
|
|
|
|
|
|
|
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
|
|
|
class Impl : public GrGLSLFragmentProcessor {
|
|
|
|
void emitCode(EmitArgs& args) override {
|
|
|
|
fMatrixVar = args.fUniformHandler->addUniform(&args.fFp, kFragment_GrShaderFlag,
|
|
|
|
kFloat3x3_GrSLType, "matrix");
|
|
|
|
SkString sample = this->invokeChildWithMatrix(0, args);
|
2020-12-14 23:04:13 +00:00
|
|
|
args.fFragBuilder->codeAppendf("return %s;\n", sample.c_str());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
void onSetData(const GrGLSLProgramDataManager& pdman,
|
|
|
|
const GrFragmentProcessor& proc) override {
|
|
|
|
pdman.setSkMatrix(fMatrixVar, SkMatrix::Scale(1, 0.5f));
|
|
|
|
}
|
|
|
|
UniformHandle fMatrixVar;
|
|
|
|
};
|
|
|
|
return new Impl;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Samples child with a variable matrix
|
|
|
|
// Translates along X
|
|
|
|
// Typically, kVariable would be due to multiple sample(matrix) invocations, but this artificially
|
|
|
|
// uses kVariable with a single (constant) matrix.
|
|
|
|
class VariableMatrixEffect : public GrFragmentProcessor {
|
|
|
|
public:
|
|
|
|
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 5;
|
|
|
|
|
|
|
|
VariableMatrixEffect(std::unique_ptr<GrFragmentProcessor> child)
|
|
|
|
: GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
|
2020-06-30 17:39:35 +00:00
|
|
|
this->registerChild(std::move(child), SkSL::SampleUsage::VariableMatrix());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* name() const override { return "VariableMatrixEffect"; }
|
|
|
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
|
|
|
bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
|
|
|
|
std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }
|
|
|
|
|
|
|
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
|
|
|
class Impl : public GrGLSLFragmentProcessor {
|
|
|
|
void emitCode(EmitArgs& args) override {
|
|
|
|
SkString sample = this->invokeChildWithMatrix(
|
|
|
|
0, args, "float3x3(1, 0, 0, 0, 1, 0, 8, 0, 1)");
|
2020-12-14 23:04:13 +00:00
|
|
|
args.fFragBuilder->codeAppendf("return %s;\n", sample.c_str());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return new Impl;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Samples child with explicit coords
|
|
|
|
// Translates along Y
|
|
|
|
class ExplicitCoordEffect : public GrFragmentProcessor {
|
|
|
|
public:
|
|
|
|
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 6;
|
|
|
|
|
|
|
|
ExplicitCoordEffect(std::unique_ptr<GrFragmentProcessor> child)
|
|
|
|
: GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
|
2020-06-30 17:39:35 +00:00
|
|
|
this->registerChild(std::move(child), SkSL::SampleUsage::Explicit());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
this->setUsesSampleCoordsDirectly();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* name() const override { return "ExplicitCoordEffect"; }
|
|
|
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
|
|
|
bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
|
|
|
|
std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }
|
|
|
|
|
|
|
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
|
|
|
class Impl : public GrGLSLFragmentProcessor {
|
|
|
|
void emitCode(EmitArgs& args) override {
|
|
|
|
args.fFragBuilder->codeAppendf("float2 coord = %s + float2(0, 8);",
|
|
|
|
args.fSampleCoord);
|
|
|
|
SkString sample = this->invokeChild(0, args, "coord");
|
2020-12-14 23:04:13 +00:00
|
|
|
args.fFragBuilder->codeAppendf("return %s;\n", sample.c_str());
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return new Impl;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Generates test pattern
|
|
|
|
class TestPatternEffect : public GrFragmentProcessor {
|
|
|
|
public:
|
|
|
|
static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 7;
|
|
|
|
|
|
|
|
TestPatternEffect() : GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
|
2020-06-26 20:02:15 +00:00
|
|
|
this->setUsesSampleCoordsDirectly();
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* name() const override { return "TestPatternEffect"; }
|
|
|
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
|
|
|
bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
|
|
|
|
std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }
|
|
|
|
|
|
|
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
|
|
|
class Impl : public GrGLSLFragmentProcessor {
|
|
|
|
void emitCode(EmitArgs& args) override {
|
|
|
|
auto fb = args.fFragBuilder;
|
|
|
|
fb->codeAppendf("float2 coord = %s / 64.0;", args.fSampleCoord);
|
|
|
|
fb->codeAppendf("coord = floor(coord * 4) / 3;");
|
2020-12-14 23:04:13 +00:00
|
|
|
fb->codeAppendf("return half2(coord).rg01;\n");
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return new Impl;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
SkBitmap make_test_bitmap() {
|
|
|
|
SkBitmap bitmap;
|
|
|
|
bitmap.allocN32Pixels(64, 64);
|
|
|
|
SkCanvas canvas(bitmap);
|
|
|
|
|
|
|
|
SkFont font(ToolUtils::create_portable_typeface());
|
|
|
|
const char* alpha = "ABCDEFGHIJKLMNOP";
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; ++i) {
|
|
|
|
int tx = i % 4,
|
|
|
|
ty = i / 4;
|
|
|
|
int x = tx * 16,
|
|
|
|
y = ty * 16;
|
|
|
|
SkPaint paint;
|
|
|
|
paint.setColor4f({ tx / 3.0f, ty / 3.0f, 0.0f, 1.0f });
|
|
|
|
canvas.drawRect(SkRect::MakeXYWH(x, y, 16, 16), paint);
|
|
|
|
paint.setColor4f({ (3-tx) / 3.0f, (3-ty)/3.0f, 1.0f, 1.0f });
|
|
|
|
canvas.drawSimpleText(alpha + i, 1, SkTextEncoding::kUTF8, x + 3, y + 13, font, paint);
|
|
|
|
}
|
|
|
|
|
|
|
|
return bitmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum EffectType {
|
|
|
|
kConstant,
|
|
|
|
kUniform,
|
|
|
|
kVariable,
|
|
|
|
kExplicit,
|
|
|
|
};
|
|
|
|
|
|
|
|
static std::unique_ptr<GrFragmentProcessor> wrap(std::unique_ptr<GrFragmentProcessor> fp,
|
|
|
|
EffectType effectType) {
|
|
|
|
switch (effectType) {
|
|
|
|
case kConstant:
|
2020-08-03 17:21:46 +00:00
|
|
|
return std::make_unique<ConstantMatrixEffect>(std::move(fp));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
case kUniform:
|
2020-08-03 17:21:46 +00:00
|
|
|
return std::make_unique<UniformMatrixEffect>(std::move(fp));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
case kVariable:
|
2020-08-03 17:21:46 +00:00
|
|
|
return std::make_unique<VariableMatrixEffect>(std::move(fp));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
case kExplicit:
|
2020-08-03 17:21:46 +00:00
|
|
|
return std::make_unique<ExplicitCoordEffect>(std::move(fp));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
}
|
|
|
|
SkUNREACHABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEF_SIMPLE_GPU_GM(fp_sample_chaining, ctx, rtCtx, canvas, 380, 306) {
|
|
|
|
SkBitmap bmp = make_test_bitmap();
|
|
|
|
|
|
|
|
GrBitmapTextureMaker maker(ctx, bmp, GrImageTexGenPolicy::kDraw);
|
|
|
|
int x = 10, y = 10;
|
|
|
|
|
|
|
|
auto nextCol = [&] { x += (64 + 10); };
|
|
|
|
auto nextRow = [&] { x = 10; y += (64 + 10); };
|
|
|
|
|
|
|
|
auto draw = [&](std::initializer_list<EffectType> effects) {
|
|
|
|
// Enable TestPatternEffect to get a fully procedural inner effect. It's not quite as nice
|
|
|
|
// visually (no text labels in each box), but it avoids the extra GrMatrixEffect.
|
|
|
|
// Switching it on actually triggers *more* shader compilation failures.
|
|
|
|
#if 0
|
|
|
|
auto fp = std::unique_ptr<GrFragmentProcessor>(new TestPatternEffect());
|
|
|
|
#else
|
2020-07-21 13:27:25 +00:00
|
|
|
auto view = maker.view(GrMipmapped::kNo);
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
auto fp = GrTextureEffect::Make(std::move(view), maker.alphaType());
|
|
|
|
#endif
|
|
|
|
for (EffectType effectType : effects) {
|
|
|
|
fp = wrap(std::move(fp), effectType);
|
|
|
|
}
|
|
|
|
GrPaint paint;
|
2020-07-21 16:28:35 +00:00
|
|
|
paint.setColorFragmentProcessor(std::move(fp));
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
rtCtx->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::Translate(x, y),
|
|
|
|
SkRect::MakeIWH(64, 64));
|
|
|
|
nextCol();
|
|
|
|
};
|
|
|
|
|
|
|
|
// Reminder, in every case, the chain is more complicated than it seems, because the
|
|
|
|
// GrTextureEffect is wrapped in a GrMatrixEffect, which is subject to the same bugs that
|
|
|
|
// we're testing (particularly the bug about owner/base in UniformMatrixEffect).
|
|
|
|
|
|
|
|
// First row: no transform, then each one independently applied
|
|
|
|
draw({}); // Identity (4 rows and columns)
|
|
|
|
draw({ kConstant }); // Scale X axis by 2x (2 visible columns)
|
|
|
|
draw({ kUniform }); // Scale Y axis by 2x (2 visible rows)
|
|
|
|
draw({ kVariable }); // Translate left by 8px
|
|
|
|
draw({ kExplicit }); // Translate up by 8px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
// Second row: transform duplicated
|
|
|
|
draw({ kConstant, kUniform }); // Scale XY by 2x (2 rows and columns)
|
|
|
|
draw({ kConstant, kConstant }); // Scale X axis by 4x (1 visible column)
|
|
|
|
draw({ kUniform, kUniform }); // Scale Y axis by 4x (1 visible row)
|
2020-06-18 17:40:26 +00:00
|
|
|
draw({ kVariable, kVariable }); // Translate left by 16px
|
|
|
|
draw({ kExplicit, kExplicit }); // Translate up by 16px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
// Remember, these are applied inside out:
|
|
|
|
draw({ kConstant, kExplicit }); // Scale X by 2x and translate up by 8px
|
|
|
|
draw({ kConstant, kVariable }); // Scale X by 2x and translate left by 8px
|
|
|
|
draw({ kUniform, kVariable }); // Scale Y by 2x and translate left by 8px
|
|
|
|
draw({ kUniform, kExplicit }); // Scale Y by 2x and translate up by 8px
|
|
|
|
draw({ kVariable, kExplicit }); // Translate left and up by 8px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
draw({ kExplicit, kExplicit, kConstant }); // Scale X by 2x and translate up by 16px
|
|
|
|
draw({ kVariable, kConstant }); // Scale X by 2x and translate left by 16px
|
|
|
|
draw({ kVariable, kVariable, kUniform }); // Scale Y by 2x and translate left by 16px
|
|
|
|
draw({ kExplicit, kUniform }); // Scale Y by 2x and translate up by 16px
|
|
|
|
draw({ kExplicit, kUniform, kVariable, kConstant }); // Scale XY by 2x and translate xy 16px
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* gConstantMatrixSkSL = R"(
|
2020-11-04 20:40:50 +00:00
|
|
|
uniform shader child;
|
2020-08-13 20:59:48 +00:00
|
|
|
half4 main(float2 xy) {
|
|
|
|
return sample(child, float3x3(0.5, 0.0, 0.0,
|
|
|
|
0.0, 1.0, 0.0,
|
|
|
|
0.0, 0.0, 1.0));
|
2020-06-18 17:40:26 +00:00
|
|
|
}
|
|
|
|
)";
|
|
|
|
|
|
|
|
const char* gUniformMatrixSkSL = R"(
|
2020-11-04 20:40:50 +00:00
|
|
|
uniform shader child;
|
2020-06-18 17:40:26 +00:00
|
|
|
uniform float3x3 matrix;
|
2020-08-13 20:59:48 +00:00
|
|
|
half4 main(float2 xy) {
|
|
|
|
return sample(child, matrix);
|
2020-06-18 17:40:26 +00:00
|
|
|
}
|
|
|
|
)";
|
|
|
|
|
|
|
|
// This form (uniform * constant) is currently detected as variable, thanks to our limited analysis
|
2020-06-29 20:48:46 +00:00
|
|
|
// when scanning for sample matrices. With that pulled into a separate local, it's highly unlikely
|
|
|
|
// we'll ever treat this as anything else.
|
2020-06-18 17:40:26 +00:00
|
|
|
const char* gVariableMatrixSkSL = R"(
|
2020-11-04 20:40:50 +00:00
|
|
|
uniform shader child;
|
2020-06-18 17:40:26 +00:00
|
|
|
uniform float3x3 matrix;
|
2020-08-13 20:59:48 +00:00
|
|
|
half4 main(float2 xy) {
|
2020-06-29 20:48:46 +00:00
|
|
|
float3x3 varMatrix = matrix * 0.5;
|
2020-08-13 20:59:48 +00:00
|
|
|
return sample(child, varMatrix);
|
2020-06-18 17:40:26 +00:00
|
|
|
}
|
|
|
|
)";
|
|
|
|
|
|
|
|
const char* gExplicitCoordSkSL = R"(
|
2020-11-04 20:40:50 +00:00
|
|
|
uniform shader child;
|
2020-08-13 20:59:48 +00:00
|
|
|
half4 main(float2 xy) {
|
|
|
|
return sample(child, xy + float2(0, 8));
|
2020-06-18 17:40:26 +00:00
|
|
|
}
|
|
|
|
)";
|
|
|
|
|
|
|
|
// Version of fp_sample_chaining that uses SkRuntimeEffect
|
|
|
|
DEF_SIMPLE_GM(sksl_sample_chaining, canvas, 380, 306) {
|
|
|
|
SkBitmap bmp = make_test_bitmap();
|
|
|
|
|
|
|
|
sk_sp<SkRuntimeEffect> effects[4] = {
|
2021-02-11 22:40:03 +00:00
|
|
|
SkRuntimeEffect::Make(SkString(gConstantMatrixSkSL)).effect,
|
|
|
|
SkRuntimeEffect::Make(SkString(gUniformMatrixSkSL)).effect,
|
|
|
|
SkRuntimeEffect::Make(SkString(gVariableMatrixSkSL)).effect,
|
|
|
|
SkRuntimeEffect::Make(SkString(gExplicitCoordSkSL)).effect,
|
2020-06-18 17:40:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
canvas->translate(10, 10);
|
|
|
|
canvas->save();
|
|
|
|
auto nextCol = [&] { canvas->translate(64 + 10, 0); };
|
|
|
|
auto nextRow = [&] { canvas->restore(); canvas->translate(0, 64 + 10); canvas->save(); };
|
|
|
|
|
|
|
|
auto draw = [&](std::initializer_list<EffectType> effectTypes) {
|
2020-12-12 16:18:31 +00:00
|
|
|
auto shader = bmp.makeShader(SkSamplingOptions());
|
2020-06-18 17:40:26 +00:00
|
|
|
|
|
|
|
for (EffectType effectType : effectTypes) {
|
|
|
|
SkRuntimeShaderBuilder builder(effects[effectType]);
|
|
|
|
builder.child("child") = shader;
|
|
|
|
switch (effectType) {
|
|
|
|
case kUniform:
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
builder.uniform("matrix") = SkMatrix::Scale(1.0f, 0.5f);
|
2020-06-18 17:40:26 +00:00
|
|
|
break;
|
|
|
|
case kVariable:
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
builder.uniform("matrix") = SkMatrix::Translate(8, 0);
|
2020-06-18 17:40:26 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
shader = builder.makeShader(nullptr, true);
|
|
|
|
}
|
|
|
|
SkPaint paint;
|
|
|
|
paint.setShader(shader);
|
|
|
|
canvas->drawRect(SkRect::MakeWH(64, 64), paint);
|
|
|
|
nextCol();
|
|
|
|
};
|
|
|
|
|
|
|
|
// Reminder, in every case, the chain is more complicated than it seems, because the
|
|
|
|
// GrTextureEffect is wrapped in a GrMatrixEffect, which is subject to the same bugs that
|
|
|
|
// we're testing (particularly the bug about owner/base in UniformMatrixEffect).
|
|
|
|
|
|
|
|
// First row: no transform, then each one independently applied
|
|
|
|
draw({}); // Identity (4 rows and columns)
|
|
|
|
draw({ kConstant }); // Scale X axis by 2x (2 visible columns)
|
|
|
|
draw({ kUniform }); // Scale Y axis by 2x (2 visible rows)
|
|
|
|
draw({ kVariable }); // Translate left by 8px
|
|
|
|
draw({ kExplicit }); // Translate up by 8px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
// Second row: transform duplicated
|
|
|
|
draw({ kConstant, kUniform }); // Scale XY by 2x (2 rows and columns)
|
|
|
|
draw({ kConstant, kConstant }); // Scale X axis by 4x (1 visible column)
|
|
|
|
draw({ kUniform, kUniform }); // Scale Y axis by 4x (1 visible row)
|
Update how sample(matrix) calls are invoked in SkSL
This removes the kMixed type of SkSL::SampleMatrix. All analysis of FP
sampling due to parent-child relationships is tracked in flags on
GrFragmentProcessor now.
The sample strategy is tracked as follows:
- An FP marks itself as using the local coordinate builtin directly (automatically done for .fp code based on reference to sk_TransformedCoords2D[0]).
- This state propagates up the parent towards the root, marking FPs as using coordinates indirectly. We stop the propagation when we hit a parent FP that explicitly samples the child because it becomes the source of the child's coordinates.
- If that parent references its local coordinates directly, that kicks off its own upwards propagation.
- Being sampled explicitly propagates down to all children, and effectively disables vertex-shader evaluation of transforms.
- A variable matrix automatically marks this flag as well, since it's essentially a shortcut to (matrix expression) * coords.
- The matrix type also propagates down, but right now that's only for whether or not there's perspective.
- This doesn't affect FS coord evaluation since each FP applies its action independently.
- But for VS-promoted transforms, the child's varying may inherit perspective (or other more general matrix types) from the parent and switch from a float2 to a float3.
- A SampleMatrix no longer tracks a base or owner, GrFragmentProcessor exposes its parent FP. An FP's sample matrix is always owned by its immediate parent.
- This means that you can have a hierarchy from root to leaf like: [uniform, none, none, uses local coords], and that leaf will have a SampleMatrix of kNone type. However, because of parent tracking, the coordinate generation can walk up to the root and detect the proper transform expression it needs to produce, and automatically de-duplicate across children.
Currently, all FP's that are explicitly sampled have a signature of (color, float2 coord). FP's that don't use local coords, or whose coords are promoted to a varying have a signature of (color).
- In this case, the shader builder either updates args.fLocalCoords to point to the varying directly, or adds a float2 local to the function body that includes the perspective divide.
GrFragmentProcessor automatically pretends it has an identity coord transform if the FP is marked as referencing the local coord builtin. This allows these FPs to still be processed as part of GrGLSLGeometryProcessor::collectTransforms, but removes the need for FP implementations to declare an identity GrCoordTransform.
- To test this theory, GrTextureEffect and GrSkSLFP no longer have coord transforms explicitly.
- Later CLs can trivially remove them from a lot of the other effects.
- The coord generation should not change because it detects in both cases that the coord transform matrices were identity.
GrGLSLGeometryProcessor's collectTransforms and emitTransformCode has been completely overhauled to recurse up an FP's parent pointers and collect the expressions that affect the result. It de-duplicates expressions between siblings, and is able to produce a single varying for the base local coord (either when there are no intervening transforms, or the root FP needs an explicit coordinate to start off with).
This also adds the fp_sample_chaining GM from Brian, with a few more configurations to fill out the cells.
Bug: skia:10396
Change-Id: I86acc0c34c9f29d6371b34370bee9a18c2acf1c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297868
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-06-24 13:04:56 +00:00
|
|
|
draw({ kVariable, kVariable }); // Translate left by 16px
|
|
|
|
draw({ kExplicit, kExplicit }); // Translate up by 16px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
// Remember, these are applied inside out:
|
|
|
|
draw({ kConstant, kExplicit }); // Scale X by 2x and translate up by 8px
|
|
|
|
draw({ kConstant, kVariable }); // Scale X by 2x and translate left by 8px
|
|
|
|
draw({ kUniform, kVariable }); // Scale Y by 2x and translate left by 8px
|
|
|
|
draw({ kUniform, kExplicit }); // Scale Y by 2x and translate up by 8px
|
|
|
|
draw({ kVariable, kExplicit }); // Translate left and up by 8px
|
|
|
|
nextRow();
|
|
|
|
|
|
|
|
draw({ kExplicit, kExplicit, kConstant }); // Scale X by 2x and translate up by 16px
|
|
|
|
draw({ kVariable, kConstant }); // Scale X by 2x and translate left by 16px
|
|
|
|
draw({ kVariable, kVariable, kUniform }); // Scale Y by 2x and translate left by 16px
|
|
|
|
draw({ kExplicit, kUniform }); // Scale Y by 2x and translate up by 16px
|
|
|
|
draw({ kExplicit, kUniform, kVariable, kConstant }); // Scale XY by 2x and translate xy 16px
|
|
|
|
}
|