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:
parent
2b8940ee5e
commit
672c47689d
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user