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 "GrPipeline.h" 9 10 #include "GrAppliedClip.h" 11 #include "GrCaps.h" 12 #include "GrGpu.h" 13 #include "GrPipelineBuilder.h" 14 #include "GrRenderTargetContext.h" 15 #include "GrRenderTargetOpList.h" 16 #include "GrRenderTargetPriv.h" 17 #include "GrXferProcessor.h" 18 19 #include "ops/GrOp.h" 20 21 GrPipelineOptimizations GrPipeline::init(const InitArgs& args) { 22 SkASSERT(args.fAnalysis); 23 SkASSERT(args.fRenderTarget); 24 25 fRenderTarget.reset(args.fRenderTarget); 26 27 fFlags = args.fFlags; 28 if (args.fAppliedClip) { 29 fScissorState = args.fAppliedClip->scissorState(); 30 if (args.fAppliedClip->hasStencilClip()) { 31 fFlags |= kHasStencilClip_Flag; 32 } 33 fWindowRectsState = args.fAppliedClip->windowRectsState(); 34 } 35 if (args.fProcessors->usesDistanceVectorField()) { 36 fFlags |= kUsesDistanceVectorField_Flag; 37 } 38 if (args.fProcessors->disableOutputConversionToSRGB()) { 39 fFlags |= kDisableOutputConversionToSRGB_Flag; 40 } 41 if (args.fProcessors->allowSRGBInputs()) { 42 fFlags |= kAllowSRGBInputs_Flag; 43 } 44 if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) { 45 fFlags |= kStencilEnabled_Flag; 46 } 47 48 fUserStencilSettings = args.fUserStencil; 49 50 fDrawFace = static_cast<int16_t>(args.fDrawFace); 51 52 bool isHWAA = kHWAntialias_Flag & args.fFlags; 53 54 // Create XferProcessor from DS's XPFactory 55 bool hasMixedSamples = args.fRenderTarget->isMixedSampled() && (isHWAA || isStencilEnabled()); 56 const GrXPFactory* xpFactory = args.fProcessors->xpFactory(); 57 sk_sp<GrXferProcessor> xferProcessor; 58 if (xpFactory) { 59 xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, hasMixedSamples, 60 &args.fDstTexture, *args.fCaps)); 61 SkASSERT(xferProcessor); 62 } else { 63 // This may return nullptr in the common case of src-over implemented using hw blending. 64 xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor( 65 *args.fCaps, *args.fAnalysis, hasMixedSamples, &args.fDstTexture)); 66 } 67 GrColor overrideColor = GrColor_ILLEGAL; 68 int colorFPsToEliminate = 69 args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(&overrideColor); 70 colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0); 71 72 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; 73 74 const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() : 75 &GrPorterDuffXPFactory::SimpleSrcOverXP(); 76 optFlags = xpForOpts->getOptimizations(*args.fAnalysis); 77 78 // No need to have an override color if it isn't even going to be used. 79 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) { 80 overrideColor = GrColor_ILLEGAL; 81 } 82 83 fXferProcessor.reset(xferProcessor.get()); 84 85 if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) { 86 colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors(); 87 } 88 89 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline, possibly removing some of the 90 // color fragment processors. 91 fNumColorProcessors = args.fProcessors->numColorFragmentProcessors() - colorFPsToEliminate; 92 int numTotalProcessors = 93 fNumColorProcessors + args.fProcessors->numCoverageFragmentProcessors(); 94 if (args.fAppliedClip && args.fAppliedClip->clipCoverageFragmentProcessor()) { 95 ++numTotalProcessors; 96 } 97 fFragmentProcessors.reset(numTotalProcessors); 98 int currFPIdx = 0; 99 for (int i = colorFPsToEliminate; i < args.fProcessors->numColorFragmentProcessors(); 100 ++i, ++currFPIdx) { 101 const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i); 102 fFragmentProcessors[currFPIdx].reset(fp); 103 } 104 105 for (int i = 0; i < args.fProcessors->numCoverageFragmentProcessors(); ++i, ++currFPIdx) { 106 const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i); 107 fFragmentProcessors[currFPIdx].reset(fp); 108 } 109 if (args.fAppliedClip) { 110 if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) { 111 fFragmentProcessors[currFPIdx].reset(fp); 112 } 113 } 114 115 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline. 116 GrPipelineOptimizations optimizations; 117 optimizations.fFlags = 0; 118 if (GrColor_ILLEGAL != overrideColor) { 119 optimizations.fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag; 120 optimizations.fOverrideColor = overrideColor; 121 } 122 if (args.fAnalysis->usesLocalCoords()) { 123 optimizations.fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag; 124 } 125 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) { 126 optimizations.fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag; 127 } 128 return optimizations; 129 } 130 131 static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) { 132 GrFragmentProcessor::TextureAccessIter iter(proc); 133 while (const GrProcessor::TextureSampler* sampler = iter.next()) { 134 SkASSERT(rt->getLastOpList()); 135 rt->getLastOpList()->addDependency(sampler->texture()); 136 } 137 } 138 139 void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const { 140 for (int i = 0; i < fFragmentProcessors.count(); ++i) { 141 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt); 142 } 143 144 const GrXferProcessor& xfer = this->getXferProcessor(); 145 146 for (int i = 0; i < xfer.numTextureSamplers(); ++i) { 147 GrTexture* texture = xfer.textureSampler(i).texture(); 148 SkASSERT(rt->getLastOpList()); 149 rt->getLastOpList()->addDependency(texture); 150 } 151 } 152 153 GrPipeline::GrPipeline(GrRenderTarget* rt, SkBlendMode blendmode) 154 : fRenderTarget(rt) 155 , fScissorState() 156 , fWindowRectsState() 157 , fUserStencilSettings(&GrUserStencilSettings::kUnused) 158 , fDrawFace(static_cast<uint16_t>(GrDrawFace::kBoth)) 159 , fFlags() 160 , fXferProcessor(GrPorterDuffXPFactory::CreateNoCoverageXP(blendmode).get()) 161 , fFragmentProcessors() 162 , fNumColorProcessors(0) { 163 } 164 165 //////////////////////////////////////////////////////////////////////////////// 166 167 bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) { 168 SkASSERT(&a != &b); 169 170 if (a.getRenderTarget() != b.getRenderTarget() || 171 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() || 172 a.fNumColorProcessors != b.fNumColorProcessors || 173 a.fScissorState != b.fScissorState || 174 a.fWindowRectsState != b.fWindowRectsState || 175 a.fFlags != b.fFlags || 176 a.fUserStencilSettings != b.fUserStencilSettings || 177 a.fDrawFace != b.fDrawFace) { 178 return false; 179 } 180 181 // Most of the time both are nullptr 182 if (a.fXferProcessor.get() || b.fXferProcessor.get()) { 183 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) { 184 return false; 185 } 186 } 187 188 for (int i = 0; i < a.numFragmentProcessors(); i++) { 189 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i))) { 190 return false; 191 } 192 } 193 return true; 194 } 195