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
18GrPipeline::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
41GrPipeline::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
64GrXferBarrierType 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
72GrPipeline::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
87void 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
111void GrPipeline::visitTextureEffects(
112 const std::function<void(const GrTextureEffect&)>& func) const {
113 for (auto& fp : fFragmentProcessors) {
114 fp->visitTextureEffects(func);
115 }
116}
117
118void 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