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 18GrPipelineBuilder::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 28GrPipelineBuilder& 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 51void 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 89bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps, 90 const GrProcOptInfo& colorPOI, 91 const GrProcOptInfo& coveragePOI) const { 92 return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI); 93} 94 95void 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 120GrPipelineBuilder::~GrPipelineBuilder() { 121 SkASSERT(0 == fBlockEffectRemovalCnt); 122} 123 124//////////////////////////////////////////////////////////////////////////////// 125 126bool 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 135void GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const { 136 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorFragmentStages()); 137 fColorProcInfoValid = false; 138 139} 140 141void GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const { 142 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(), 143 this->numCoverageFragmentStages()); 144 fCoverageProcInfoValid = false; 145} 146 147void GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const { 148 fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorFragmentStages()); 149 fColorProcInfoValid = false; 150} 151 152void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const { 153 fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(), 154 this->numCoverageFragmentStages()); 155 fCoverageProcInfoValid = false; 156} 157 158 159void 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 169void 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