• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ganesh/GrPipeline.h"
9 
10 #include "src/gpu/KeyBuilder.h"
11 #include "src/gpu/ganesh/GrAppliedClip.h"
12 #include "src/gpu/ganesh/GrCaps.h"
13 #include "src/gpu/ganesh/GrTexture.h"
14 #include "src/gpu/ganesh/GrXferProcessor.h"
15 #include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
16 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.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         : fDstProxy(args.fDstProxyView)
22         , fWindowRectsState(hardClip.windowRectsState())
23         , fXferProcessor(std::move(xferProcessor))
24         , fWriteSwizzle(args.fWriteSwizzle) {
25     fFlags = (Flags)args.fInputFlags;
26     if (hardClip.hasStencilClip()) {
27         fFlags |= Flags::kHasStencilClip;
28     }
29     if (hardClip.scissorState().enabled()) {
30         fFlags |= Flags::kScissorTestEnabled;
31     }
32     // If we have any special dst sample flags we better also have a dst proxy
33     SkASSERT(this->dstSampleFlags() == GrDstSampleFlags::kNone || this->dstProxyView());
34 }
35 
GrPipeline(const InitArgs & args,GrProcessorSet && processors,GrAppliedClip && appliedClip)36 GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
37                        GrAppliedClip&& appliedClip)
38         : GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) {
39     SkASSERT(processors.isFinalized());
40     // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
41     fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
42     int numTotalProcessors = fNumColorProcessors +
43                              (processors.hasCoverageFragmentProcessor() ? 1 : 0) +
44                              (appliedClip.hasCoverageFragmentProcessor() ? 1 : 0);
45     fFragmentProcessors.reset(numTotalProcessors);
46 
47     int currFPIdx = 0;
48     if (processors.hasColorFragmentProcessor()) {
49         fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor();
50     }
51     if (processors.hasCoverageFragmentProcessor()) {
52         fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
53     }
54     if (appliedClip.hasCoverageFragmentProcessor()) {
55         fFragmentProcessors[currFPIdx++] = appliedClip.detachCoverageFragmentProcessor();
56     }
57 }
58 
xferBarrierType(const GrCaps & caps) const59 GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
60     if (this->dstSampleFlags() & GrDstSampleFlags::kRequiresTextureBarrier) {
61         return kTexture_GrXferBarrierType;
62     }
63     return this->getXferProcessor().xferBarrierType(caps);
64 }
65 
GrPipeline(GrScissorTest scissorTest,sk_sp<const GrXferProcessor> xp,const skgpu::Swizzle & writeSwizzle,InputFlags inputFlags)66 GrPipeline::GrPipeline(GrScissorTest scissorTest,
67                        sk_sp<const GrXferProcessor> xp,
68                        const skgpu::Swizzle& writeSwizzle,
69                        InputFlags inputFlags)
70         : fWindowRectsState()
71         , fFlags((Flags)inputFlags)
72         , fXferProcessor(std::move(xp))
73         , fWriteSwizzle(writeSwizzle) {
74     if (GrScissorTest::kEnabled == scissorTest) {
75         fFlags |= Flags::kScissorTestEnabled;
76     }
77 }
78 
genKey(skgpu::KeyBuilder * b,const GrCaps & caps) const79 void GrPipeline::genKey(skgpu::KeyBuilder* b, const GrCaps& caps) const {
80     // kSnapVerticesToPixelCenters is implemented in a shader.
81     InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
82     b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags, "flags");
83 
84     const skgpu::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
85 
86     static constexpr uint32_t kBlendCoeffSize = 5;
87     static constexpr uint32_t kBlendEquationSize = 5;
88     static_assert(static_cast<int>(skgpu::BlendCoeff::kLast) < (1 << kBlendCoeffSize));
89     static_assert(static_cast<int>(skgpu::BlendEquation::kLast) < (1 << kBlendEquationSize));
90 
91     b->addBool(blendInfo.fWritesColor, "writesColor");
92     b->addBits(kBlendCoeffSize, static_cast<int>(blendInfo.fSrcBlend), "srcBlend");
93     b->addBits(kBlendCoeffSize, static_cast<int>(blendInfo.fDstBlend), "dstBlend");
94     b->addBits(kBlendEquationSize, static_cast<int>(blendInfo.fEquation), "equation");
95     b->addBool(this->usesDstInputAttachment(), "inputAttach");
96 }
97 
visitTextureEffects(const std::function<void (const GrTextureEffect &)> & func) const98 void GrPipeline::visitTextureEffects(
99         const std::function<void(const GrTextureEffect&)>& func) const {
100     for (auto& fp : fFragmentProcessors) {
101         fp->visitTextureEffects(func);
102     }
103 }
104 
visitProxies(const GrVisitProxyFunc & func) const105 void GrPipeline::visitProxies(const GrVisitProxyFunc& func) const {
106     // This iteration includes any clip coverage FPs
107     for (auto& fp : fFragmentProcessors) {
108         fp->visitProxies(func);
109     }
110     if (this->usesDstTexture()) {
111         func(this->dstProxyView().proxy(), GrMipmapped::kNo);
112     }
113 }
114 
setDstTextureUniforms(const GrGLSLProgramDataManager & pdm,GrGLSLBuiltinUniformHandles * fBuiltinUniformHandles) const115 void GrPipeline::setDstTextureUniforms(const GrGLSLProgramDataManager& pdm,
116                                        GrGLSLBuiltinUniformHandles* fBuiltinUniformHandles) const {
117     GrTexture* dstTexture = this->peekDstTexture();
118 
119     if (dstTexture) {
120         if (fBuiltinUniformHandles->fDstTextureCoordsUni.isValid()) {
121             float scaleX = 1.f;
122             float scaleY = 1.f;
123             if (dstTexture->textureType() == GrTextureType::kRectangle) {
124                 // When we have a rectangle texture, we use the scaleX component to store the height
125                 // in case we need to flip the coords when using a bottom left origin.
126                 scaleX = dstTexture->height();
127             } else {
128                 scaleX /= dstTexture->width();
129                 scaleY /= dstTexture->height();
130             }
131             pdm.set4f(fBuiltinUniformHandles->fDstTextureCoordsUni,
132                       static_cast<float>(this->dstTextureOffset().fX),
133                       static_cast<float>(this->dstTextureOffset().fY),
134                       scaleX,
135                       scaleY);
136         }
137     } else {
138         SkASSERT(!fBuiltinUniformHandles->fDstTextureCoordsUni.isValid());
139     }
140 }
141