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 "GrXferProcessor.h"
16 
17 #include "ops/GrOp.h"
18 
19 GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
20                        GrAppliedClip&& appliedClip) {
21     SkASSERT(args.fProxy);
22     SkASSERT(processors.isFinalized());
23 
24     fProxy.reset(args.fProxy);
25 
26     fFlags = args.fFlags;
27     fScissorState = appliedClip.scissorState();
28     if (appliedClip.hasStencilClip()) {
29         fFlags |= kHasStencilClip_Flag;
30     }
31     fWindowRectsState = appliedClip.windowRectsState();
32     if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) {
33         fFlags |= kStencilEnabled_Flag;
34     }
35 
36     fUserStencilSettings = args.fUserStencil;
37 
38     fXferProcessor = processors.refXferProcessor();
39 
40     if (args.fDstProxy.proxy()) {
41         if (!args.fDstProxy.proxy()->instantiate(args.fResourceProvider)) {
42             this->markAsBad();
43         }
44 
45         fDstTextureProxy.reset(args.fDstProxy.proxy());
46         fDstTextureOffset = args.fDstProxy.offset();
47     }
48 
49     // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
50     fNumColorProcessors = processors.numColorFragmentProcessors();
51     int numTotalProcessors = fNumColorProcessors +
52                              processors.numCoverageFragmentProcessors() +
53                              appliedClip.numClipCoverageFragmentProcessors();
54     fFragmentProcessors.reset(numTotalProcessors);
55     int currFPIdx = 0;
56     for (int i = 0; i < processors.numColorFragmentProcessors(); ++i, ++currFPIdx) {
57         fFragmentProcessors[currFPIdx] = processors.detachColorFragmentProcessor(i);
58         if (!fFragmentProcessors[currFPIdx]->instantiate(args.fResourceProvider)) {
59             this->markAsBad();
60         }
61     }
62     for (int i = 0; i < processors.numCoverageFragmentProcessors(); ++i, ++currFPIdx) {
63         fFragmentProcessors[currFPIdx] = processors.detachCoverageFragmentProcessor(i);
64         if (!fFragmentProcessors[currFPIdx]->instantiate(args.fResourceProvider)) {
65             this->markAsBad();
66         }
67     }
68     for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i, ++currFPIdx) {
69         fFragmentProcessors[currFPIdx] = appliedClip.detachClipCoverageFragmentProcessor(i);
70         if (!fFragmentProcessors[currFPIdx]->instantiate(args.fResourceProvider)) {
71             this->markAsBad();
72         }
73     }
74 }
75 
76 void GrPipeline::addDependenciesTo(GrOpList* opList, const GrCaps& caps) const {
77     for (int i = 0; i < fFragmentProcessors.count(); ++i) {
78         GrFragmentProcessor::TextureAccessIter iter(fFragmentProcessors[i].get());
79         while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
80             opList->addDependency(sampler->proxy(), caps);
81         }
82     }
83 
84     if (fDstTextureProxy) {
85         opList->addDependency(fDstTextureProxy.get(), caps);
86     }
87 
88 }
89 
90 GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
91     if (fDstTextureProxy.get() &&
92         fDstTextureProxy.get()->priv().peekTexture() == fProxy.get()->priv().peekTexture()) {
93         return kTexture_GrXferBarrierType;
94     }
95     return this->getXferProcessor().xferBarrierType(caps);
96 }
97 
98 GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, SkBlendMode blendmode)
99         : fProxy(proxy)
100         , fScissorState()
101         , fWindowRectsState()
102         , fUserStencilSettings(&GrUserStencilSettings::kUnused)
103         , fFlags()
104         , fXferProcessor(GrPorterDuffXPFactory::MakeNoCoverageXP(blendmode))
105         , fFragmentProcessors()
106         , fNumColorProcessors(0) {
107     SkASSERT(proxy);
108     if (ScissorState::kEnabled == scissorState) {
109         fScissorState.set({0, 0, 0, 0}); // caller will use the DynamicState struct.
110     }
111 }
112