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

Side by Side Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 1164973002: Add mixed samples support to XPs (Closed) Base URL: https://skia.googlesource.com/skia.git@upload2_reenablebea
Patch Set: Created 5 years, 6 months 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 unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDisableColorXP.cpp ('k') | src/gpu/gl/GrGLXferProcessor.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "effects/GrPorterDuffXferProcessor.h" 8 #include "effects/GrPorterDuffXferProcessor.h"
9 9
10 #include "GrBlend.h" 10 #include "GrBlend.h"
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), 281 /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
282 /* dst-out */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_Out putType), 282 /* dst-out */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_Out putType),
283 /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff), 283 /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff),
284 /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff), 284 /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
285 /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), 285 /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
286 /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff), 286 /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
287 /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_ OutputType), 287 /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_ OutputType),
288 /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), 288 /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
289 }}}; 289 }}};
290 290
291 static BlendFormula get_blend_formula(SkXfermode::Mode xfermode, 291 static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI,
292 const GrProcOptInfo& colorPOI, 292 const GrProcOptInfo& coveragePOI,
293 const GrProcOptInfo& coveragePOI) { 293 bool hasMixedSamples,
294 SkXfermode::Mode xfermode) {
294 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); 295 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode);
295 SkASSERT(!coveragePOI.isFourChannelOutput()); 296 SkASSERT(!coveragePOI.isFourChannelOutput());
296 297
297 return gBlendTable[colorPOI.isOpaque()][!coveragePOI.isSolidWhite()][xfermod e]; 298 bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples;
299 return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode];
298 } 300 }
299 301
300 /////////////////////////////////////////////////////////////////////////////// 302 ///////////////////////////////////////////////////////////////////////////////
301 303
302 class PorterDuffXferProcessor : public GrXferProcessor { 304 class PorterDuffXferProcessor : public GrXferProcessor {
303 public: 305 public:
304 static GrXferProcessor* Create(BlendFormula blendFormula) { 306 PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendForm ula) {
305 return SkNEW_ARGS(PorterDuffXferProcessor, (blendFormula)); 307 this->initClassID<PorterDuffXferProcessor>();
306 } 308 }
307 309
308 const char* name() const override { return "Porter Duff"; } 310 const char* name() const override { return "Porter Duff"; }
309 311
310 GrGLXferProcessor* createGLInstance() const override; 312 GrGLXferProcessor* createGLInstance() const override;
311 313
312 BlendFormula getBlendFormula() const { return fBlendFormula; } 314 BlendFormula getBlendFormula() const { return fBlendFormula; }
313 315
314 private: 316 private:
315 PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendForm ula) {
316 this->initClassID<PorterDuffXferProcessor>();
317 }
318
319 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, 317 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
320 const GrProcOptInfo& coveragePO I, 318 const GrProcOptInfo& coveragePO I,
321 bool doesStencilWrite, 319 bool doesStencilWrite,
322 GrColor* overrideColor, 320 GrColor* overrideColor,
323 const GrCaps& caps) override; 321 const GrCaps& caps) override;
324 322
325 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 323 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
326 324
327 bool onHasSecondaryOutput() const override { return fBlendFormula.hasSeconda ryOutput(); } 325 bool onHasSecondaryOutput() const override { return fBlendFormula.hasSeconda ryOutput(); }
328 326
(...skipping 17 matching lines...) Expand all
346 /////////////////////////////////////////////////////////////////////////////// 344 ///////////////////////////////////////////////////////////////////////////////
347 345
348 static void append_color_output(const PorterDuffXferProcessor& xp, GrGLXPFragmen tBuilder* fsBuilder, 346 static void append_color_output(const PorterDuffXferProcessor& xp, GrGLXPFragmen tBuilder* fsBuilder,
349 BlendFormula::OutputType outputType, const char* output, 347 BlendFormula::OutputType outputType, const char* output,
350 const char* inColor, const char* inCoverage) { 348 const char* inColor, const char* inCoverage) {
351 switch (outputType) { 349 switch (outputType) {
352 case BlendFormula::kNone_OutputType: 350 case BlendFormula::kNone_OutputType:
353 fsBuilder->codeAppendf("%s = vec4(0.0);", output); 351 fsBuilder->codeAppendf("%s = vec4(0.0);", output);
354 break; 352 break;
355 case BlendFormula::kCoverage_OutputType: 353 case BlendFormula::kCoverage_OutputType:
354 // We can have a coverage formula while not reading coverage if ther e are mixed samples.
356 fsBuilder->codeAppendf("%s = %s;", 355 fsBuilder->codeAppendf("%s = %s;",
357 output, xp.readsCoverage() ? inCoverage : "ve c4(1.0)"); 356 output, xp.readsCoverage() ? inCoverage : "ve c4(1.0)");
358 break; 357 break;
359 case BlendFormula::kModulate_OutputType: 358 case BlendFormula::kModulate_OutputType:
360 if (xp.readsCoverage()) { 359 if (xp.readsCoverage()) {
361 fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCover age); 360 fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCover age);
362 } else { 361 } else {
363 fsBuilder->codeAppendf("%s = %s;", output, inColor); 362 fsBuilder->codeAppendf("%s = %s;", output, inColor);
364 } 363 }
365 break; 364 break;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; 447 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
449 } 448 }
450 } 449 }
451 return optFlags; 450 return optFlags;
452 } 451 }
453 452
454 /////////////////////////////////////////////////////////////////////////////// 453 ///////////////////////////////////////////////////////////////////////////////
455 454
456 class ShaderPDXferProcessor : public GrXferProcessor { 455 class ShaderPDXferProcessor : public GrXferProcessor {
457 public: 456 public:
458 static GrXferProcessor* Create(SkXfermode::Mode xfermode, const DstTexture* dstTexture) { 457 ShaderPDXferProcessor(const DstTexture* dstTexture,
459 return SkNEW_ARGS(ShaderPDXferProcessor, (xfermode, dstTexture)); 458 bool hasMixedSamples,
459 SkXfermode::Mode xfermode)
460 : INHERITED(dstTexture, true, hasMixedSamples)
461 , fXfermode(xfermode) {
462 this->initClassID<ShaderPDXferProcessor>();
460 } 463 }
461 464
462 const char* name() const override { return "Porter Duff Shader"; } 465 const char* name() const override { return "Porter Duff Shader"; }
463 466
464 GrGLXferProcessor* createGLInstance() const override; 467 GrGLXferProcessor* createGLInstance() const override;
465 468
466 SkXfermode::Mode getXfermode() const { return fXfermode; } 469 SkXfermode::Mode getXfermode() const { return fXfermode; }
467 470
468 private: 471 private:
469 ShaderPDXferProcessor(SkXfermode::Mode xfermode, const DstTexture* dstTextur e)
470 : INHERITED(dstTexture, true)
471 , fXfermode(xfermode) {
472 this->initClassID<ShaderPDXferProcessor>();
473 }
474
475 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo&, const GrP rocOptInfo&, 472 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo&, const GrP rocOptInfo&,
476 bool, GrColor*, const GrCaps&) override { 473 bool, GrColor*, const GrCaps&) override {
477 return kNone_Opt; 474 return kNone_Opt;
478 } 475 }
479 476
480 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 477 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
481 478
482 bool onIsEqual(const GrXferProcessor& xpBase) const override { 479 bool onIsEqual(const GrXferProcessor& xpBase) const override {
483 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); 480 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>();
484 return fXfermode == xp.fXfermode; 481 return fXfermode == xp.fXfermode;
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) { 728 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) {
732 return NULL; 729 return NULL;
733 } 730 }
734 return SkRef(gFactories[xfermode]); 731 return SkRef(gFactories[xfermode]);
735 } 732 }
736 733
737 GrXferProcessor* 734 GrXferProcessor*
738 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, 735 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
739 const GrProcOptInfo& colorPOI, 736 const GrProcOptInfo& colorPOI,
740 const GrProcOptInfo& covPOI, 737 const GrProcOptInfo& covPOI,
738 bool hasMixedSamples,
741 const DstTexture* dstTexture) const { 739 const DstTexture* dstTexture) const {
742 if (covPOI.isFourChannelOutput()) { 740 if (covPOI.isFourChannelOutput()) {
743 SkASSERT(!dstTexture || !dstTexture->texture()); 741 SkASSERT(!dstTexture || !dstTexture->texture());
744 return PDLCDXferProcessor::Create(fXfermode, colorPOI); 742 return PDLCDXferProcessor::Create(fXfermode, colorPOI);
745 } 743 }
746 744
747 BlendFormula blendFormula = get_blend_formula(fXfermode, colorPOI, covPOI); 745 BlendFormula blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamp les, fXfermode);
748 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend ingSupport()) { 746 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend ingSupport()) {
749 return ShaderPDXferProcessor::Create(fXfermode, dstTexture); 747 return SkNEW_ARGS(ShaderPDXferProcessor, (dstTexture, hasMixedSamples, f Xfermode));
750 } 748 }
751 749
752 SkASSERT(!dstTexture || !dstTexture->texture()); 750 SkASSERT(!dstTexture || !dstTexture->texture());
753 return PorterDuffXferProcessor::Create(blendFormula); 751 return SkNEW_ARGS(PorterDuffXferProcessor, (blendFormula));
754 } 752 }
755 753
756 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, 754 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
757 uint32_t knownColorFlags) const { 755 uint32_t knownColorFlags) const {
758 if (SkXfermode::kSrcOver_Mode == fXfermode && 756 if (SkXfermode::kSrcOver_Mode == fXfermode &&
759 kRGBA_GrColorComponentFlags == knownColorFlags) { 757 kRGBA_GrColorComponentFlags == knownColorFlags) {
760 return true; 758 return true;
761 } 759 }
762 return false; 760 return false;
763 } 761 }
(...skipping 24 matching lines...) Expand all
788 return; 786 return;
789 787
790 default: 788 default:
791 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; 789 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
792 return; 790 return;
793 } 791 }
794 } 792 }
795 793
796 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, 794 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps,
797 const GrProcOptInfo& colorPOI, 795 const GrProcOptInfo& colorPOI,
798 const GrProcOptInfo& coveragePOI) c onst { 796 const GrProcOptInfo& covPOI,
799 if (coveragePOI.isFourChannelOutput()) { 797 bool hasMixedSamples) const {
800 return false; // The LCD XP never does a dst read. 798 if (caps.shaderCaps()->dualSourceBlendingSupport()) {
799 return false;
801 } 800 }
802 801 if (covPOI.isFourChannelOutput()) {
802 return false; // The LCD XP will abort rather than doing a dst read.
803 }
803 // We fallback on the shader XP when the blend formula would use dual source blending but we 804 // We fallback on the shader XP when the blend formula would use dual source blending but we
804 // don't have support for it. 805 // don't have support for it.
805 return !caps.shaderCaps()->dualSourceBlendingSupport() && 806 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe condaryOutput();
806 get_blend_formula(fXfermode, colorPOI, coveragePOI).hasSecondaryOutpu t();
807 } 807 }
808 808
809 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 809 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
810 810
811 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, 811 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
812 GrContext*, 812 GrContext*,
813 const GrCaps&, 813 const GrCaps&,
814 GrTexture*[]) { 814 GrTexture*[]) {
815 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode)); 815 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode));
816 return GrPorterDuffXPFactory::Create(mode); 816 return GrPorterDuffXPFactory::Create(mode);
817 } 817 }
818 818
819 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, 819 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp,
820 int* outPrimary, 820 int* outPrimary,
821 int* outSecondary) { 821 int* outSecondary) {
822 if (!!strcmp(xp->name(), "Porter Duff")) { 822 if (!!strcmp(xp->name(), "Porter Duff")) {
823 *outPrimary = *outSecondary = -1; 823 *outPrimary = *outSecondary = -1;
824 return; 824 return;
825 } 825 }
826 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)- >getBlendFormula(); 826 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)- >getBlendFormula();
827 *outPrimary = blendFormula.fPrimaryOutputType; 827 *outPrimary = blendFormula.fPrimaryOutputType;
828 *outSecondary = blendFormula.fSecondaryOutputType; 828 *outSecondary = blendFormula.fSecondaryOutputType;
829 } 829 }
830 830
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDisableColorXP.cpp ('k') | src/gpu/gl/GrGLXferProcessor.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698