Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(299)

Unified Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 764643004: Create xfer processor backend. (Closed) Base URL: https://skia.googlesource.com/skia.git@xferBlendSolo
Patch Set: Blend off ODS and only on XP Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrProgramDesc.h ('k') | src/gpu/gl/GrGLProcessor.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/effects/GrPorterDuffXferProcessor.cpp
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 2b4b1334f89828b96cc142a688f8492437f7dcfa..6255e4a9138773db51495591f9d7244c270f3727 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -9,11 +9,12 @@
#include "GrBlend.h"
#include "GrDrawState.h"
+#include "GrDrawTargetCaps.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
#include "GrTypes.h"
#include "GrXferProcessor.h"
-#include "gl/GrGLProcessor.h"
+#include "gl/GrGLXferProcessor.h"
#include "gl/builders/GrGLFragmentShaderBuilder.h"
#include "gl/builders/GrGLProgramBuilder.h"
@@ -42,19 +43,45 @@ public:
virtual ~GrGLPorterDuffXferProcessor() {}
- virtual void emitCode(GrGLFPBuilder* builder,
- const GrFragmentProcessor& fp,
- const char* outputColor,
- const char* inputColor,
- const TransformedCoordsArray& coords,
- const TextureSamplerArray& samplers) SK_OVERRIDE {
- GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
- fsBuilder->codeAppendf("%s = %s;", outputColor, inputColor);
+ virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+ const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>();
+ GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
+ if (xp.hasSecondaryOutput()) {
+ switch(xp.secondaryOutputType()) {
+ case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType:
+ fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
+ break;
+ case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
+ fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
+ args.fOutputSecondary, args.fInputColor,
+ args.fInputCoverage);
+ break;
+ case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
+ fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
+ args.fOutputSecondary, args.fInputColor,
+ args.fInputCoverage);
+ break;
+ default:
+ SkFAIL("Unexpected Secondary Output");
+ }
+ }
+
+ fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
+ args.fInputCoverage);
+ if (GrPorterDuffXferProcessor::kCombineWithDst_PrimaryOutputType == xp.primaryOutputType()){
+ fsBuilder->codeAppendf("%s += (vec4(1.0) - %s) * %s;", args.fOutputPrimary,
+ args.fInputCoverage, fsBuilder->dstColor());
+ }
}
- virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {};
+ virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
- static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b) {};
+ static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
+ GrProcessorKeyBuilder* b) {
+ const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
+ b->add32(xp.primaryOutputType());
+ b->add32(xp.secondaryOutputType());
+ };
private:
typedef GrGLXferProcessor INHERITED;
@@ -64,7 +91,11 @@ private:
GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
GrColor constant)
- : fSrcBlend(srcBlend), fDstBlend(dstBlend), fBlendConstant(constant) {
+ : fSrcBlend(srcBlend)
+ , fDstBlend(dstBlend)
+ , fBlendConstant(constant)
+ , fPrimaryOutputType(kModulate_PrimaryOutputType)
+ , fSecondaryOutputType(kNone_SecondaryOutputType) {
this->initClassID<GrPorterDuffXferProcessor>();
}
@@ -76,7 +107,7 @@ void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps,
GrGLPorterDuffXferProcessor::GenKey(*this, caps, b);
}
-GrGLFragmentProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
+GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this));
}
@@ -90,7 +121,58 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
bool isCoverageDrawing,
bool colorWriteDisabled,
bool doesStencilWrite,
- GrColor* color, uint8_t* coverage) {
+ GrColor* color, uint8_t* coverage,
+ const GrDrawTargetCaps& caps) {
+ GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI,
+ coveragePOI,
+ isCoverageDrawing,
+ colorWriteDisabled,
+ doesStencilWrite,
+ color,
+ coverage);
+
+ this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSolidWhite(),
+ colorPOI.readsDst() || coveragePOI.readsDst());
+ return optFlags;
+}
+
+void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags,
+ const GrDrawTargetCaps& caps,
+ bool hasSolidCoverage, bool readsDst) {
+ // If we do have coverage determine whether it matters. Dual source blending is expensive so
+ // we don't do it if we are doing coverage drawing. If we aren't then We always do dual source
+ // blending if we have any effective coverage stages OR the geometry processor doesn't emits
+ // solid coverage.
+ if (!(optFlags & kSetCoverageDrawing_OptFlag) && !hasSolidCoverage) {
+ if (caps.dualSourceBlendingSupport()) {
+ if (kZero_GrBlendCoeff == fDstBlend) {
+ // write the coverage value to second color
+ fSecondaryOutputType = kCoverage_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSA_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSC_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ }
+ } else if (readsDst &&
+ kOne_GrBlendCoeff == fSrcBlend &&
+ kZero_GrBlendCoeff == fDstBlend) {
+ fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
+ }
+ }
+}
+
+GrXferProcessor::OptFlags
+GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool isCoverageDrawing,
+ bool colorWriteDisabled,
+ bool doesStencilWrite,
+ GrColor* color, uint8_t* coverage) {
if (colorWriteDisabled) {
fSrcBlend = kZero_GrBlendCoeff;
fDstBlend = kOne_GrBlendCoeff;
@@ -192,6 +274,11 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
return GrXferProcessor::kNone_Opt;
}
+
+bool GrPorterDuffXferProcessor::hasSecondaryOutput() const {
+ return kNone_SecondaryOutputType != fSecondaryOutputType;
+}
+
///////////////////////////////////////////////////////////////////////////////
GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
@@ -450,4 +537,22 @@ bool GrPorterDuffXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& colorPOI
return opaque;
}
+GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
+
+GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
+ GrContext*,
+ const GrDrawTargetCaps&,
+ GrTexture*[]) {
+ GrBlendCoeff src;
+ do {
+ src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+ } while (GrBlendCoeffRefsSrc(src));
+
+ GrBlendCoeff dst;
+ do {
+ dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+ } while (GrBlendCoeffRefsDst(dst));
+
+ return GrPorterDuffXPFactory::Create(src, dst);
+}
« no previous file with comments | « src/gpu/GrProgramDesc.h ('k') | src/gpu/gl/GrGLProcessor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698