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 GrGeometryProcessor_DEFINED
9#define GrGeometryProcessor_DEFINED
10
11#include "GrPrimitiveProcessor.h"
12
13/**
14 * A GrGeometryProcessor is a flexible method for rendering a primitive.  The GrGeometryProcessor
15 * has complete control over vertex attributes and uniforms(aside from the render target) but it
16 * must obey the same contract as any GrPrimitiveProcessor, specifically it must emit a color and
17 * coverage into the fragment shader.  Where this color and coverage come from is completely the
18 * responsibility of the GrGeometryProcessor.
19 */
20class GrGeometryProcessor : public GrPrimitiveProcessor {
21public:
22    GrGeometryProcessor()
23        : INHERITED(false)
24        , fWillUseGeoShader(false)
25        , fHasLocalCoords(false) {}
26
27    bool willUseGeoShader() const { return fWillUseGeoShader; }
28
29    // TODO delete this when paths are in batch
30    bool canMakeEqual(const GrBatchTracker& mine,
31                      const GrPrimitiveProcessor& that,
32                      const GrBatchTracker& theirs) const override {
33        SkFAIL("Unsupported\n");
34        return false;
35    }
36
37    // TODO Delete when paths are in batch
38    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
39        SkFAIL("Unsupported\n");
40    }
41    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
42        SkFAIL("Unsupported\n");
43    }
44
45protected:
46    /*
47     * An optional simple helper function to determine by what means the GrGeometryProcessor should
48     * use to provide color.  If we are given an override color(ie the given overridecolor is NOT
49     * GrColor_ILLEGAL) then we must always emit that color(currently overrides are only supported
50     * via uniform, but with deferred Geometry we could use attributes).  Otherwise, if our color is
51     * ignored then we should not emit a color.  Lastly, if we don't have vertex colors then we must
52     * emit a color via uniform
53     * TODO this function changes quite a bit with deferred geometry.  There the GrGeometryProcessor
54     * can upload a new color via attribute if needed.
55     */
56    static GrGPInput GetColorInputType(GrColor* color, GrColor primitiveColor,
57                                       const GrPipelineInfo& init,
58                                       bool hasVertexColor) {
59        if (init.fColorIgnored) {
60            *color = GrColor_ILLEGAL;
61            return kIgnored_GrGPInput;
62        } else if (GrColor_ILLEGAL != init.fOverrideColor) {
63            *color = init.fOverrideColor;
64            return kUniform_GrGPInput;
65        }
66
67        *color = primitiveColor;
68        if (hasVertexColor) {
69            return kAttribute_GrGPInput;
70        } else {
71            return kUniform_GrGPInput;
72        }
73    }
74
75    /**
76     * Subclasses call this from their constructor to register vertex attributes.  Attributes
77     * will be padded to the nearest 4 bytes for performance reasons.
78     * TODO After deferred geometry, we should do all of this inline in GenerateGeometry alongside
79     * the struct used to actually populate the attributes.  This is all extremely fragile, vertex
80     * attributes have to be added in the order they will appear in the struct which maps memory.
81     * The processor key should reflect the vertex attributes, or there lack thereof in the
82     * GrGeometryProcessor.
83     */
84    const Attribute& addVertexAttrib(const Attribute& attribute) {
85        SkASSERT(fNumAttribs < kMaxVertexAttribs);
86        fVertexStride += attribute.fOffset;
87        fAttribs[fNumAttribs] = attribute;
88        return fAttribs[fNumAttribs++];
89    }
90
91    void setWillUseGeoShader() { fWillUseGeoShader = true; }
92
93    // TODO hack see above
94    void setHasLocalCoords() { fHasLocalCoords = true; }
95
96private:
97    bool hasExplicitLocalCoords() const override { return fHasLocalCoords; }
98
99    bool fWillUseGeoShader;
100    bool fHasLocalCoords;
101
102    typedef GrPrimitiveProcessor INHERITED;
103};
104
105#endif
106