aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrEffect.h
blob: 4eb8f2a74dd0798a8e510108cc1d27a35e9845d2 (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
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrEffect_DEFINED
#define GrEffect_DEFINED

#include "GrRefCnt.h"
#include "GrNoncopyable.h"
#include "GrProgramStageFactory.h"
#include "GrEffectUnitTest.h"
#include "GrTextureAccess.h"

class GrContext;
class GrTexture;
class SkString;

/** Provides custom vertex shader, fragment shader, uniform data for a
    particular stage of the Ganesh shading pipeline.
    Subclasses must have a function that produces a human-readable name:
        static const char* Name();
    GrEffect objects *must* be immutable: after being constructed,
    their fields may not change.  (Immutability isn't actually required
    until they've been used in a draw call, but supporting that would require
    setters and getters that could fail, copy-on-write, or deep copying of these
    objects when they're stored by a GrGLProgramStage.)
  */
class GrEffect : public GrRefCnt {

public:
    SK_DECLARE_INST_COUNT(GrEffect)

    typedef GrProgramStageFactory::StageKey StageKey;

    explicit GrEffect(int numTextures);
    virtual ~GrEffect();

    /** If given an input texture that is/is not opaque, is this
        effect guaranteed to produce an opaque output? */
    virtual bool isOpaque(bool inputTextureIsOpaque) const;

    /** This object, besides creating back-end-specific helper
        objects, is used for run-time-type-identification. The factory should be
        an instance of templated class, GrTProgramStageFactory. It is templated
        on the subclass of GrEffect. The subclass must have a nested type
        (or typedef) named GLProgramStage which will be the subclass of
        GrGLProgramStage created by the factory.

        Example:
        class MyCustomEffect : public GrEffect {
        ...
            virtual const GrProgramStageFactory& getFactory() const
                                                            SK_OVERRIDE {
                return GrTProgramStageFactory<MyCustomEffect>::getInstance();
            }
        ...
        };
     */
    virtual const GrProgramStageFactory& getFactory() const = 0;

    /** Returns true if the other effect will generate identical output.
        Must only be called if the two are already known to be of the
        same type (i.e.  they return the same value from getFactory()).

        Equality is not the same thing as equivalence.
        To test for equivalence (that they will generate the same
        shader code, but may have different uniforms), check equality
        of the stageKey produced by the GrProgramStageFactory:
        a.getFactory().glStageKey(a) == b.getFactory().glStageKey(b).

        The default implementation of this function returns true iff
        the two stages have the same return value for numTextures() and
        for texture() over all valid indicse.
     */
    virtual bool isEqual(const GrEffect&) const;

    /** Human-meaningful string to identify this effect; may be embedded
        in generated shader code. */
    const char* name() const { return this->getFactory().name(); }

    int numTextures() const { return fNumTextures; }

    /** Returns the access pattern for the texture at index. index must be valid according to
        numTextures(). */
    virtual const GrTextureAccess& textureAccess(int index) const;

    /** Shortcut for textureAccess(index).texture(); */
    GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }

    void* operator new(size_t size);
    void operator delete(void* target);

private:
    int fNumTextures;
    typedef GrRefCnt INHERITED;
};

#endif