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