1 /* 2 * Copyright 2017 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 "GrSimpleMeshDrawOpHelper.h" 9 #include "GrAppliedClip.h" 10 #include "GrProcessorSet.h" 11 #include "GrRect.h" 12 #include "GrUserStencilSettings.h" 13 14 GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType, 15 Flags flags) 16 : fProcessors(args.fProcessorSet) 17 , fPipelineFlags(args.fSRGBFlags) 18 , fAAType((int)aaType) 19 , fRequiresDstTexture(false) 20 , fUsesLocalCoords(false) 21 , fCompatibleWithAlphaAsCoveage(false) { 22 SkDEBUGCODE(fDidAnalysis = false); 23 if (GrAATypeIsHW(aaType)) { 24 fPipelineFlags |= GrPipeline::kHWAntialias_Flag; 25 } 26 if (flags & Flags::kSnapVerticesToPixelCenters) { 27 fPipelineFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag; 28 } 29 } 30 31 GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() { 32 if (fProcessors) { 33 fProcessors->~GrProcessorSet(); 34 } 35 } 36 37 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const { 38 return GrAATypeIsHW((this->aaType())) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA 39 : GrDrawOp::FixedFunctionFlags::kNone; 40 } 41 42 bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that, 43 const GrCaps& caps, const SkRect& thisBounds, 44 const SkRect& thatBounds) const { 45 if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) { 46 return false; 47 } 48 if (fProcessors) { 49 if (*fProcessors != *that.fProcessors) { 50 return false; 51 } 52 if (fRequiresDstTexture || 53 (fProcessors->xferProcessor() && fProcessors->xferProcessor()->xferBarrierType(caps))) { 54 if (GrRectsTouchOrOverlap(thisBounds, thatBounds)) { 55 return false; 56 } 57 } 58 } 59 bool result = fPipelineFlags == that.fPipelineFlags && fAAType == that.fAAType; 60 SkASSERT(!result || fCompatibleWithAlphaAsCoveage == that.fCompatibleWithAlphaAsCoveage); 61 SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords); 62 return result; 63 } 64 65 GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture( 66 const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage, 67 GrProcessorAnalysisColor* geometryColor) { 68 SkDEBUGCODE(fDidAnalysis = true); 69 GrProcessorSet::Analysis analysis; 70 if (fProcessors) { 71 GrProcessorAnalysisCoverage coverage = geometryCoverage; 72 if (GrProcessorAnalysisCoverage::kNone == coverage) { 73 coverage = clip->clipCoverageFragmentProcessor() 74 ? GrProcessorAnalysisCoverage::kSingleChannel 75 : GrProcessorAnalysisCoverage::kNone; 76 } 77 bool isMixedSamples = this->aaType() == GrAAType::kMixedSamples; 78 GrColor overrideColor; 79 analysis = fProcessors->finalize(*geometryColor, coverage, clip, isMixedSamples, caps, 80 &overrideColor); 81 if (analysis.inputColorIsOverridden()) { 82 *geometryColor = overrideColor; 83 } 84 } else { 85 analysis = GrProcessorSet::EmptySetAnalysis(); 86 } 87 fRequiresDstTexture = analysis.requiresDstTexture(); 88 fUsesLocalCoords = analysis.usesLocalCoords(); 89 fCompatibleWithAlphaAsCoveage = analysis.isCompatibleWithCoverageAsAlpha(); 90 return analysis.requiresDstTexture() ? GrDrawOp::RequiresDstTexture::kYes 91 : GrDrawOp::RequiresDstTexture::kNo; 92 } 93 94 GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture( 95 const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage, 96 GrColor* geometryColor) { 97 GrProcessorAnalysisColor color = *geometryColor; 98 auto result = this->xpRequiresDstTexture(caps, clip, geometryCoverage, &color); 99 color.isConstant(geometryColor); 100 return result; 101 } 102 103 SkString GrSimpleMeshDrawOpHelper::dumpInfo() const { 104 SkString result = this->processors().dumpProcessors(); 105 result.append("AA Type: "); 106 switch (this->aaType()) { 107 case GrAAType::kNone: 108 result.append(" none\n"); 109 break; 110 case GrAAType::kCoverage: 111 result.append(" coverage\n"); 112 break; 113 case GrAAType::kMSAA: 114 result.append(" msaa\n"); 115 break; 116 case GrAAType::kMixedSamples: 117 result.append(" mixed samples\n"); 118 break; 119 } 120 result.append(GrPipeline::DumpFlags(fPipelineFlags)); 121 return result; 122 } 123 124 GrPipeline::InitArgs GrSimpleMeshDrawOpHelper::pipelineInitArgs( 125 GrMeshDrawOp::Target* target) const { 126 GrPipeline::InitArgs args; 127 args.fFlags = this->pipelineFlags(); 128 args.fProcessors = &this->processors(); 129 args.fRenderTarget = target->renderTarget(); 130 args.fAppliedClip = target->clip(); 131 args.fDstProxy = target->dstProxy(); 132 args.fCaps = &target->caps(); 133 args.fResourceProvider = target->resourceProvider(); 134 return args; 135 } 136 137 GrSimpleMeshDrawOpHelperWithStencil::GrSimpleMeshDrawOpHelperWithStencil( 138 const MakeArgs& args, GrAAType aaType, const GrUserStencilSettings* stencilSettings, 139 Flags flags) 140 : INHERITED(args, aaType, flags) 141 , fStencilSettings(stencilSettings ? stencilSettings : &GrUserStencilSettings::kUnused) {} 142 143 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelperWithStencil::fixedFunctionFlags() const { 144 GrDrawOp::FixedFunctionFlags flags = INHERITED::fixedFunctionFlags(); 145 if (fStencilSettings != &GrUserStencilSettings::kUnused) { 146 flags |= GrDrawOp::FixedFunctionFlags::kUsesStencil; 147 } 148 return flags; 149 } 150 151 bool GrSimpleMeshDrawOpHelperWithStencil::isCompatible( 152 const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps& caps, 153 const SkRect& thisBounds, const SkRect& thatBounds) const { 154 return INHERITED::isCompatible(that, caps, thisBounds, thatBounds) && 155 fStencilSettings == that.fStencilSettings; 156 } 157 158 const GrPipeline* GrSimpleMeshDrawOpHelperWithStencil::makePipeline( 159 GrMeshDrawOp::Target* target) const { 160 auto args = INHERITED::pipelineInitArgs(target); 161 args.fUserStencil = fStencilSettings; 162 return target->allocPipeline(args); 163 } 164 165 SkString GrSimpleMeshDrawOpHelperWithStencil::dumpInfo() const { 166 SkString result = INHERITED::dumpInfo(); 167 result.appendf("Stencil settings: %s\n", (fStencilSettings ? "yes" : "no")); 168 return result; 169 } 170