1/*
2 * Copyright 2013 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#ifndef GrPrimitiveProcessor_DEFINED
9#define GrPrimitiveProcessor_DEFINED
10
11#include "GrColor.h"
12#include "GrProcessor.h"
13#include "GrShaderVar.h"
14
15/*
16 * The GrPrimitiveProcessor represents some kind of geometric primitive.  This includes the shape
17 * of the primitive and the inherent color of the primitive.  The GrPrimitiveProcessor is
18 * responsible for providing a color and coverage input into the Ganesh rendering pipeline.  Through
19 * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
20 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
21 * functionality.  We also use the GrPrimitiveProcessor to make batching decisions.
22 *
23 * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
24 * GrPrimitiveProcessor.  These loops run on the CPU and compute any invariant components which
25 * might be useful for correctness / optimization decisions.  The GrPrimitiveProcessor seeds these
26 * loops, one with initial color and one with initial coverage, in its
27 * onComputeInvariantColor / Coverage calls.  These seed values are processed by the subsequent
28 * stages of the rendering pipeline and the output is then fed back into the GrPrimitiveProcessor in
29 * the initBatchTracker call, where the GrPrimitiveProcessor can then initialize the GrBatchTracker
30 * struct with the appropriate values.
31 *
32 * We are evolving this system to move towards generating geometric meshes and their associated
33 * vertex data after we have batched and reordered draws.  This system, known as 'deferred geometry'
34 * will allow the GrPrimitiveProcessor much greater control over how data is transmitted to shaders.
35 *
36 * In a deferred geometry world, the GrPrimitiveProcessor can always 'batch'  To do this, each
37 * primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
38 * it draws.  Each primitive draw will bundle all required data to perform the draw, and these
39 * bundles of data will be owned by an instance of the associated GrPrimitiveProcessor.  Bundles
40 * can be updated alongside the GrBatchTracker struct itself, ultimately allowing the
41 * GrPrimitiveProcessor complete control of how it gets data into the fragment shader as long as
42 * it emits the appropriate color, or none at all, as directed.
43 */
44
45class GrGLSLCaps;
46class GrGLSLPrimitiveProcessor;
47
48struct GrInitInvariantOutput;
49
50// Describes the state of pixel local storage with respect to the current draw.
51enum GrPixelLocalStorageState {
52    // The draw is actively updating PLS.
53    kDraw_GrPixelLocalStorageState,
54    // The draw is a "finish" operation which is reading from PLS and writing color.
55    kFinish_GrPixelLocalStorageState,
56    // The draw does not use PLS.
57    kDisabled_GrPixelLocalStorageState
58};
59
60/*
61 * This class allows the GrPipeline to communicate information about the pipeline to a
62 * GrBatch which should be forwarded to the GrPrimitiveProcessor(s) created by the batch.
63 * These are not properly part of the pipeline because they assume the specific inputs
64 * that the batch provided when it created the pipeline. Identical pipelines may be
65 * created by different batches with different input assumptions and therefore different
66 * computed optimizations. It is the batch-specific optimizations that allow the pipelines
67 * to be equal.
68 */
69class GrXPOverridesForBatch {
70public:
71    /** Does the pipeline require the GrPrimitiveProcessor's color? */
72    bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
73
74    /** Does the pipeline require the GrPrimitiveProcessor's coverage? */
75    bool readsCoverage() const { return
76        SkToBool(kReadsCoverage_Flag & fFlags); }
77
78    /** Does the pipeline require access to (implicit or explicit) local coordinates? */
79    bool readsLocalCoords() const {
80        return SkToBool(kReadsLocalCoords_Flag & fFlags);
81    }
82
83    /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
84        color output ? */
85    bool canTweakAlphaForCoverage() const {
86        return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
87    }
88
89    /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
90        so get the color)? */
91    bool getOverrideColorIfSet(GrColor* overrideColor) const {
92        if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
93            SkASSERT(SkToBool(kReadsColor_Flag & fFlags));
94            if (overrideColor) {
95                *overrideColor = fOverrideColor;
96            }
97            return true;
98        }
99        return false;
100    }
101
102    /**
103     * Returns true if the pipeline's color output will be affected by the existing render target
104     * destination pixel values (meaning we need to be careful with overlapping draws). Note that we
105     * can conflate coverage and color, so the destination color may still bleed into pixels that
106     * have partial coverage, even if this function returns false.
107     *
108     * The above comment seems incorrect for the use case. This funciton is used to turn two
109     * overlapping draws into a single draw (really to stencil multiple paths and do a single
110     * cover). It seems that what really matters is whether the dst is read for color OR for
111     * coverage.
112     */
113    bool willColorBlendWithDst() const { return SkToBool(kWillColorBlendWithDst_Flag & fFlags); }
114
115private:
116    enum {
117        // If this is not set the primitive processor need not produce a color output
118        kReadsColor_Flag                = 0x1,
119
120        // If this is not set the primitive processor need not produce a coverage output
121        kReadsCoverage_Flag             = 0x2,
122
123        // If this is not set the primitive processor need not produce local coordinates
124        kReadsLocalCoords_Flag          = 0x4,
125
126        // If this flag is set then the primitive processor may produce color*coverage as
127        // its color output (and not output a separate coverage).
128        kCanTweakAlphaForCoverage_Flag  = 0x8,
129
130        // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
131        // output color. If not set fOverrideColor is to be ignored.
132        kUseOverrideColor_Flag          = 0x10,
133
134        kWillColorBlendWithDst_Flag     = 0x20,
135    };
136
137    uint32_t    fFlags;
138    GrColor     fOverrideColor;
139
140    friend class GrPipeline; // To initialize this
141};
142
143/*
144 * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
145 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
146 * pipelines, and they must provide some notion of equality
147 */
148class GrPrimitiveProcessor : public GrProcessor {
149public:
150    // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
151    // we put these calls on the base class to prevent having to cast
152    virtual bool willUseGeoShader() const = 0;
153
154    /*
155     * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
156     * attribute limits. This number can almost certainly be raised if required.
157     */
158    static const int kMaxVertexAttribs = 8;
159
160    struct Attribute {
161        Attribute()
162            : fName(nullptr)
163            , fType(kFloat_GrVertexAttribType)
164            , fOffset(0) {}
165        Attribute(const char* name, GrVertexAttribType type,
166                  GrSLPrecision precision = kDefault_GrSLPrecision)
167            : fName(name)
168            , fType(type)
169            , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
170            , fPrecision(precision) {}
171        const char* fName;
172        GrVertexAttribType fType;
173        size_t fOffset;
174        GrSLPrecision fPrecision;
175    };
176
177    int numAttribs() const { return fNumAttribs; }
178    const Attribute& getAttrib(int index) const {
179        SkASSERT(index < fNumAttribs);
180        return fAttribs[index];
181    }
182
183    // Returns the vertex stride of the GP.  A common use case is to request geometry from a
184    // drawtarget based off of the stride, and to populate this memory using an implicit array of
185    // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
186    size_t getVertexStride() const { return fVertexStride; }
187
188    /**
189     * Computes a transformKey from an array of coord transforms. Will only look at the first
190     * <numCoords> transforms in the array.
191     *
192     * TODO: A better name for this function  would be "compute" instead of "get".
193     */
194    uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
195                             int numCoords) const;
196
197    /**
198     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
199     * processor's GL backend implementation.
200     *
201     * TODO: A better name for this function  would be "compute" instead of "get".
202     */
203    virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
204                                     GrProcessorKeyBuilder* b) const = 0;
205
206
207    /** Returns a new instance of the appropriate *GL* implementation class
208        for the given GrProcessor; caller is responsible for deleting
209        the object. */
210    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps& caps) const = 0;
211
212    virtual bool isPathRendering() const { return false; }
213
214    /**
215     * No Local Coord Transformation is needed in the shader, instead transformed local coords will
216     * be provided via vertex attribute.
217     */
218    virtual bool hasTransformedLocalCoords() const = 0;
219
220    virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
221        return kDisabled_GrPixelLocalStorageState;
222    }
223
224    /**
225     * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
226     */
227    virtual const char* getDestColorOverride() const { return nullptr; }
228
229protected:
230    GrPrimitiveProcessor()
231        : fNumAttribs(0)
232        , fVertexStride(0) {}
233
234    Attribute fAttribs[kMaxVertexAttribs];
235    int fNumAttribs;
236    size_t fVertexStride;
237
238private:
239    void notifyRefCntIsZero() const final {};
240    virtual bool hasExplicitLocalCoords() const = 0;
241
242    typedef GrProcessor INHERITED;
243};
244
245#endif
246