Home | History | Annotate | Download | only in ops
      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