Add in shader blending for CoverageSetOp XP
BUG=skia: Review URL: https://codereview.chromium.org/1488213002
This commit is contained in:
parent
7bceedc550
commit
f34b293681
@ -213,8 +213,10 @@ private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* srcCoverage,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const char* outColorSecondary,
|
||||
const GrXferProcessor& proc) override {
|
||||
fKUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, kDefault_GrSLPrecision,
|
||||
@ -222,6 +224,19 @@ private:
|
||||
const char* kUni = pb->getUniformCStr(fKUni);
|
||||
|
||||
add_arithmetic_code(fragBuilder, srcColor, dstColor, outColor, kUni, fEnforcePMColor);
|
||||
|
||||
// Apply coverage.
|
||||
if (proc.dstReadUsesMixedSamples()) {
|
||||
if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage);
|
||||
} else {
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary);
|
||||
}
|
||||
} else if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
outColor, srcCoverage, outColor, srcCoverage, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GrColor.h"
|
||||
#include "GrProcessor.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "glsl/GrGLSLBlend.h"
|
||||
#include "glsl/GrGLSLProgramBuilder.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "glsl/GrGLSLXferProcessor.h"
|
||||
@ -146,6 +147,96 @@ void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) cons
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ShaderCSOXferProcessor : public GrXferProcessor {
|
||||
public:
|
||||
ShaderCSOXferProcessor(const DstTexture* dstTexture,
|
||||
bool hasMixedSamples,
|
||||
SkXfermode::Mode xfermode,
|
||||
SkRegion::Op regionOp,
|
||||
bool invertCoverage)
|
||||
: INHERITED(dstTexture, true, hasMixedSamples)
|
||||
, fRegionOp(regionOp)
|
||||
, fInvertCoverage(invertCoverage) {
|
||||
this->initClassID<ShaderCSOXferProcessor>();
|
||||
}
|
||||
|
||||
const char* name() const override { return "Coverage Set Op Shader"; }
|
||||
|
||||
GrGLSLXferProcessor* createGLSLInstance() const override;
|
||||
|
||||
SkRegion::Op regionOp() const { return fRegionOp; }
|
||||
bool invertCoverage() const { return fInvertCoverage; }
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&, bool, GrColor*,
|
||||
const GrCaps&) const override {
|
||||
// We never look at the color input
|
||||
return GrXferProcessor::kIgnoreColor_OptFlag;
|
||||
}
|
||||
|
||||
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
bool onIsEqual(const GrXferProcessor& xpBase) const override {
|
||||
const ShaderCSOXferProcessor& xp = xpBase.cast<ShaderCSOXferProcessor>();
|
||||
return (fRegionOp == xp.fRegionOp &&
|
||||
fInvertCoverage == xp.fInvertCoverage);
|
||||
}
|
||||
|
||||
SkRegion::Op fRegionOp;
|
||||
bool fInvertCoverage;
|
||||
|
||||
typedef GrXferProcessor INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GLShaderCSOXferProcessor : public GrGLSLXferProcessor {
|
||||
public:
|
||||
static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) {
|
||||
const ShaderCSOXferProcessor& xp = processor.cast<ShaderCSOXferProcessor>();
|
||||
b->add32(xp.regionOp());
|
||||
uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* srcCoverage,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const char* outColorSecondary,
|
||||
const GrXferProcessor& proc) override {
|
||||
const ShaderCSOXferProcessor& xp = proc.cast<ShaderCSOXferProcessor>();
|
||||
|
||||
if (xp.invertCoverage()) {
|
||||
fragBuilder->codeAppendf("%s = 1.0 - %s;", outColor, srcCoverage);
|
||||
} else {
|
||||
fragBuilder->codeAppendf("%s = %s;", outColor, srcCoverage);
|
||||
}
|
||||
|
||||
GrGLSLBlend::AppendRegionOp(fragBuilder, outColor, dstColor, outColor, xp.regionOp());
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
|
||||
typedef GrGLSLXferProcessor INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ShaderCSOXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GLShaderCSOXferProcessor::GenKey(*this, b);
|
||||
}
|
||||
|
||||
GrGLSLXferProcessor* ShaderCSOXferProcessor::createGLSLInstance() const {
|
||||
return new GLShaderCSOXferProcessor;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage)
|
||||
: fRegionOp(regionOp)
|
||||
, fInvertCoverage(invertCoverage) {
|
||||
|
@ -161,13 +161,28 @@ private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* srcCoverage,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const char* outColorSecondary,
|
||||
const GrXferProcessor& proc) override {
|
||||
const CustomXP& xp = proc.cast<CustomXP>();
|
||||
SkASSERT(!xp.hasHWBlendEquation());
|
||||
|
||||
GrGLSLBlend::AppendMode(fragBuilder, srcColor, dstColor, outColor, xp.mode());
|
||||
|
||||
// Apply coverage.
|
||||
if (xp.dstReadUsesMixedSamples()) {
|
||||
if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage);
|
||||
} else {
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary);
|
||||
}
|
||||
} else if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
outColor, srcCoverage, outColor, srcCoverage, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
|
@ -548,12 +548,27 @@ private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* srcCoverage,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const char* outColorSecondary,
|
||||
const GrXferProcessor& proc) override {
|
||||
const ShaderPDXferProcessor& xp = proc.cast<ShaderPDXferProcessor>();
|
||||
|
||||
GrGLSLBlend::AppendMode(fragBuilder, srcColor, dstColor, outColor, xp.getXfermode());
|
||||
|
||||
// Apply coverage.
|
||||
if (xp.dstReadUsesMixedSamples()) {
|
||||
if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage);
|
||||
} else {
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary);
|
||||
}
|
||||
} else if (srcCoverage) {
|
||||
fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
outColor, srcCoverage, outColor, srcCoverage, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
|
@ -433,3 +433,50 @@ void GrGLSLBlend::AppendMode(GrGLSLFragmentBuilder* fsBuilder, const char* srcCo
|
||||
emit_advanced_xfermode_code(fsBuilder, srcColor, dstColor, outColor, mode);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLSLBlend::AppendRegionOp(GrGLSLFragmentBuilder* fsBuilder, const char* srcColor,
|
||||
const char* dstColor, const char* outColor,
|
||||
SkRegion::Op regionOp) {
|
||||
SkXfermode::Coeff srcCoeff, dstCoeff;
|
||||
switch (regionOp) {
|
||||
case SkRegion::kReplace_Op:
|
||||
srcCoeff = SkXfermode::kOne_Coeff;
|
||||
dstCoeff = SkXfermode::kZero_Coeff;
|
||||
break;
|
||||
case SkRegion::kIntersect_Op:
|
||||
srcCoeff = SkXfermode::kDC_Coeff;
|
||||
dstCoeff = SkXfermode::kZero_Coeff;
|
||||
break;
|
||||
case SkRegion::kUnion_Op:
|
||||
srcCoeff = SkXfermode::kOne_Coeff;
|
||||
dstCoeff = SkXfermode::kISC_Coeff;
|
||||
break;
|
||||
case SkRegion::kXOR_Op:
|
||||
srcCoeff = SkXfermode::kIDC_Coeff;
|
||||
dstCoeff = SkXfermode::kISC_Coeff;
|
||||
break;
|
||||
case SkRegion::kDifference_Op:
|
||||
srcCoeff = SkXfermode::kZero_Coeff;
|
||||
dstCoeff = SkXfermode::kISC_Coeff;
|
||||
break;
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
srcCoeff = SkXfermode::kIDC_Coeff;
|
||||
dstCoeff = SkXfermode::kZero_Coeff;
|
||||
break;
|
||||
default:
|
||||
SkFAIL("Unsupported Op");
|
||||
// We should never get here but to make compiler happy
|
||||
srcCoeff = SkXfermode::kZero_Coeff;
|
||||
dstCoeff = SkXfermode::kZero_Coeff;
|
||||
}
|
||||
fsBuilder->codeAppendf("%s = ", outColor);
|
||||
// append src blend
|
||||
bool didAppend = append_porterduff_term(fsBuilder, srcCoeff, srcColor, srcColor, dstColor,
|
||||
false);
|
||||
// append dst blend
|
||||
if(!append_porterduff_term(fsBuilder, dstCoeff, dstColor, srcColor, dstColor, didAppend)) {
|
||||
fsBuilder->codeAppend("vec4(0, 0, 0, 0)");
|
||||
}
|
||||
fsBuilder->codeAppend(";");
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef GrGLBlend_DEFINED
|
||||
#define GrGLBlend_DEFINED
|
||||
|
||||
#include "SkRegion.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class GrGLSLFragmentBuilder;
|
||||
@ -19,6 +20,9 @@ namespace GrGLSLBlend {
|
||||
*/
|
||||
void AppendMode(GrGLSLFragmentBuilder* fsBuilder, const char* srcColor,
|
||||
const char* dstColor, const char* outColor, SkXfermode::Mode mode);
|
||||
|
||||
void AppendRegionOp(GrGLSLFragmentBuilder* fsBuilder, const char* srcColor,
|
||||
const char* dstColor, const char* outColor, SkRegion::Op regionOp);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -63,23 +63,11 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
|
||||
this->emitBlendCodeForDstRead(args.fPB,
|
||||
fragBuilder,
|
||||
args.fInputColor,
|
||||
args.fInputCoverage,
|
||||
dstColor,
|
||||
args.fOutputPrimary,
|
||||
args.fOutputSecondary,
|
||||
args.fXP);
|
||||
|
||||
// Apply coverage.
|
||||
if (args.fXP.dstReadUsesMixedSamples()) {
|
||||
if (args.fInputCoverage) {
|
||||
fragBuilder->codeAppendf("%s *= %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
|
||||
} else {
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputSecondary);
|
||||
}
|
||||
} else if (args.fInputCoverage) {
|
||||
fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage,
|
||||
args.fOutputPrimary, args.fInputCoverage, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
|
||||
|
@ -85,8 +85,10 @@ private:
|
||||
virtual void emitBlendCodeForDstRead(GrGLSLXPBuilder*,
|
||||
GrGLSLXPFragmentBuilder*,
|
||||
const char* srcColor,
|
||||
const char* srcCoverage,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const char* outColorSecondary,
|
||||
const GrXferProcessor&) {
|
||||
SkFAIL("emitBlendCodeForDstRead not implemented.");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user