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     this->setUserStencil(args.fUserStencil);
32 
33     fXferProcessor = std::move(xferProcessor);
34 
35     if (args.fDstProxyView.proxy()) {
36         fDstProxyView = args.fDstProxyView.proxyView();
37         fDstTextureOffset = args.fDstProxyView.offset();
38     }
39 }
40 
GrPipeline(const InitArgs & args,GrProcessorSet && processors,GrAppliedClip && appliedClip)41 GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
42                        GrAppliedClip&& appliedClip)
43         : GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) {
44     SkASSERT(processors.isFinalized());
45     // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
46     fNumColorProcessors = processors.numColorFragmentProcessors();
47     int numTotalProcessors = fNumColorProcessors +
48                              processors.numCoverageFragmentProcessors() +
49                              appliedClip.numClipCoverageFragmentProcessors();
50     fFragmentProcessors.reset(numTotalProcessors);
51 
52     int currFPIdx = 0;
53     for (int i = 0; i < processors.numColorFragmentProcessors(); ++i, ++currFPIdx) {
54         fFragmentProcessors[currFPIdx] = processors.detachColorFragmentProcessor(i);
55     }
56     for (int i = 0; i < processors.numCoverageFragmentProcessors(); ++i, ++currFPIdx) {
57         fFragmentProcessors[currFPIdx] = processors.detachCoverageFragmentProcessor(i);
58     }
59     for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i, ++currFPIdx) {
60         fFragmentProcessors[currFPIdx] = appliedClip.detachClipCoverageFragmentProcessor(i);
61     }
62 }
63 
xferBarrierType(GrTexture * texture,const GrCaps & caps) const64 GrXferBarrierType GrPipeline::xferBarrierType(GrTexture* texture, const GrCaps& caps) const {
65     auto proxy = fDstProxyView.proxy();
66     if (proxy && proxy->peekTexture() == texture) {
67         return kTexture_GrXferBarrierType;
68     }
69     return this->getXferProcessor().xferBarrierType(caps);
70 }
71 
GrPipeline(GrScissorTest scissorTest,sk_sp<const GrXferProcessor> xp,const GrSwizzle & writeSwizzle,InputFlags inputFlags,const GrUserStencilSettings * userStencil)72 GrPipeline::GrPipeline(GrScissorTest scissorTest,
73                        sk_sp<const GrXferProcessor> xp,
74                        const GrSwizzle& writeSwizzle,
75                        InputFlags inputFlags,
76                        const GrUserStencilSettings* userStencil)
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     this->setUserStencil(userStencil);
85 }
86 
genKey(GrProcessorKeyBuilder * b,const GrCaps & caps) const87 void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
88     // kSnapVerticesToPixelCenters is implemented in a shader.
89     InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
90     if (!caps.multisampleDisableSupport()) {
91         // Ganesh will omit kHWAntialias regardless multisampleDisableSupport.
92         ignoredFlags |= InputFlags::kHWAntialias;
93     }
94     b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags);
95 
96     const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
97 
98     static const uint32_t kBlendWriteShift = 1;
99     static const uint32_t kBlendCoeffShift = 5;
100     static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift), "");
101     static_assert(kFirstAdvancedGrBlendEquation - 1 < 4, "");
102 
103     uint32_t blendKey = blendInfo.fWriteColor;
104     blendKey |= (blendInfo.fSrcBlend << kBlendWriteShift);
105     blendKey |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
106     blendKey |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
107 
108     b->add32(blendKey);
109 }
110 
visitProxies(const GrOp::VisitProxyFunc & func) const111 void GrPipeline::visitProxies(const GrOp::VisitProxyFunc& func) const {
112     // This iteration includes any clip coverage FPs
113     const auto& rng = GrFragmentProcessor::PipelineTextureSamplerRange(*this);
114     for (auto it = rng.begin(); it != rng.end(); ++it) {
115         auto t = *it;
116         const GrFragmentProcessor::TextureSampler& sampler = t.first;
117         bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
118         func(sampler.view().proxy(), GrMipMapped(mipped));
119     }
120     if (fDstProxyView.asTextureProxy()) {
121         func(fDstProxyView.asTextureProxy(), GrMipMapped::kNo);
122     }
123 }
124