Avoid multiplication by alpha in fragment shader when known to be 1.
Implemented for image shaders, image draws, and gradient shaders. Reimplement GrFragmentProcessor::OverrideInput as GrOverrideInputFragmentProcessor.fp. It allows specification of whether the replacement input color should be a literal in the shader code or a uniform. For above use case use with literal white. Make key in variables in fp files work for 4f colors. Fix issue in CPP code gen from .fp where when + key vars that pushed multiple values into the shader key only skipped the first key value when the when condition is not true. Bug: skia:7722 Change-Id: Id7c865132d620e8cdea8b00f2a627103eef171ac Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201985 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
6c431d5202
commit
c0d79e525f
@ -372,6 +372,8 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/effects/generated/GrMagnifierEffect.h",
|
||||
"$_src/gpu/effects/generated/GrMixerEffect.cpp",
|
||||
"$_src/gpu/effects/generated/GrMixerEffect.h",
|
||||
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp",
|
||||
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h",
|
||||
"$_src/gpu/effects/generated/GrPremulInputFragmentProcessor.cpp",
|
||||
"$_src/gpu/effects/generated/GrPremulInputFragmentProcessor.h",
|
||||
"$_src/gpu/effects/generated/GrRectBlurEffect.cpp",
|
||||
|
@ -45,6 +45,7 @@ skia_gpu_processor_sources = [
|
||||
"$_src/gpu/effects/GrLumaColorFilterEffect.fp",
|
||||
"$_src/gpu/effects/GrMagnifierEffect.fp",
|
||||
"$_src/gpu/effects/GrMixerEffect.fp",
|
||||
"$_src/gpu/effects/GrOverrideInputFragmentProcessor.fp",
|
||||
"$_src/gpu/effects/GrPremulInputFragmentProcessor.fp",
|
||||
"$_src/gpu/effects/GrRectBlurEffect.fp",
|
||||
"$_src/gpu/effects/GrRRectBlurEffect.fp",
|
||||
|
@ -42,6 +42,9 @@ struct GrFPArgs {
|
||||
const SkMatrix* fPreLocalMatrix = nullptr;
|
||||
const SkMatrix* fPostLocalMatrix = nullptr;
|
||||
|
||||
// Make this SkAlphaType?
|
||||
bool fInputColorIsOpaque = false;
|
||||
|
||||
SkFilterQuality fFilterQuality;
|
||||
const GrColorSpaceInfo* fDstColorSpaceInfo;
|
||||
};
|
||||
|
@ -9,9 +9,10 @@
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrPipeline.h"
|
||||
#include "GrProcessorAnalysis.h"
|
||||
#include "effects/generated/GrConstColorProcessor.h"
|
||||
#include "effects/generated/GrPremulInputFragmentProcessor.h"
|
||||
#include "effects/GrXfermodeFragmentProcessor.h"
|
||||
#include "effects/generated/GrConstColorProcessor.h"
|
||||
#include "effects/generated/GrOverrideInputFragmentProcessor.h"
|
||||
#include "effects/generated/GrPremulInputFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
@ -282,93 +283,11 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulB
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
|
||||
std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color) {
|
||||
class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
|
||||
public:
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
|
||||
const SkPMColor4f& color) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new ReplaceInputFragmentProcessor(std::move(child), color));
|
||||
}
|
||||
|
||||
const char* name() const override { return "Replace Color"; }
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> clone() const override {
|
||||
return Make(this->childProcessor(0).clone(), fColor);
|
||||
}
|
||||
|
||||
private:
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
||||
class GLFP : public GrGLSLFragmentProcessor {
|
||||
public:
|
||||
GLFP() : fHaveSetColor(false) {}
|
||||
void emitCode(EmitArgs& args) override {
|
||||
const char* colorName;
|
||||
fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||
kHalf4_GrSLType,
|
||||
"Color", &colorName);
|
||||
this->emitChild(0, colorName, args);
|
||||
}
|
||||
|
||||
private:
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrFragmentProcessor& fp) override {
|
||||
SkPMColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
|
||||
if (!fHaveSetColor || color != fPreviousColor) {
|
||||
pdman.set4fv(fColorUni, 1, color.vec());
|
||||
fPreviousColor = color;
|
||||
fHaveSetColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
GrGLSLProgramDataManager::UniformHandle fColorUni;
|
||||
bool fHaveSetColor;
|
||||
SkPMColor4f fPreviousColor;
|
||||
};
|
||||
|
||||
return new GLFP;
|
||||
}
|
||||
|
||||
ReplaceInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child,
|
||||
const SkPMColor4f& color)
|
||||
: INHERITED(kReplaceInputFragmentProcessor_ClassID, OptFlags(child.get(), color))
|
||||
, fColor(color) {
|
||||
this->registerChildProcessor(std::move(child));
|
||||
}
|
||||
|
||||
static OptimizationFlags OptFlags(const GrFragmentProcessor* child,
|
||||
const SkPMColor4f& color) {
|
||||
OptimizationFlags childFlags = child->optimizationFlags();
|
||||
OptimizationFlags flags = kNone_OptimizationFlags;
|
||||
if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
|
||||
flags |= kConstantOutputForConstantInput_OptimizationFlag;
|
||||
}
|
||||
if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
|
||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
|
||||
{}
|
||||
|
||||
bool onIsEqual(const GrFragmentProcessor& that) const override {
|
||||
return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
|
||||
}
|
||||
|
||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override {
|
||||
return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
|
||||
}
|
||||
|
||||
SkPMColor4f fColor;
|
||||
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color, bool useUniform) {
|
||||
if (!fp) {
|
||||
return nullptr;
|
||||
}
|
||||
return ReplaceInputFragmentProcessor::Make(std::move(fp), color);
|
||||
return GrOverrideInputFragmentProcessor::Make(std::move(fp), color, useUniform);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
|
||||
|
@ -63,7 +63,8 @@ public:
|
||||
* child.
|
||||
*/
|
||||
static std::unique_ptr<GrFragmentProcessor> OverrideInput(std::unique_ptr<GrFragmentProcessor>,
|
||||
const SkPMColor4f&);
|
||||
const SkPMColor4f&,
|
||||
bool useUniform = true);
|
||||
|
||||
/**
|
||||
* Returns a fragment processor that premuls the input before calling the passed in fragment
|
||||
@ -293,6 +294,11 @@ protected:
|
||||
return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
|
||||
}
|
||||
|
||||
/** Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.*/
|
||||
static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor* fp) {
|
||||
return fp->optimizationFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows one subclass to access another subclass's implementation of
|
||||
* constantOutputForConstantInput. It must only be called when
|
||||
|
@ -124,6 +124,7 @@ public:
|
||||
kGrMorphologyEffect_ClassID,
|
||||
kGrMixerEffect_ClassID,
|
||||
kGrOverdrawFragmentProcessor_ClassID,
|
||||
kGrOverrideInputFragmentProcessor_ClassID,
|
||||
kGrPathProcessor_ClassID,
|
||||
kGrPerlinNoise2Effect_ClassID,
|
||||
kGrPipelineDynamicStateTestProcessor_ClassID,
|
||||
|
@ -1060,9 +1060,13 @@ void SkGpuDevice::drawSpecial(SkSpecialImage* special, int left, int top, const
|
||||
fRenderTargetContext->colorSpaceInfo().colorSpace());
|
||||
if (GrPixelConfigIsAlphaOnly(config)) {
|
||||
fp = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
|
||||
} else {
|
||||
if (paint.getColor4f().isOpaque()) {
|
||||
fp = GrFragmentProcessor::OverrideInput(std::move(fp), SK_PMColor4fWHITE, false);
|
||||
} else {
|
||||
fp = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
|
||||
}
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaintReplaceShader(this->context(), fRenderTargetContext->colorSpaceInfo(),
|
||||
|
@ -355,12 +355,13 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
||||
// Convert SkPaint color to 4f format in the destination color space
|
||||
SkColor4f origColor = SkColor4fPrepForDst(skPaint.getColor4f(), colorSpaceInfo);
|
||||
|
||||
const GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
|
||||
GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
|
||||
|
||||
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
|
||||
// of per-vertex colors.
|
||||
std::unique_ptr<GrFragmentProcessor> shaderFP;
|
||||
if (!primColorMode || blend_requires_shader(*primColorMode)) {
|
||||
fpArgs.fInputColorIsOpaque = origColor.isOpaque();
|
||||
if (shaderProcessor) {
|
||||
shaderFP = std::move(*shaderProcessor);
|
||||
} else if (const auto* shader = as_SB(skPaint.getShader())) {
|
||||
@ -457,6 +458,8 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
||||
|
||||
SkMaskFilterBase* maskFilter = as_MFB(skPaint.getMaskFilter());
|
||||
if (maskFilter) {
|
||||
// We may have set this before passing to the SkShader.
|
||||
fpArgs.fInputColorIsOpaque = false;
|
||||
if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
|
||||
grPaint->addCoverageFragmentProcessor(std::move(mfFP));
|
||||
}
|
||||
@ -550,9 +553,13 @@ bool SkPaintToGrPaintWithTexture(GrRecordingContext* context,
|
||||
} else {
|
||||
shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
|
||||
}
|
||||
} else {
|
||||
if (paint.getColor4f().isOpaque()) {
|
||||
shaderFP = GrFragmentProcessor::OverrideInput(std::move(fp), SK_PMColor4fWHITE, false);
|
||||
} else {
|
||||
shaderFP = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
|
||||
}
|
||||
}
|
||||
|
||||
return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),
|
||||
grPaint);
|
||||
|
@ -15,27 +15,11 @@ in uniform half weight;
|
||||
|
||||
static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
|
||||
const std::unique_ptr<GrFragmentProcessor>& fp1) {
|
||||
auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
|
||||
auto flags = kNone_OptimizationFlags;
|
||||
|
||||
if (fp->compatibleWithCoverageAsAlpha()) {
|
||||
flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
||||
auto flags = ProcessorOptimizationFlags(fp0.get());
|
||||
if (fp1) {
|
||||
flags &= ProcessorOptimizationFlags(fp1.get());
|
||||
}
|
||||
|
||||
if (fp->preservesOpaqueInput()) {
|
||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
||||
}
|
||||
|
||||
if (fp->hasConstantOutputForConstantInput()) {
|
||||
flags |= kConstantOutputForConstantInput_OptimizationFlag;
|
||||
}
|
||||
|
||||
return flags;
|
||||
};
|
||||
|
||||
const auto fp0_flags = get_flags(fp0);
|
||||
|
||||
return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_flags;
|
||||
}
|
||||
|
||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
||||
|
55
src/gpu/effects/GrOverrideInputFragmentProcessor.fp
Normal file
55
src/gpu/effects/GrOverrideInputFragmentProcessor.fp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// Ignores its own input color and invokes 'fp' with a constant color
|
||||
// The constant color can either be specified as a literal or as a
|
||||
// uniform, controlled by useUniform.
|
||||
|
||||
in fragmentProcessor fp;
|
||||
layout(key) in bool useUniform;
|
||||
layout(when=useUniform, ctype=SkPMColor4f) in uniform half4 uniformColor;
|
||||
layout(when=!useUniform, key, ctype=SkPMColor4f) in half4 literalColor;
|
||||
|
||||
@make {
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
|
||||
const SkPMColor4f& color,
|
||||
bool useUniform = true) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new GrOverrideInputFragmentProcessor(std::move(fp), useUniform, color, color));
|
||||
}
|
||||
}
|
||||
|
||||
@class {
|
||||
static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp,
|
||||
const SkPMColor4f& color) {
|
||||
auto childFlags = ProcessorOptimizationFlags(fp.get());
|
||||
auto flags = kNone_OptimizationFlags;
|
||||
if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
|
||||
flags |= kConstantOutputForConstantInput_OptimizationFlag;
|
||||
}
|
||||
if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
|
||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
||||
return ConstantOutputForConstantInput(this->childProcessor(0), uniformColor);
|
||||
}
|
||||
}
|
||||
|
||||
@optimizationFlags { OptFlags(fp, useUniform ? uniformColor : literalColor) }
|
||||
|
||||
void main() {
|
||||
half4 constColor;
|
||||
@if(useUniform) {
|
||||
constColor = uniformColor;
|
||||
} else {
|
||||
constColor = literalColor;
|
||||
}
|
||||
sk_OutColor = process(fp, constColor);
|
||||
}
|
@ -326,17 +326,8 @@ private:
|
||||
case SkBlendMode::kSrcIn:
|
||||
case SkBlendMode::kDstIn:
|
||||
case SkBlendMode::kModulate:
|
||||
if (fp->compatibleWithCoverageAsAlpha()) {
|
||||
if (fp->preservesOpaqueInput()) {
|
||||
flags = kPreservesOpaqueInput_OptimizationFlag |
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
||||
} else {
|
||||
flags = kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
||||
}
|
||||
} else {
|
||||
flags = fp->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
|
||||
: kNone_OptimizationFlags;
|
||||
}
|
||||
flags = ProcessorOptimizationFlags(fp) &
|
||||
~kConstantOutputForConstantInput_OptimizationFlag;
|
||||
break;
|
||||
|
||||
// Produces zero when both are opaque, indeterminate if one is opaque.
|
||||
|
@ -17,27 +17,11 @@ class GrMixerEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
|
||||
const std::unique_ptr<GrFragmentProcessor>& fp1) {
|
||||
auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
|
||||
auto flags = kNone_OptimizationFlags;
|
||||
|
||||
if (fp->compatibleWithCoverageAsAlpha()) {
|
||||
flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
||||
auto flags = ProcessorOptimizationFlags(fp0.get());
|
||||
if (fp1) {
|
||||
flags &= ProcessorOptimizationFlags(fp1.get());
|
||||
}
|
||||
|
||||
if (fp->preservesOpaqueInput()) {
|
||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
||||
}
|
||||
|
||||
if (fp->hasConstantOutputForConstantInput()) {
|
||||
flags |= kConstantOutputForConstantInput_OptimizationFlag;
|
||||
}
|
||||
|
||||
return flags;
|
||||
};
|
||||
|
||||
const auto fp0_flags = get_flags(fp0);
|
||||
|
||||
return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_flags;
|
||||
}
|
||||
|
||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**************************************************************************************************
|
||||
*** This file was autogenerated from GrOverrideInputFragmentProcessor.fp; do not modify.
|
||||
**************************************************************************************************/
|
||||
#include "GrOverrideInputFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "glsl/GrGLSLProgramBuilder.h"
|
||||
#include "GrTexture.h"
|
||||
#include "SkSLCPP.h"
|
||||
#include "SkSLUtil.h"
|
||||
class GrGLSLOverrideInputFragmentProcessor : public GrGLSLFragmentProcessor {
|
||||
public:
|
||||
GrGLSLOverrideInputFragmentProcessor() {}
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const GrOverrideInputFragmentProcessor& _outer =
|
||||
args.fFp.cast<GrOverrideInputFragmentProcessor>();
|
||||
(void)_outer;
|
||||
auto useUniform = _outer.useUniform;
|
||||
(void)useUniform;
|
||||
auto uniformColor = _outer.uniformColor;
|
||||
(void)uniformColor;
|
||||
auto literalColor = _outer.literalColor;
|
||||
(void)literalColor;
|
||||
if (useUniform) {
|
||||
uniformColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||
kHalf4_GrSLType, "uniformColor");
|
||||
}
|
||||
fragBuilder->codeAppendf(
|
||||
"half4 constColor;\n@if (%s) {\n constColor = %s;\n} else {\n constColor = "
|
||||
"half4(%f, %f, %f, %f);\n}",
|
||||
(_outer.useUniform ? "true" : "false"),
|
||||
uniformColorVar.isValid() ? args.fUniformHandler->getUniformCStr(uniformColorVar)
|
||||
: "half4(0)",
|
||||
_outer.literalColor.fR, _outer.literalColor.fG, _outer.literalColor.fB,
|
||||
_outer.literalColor.fA);
|
||||
SkString _input0("constColor");
|
||||
SkString _child0("_child0");
|
||||
this->emitChild(_outer.fp_index, _input0.c_str(), &_child0, args);
|
||||
fragBuilder->codeAppendf("\n%s = %s;\n", args.fOutputColor, _child0.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrFragmentProcessor& _proc) override {
|
||||
const GrOverrideInputFragmentProcessor& _outer =
|
||||
_proc.cast<GrOverrideInputFragmentProcessor>();
|
||||
{
|
||||
if (uniformColorVar.isValid()) {
|
||||
pdman.set4fv(uniformColorVar, 1, (_outer.uniformColor).vec());
|
||||
}
|
||||
}
|
||||
}
|
||||
UniformHandle uniformColorVar;
|
||||
};
|
||||
GrGLSLFragmentProcessor* GrOverrideInputFragmentProcessor::onCreateGLSLInstance() const {
|
||||
return new GrGLSLOverrideInputFragmentProcessor();
|
||||
}
|
||||
void GrOverrideInputFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
b->add32((int32_t)useUniform);
|
||||
if (!useUniform) {
|
||||
uint16_t red = SkFloatToHalf(literalColor.fR);
|
||||
uint16_t green = SkFloatToHalf(literalColor.fG);
|
||||
uint16_t blue = SkFloatToHalf(literalColor.fB);
|
||||
uint16_t alpha = SkFloatToHalf(literalColor.fA);
|
||||
b->add32(((uint32_t)red << 16) | green);
|
||||
b->add32(((uint32_t)blue << 16) | alpha);
|
||||
}
|
||||
}
|
||||
bool GrOverrideInputFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
|
||||
const GrOverrideInputFragmentProcessor& that = other.cast<GrOverrideInputFragmentProcessor>();
|
||||
(void)that;
|
||||
if (useUniform != that.useUniform) return false;
|
||||
if (uniformColor != that.uniformColor) return false;
|
||||
if (literalColor != that.literalColor) return false;
|
||||
return true;
|
||||
}
|
||||
GrOverrideInputFragmentProcessor::GrOverrideInputFragmentProcessor(
|
||||
const GrOverrideInputFragmentProcessor& src)
|
||||
: INHERITED(kGrOverrideInputFragmentProcessor_ClassID, src.optimizationFlags())
|
||||
, fp_index(src.fp_index)
|
||||
, useUniform(src.useUniform)
|
||||
, uniformColor(src.uniformColor)
|
||||
, literalColor(src.literalColor) {
|
||||
this->registerChildProcessor(src.childProcessor(fp_index).clone());
|
||||
}
|
||||
std::unique_ptr<GrFragmentProcessor> GrOverrideInputFragmentProcessor::clone() const {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new GrOverrideInputFragmentProcessor(*this));
|
||||
}
|
69
src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h
Normal file
69
src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**************************************************************************************************
|
||||
*** This file was autogenerated from GrOverrideInputFragmentProcessor.fp; do not modify.
|
||||
**************************************************************************************************/
|
||||
#ifndef GrOverrideInputFragmentProcessor_DEFINED
|
||||
#define GrOverrideInputFragmentProcessor_DEFINED
|
||||
#include "SkTypes.h"
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
class GrOverrideInputFragmentProcessor : public GrFragmentProcessor {
|
||||
public:
|
||||
static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp,
|
||||
const SkPMColor4f& color) {
|
||||
auto childFlags = ProcessorOptimizationFlags(fp.get());
|
||||
auto flags = kNone_OptimizationFlags;
|
||||
if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
|
||||
flags |= kConstantOutputForConstantInput_OptimizationFlag;
|
||||
}
|
||||
if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
|
||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
||||
return ConstantOutputForConstantInput(this->childProcessor(0), uniformColor);
|
||||
}
|
||||
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
|
||||
const SkPMColor4f& color,
|
||||
bool useUniform = true) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new GrOverrideInputFragmentProcessor(std::move(fp), useUniform, color, color));
|
||||
}
|
||||
GrOverrideInputFragmentProcessor(const GrOverrideInputFragmentProcessor& src);
|
||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||
const char* name() const override { return "OverrideInputFragmentProcessor"; }
|
||||
int fp_index = -1;
|
||||
bool useUniform;
|
||||
SkPMColor4f uniformColor;
|
||||
SkPMColor4f literalColor;
|
||||
|
||||
private:
|
||||
GrOverrideInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp,
|
||||
bool useUniform,
|
||||
SkPMColor4f uniformColor,
|
||||
SkPMColor4f literalColor)
|
||||
: INHERITED(kGrOverrideInputFragmentProcessor_ClassID,
|
||||
(OptimizationFlags)OptFlags(fp, useUniform ? uniformColor : literalColor))
|
||||
, useUniform(useUniform)
|
||||
, uniformColor(uniformColor)
|
||||
, literalColor(literalColor) {
|
||||
SkASSERT(fp);
|
||||
fp_index = this->numChildProcessors();
|
||||
this->registerChildProcessor(std::move(fp));
|
||||
}
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
#endif
|
@ -236,7 +236,9 @@ static std::unique_ptr<GrFragmentProcessor> make_gradient(const SkGradientShader
|
||||
// Unexpected tile mode
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (args.fInputColorIsOpaque) {
|
||||
return GrFragmentProcessor::OverrideInput(std::move(master), SK_PMColor4fWHITE, false);
|
||||
}
|
||||
return GrFragmentProcessor::MulChildByInputAlpha(std::move(master));
|
||||
}
|
||||
|
||||
|
@ -257,6 +257,8 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
|
||||
args.fDstColorSpaceInfo->colorSpace());
|
||||
if (isAlphaOnly) {
|
||||
return inner;
|
||||
} else if (args.fInputColorIsOpaque) {
|
||||
return GrFragmentProcessor::OverrideInput(std::move(inner), SK_PMColor4fWHITE, false);
|
||||
}
|
||||
return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
|
||||
}
|
||||
|
@ -1106,7 +1106,7 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
switch (param->fModifiers.fLayout.fKey) {
|
||||
case Layout::kKey_Key:
|
||||
if (param->fModifiers.fLayout.fWhen.size()) {
|
||||
this->writef("if (%s) ", param->fModifiers.fLayout.fWhen.c_str());
|
||||
this->writef("if (%s) {", param->fModifiers.fLayout.fWhen.c_str());
|
||||
}
|
||||
if (param->fType == *fContext.fFloat4x4_Type) {
|
||||
ABORT("no automatic key handling for float4x4\n");
|
||||
@ -1124,10 +1124,24 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" b->add32(%s.height());\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
} else if (param->fType == *fContext.fHalf4_Type) {
|
||||
this->writef(" uint16_t red = SkFloatToHalf(%s.fR);\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" uint16_t green = SkFloatToHalf(%s.fG);\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" uint16_t blue = SkFloatToHalf(%s.fB);\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" uint16_t alpha = SkFloatToHalf(%s.fA);\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
this->write(" b->add32(((uint32_t)red << 16) | green);\n");
|
||||
this->write(" b->add32(((uint32_t)blue << 16) | alpha);\n");
|
||||
} else {
|
||||
this->writef(" b->add32((int32_t) %s);\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
}
|
||||
if (param->fModifiers.fLayout.fWhen.size()) {
|
||||
this->write("}");
|
||||
}
|
||||
break;
|
||||
case Layout::kIdentity_Key:
|
||||
if (param->fType.kind() != Type::kMatrix_Kind) {
|
||||
|
Loading…
Reference in New Issue
Block a user