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 "GrPipelineBuilder.h"
      9 
     10 #include "GrBatch.h"
     11 #include "GrBlend.h"
     12 #include "GrPaint.h"
     13 #include "GrPipeline.h"
     14 #include "GrProcOptInfo.h"
     15 #include "GrXferProcessor.h"
     16 #include "effects/GrPorterDuffXferProcessor.h"
     17 
     18 GrPipelineBuilder::GrPipelineBuilder()
     19     : fFlags(0x0)
     20     , fDrawFace(kBoth_DrawFace)
     21     , fColorProcInfoValid(false)
     22     , fCoverageProcInfoValid(false)
     23     , fColorCache(GrColor_ILLEGAL)
     24     , fCoverageCache(GrColor_ILLEGAL) {
     25     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
     26 }
     27 
     28 GrPipelineBuilder& GrPipelineBuilder::operator=(const GrPipelineBuilder& that) {
     29     fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
     30     fFlags = that.fFlags;
     31     fStencilSettings = that.fStencilSettings;
     32     fDrawFace = that.fDrawFace;
     33     fXPFactory.reset(SkRef(that.getXPFactory()));
     34     fColorStages = that.fColorStages;
     35     fCoverageStages = that.fCoverageStages;
     36     fClip = that.fClip;
     37 
     38     fColorProcInfoValid = that.fColorProcInfoValid;
     39     fCoverageProcInfoValid = that.fCoverageProcInfoValid;
     40     fColorCache = that.fColorCache;
     41     fCoverageCache = that.fCoverageCache;
     42     if (fColorProcInfoValid) {
     43         fColorProcInfo = that.fColorProcInfo;
     44     }
     45     if (fCoverageProcInfoValid) {
     46         fCoverageProcInfo = that.fCoverageProcInfo;
     47     }
     48     return *this;
     49 }
     50 
     51 void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip) {
     52     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
     53 
     54     fColorStages.reset();
     55     fCoverageStages.reset();
     56 
     57     for (int i = 0; i < paint.numColorStages(); ++i) {
     58         fColorStages.push_back(paint.getColorStage(i));
     59     }
     60 
     61     for (int i = 0; i < paint.numCoverageStages(); ++i) {
     62         fCoverageStages.push_back(paint.getCoverageStage(i));
     63     }
     64 
     65     fXPFactory.reset(SkRef(paint.getXPFactory()));
     66 
     67     this->setRenderTarget(rt);
     68 
     69     // These have no equivalent in GrPaint, set them to defaults
     70     fDrawFace = kBoth_DrawFace;
     71     fStencilSettings.setDisabled();
     72     fFlags = 0;
     73 
     74     fClip = clip;
     75 
     76     this->setState(GrPipelineBuilder::kDither_Flag, paint.isDither());
     77     this->setState(GrPipelineBuilder::kHWAntialias_Flag,
     78                    rt->isMultisampled() && paint.isAntiAlias());
     79 
     80     fColorProcInfoValid = false;
     81     fCoverageProcInfoValid = false;
     82 
     83     fColorCache = GrColor_ILLEGAL;
     84     fCoverageCache = GrColor_ILLEGAL;
     85 }
     86 
     87 //////////////////////////////////////////////////////////////////////////////s
     88 
     89 bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps,
     90                                           const GrProcOptInfo& colorPOI,
     91                                           const GrProcOptInfo& coveragePOI) const {
     92     return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI);
     93 }
     94 
     95 void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {
     96     if (fPipelineBuilder) {
     97         int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt;
     98         SkASSERT(m >= 0);
     99         fPipelineBuilder->fColorStages.pop_back_n(m);
    100 
    101         int n = fPipelineBuilder->numCoverageFragmentStages() - fCoverageEffectCnt;
    102         SkASSERT(n >= 0);
    103         fPipelineBuilder->fCoverageStages.pop_back_n(n);
    104         if (m + n > 0) {
    105             fPipelineBuilder->fColorProcInfoValid = false;
    106             fPipelineBuilder->fCoverageProcInfoValid = false;
    107         }
    108         SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
    109     }
    110     fPipelineBuilder = pipelineBuilder;
    111     if (NULL != pipelineBuilder) {
    112         fColorEffectCnt = pipelineBuilder->numColorFragmentStages();
    113         fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentStages();
    114         SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
    115     }
    116 }
    117 
    118 ////////////////////////////////////////////////////////////////////////////////
    119 
    120 GrPipelineBuilder::~GrPipelineBuilder() {
    121     SkASSERT(0 == fBlockEffectRemovalCnt);
    122 }
    123 
    124 ////////////////////////////////////////////////////////////////////////////////
    125 
    126 bool GrPipelineBuilder::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
    127     this->calcColorInvariantOutput(pp);
    128     this->calcCoverageInvariantOutput(pp);
    129 
    130     GrXPFactory::InvariantOutput output;
    131     fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
    132     return output.fWillBlendWithDst;
    133 }
    134 
    135 void GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
    136     fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorFragmentStages());
    137     fColorProcInfoValid = false;
    138 
    139 }
    140 
    141 void GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
    142     fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
    143                                                this->numCoverageFragmentStages());
    144     fCoverageProcInfoValid = false;
    145 }
    146 
    147 void GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const {
    148     fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorFragmentStages());
    149     fColorProcInfoValid = false;
    150 }
    151 
    152 void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const {
    153     fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(),
    154                                             this->numCoverageFragmentStages());
    155     fCoverageProcInfoValid = false;
    156 }
    157 
    158 
    159 void GrPipelineBuilder::calcColorInvariantOutput(GrColor color) const {
    160     if (!fColorProcInfoValid || color != fColorCache) {
    161         GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
    162         fColorProcInfo.calcWithInitialValues(fColorStages.begin(),this->numColorFragmentStages(),
    163                                              color, flags, false);
    164         fColorProcInfoValid = true;
    165         fColorCache = color;
    166     }
    167 }
    168 
    169 void GrPipelineBuilder::calcCoverageInvariantOutput(GrColor coverage) const {
    170     if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
    171         GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
    172         fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
    173                                                 this->numCoverageFragmentStages(), coverage, flags,
    174                                                 true);
    175         fCoverageProcInfoValid = true;
    176         fCoverageCache = coverage;
    177     }
    178 }
    179