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 | |
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 | |
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 | |
64 | 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 | |
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 | |
87 | 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 | |
111 | void GrPipeline::visitProxies(const GrOp::VisitProxyFunc& func) const { |
112 | // This iteration includes any clip coverage FPs |
113 | for (auto [sampler, fp] : GrFragmentProcessor::PipelineTextureSamplerRange(*this)) { |
114 | bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter()); |
115 | func(sampler.view().proxy(), GrMipMapped(mipped)); |
116 | } |
117 | if (fDstProxyView.asTextureProxy()) { |
118 | func(fDstProxyView.asTextureProxy(), GrMipMapped::kNo); |
119 | } |
120 | } |
121 | |