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