aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPipeline.h
blob: c4319958a47a3a58880f73770cf85533cce6a809 (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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 * 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 "GrProcessorSet.h"
#include "GrProgramDesc.h"
#include "GrRect.h"
#include "GrRenderTargetProxy.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 GrRenderTargetContext;

/**
 * This immutable object contains information needed to set build a shader program and set API
 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
 * data (GrMesh or GrPath) to draw.
 */
class 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,
        /** Disables conversion to sRGB from linear when writing to a sRGB destination. */
        kDisableOutputConversionToSRGB_Flag = 0x4,
        /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */
        kAllowSRGBInputs_Flag = 0x8,
    };

    static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
        uint32_t flags = 0;
        if (paint.getAllowSRGBInputs()) {
            flags |= kAllowSRGBInputs_Flag;
        }
        if (paint.getDisableOutputConversionToSRGB()) {
            flags |= kDisableOutputConversionToSRGB_Flag;
        }
        return flags;
    }

    enum ScissorState : bool {
        kEnabled = true,
        kDisabled = false
    };

    struct InitArgs {
        uint32_t fFlags = 0;
        const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
        GrRenderTargetProxy* fProxy = nullptr;
        const GrCaps* fCaps = nullptr;
        GrResourceProvider* fResourceProvider = nullptr;
        GrXferProcessor::DstProxy fDstProxy;
    };

    /**
     *  Graphics state that can change dynamically without creating a new pipeline.
     **/
    struct DynamicState {
        // Overrides the scissor rectangle (if scissor is enabled in the pipeline).
        // TODO: eventually this should be the only way to specify a scissor rectangle, as is the
        // case with the simple constructor.
        SkIRect fScissorRect;
    };

    /**
     * Creates a simple pipeline with default settings and no processors. The provided blend mode
     * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
     * specify a scissor rectangle through the DynamicState struct.
     **/
    GrPipeline(GrRenderTargetProxy*, ScissorState, SkBlendMode);

    GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);

    GrPipeline(const GrPipeline&) = delete;
    GrPipeline& operator=(const GrPipeline&) = delete;

    /// @}

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

    // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline
    void addDependenciesTo(GrOpList* recipient, const GrCaps&) 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) {
            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();
        }
    }

    /**
     * If the GrXferProcessor uses a texture to access the dst color, then this returns that
     * texture and the offset to the dst contents within that texture.
     */
    GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
        if (offset) {
            *offset = fDstTextureOffset;
        }
        return fDstTextureProxy.get();
    }

    GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
        if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
            return dstProxy->priv().peekTexture();
        }

        return nullptr;
    }

    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.
     */
    GrRenderTargetProxy* proxy() const { return fProxy.get(); }
    GrRenderTarget* renderTarget() const { return fProxy.get()->priv().peekRenderTarget(); }

    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 hasStencilClip() const {
        return SkToBool(fFlags & kHasStencilClip_Flag);
    }
    bool isStencilEnabled() const {
        return SkToBool(fFlags & kStencilEnabled_Flag);
    }
    bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }

    GrXferBarrierType xferBarrierType(const GrCaps& caps) const;

    static SkString DumpFlags(uint32_t flags) {
        if (flags) {
            SkString result;
            if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) {
                result.append("Snap vertices to pixel center.\n");
            }
            if (flags & GrPipeline::kHWAntialias_Flag) {
                result.append("HW Antialiasing enabled.\n");
            }
            if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) {
                result.append("Disable output conversion to sRGB.\n");
            }
            if (flags & GrPipeline::kAllowSRGBInputs_Flag) {
                result.append("Allow sRGB Inputs.\n");
            }
            return result;
        }
        return SkString("No pipeline flags\n");
    }

private:
    void markAsBad() { fFlags |= kIsBad_Flag; }

    /** This is a continuation of the public "Flags" enum. */
    enum PrivateFlags {
        kHasStencilClip_Flag = 0x10,
        kStencilEnabled_Flag = 0x20,
        kIsBad_Flag = 0x40,
    };

    using RenderTargetProxy = GrPendingIOResource<GrRenderTargetProxy, kWrite_GrIOType>;
    using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
    using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;

    DstTextureProxy fDstTextureProxy;
    SkIPoint fDstTextureOffset;
    // MDB TODO: do we still need the destination proxy here?
    RenderTargetProxy fProxy;
    GrScissorState fScissorState;
    GrWindowRectsState fWindowRectsState;
    const GrUserStencilSettings* fUserStencilSettings;
    uint16_t fFlags;
    sk_sp<const GrXferProcessor> fXferProcessor;
    FragmentProcessorArray fFragmentProcessors;

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

    typedef SkRefCnt INHERITED;
};

#endif