1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrXferProcessor.h" 9 10 #include "GrCaps.h" 11 #include "GrPipeline.h" 12 13 GrXferProcessor::GrXferProcessor(ClassID classID) 14 : INHERITED(classID) 15 , fWillReadDstColor(false) 16 , fDstReadUsesMixedSamples(false) 17 , fIsLCD(false) {} 18 19 GrXferProcessor::GrXferProcessor(ClassID classID, bool willReadDstColor, bool hasMixedSamples, 20 GrProcessorAnalysisCoverage coverage) 21 : INHERITED(classID) 22 , fWillReadDstColor(willReadDstColor) 23 , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples) 24 , fIsLCD(GrProcessorAnalysisCoverage::kLCD == coverage) {} 25 26 bool GrXferProcessor::hasSecondaryOutput() const { 27 if (!this->willReadDstColor()) { 28 return this->onHasSecondaryOutput(); 29 } 30 return this->dstReadUsesMixedSamples(); 31 } 32 33 void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const { 34 blendInfo->reset(); 35 if (!this->willReadDstColor()) { 36 this->onGetBlendInfo(blendInfo); 37 } else if (this->dstReadUsesMixedSamples()) { 38 blendInfo->fDstBlend = kIS2A_GrBlendCoeff; 39 } 40 } 41 42 void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b, 43 const GrSurfaceOrigin* originIfDstTexture) const { 44 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0; 45 if (key) { 46 if (originIfDstTexture) { 47 key |= 0x2; 48 if (kTopLeft_GrSurfaceOrigin == *originIfDstTexture) { 49 key |= 0x4; 50 } 51 } 52 if (this->dstReadUsesMixedSamples()) { 53 key |= 0x8; 54 } 55 } 56 if (fIsLCD) { 57 key |= 0x10; 58 } 59 b->add32(key); 60 this->onGetGLSLProcessorKey(caps, b); 61 } 62 63 #ifdef SK_DEBUG 64 static const char* equation_string(GrBlendEquation eq) { 65 switch (eq) { 66 case kAdd_GrBlendEquation: 67 return "add"; 68 case kSubtract_GrBlendEquation: 69 return "subtract"; 70 case kReverseSubtract_GrBlendEquation: 71 return "reverse_subtract"; 72 case kScreen_GrBlendEquation: 73 return "screen"; 74 case kOverlay_GrBlendEquation: 75 return "overlay"; 76 case kDarken_GrBlendEquation: 77 return "darken"; 78 case kLighten_GrBlendEquation: 79 return "lighten"; 80 case kColorDodge_GrBlendEquation: 81 return "color_dodge"; 82 case kColorBurn_GrBlendEquation: 83 return "color_burn"; 84 case kHardLight_GrBlendEquation: 85 return "hard_light"; 86 case kSoftLight_GrBlendEquation: 87 return "soft_light"; 88 case kDifference_GrBlendEquation: 89 return "difference"; 90 case kExclusion_GrBlendEquation: 91 return "exclusion"; 92 case kMultiply_GrBlendEquation: 93 return "multiply"; 94 case kHSLHue_GrBlendEquation: 95 return "hsl_hue"; 96 case kHSLSaturation_GrBlendEquation: 97 return "hsl_saturation"; 98 case kHSLColor_GrBlendEquation: 99 return "hsl_color"; 100 case kHSLLuminosity_GrBlendEquation: 101 return "hsl_luminosity"; 102 case kIllegal_GrBlendEquation: 103 SkASSERT(false); 104 return "<illegal>"; 105 } 106 return ""; 107 } 108 109 static const char* coeff_string(GrBlendCoeff coeff) { 110 switch (coeff) { 111 case kZero_GrBlendCoeff: 112 return "zero"; 113 case kOne_GrBlendCoeff: 114 return "one"; 115 case kSC_GrBlendCoeff: 116 return "src_color"; 117 case kISC_GrBlendCoeff: 118 return "inv_src_color"; 119 case kDC_GrBlendCoeff: 120 return "dst_color"; 121 case kIDC_GrBlendCoeff: 122 return "inv_dst_color"; 123 case kSA_GrBlendCoeff: 124 return "src_alpha"; 125 case kISA_GrBlendCoeff: 126 return "inv_src_alpha"; 127 case kDA_GrBlendCoeff: 128 return "dst_alpha"; 129 case kIDA_GrBlendCoeff: 130 return "inv_dst_alpha"; 131 case kConstC_GrBlendCoeff: 132 return "const_color"; 133 case kIConstC_GrBlendCoeff: 134 return "inv_const_color"; 135 case kConstA_GrBlendCoeff: 136 return "const_alpha"; 137 case kIConstA_GrBlendCoeff: 138 return "inv_const_alpha"; 139 case kS2C_GrBlendCoeff: 140 return "src2_color"; 141 case kIS2C_GrBlendCoeff: 142 return "inv_src2_color"; 143 case kS2A_GrBlendCoeff: 144 return "src2_alpha"; 145 case kIS2A_GrBlendCoeff: 146 return "inv_src2_alpha"; 147 case kIllegal_GrBlendCoeff: 148 SkASSERT(false); 149 return "<illegal>"; 150 } 151 return ""; 152 } 153 154 SkString GrXferProcessor::BlendInfo::dump() const { 155 SkString out; 156 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)", 157 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend), 158 coeff_string(fDstBlend), fBlendConstant.toBytes_RGBA()); 159 return out; 160 } 161 #endif 162 163 /////////////////////////////////////////////////////////////////////////////// 164 165 GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties( 166 const GrXPFactory* factory, 167 const GrProcessorAnalysisColor& color, 168 const GrProcessorAnalysisCoverage& coverage, 169 const GrCaps& caps) { 170 AnalysisProperties result; 171 if (factory) { 172 result = factory->analysisProperties(color, coverage, caps); 173 } else { 174 result = GrPorterDuffXPFactory::SrcOverAnalysisProperties(color, coverage, caps); 175 } 176 SkASSERT(!(result & AnalysisProperties::kRequiresDstTexture)); 177 if ((result & AnalysisProperties::kReadsDstInShader) && 178 !caps.shaderCaps()->dstReadInShaderSupport()) { 179 result |= AnalysisProperties::kRequiresDstTexture | 180 AnalysisProperties::kRequiresNonOverlappingDraws; 181 } 182 return result; 183 } 184 185 sk_sp<const GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* factory, 186 const GrProcessorAnalysisColor& color, 187 GrProcessorAnalysisCoverage coverage, 188 bool hasMixedSamples, 189 const GrCaps& caps) { 190 SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport()); 191 if (factory) { 192 return factory->makeXferProcessor(color, coverage, hasMixedSamples, caps); 193 } else { 194 return GrPorterDuffXPFactory::MakeSrcOverXferProcessor(color, coverage, hasMixedSamples, 195 caps); 196 } 197 } 198