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