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 "src/gpu/GrPipeline.h"
9 
10 #include "src/gpu/GrAppliedClip.h"
11 #include "src/gpu/GrCaps.h"
12 #include "src/gpu/GrGpu.h"
13 #include "src/gpu/GrRenderTargetContext.h"
14 #include "src/gpu/GrXferProcessor.h"
15 
16 #include "src/gpu/ops/GrOp.h"
17 
GrPipeline(const InitArgs & args,sk_sp<const GrXferProcessor> xferProcessor,const GrAppliedHardClip & hardClip)18 GrPipeline::GrPipeline(const InitArgs& args,
19                        sk_sp<const GrXferProcessor> xferProcessor,
20                        const GrAppliedHardClip& hardClip)
21         : fWriteSwizzle(args.fWriteSwizzle) {
22     fFlags = (Flags)args.fInputFlags;
23     if (hardClip.hasStencilClip()) {
24         fFlags |= Flags::kHasStencilClip;
25     }
26     if (hardClip.scissorState().enabled()) {
27         fFlags |= Flags::kScissorTestEnabled;
28     }
29 
30     fWindowRectsState = hardClip.windowRectsState();
31 
32     fXferProcessor = std::move(xferProcessor);
33 
34     SkASSERT((args.fDstProxyView.dstSampleType() != GrDstSampleType::kNone) ==
35              SkToBool(args.fDstProxyView.proxy()));
36     if (args.fDstProxyView.proxy()) {
37         fDstProxyView = args.fDstProxyView.proxyView();
38         fDstTextureOffset = args.fDstProxyView.offset();
39     }
40     fDstSampleType = args.fDstProxyView.dstSampleType();
41 }
42 
GrPipeline(const InitArgs & args,GrProcessorSet && processors,GrAppliedClip && appliedClip)43 GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
44                        GrAppliedClip&& appliedClip)
45         : GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) {
46     SkASSERT(processors.isFinalized());
47     // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
48     fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
49     int numTotalProcessors = fNumColorProcessors +
50                              (processors.hasCoverageFragmentProcessor() ? 1 : 0) +
51                              (appliedClip.hasCoverageFragmentProcessor() ? 1 : 0);
52     fFragmentProcessors.reset(numTotalProcessors);
53 
54     int currFPIdx = 0;
55     if (processors.hasColorFragmentProcessor()) {
56         fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor();
57     }
58     if (processors.hasCoverageFragmentProcessor()) {
59         fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
60     }
61     if (appliedClip.hasCoverageFragmentProcessor()) {
62         fFragmentProcessors[currFPIdx++] = appliedClip.detachCoverageFragmentProcessor();
63     }
64 }
65 
xferBarrierType(const GrCaps & caps) const66 GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
67     if (fDstProxyView.proxy() && GrDstSampleTypeDirectlySamplesDst(fDstSampleType)) {
68         return kTexture_GrXferBarrierType;
69     }
70     return this->getXferProcessor().xferBarrierType(caps);
71 }
72 
GrPipeline(GrScissorTest scissorTest,sk_sp<const GrXferProcessor> xp,const GrSwizzle & writeSwizzle,InputFlags inputFlags)73 GrPipeline::GrPipeline(GrScissorTest scissorTest,
74                        sk_sp<const GrXferProcessor> xp,
75                        const GrSwizzle& writeSwizzle,
76                        InputFlags inputFlags)
77         : fWindowRectsState()
78         , fFlags((Flags)inputFlags)
79         , fXferProcessor(std::move(xp))
80         , fWriteSwizzle(writeSwizzle) {
81     if (GrScissorTest::kEnabled == scissorTest) {
82         fFlags |= Flags::kScissorTestEnabled;
83     }
84 }
85 
genKey(GrProcessorKeyBuilder * b,const GrCaps & caps) const86 void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
87     // kSnapVerticesToPixelCenters is implemented in a shader.
88     InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
89     if (!caps.multisampleDisableSupport()) {
90         // Ganesh will omit kHWAntialias regardless of multisampleDisableSupport.
91         ignoredFlags |= InputFlags::kHWAntialias;
92     }
93     b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags);
94 
95     const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
96 
97     static constexpr uint32_t kBlendWriteShift = 1;
98     static constexpr uint32_t kBlendCoeffShift = 5;
99     static constexpr uint32_t kBlendEquationShift = 5;
100     static constexpr uint32_t kDstSampleTypeInputShift = 1;
101     static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
102     static_assert(kLast_GrBlendEquation < (1 << kBlendEquationShift));
103     static_assert(kBlendWriteShift +
104                   2 * kBlendCoeffShift +
105                   kBlendEquationShift +
106                   kDstSampleTypeInputShift <= 32);
107 
108     uint32_t blendKey = blendInfo.fWriteColor;
109     blendKey |= (blendInfo.fSrcBlend << kBlendWriteShift);
110     blendKey |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
111     blendKey |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
112     // Note that we use the general fDstSampleType here and not localDstSampleType()
113     blendKey |= ((fDstSampleType == GrDstSampleType::kAsInputAttachment)
114                  << (kBlendWriteShift + 2 * kBlendCoeffShift + kBlendEquationShift));
115 
116     b->add32(blendKey);
117 }
118 
visitTextureEffects(const std::function<void (const GrTextureEffect &)> & func) const119 void GrPipeline::visitTextureEffects(
120         const std::function<void(const GrTextureEffect&)>& func) const {
121     for (auto& fp : fFragmentProcessors) {
122         fp->visitTextureEffects(func);
123     }
124 }
125 
visitProxies(const GrOp::VisitProxyFunc & func) const126 void GrPipeline::visitProxies(const GrOp::VisitProxyFunc& func) const {
127     // This iteration includes any clip coverage FPs
128     for (auto& fp : fFragmentProcessors) {
129         fp->visitProxies(func);
130     }
131     if (this->usesDstTexture()) {
132         func(fDstProxyView.proxy(), GrMipmapped::kNo);
133     }
134 }
135