aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPipeline.h
blob: 7f2ac79b4ffe931d6bb4d6828d738243baa902c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrPipeline_DEFINED
#define GrPipeline_DEFINED

#include "GrColor.h"
#include "GrFragmentProcessor.h"
#include "GrNonAtomicRef.h"
#include "GrPendingProgramElement.h"
#include "GrPrimitiveProcessor.h"
#include "GrProcOptInfo.h"
#include "GrProcessorSet.h"
#include "GrProgramDesc.h"
#include "GrScissorState.h"
#include "GrUserStencilSettings.h"
#include "GrWindowRectsState.h"
#include "SkMatrix.h"
#include "SkRefCnt.h"
#include "effects/GrCoverageSetOpXP.h"
#include "effects/GrDisableColorXP.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"

class GrAppliedClip;
class GrDeviceCoordTexture;
class GrOp;
class GrPipelineBuilder;
class GrRenderTargetContext;

/**
 * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
 * class, and contains all data needed to set the state for a gpu draw.
 */
class GrPipeline : public GrNonAtomicRef<GrPipeline> {
public:
    ///////////////////////////////////////////////////////////////////////////
    /// @name Creation

    enum Flags {
        /**
         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
         * the 3D API.
         */
        kHWAntialias_Flag = 0x1,

        /**
         * Modifies the vertex shader so that vertices will be positioned at pixel centers.
         */
        kSnapVerticesToPixelCenters_Flag = 0x2,
    };

    struct InitArgs {
        uint32_t fFlags = 0;
        GrDrawFace fDrawFace = GrDrawFace::kBoth;
        const GrProcessorSet* fProcessors = nullptr;
        const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis;
        const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
        const GrAppliedClip* fAppliedClip = nullptr;
        GrRenderTarget* fRenderTarget = nullptr;
        const GrCaps* fCaps = nullptr;
        GrXferProcessor::DstTexture fDstTexture;
    };

    /**
     * A Default constructed pipeline is unusable until init() is called.
     **/
    GrPipeline() = default;

    /**
     * Creates a simple pipeline with default settings and no processors. The provided blend mode
     * must be "Porter Duff" (<= kLastCoeffMode). This pipeline is initialized without requiring
     * a call to init().
     **/
    GrPipeline(GrRenderTarget*, SkBlendMode);

    /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
    GrPipelineOptimizations init(const InitArgs&);

    /** True if the pipeline has been initialized. */
    bool isInitialized() const { return SkToBool(fRenderTarget.get()); }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Comparisons

    /**
     * Returns true if these pipelines are equivalent.  Coord transforms may be applied either on
     * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
     * to combine draws. Therefore we take a param that indicates whether coord transforms should be
     * compared."
     */
    static bool AreEqual(const GrPipeline& a, const GrPipeline& b);

    /**
     * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
     * stricter test than isEqual because it also considers blend barriers when the two ops'
     * bounds overlap
     */
    static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
                           const GrPipeline& b, const SkRect& bBounds,
                           const GrCaps& caps)  {
        if (!AreEqual(a, b)) {
            return false;
        }
        if (a.xferBarrierType(caps)) {
            return aBounds.fRight <= bBounds.fLeft ||
                   aBounds.fBottom <= bBounds.fTop ||
                   bBounds.fRight <= aBounds.fLeft ||
                   bBounds.fBottom <= aBounds.fTop;
        }
        return true;
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name GrFragmentProcessors

    // Make the renderTarget's GrOpList (if it exists) be dependent on any
    // GrOpLists in this pipeline
    void addDependenciesTo(GrRenderTarget* rt) const;

    int numColorFragmentProcessors() const { return fNumColorProcessors; }
    int numCoverageFragmentProcessors() const {
        return fFragmentProcessors.count() - fNumColorProcessors;
    }
    int numFragmentProcessors() const { return fFragmentProcessors.count(); }

    const GrXferProcessor& getXferProcessor() const {
        if (fXferProcessor.get()) {
            return *fXferProcessor.get();
        } else {
            // A null xp member means the common src-over case. GrXferProcessor's ref'ing
            // mechanism is not thread safe so we do not hold a ref on this global.
            return GrPorterDuffXPFactory::SimpleSrcOverXP();
        }
    }

    const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
        SkASSERT(idx < this->numColorFragmentProcessors());
        return *fFragmentProcessors[idx].get();
    }

    const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
        SkASSERT(idx < this->numCoverageFragmentProcessors());
        return *fFragmentProcessors[fNumColorProcessors + idx].get();
    }

    const GrFragmentProcessor& getFragmentProcessor(int idx) const {
        return *fFragmentProcessors[idx].get();
    }

    /// @}

    /**
     * Retrieves the currently set render-target.
     *
     * @return    The currently set render target.
     */
    GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }

    const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }

    const GrScissorState& getScissorState() const { return fScissorState; }

    const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }

    bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
    bool snapVerticesToPixelCenters() const {
        return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
    }
    bool getDisableOutputConversionToSRGB() const {
        return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
    }
    bool getAllowSRGBInputs() const {
        return SkToBool(fFlags & kAllowSRGBInputs_Flag);
    }
    bool usesDistanceVectorField() const {
        return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
    }
    bool hasStencilClip() const {
        return SkToBool(fFlags & kHasStencilClip_Flag);
    }
    bool isStencilEnabled() const {
        return SkToBool(fFlags & kStencilEnabled_Flag);
    }

    GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
        return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
    }

    /**
     * Gets whether the target is drawing clockwise, counterclockwise,
     * or both faces.
     * @return the current draw face(s).
     */
    GrDrawFace getDrawFace() const { return static_cast<GrDrawFace>(fDrawFace); }

private:
    /** This is a continuation of the public "Flags" enum. */
    enum PrivateFlags {
        kDisableOutputConversionToSRGB_Flag = 0x4,
        kAllowSRGBInputs_Flag = 0x8,
        kUsesDistanceVectorField_Flag = 0x10,
        kHasStencilClip_Flag = 0x20,
        kStencilEnabled_Flag = 0x40,
    };

    typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
    typedef GrPendingProgramElement<const GrFragmentProcessor> PendingFragmentProcessor;
    typedef SkAutoSTArray<8, PendingFragmentProcessor> FragmentProcessorArray;
    typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
    RenderTarget                        fRenderTarget;
    GrScissorState                      fScissorState;
    GrWindowRectsState                  fWindowRectsState;
    const GrUserStencilSettings*        fUserStencilSettings;
    uint16_t                            fDrawFace;
    uint16_t                            fFlags;
    ProgramXferProcessor                fXferProcessor;
    FragmentProcessorArray              fFragmentProcessors;

    // This value is also the index in fFragmentProcessors where coverage processors begin.
    int                                 fNumColorProcessors;

    typedef SkRefCnt INHERITED;
};

#endif