Home | History | Annotate | Download | only in gpu
      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