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 "GrPipeline.h"
9
10 #include "GrAppliedClip.h"
11 #include "GrCaps.h"
12 #include "GrGpu.h"
13 #include "GrRenderTargetContext.h"
14 #include "GrRenderTargetOpList.h"
15 #include "GrRenderTargetPriv.h"
16 #include "GrXferProcessor.h"
17
18 #include "ops/GrOp.h"
19
init(const InitArgs & args)20 void GrPipeline::init(const InitArgs& args) {
21 SkASSERT(args.fRenderTarget);
22 SkASSERT(args.fProcessors);
23 SkASSERT(args.fProcessors->isFinalized());
24
25 fRenderTarget.reset(args.fRenderTarget);
26
27 fFlags = args.fFlags;
28 if (args.fAppliedClip) {
29 fScissorState = args.fAppliedClip->scissorState();
30 if (args.fAppliedClip->hasStencilClip()) {
31 fFlags |= kHasStencilClip_Flag;
32 }
33 fWindowRectsState = args.fAppliedClip->windowRectsState();
34 }
35 if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) {
36 fFlags |= kStencilEnabled_Flag;
37 }
38
39 fUserStencilSettings = args.fUserStencil;
40
41 fXferProcessor = args.fProcessors->refXferProcessor();
42
43 if (args.fDstProxy.proxy()) {
44 if (!args.fDstProxy.proxy()->instantiate(args.fResourceProvider)) {
45 this->markAsBad();
46 }
47
48 fDstTextureProxy.reset(args.fDstProxy.proxy());
49 fDstTextureOffset = args.fDstProxy.offset();
50 }
51
52 // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
53 fNumColorProcessors = args.fProcessors->numColorFragmentProcessors();
54 int numTotalProcessors =
55 fNumColorProcessors + args.fProcessors->numCoverageFragmentProcessors();
56 if (args.fAppliedClip && args.fAppliedClip->clipCoverageFragmentProcessor()) {
57 ++numTotalProcessors;
58 }
59 fFragmentProcessors.reset(numTotalProcessors);
60 int currFPIdx = 0;
61 for (int i = 0; i < args.fProcessors->numColorFragmentProcessors(); ++i, ++currFPIdx) {
62 const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i);
63 fFragmentProcessors[currFPIdx].reset(fp);
64 if (!fp->instantiate(args.fResourceProvider)) {
65 this->markAsBad();
66 }
67 }
68
69 for (int i = 0; i < args.fProcessors->numCoverageFragmentProcessors(); ++i, ++currFPIdx) {
70 const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i);
71 fFragmentProcessors[currFPIdx].reset(fp);
72 if (!fp->instantiate(args.fResourceProvider)) {
73 this->markAsBad();
74 }
75 }
76 if (args.fAppliedClip) {
77 if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) {
78 fFragmentProcessors[currFPIdx].reset(fp);
79 if (!fp->instantiate(args.fResourceProvider)) {
80 this->markAsBad();
81 }
82 }
83 }
84 }
85
addDependenciesTo(GrOpList * opList,const GrCaps & caps) const86 void GrPipeline::addDependenciesTo(GrOpList* opList, const GrCaps& caps) const {
87 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
88 GrFragmentProcessor::TextureAccessIter iter(fFragmentProcessors[i].get());
89 while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
90 opList->addDependency(sampler->proxy(), caps);
91 }
92 }
93
94 if (fDstTextureProxy) {
95 opList->addDependency(fDstTextureProxy.get(), caps);
96 }
97
98 }
99
xferBarrierType(const GrCaps & caps) const100 GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
101 if (fDstTextureProxy.get() &&
102 fDstTextureProxy.get()->priv().peekTexture() == fRenderTarget.get()->asTexture()) {
103 return kTexture_GrXferBarrierType;
104 }
105 return this->getXferProcessor().xferBarrierType(caps);
106 }
107
GrPipeline(GrRenderTarget * rt,ScissorState scissorState,SkBlendMode blendmode)108 GrPipeline::GrPipeline(GrRenderTarget* rt, ScissorState scissorState, SkBlendMode blendmode)
109 : fRenderTarget(rt)
110 , fScissorState()
111 , fWindowRectsState()
112 , fUserStencilSettings(&GrUserStencilSettings::kUnused)
113 , fFlags()
114 , fXferProcessor(GrPorterDuffXPFactory::MakeNoCoverageXP(blendmode))
115 , fFragmentProcessors()
116 , fNumColorProcessors(0) {
117 if (ScissorState::kEnabled == scissorState) {
118 fScissorState.set({0, 0, 0, 0}); // caller will use the DynamicState struct.
119 }
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////
123
AreEqual(const GrPipeline & a,const GrPipeline & b)124 bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) {
125 SkASSERT(&a != &b);
126
127 if (a.getRenderTarget() != b.getRenderTarget() ||
128 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
129 a.fNumColorProcessors != b.fNumColorProcessors ||
130 a.fScissorState != b.fScissorState ||
131 a.fWindowRectsState != b.fWindowRectsState ||
132 a.fFlags != b.fFlags ||
133 a.fUserStencilSettings != b.fUserStencilSettings) {
134 return false;
135 }
136
137 // Most of the time both are nullptr
138 if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
139 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
140 return false;
141 }
142 }
143
144 for (int i = 0; i < a.numFragmentProcessors(); i++) {
145 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i))) {
146 return false;
147 }
148 }
149 return true;
150 }
151