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 "gl/GrGLCaps.h" 10 11GrXferProcessor::GrXferProcessor() 12 : fWillReadDstColor(false), fReadsCoverage(true), fDstCopyTextureOffset() { 13} 14 15GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) 16 : fWillReadDstColor(willReadDstColor) 17 , fReadsCoverage(true) 18 , fDstCopyTextureOffset() { 19 if (dstCopy && dstCopy->texture()) { 20 fDstCopy.reset(dstCopy->texture()); 21 fDstCopyTextureOffset = dstCopy->offset(); 22 this->addTextureAccess(&fDstCopy); 23 this->setWillReadFragmentPosition(); 24 } 25} 26 27GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, 28 const GrProcOptInfo& coveragePOI, 29 bool doesStencilWrite, 30 GrColor* overrideColor, 31 const GrDrawTargetCaps& caps) { 32 GrXferProcessor::OptFlags flags = this->onGetOptimizations(colorPOI, 33 coveragePOI, 34 doesStencilWrite, 35 overrideColor, 36 caps); 37 38 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) { 39 fReadsCoverage = false; 40 } 41 return flags; 42} 43 44void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 45 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0; 46 if (this->getDstCopyTexture() && 47 kTopLeft_GrSurfaceOrigin == this->getDstCopyTexture()->origin()) { 48 key |= 0x2; 49 } 50 b->add32(key); 51 this->onGetGLProcessorKey(caps, b); 52} 53 54bool GrXferProcessor::willNeedXferBarrier(const GrRenderTarget* rt, 55 const GrDrawTargetCaps& caps, 56 GrXferBarrierType* outBarrierType) const { 57 if (static_cast<const GrSurface*>(rt) == this->getDstCopyTexture()) { 58 // Texture barriers are required when a shader reads and renders to the same texture. 59 SkASSERT(rt); 60 SkASSERT(caps.textureBarrierSupport()); 61 *outBarrierType = kTexture_GrXferBarrierType; 62 return true; 63 } 64 return this->onWillNeedXferBarrier(rt, caps, outBarrierType); 65} 66 67#ifdef SK_DEBUG 68static const char* equation_string(GrBlendEquation eq) { 69 switch (eq) { 70 case kAdd_GrBlendEquation: 71 return "add"; 72 case kSubtract_GrBlendEquation: 73 return "subtract"; 74 case kReverseSubtract_GrBlendEquation: 75 return "reverse_subtract"; 76 case kScreen_GrBlendEquation: 77 return "screen"; 78 case kOverlay_GrBlendEquation: 79 return "overlay"; 80 case kDarken_GrBlendEquation: 81 return "darken"; 82 case kLighten_GrBlendEquation: 83 return "lighten"; 84 case kColorDodge_GrBlendEquation: 85 return "color_dodge"; 86 case kColorBurn_GrBlendEquation: 87 return "color_burn"; 88 case kHardLight_GrBlendEquation: 89 return "hard_light"; 90 case kSoftLight_GrBlendEquation: 91 return "soft_light"; 92 case kDifference_GrBlendEquation: 93 return "difference"; 94 case kExclusion_GrBlendEquation: 95 return "exclusion"; 96 case kMultiply_GrBlendEquation: 97 return "multiply"; 98 case kHSLHue_GrBlendEquation: 99 return "hsl_hue"; 100 case kHSLSaturation_GrBlendEquation: 101 return "hsl_saturation"; 102 case kHSLColor_GrBlendEquation: 103 return "hsl_color"; 104 case kHSLLuminosity_GrBlendEquation: 105 return "hsl_luminosity"; 106 }; 107 return ""; 108} 109 110static const char* coeff_string(GrBlendCoeff coeff) { 111 switch (coeff) { 112 case kZero_GrBlendCoeff: 113 return "zero"; 114 case kOne_GrBlendCoeff: 115 return "one"; 116 case kSC_GrBlendCoeff: 117 return "src_color"; 118 case kISC_GrBlendCoeff: 119 return "inv_src_color"; 120 case kDC_GrBlendCoeff: 121 return "dst_color"; 122 case kIDC_GrBlendCoeff: 123 return "inv_dst_color"; 124 case kSA_GrBlendCoeff: 125 return "src_alpha"; 126 case kISA_GrBlendCoeff: 127 return "inv_src_alpha"; 128 case kDA_GrBlendCoeff: 129 return "dst_alpha"; 130 case kIDA_GrBlendCoeff: 131 return "inv_dst_alpha"; 132 case kConstC_GrBlendCoeff: 133 return "const_color"; 134 case kIConstC_GrBlendCoeff: 135 return "inv_const_color"; 136 case kConstA_GrBlendCoeff: 137 return "const_alpha"; 138 case kIConstA_GrBlendCoeff: 139 return "inv_const_alpha"; 140 case kS2C_GrBlendCoeff: 141 return "src2_color"; 142 case kIS2C_GrBlendCoeff: 143 return "inv_src2_color"; 144 case kS2A_GrBlendCoeff: 145 return "src2_alpha"; 146 case kIS2A_GrBlendCoeff: 147 return "inv_src2_alpha"; 148 } 149 return ""; 150} 151 152SkString GrXferProcessor::BlendInfo::dump() const { 153 SkString out; 154 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)", 155 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend), 156 coeff_string(fDstBlend), fBlendConstant); 157 return out; 158} 159#endif 160 161/////////////////////////////////////////////////////////////////////////////// 162 163GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, 164 const GrProcOptInfo& coveragePOI, 165 const GrDeviceCoordTexture* dstCopy, 166 const GrDrawTargetCaps& caps) const { 167#ifdef SK_DEBUG 168 if (this->willReadDstColor(caps, colorPOI, coveragePOI)) { 169 if (!caps.shaderCaps()->dstReadInShaderSupport()) { 170 SkASSERT(dstCopy && dstCopy->texture()); 171 } else { 172 SkASSERT(!dstCopy || !dstCopy->texture()); 173 } 174 } else { 175 SkASSERT(!dstCopy || !dstCopy->texture()); 176 } 177#endif 178 return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstCopy); 179} 180 181bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI, 182 const GrProcOptInfo& coveragePOI) const { 183 return (this->willReadDstColor(caps, colorPOI, coveragePOI) 184 && !caps.shaderCaps()->dstReadInShaderSupport()); 185} 186 187