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.hasColorFragmentProcessor() ? 1 : 0; |
47 | int numTotalProcessors = fNumColorProcessors + |
48 | (processors.hasCoverageFragmentProcessor() ? 1 : 0) + |
49 | (appliedClip.hasCoverageFragmentProcessor() ? 1 : 0); |
50 | fFragmentProcessors.reset(numTotalProcessors); |
51 | |
52 | int currFPIdx = 0; |
53 | if (processors.hasColorFragmentProcessor()) { |
54 | fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor(); |
55 | } |
56 | if (processors.hasCoverageFragmentProcessor()) { |
57 | fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor(); |
58 | } |
59 | if (appliedClip.hasCoverageFragmentProcessor()) { |
60 | fFragmentProcessors[currFPIdx++] = appliedClip.detachCoverageFragmentProcessor(); |
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 of 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 constexpr uint32_t kBlendWriteShift = 1; |
99 | static constexpr 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::visitTextureEffects( |
112 | const std::function<void(const GrTextureEffect&)>& func) const { |
113 | for (auto& fp : fFragmentProcessors) { |
114 | fp->visitTextureEffects(func); |
115 | } |
116 | } |
117 | |
118 | void GrPipeline::visitProxies(const GrOp::VisitProxyFunc& func) const { |
119 | // This iteration includes any clip coverage FPs |
120 | for (auto& fp : fFragmentProcessors) { |
121 | fp->visitProxies(func); |
122 | } |
123 | if (fDstProxyView.asTextureProxy()) { |
124 | func(fDstProxyView.asTextureProxy(), GrMipmapped::kNo); |
125 | } |
126 | } |
127 | |