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