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.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
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 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
111void 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