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