Replace 'master' with 'top-level' or 'gradient'

Bug: skia:10570
Change-Id: I257380fda62d99c7c27efabf2105478d20f23c57
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308336
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
Michael Ludwig 2020-08-05 17:28:42 -04:00 committed by Skia Commit-Bot
parent 2b8940ee5e
commit 672c47689d
4 changed files with 37 additions and 36 deletions

View File

@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
// This master effect implements clamping on the layout coordinate and requires specifying the
// This top-level effect implements clamping on the layout coordinate and requires specifying the
// border colors that are used when outside the clamped boundary. Gradients with the
// SkShader::kClamp_TileMode should use the colors at their first and last stop (after adding dummy
// stops for t=0,t=1) as the border color. This will automatically replicate the edge color, even if

View File

@ -151,7 +151,7 @@ static std::unique_ptr<GrFragmentProcessor> make_colorizer(const SkPMColor4f* co
return make_textured_colorizer(colors + offset, positions + offset, count, premul, args);
}
// Combines the colorizer and layout with an appropriately configured master effect based on the
// Combines the colorizer and layout with an appropriately configured top-level effect based on the
// gradient's tile mode
static std::unique_ptr<GrFragmentProcessor> make_gradient(const SkGradientShaderBase& shader,
const GrFPArgs& args, std::unique_ptr<GrFragmentProcessor> layout) {
@ -200,22 +200,23 @@ static std::unique_ptr<GrFragmentProcessor> make_gradient(const SkGradientShader
return nullptr;
}
// The master effect has to export premul colors, but under certain conditions it doesn't need
// to do anything to achieve that: i.e. its interpolating already premul colors (inputPremul)
// or all the colors have a = 1, in which case premul is a no op. Note that this allOpaque
// check is more permissive than SkGradientShaderBase's isOpaque(), since we can optimize away
// the make-premul op for two point conical gradients (which report false for isOpaque).
// The top-level effect has to export premul colors, but under certain conditions it doesn't
// need to do anything to achieve that: i.e. its interpolating already premul colors
// (inputPremul) or all the colors have a = 1, in which case premul is a no op. Note that this
// allOpaque check is more permissive than SkGradientShaderBase's isOpaque(), since we can
// optimize away the make-premul op for two point conical gradients (which report false for
// isOpaque).
bool makePremul = !inputPremul && !allOpaque;
// All tile modes are supported (unless something was added to SkShader)
std::unique_ptr<GrFragmentProcessor> master;
std::unique_ptr<GrFragmentProcessor> gradient;
switch(shader.getTileMode()) {
case SkTileMode::kRepeat:
master = GrTiledGradientEffect::Make(std::move(colorizer), std::move(layout),
gradient = GrTiledGradientEffect::Make(std::move(colorizer), std::move(layout),
/* mirror */ false, makePremul, allOpaque);
break;
case SkTileMode::kMirror:
master = GrTiledGradientEffect::Make(std::move(colorizer), std::move(layout),
gradient = GrTiledGradientEffect::Make(std::move(colorizer), std::move(layout),
/* mirror */ true, makePremul, allOpaque);
break;
case SkTileMode::kClamp:
@ -223,26 +224,28 @@ static std::unique_ptr<GrFragmentProcessor> make_gradient(const SkGradientShader
// to t=0 and t=1, because SkGradientShaderBase enforces that by adding color stops as
// appropriate. If there is a hard stop, this grabs the expected outer colors for the
// border.
master = GrClampedGradientEffect::Make(std::move(colorizer), std::move(layout),
colors[0], colors[shader.fColorCount - 1], makePremul, allOpaque);
gradient = GrClampedGradientEffect::Make(std::move(colorizer), std::move(layout),
colors[0], colors[shader.fColorCount - 1],
makePremul, allOpaque);
break;
case SkTileMode::kDecal:
// Even if the gradient colors are opaque, the decal borders are transparent so
// disable that optimization
master = GrClampedGradientEffect::Make(std::move(colorizer), std::move(layout),
SK_PMColor4fTRANSPARENT, SK_PMColor4fTRANSPARENT,
gradient = GrClampedGradientEffect::Make(std::move(colorizer), std::move(layout),
SK_PMColor4fTRANSPARENT,
SK_PMColor4fTRANSPARENT,
makePremul, /* colorsAreOpaque */ false);
break;
}
if (master == nullptr) {
if (gradient == nullptr) {
// Unexpected tile mode
return nullptr;
}
if (args.fInputColorIsOpaque) {
return GrFragmentProcessor::OverrideInput(std::move(master), SK_PMColor4fWHITE, false);
return GrFragmentProcessor::OverrideInput(std::move(gradient), SK_PMColor4fWHITE, false);
}
return GrFragmentProcessor::MulChildByInputAlpha(std::move(master));
return GrFragmentProcessor::MulChildByInputAlpha(std::move(gradient));
}
namespace GrGradientShader {

View File

@ -12,8 +12,8 @@ Gradients can be thought of, at a very high level, as three pieces:
distinguishes itself. When designing a new gradient, this is the component
that you have to implement. A layout will generally be named
GrXGradientLayout
3. A master effect that composes the layout and color interpolator together. It
is also responsible for implementing the clamping behavior that can be
3. A top-level effect that composes the layout and color interpolator together.
It is also responsible for implementing the clamping behavior that can be
abstracted away from both the layout and colorization.
@ -21,7 +21,7 @@ GrClampedGradientEffect handles clamped and decal tile modes, while
GrTiledGradientEffect implements repeat and mirror tile modes. The
GrClampedGradientEffect requires border colors to be specified outside of its
colorizer child, but these border colors may be defined by the gradient color
stops. Both of these master effects delegate calculating a t interpolant to a
stops. Both of these top-level effects delegate calculating a t interpolant to a
child process, perform their respective tile mode operations, and possibly
convert the tiled t value (guaranteed to be within 0 and 1) into an output
color using their child colorizer process.
@ -29,12 +29,12 @@ color using their child colorizer process.
Because of how child processors are currently defined, where they have a single
half4 input and a single half4 output, their is a type mismatch between the 1D
t value and the 4D inputs/outputs of the layout and colorizer processes. For
now, the master effect assumes an untiled t is output in sk_OutColor.x by the
now, the top-level effect assumes an untiled t is output in sk_OutColor.x by the
layout and it tiles solely off of that value.
However, layouts can output a negative value in the y component to invalidate
the gradient location (currently on the two point conical gradient does this).
When invalidated, the master effect outputs transparent black and does not
When invalidated, the top-level effect outputs transparent black and does not
invoke the child processor. Other than this condition, any value in y, z, or w
are passed into the colorizer unmodified. The colorizer should assume that the
valid tiled t value is in sk_InColor.x and can safely ignore y, z, and w.
@ -51,12 +51,12 @@ Optimization Flags
At an abstract level, gradient shaders are compatible with coverage as alpha
and, under certain conditions, preserve opacity when the inputs are opaque. To
reduce the amount of duplicate code and boilerplate, these optimization
decisions are implemented in the master effects and not in the colorizers. It
decisions are implemented in the top-level effects and not in the colorizers. It
is assumed that all colorizer FPs will be compatible with coverage as alpha and
will preserve opacity if input colors are opaque. Since this is assumed by the
master effects, they do not need to report these optimizations or check input
top-level effects, they do not need to report these optimizations or check input
opacity (this does mean if the colorizers are used independently from the
master effect shader that the reported flags might not be optimal, but since
top-level effect shader that the reported flags might not be optimal, but since
that is unlikely, this convention really simplifies the colorizer
implementations).
@ -66,6 +66,4 @@ opacity of a pixel outside of how the gradient would otherwise color it.
Layouts that potentially reject pixels (i.e. could output a negative y value)
must not report kPreservesOpaqueInput_OptimizationFlag. Layouts that never
reject a pixel should report kPreservesOpaqueInput_OptimizationFlag since the
master effects can optimize away checking if the layout rejects a pixel.
top-level effects can optimize away checking if the layout rejects a pixel.

View File

@ -36,7 +36,7 @@ public:
kHalf4_GrSLType, "leftBorderColor");
rightBorderColorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
kHalf4_GrSLType, "rightBorderColor");
SkString _sample1099 = this->invokeChild(1, args);
SkString _sample1102 = this->invokeChild(1, args);
fragBuilder->codeAppendf(
R"SkSL(half4 t = %s;
if (!%s && t.y < 0.0) {
@ -46,13 +46,13 @@ if (!%s && t.y < 0.0) {
} else if (t.x > 1.0) {
%s = %s;
} else {)SkSL",
_sample1099.c_str(),
_sample1102.c_str(),
(_outer.childProcessor(1)->preservesOpaqueInput() ? "true" : "false"),
args.fOutputColor, args.fOutputColor,
args.fUniformHandler->getUniformCStr(leftBorderColorVar), args.fOutputColor,
args.fUniformHandler->getUniformCStr(rightBorderColorVar));
SkString _coords1868("float2(half2(t.x, 0))");
SkString _sample1868 = this->invokeChild(0, args, _coords1868.c_str());
SkString _coords1871("float2(half2(t.x, 0))");
SkString _sample1871 = this->invokeChild(0, args, _coords1871.c_str());
fragBuilder->codeAppendf(
R"SkSL(
%s = %s;
@ -61,7 +61,7 @@ if (!%s && t.y < 0.0) {
%s.xyz *= %s.w;
}
)SkSL",
args.fOutputColor, _sample1868.c_str(), (_outer.makePremul ? "true" : "false"),
args.fOutputColor, _sample1871.c_str(), (_outer.makePremul ? "true" : "false"),
args.fOutputColor, args.fOutputColor);
}