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()
     13         : fWillReadDstColor(false)
     14         , fDstReadUsesMixedSamples(false)
     15         , fIsLCD(false) {}
     16 
     17 GrXferProcessor::GrXferProcessor(bool willReadDstColor, bool hasMixedSamples,
     18                                  GrProcessorAnalysisCoverage coverage)
     19         : fWillReadDstColor(willReadDstColor)
     20         , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
     21         , fIsLCD(GrProcessorAnalysisCoverage::kLCD == coverage) {}
     22 
     23 bool GrXferProcessor::hasSecondaryOutput() const {
     24     if (!this->willReadDstColor()) {
     25         return this->onHasSecondaryOutput();
     26     }
     27     return this->dstReadUsesMixedSamples();
     28 }
     29 
     30 void 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 
     39 void 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
     61 static 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 
    103 static 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 
    145 SkString 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 
    156 GrXPFactory::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 
    178 sk_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