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/GrXferProcessor.h"
13 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
14 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
15
GrPipeline(const InitArgs & args,sk_sp<const GrXferProcessor> xferProcessor,const GrAppliedHardClip & hardClip)16 GrPipeline::GrPipeline(const InitArgs& args,
17 sk_sp<const GrXferProcessor> xferProcessor,
18 const GrAppliedHardClip& hardClip)
19 : fDstProxy(args.fDstProxyView)
20 , fWindowRectsState(hardClip.windowRectsState())
21 , fXferProcessor(std::move(xferProcessor))
22 , fWriteSwizzle(args.fWriteSwizzle) {
23 fFlags = (Flags)args.fInputFlags;
24 if (hardClip.hasStencilClip()) {
25 fFlags |= Flags::kHasStencilClip;
26 }
27 if (hardClip.scissorState().enabled()) {
28 fFlags |= Flags::kScissorTestEnabled;
29 }
30 // If we have any special dst sample flags we better also have a dst proxy
31 SkASSERT(this->dstSampleFlags() == GrDstSampleFlags::kNone || this->dstProxyView());
32 }
33
GrPipeline(const InitArgs & args,GrProcessorSet && processors,GrAppliedClip && appliedClip)34 GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
35 GrAppliedClip&& appliedClip)
36 : GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) {
37 SkASSERT(processors.isFinalized());
38 // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
39 fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
40 int numTotalProcessors = fNumColorProcessors +
41 (processors.hasCoverageFragmentProcessor() ? 1 : 0) +
42 (appliedClip.hasCoverageFragmentProcessor() ? 1 : 0);
43 fFragmentProcessors.reset(numTotalProcessors);
44
45 int currFPIdx = 0;
46 if (processors.hasColorFragmentProcessor()) {
47 fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor();
48 }
49 if (processors.hasCoverageFragmentProcessor()) {
50 fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
51 }
52 if (appliedClip.hasCoverageFragmentProcessor()) {
53 fFragmentProcessors[currFPIdx++] = appliedClip.detachCoverageFragmentProcessor();
54 }
55 }
56
xferBarrierType(const GrCaps & caps) const57 GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
58 if (this->dstSampleFlags() & GrDstSampleFlags::kRequiresTextureBarrier) {
59 return kTexture_GrXferBarrierType;
60 }
61 return this->getXferProcessor().xferBarrierType(caps);
62 }
63
GrPipeline(GrScissorTest scissorTest,sk_sp<const GrXferProcessor> xp,const GrSwizzle & writeSwizzle,InputFlags inputFlags)64 GrPipeline::GrPipeline(GrScissorTest scissorTest,
65 sk_sp<const GrXferProcessor> xp,
66 const GrSwizzle& writeSwizzle,
67 InputFlags inputFlags)
68 : fWindowRectsState()
69 , fFlags((Flags)inputFlags)
70 , fXferProcessor(std::move(xp))
71 , fWriteSwizzle(writeSwizzle) {
72 if (GrScissorTest::kEnabled == scissorTest) {
73 fFlags |= Flags::kScissorTestEnabled;
74 }
75 }
76
genKey(GrProcessorKeyBuilder * b,const GrCaps & caps) const77 void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
78 // kSnapVerticesToPixelCenters is implemented in a shader.
79 InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
80 b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags, "flags");
81
82 const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
83
84 static constexpr uint32_t kBlendCoeffSize = 5;
85 static constexpr uint32_t kBlendEquationSize = 5;
86 static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffSize));
87 static_assert(kLast_GrBlendEquation < (1 << kBlendEquationSize));
88
89 b->addBool(blendInfo.fWriteColor, "writeColor");
90 b->addBits(kBlendCoeffSize, blendInfo.fSrcBlend, "srcBlend");
91 b->addBits(kBlendCoeffSize, blendInfo.fDstBlend, "dstBlend");
92 b->addBits(kBlendEquationSize, blendInfo.fEquation, "equation");
93 b->addBool(this->usesDstInputAttachment(), "inputAttach");
94 }
95
visitTextureEffects(const std::function<void (const GrTextureEffect &)> & func) const96 void GrPipeline::visitTextureEffects(
97 const std::function<void(const GrTextureEffect&)>& func) const {
98 for (auto& fp : fFragmentProcessors) {
99 fp->visitTextureEffects(func);
100 }
101 }
102
visitProxies(const GrVisitProxyFunc & func) const103 void GrPipeline::visitProxies(const GrVisitProxyFunc& func) const {
104 // This iteration includes any clip coverage FPs
105 for (auto& fp : fFragmentProcessors) {
106 fp->visitProxies(func);
107 }
108 if (this->usesDstTexture()) {
109 func(this->dstProxyView().proxy(), GrMipmapped::kNo);
110 }
111 }
112
setDstTextureUniforms(const GrGLSLProgramDataManager & pdm,GrGLSLBuiltinUniformHandles * fBuiltinUniformHandles) const113 void GrPipeline::setDstTextureUniforms(const GrGLSLProgramDataManager& pdm,
114 GrGLSLBuiltinUniformHandles* fBuiltinUniformHandles) const {
115 GrTexture* dstTexture = this->peekDstTexture();
116
117 if (dstTexture) {
118 if (fBuiltinUniformHandles->fDstTextureCoordsUni.isValid()) {
119 pdm.set4f(fBuiltinUniformHandles->fDstTextureCoordsUni,
120 static_cast<float>(this->dstTextureOffset().fX),
121 static_cast<float>(this->dstTextureOffset().fY),
122 1.f / dstTexture->width(),
123 1.f / dstTexture->height());
124 }
125 } else {
126 SkASSERT(!fBuiltinUniformHandles->fDstTextureCoordsUni.isValid());
127 }
128 }
129