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
45/*
46 * A struct for tracking batching decisions.  While this lives on GrOptState, it is managed
47 * entirely by the derived classes of the GP.
48 * // TODO this was an early attempt at handling out of order batching.  It should be
49 * used carefully as it is being replaced by GrBatch
50 */
51class GrBatchTracker {
52public:
53    template <typename T> const T& cast() const {
54        SkASSERT(sizeof(T) <= kMaxSize);
55        return *reinterpret_cast<const T*>(fData.get());
56    }
57
58    template <typename T> T* cast() {
59        SkASSERT(sizeof(T) <= kMaxSize);
60        return reinterpret_cast<T*>(fData.get());
61    }
62
63    static const size_t kMaxSize = 32;
64
65private:
66    SkAlignedSStorage<kMaxSize> fData;
67};
68
69class GrGLSLCaps;
70class GrGLPrimitiveProcessor;
71
72struct GrInitInvariantOutput;
73
74/*
75 * This struct allows the GrPipeline to communicate information about the pipeline.  Most of this
76 * is overrides, but some of it is general information.  Logically it should live in GrPipeline.h,
77 * but this is problematic due to circular dependencies.
78 */
79struct GrPipelineInfo {
80    bool fColorIgnored;
81    bool fCoverageIgnored;
82    GrColor fOverrideColor;
83    bool fUsesLocalCoords;
84    bool fCanTweakAlphaForCoverage;
85};
86
87/*
88 * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to coordinate shaders
89 * with vertex attributes / uniforms.
90 */
91enum GrGPInput {
92    kAllOnes_GrGPInput,
93    kAttribute_GrGPInput,
94    kUniform_GrGPInput,
95    kIgnored_GrGPInput,
96};
97
98/*
99 * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
100 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
101 * pipelines, and they must provide some notion of equality
102 */
103class GrPrimitiveProcessor : public GrProcessor {
104public:
105    virtual void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const = 0;
106
107    virtual bool canMakeEqual(const GrBatchTracker& mine,
108                              const GrPrimitiveProcessor& that,
109                              const GrBatchTracker& theirs) const = 0;
110
111    virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
112    virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
113
114    // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
115    // we put these calls on the base class to prevent having to cast
116    virtual bool willUseGeoShader() const = 0;
117
118    /*
119     * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
120     * attribute limits. This number can almost certainly be raised if required.
121     */
122    static const int kMaxVertexAttribs = 6;
123
124    struct Attribute {
125        Attribute()
126            : fName(NULL)
127            , fType(kFloat_GrVertexAttribType)
128            , fOffset(0) {}
129        Attribute(const char* name, GrVertexAttribType type,
130                  GrSLPrecision precision = kDefault_GrSLPrecision)
131            : fName(name)
132            , fType(type)
133            , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
134            , fPrecision(precision) {}
135        const char* fName;
136        GrVertexAttribType fType;
137        size_t fOffset;
138        GrSLPrecision fPrecision;
139    };
140
141    int numAttribs() const { return fNumAttribs; }
142    const Attribute& getAttrib(int index) const {
143        SkASSERT(index < fNumAttribs);
144        return fAttribs[index];
145    }
146
147    // Returns the vertex stride of the GP.  A common use case is to request geometry from a
148    // drawtarget based off of the stride, and to populate this memory using an implicit array of
149    // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
150    size_t getVertexStride() const { return fVertexStride; }
151
152    /**
153     * Gets a transformKey from an array of coord transforms
154     */
155    uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>&) const;
156
157    /**
158     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
159     * processor's GL backend implementation.
160     */
161    virtual void getGLProcessorKey(const GrBatchTracker& bt,
162                                   const GrGLSLCaps& caps,
163                                   GrProcessorKeyBuilder* b) const = 0;
164
165
166    /** Returns a new instance of the appropriate *GL* implementation class
167        for the given GrProcessor; caller is responsible for deleting
168        the object. */
169    virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
170                                                     const GrGLSLCaps& caps) const = 0;
171
172    bool isPathRendering() const { return fIsPathRendering; }
173
174protected:
175    GrPrimitiveProcessor(bool isPathRendering)
176        : fNumAttribs(0)
177        , fVertexStride(0)
178        , fIsPathRendering(isPathRendering) {}
179
180    Attribute fAttribs[kMaxVertexAttribs];
181    int fNumAttribs;
182    size_t fVertexStride;
183
184private:
185    virtual bool hasExplicitLocalCoords() const = 0;
186
187    bool fIsPathRendering;
188
189    typedef GrProcessor INHERITED;
190};
191
192#endif
193