aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLProgramStage.h
blob: 60ab60dbd88454a6ed226091c6a30e35487581bf (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
/*
 * 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 GrGLCustomStage_DEFINED
#define GrGLCustomStage_DEFINED

#include "GrAllocator.h"
#include "GrCustomStage.h"
#include "GrGLProgram.h"
#include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
#include "GrStringBuilder.h"

struct GrGLInterface;
class GrGLTexture;

/** @file
    This file contains specializations for OpenGL of the shader stages
    declared in src/gpu/GrCustomStage.h. All the functions emit
    GLSL shader code and OpenGL calls.

    These objects are created by a factory function on the
    GrCustomStage.
    TODO: lifetime management.
*/

class GrGLProgramStage {

public:
    typedef GrCustomStage::StageKey StageKey ;
    // TODO: redundant with GrGLProgram.cpp
    enum {
        kUnusedUniform = -1,
        kUseUniform = 2000
    };

    GrGLProgramStage(const GrProgramStageFactory&);

    virtual ~GrGLProgramStage();

    /** Creates any uniform variables the vertex shader requires
        and appends them to vsUnis;
        must guarantee they are unique (typically done by
        appending the stage number). */
    virtual void setupVSUnis(VarArray* vsUnis, int stage);

    /** Creates any uniform variables the fragment shader requires
        and appends them to fsUnis;
        must guarantee they are unique (typically done by
        appending the stage number). */
    virtual void setupFSUnis(VarArray* fsUnis, int stage);

    /** Creates any varying variables shared between the shaders;
        must guarantee they are unique (typically done by
        appending the stage number). */
    virtual void setupVaryings(GrGLShaderBuilder* state, int stage);

    /** Appends vertex code to the appropriate GrStringBuilder
        on the state.
        The code will be inside an otherwise-empty block.
        Vertex shader input is a vec2 of coordinates, which may
        be altered.
        The code will be inside an otherwise-empty block. */
    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) = 0;

    /** Appends fragment code to the appropriate GrStringBuilder
        on the state.
        The code will be inside an otherwise-empty block.
        Fragment shader inputs are a vec2 of coordinates, one texture,
        and a color; output is a color. */
    /* TODO: don't give them the samplerName, just a handle; then give
       a function here for them to call into that'll apply any texture
       domain - but do we force them to be honest about texture domain
       parameters? */
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) = 0;

    /** Binds uniforms; we must have already bound the program and
        determined its GL program ID. */
    virtual void initUniforms(const GrGLInterface* gl, int programID);

    /** A GrGLCustomStage instance can be reused with any GrCustomStage
        that produces the same stage key; this function reads data from
        a stage and uploads any uniform variables required by the shaders
        created in emit*(). */
    virtual void setData(const GrGLInterface* gl,
                         const GrGLTexture& texture,
                         GrCustomStage* stage,
                         int stageNum);

    // TODO: needs a better name
    enum SamplerMode {
        kDefault_SamplerMode,
        kProj_SamplerMode,
        kExplicitDivide_SamplerMode  // must do an explicit divide
    };

    void setSamplerMode(SamplerMode samplerMode) { fSamplerMode = samplerMode; }

    /** Does perspective divide or other necessary transform, then
        updates the name of the sample coordinates. */
    void emitTextureSetup(GrGLShaderBuilder* segments);

     /** Human-meaningful string to identify this effect; may be embedded
         in generated shader code. Because the implementation is delegated to
         the factory, the name will be the same as that of the generating
         GrCustomStage. */
    const char* name() const { return fFactory.name(); }

protected:

    /** Convenience function for subclasses to write texture2D() or
        texture2DProj(), depending on fSamplerMode. */
    void emitTextureLookup(GrStringBuilder* code,
                           const char* samplerName,
                           const char* coordName);

    /** Standard texture fetch, complete with swizzle & modulate if
        appropriate. */
    void emitDefaultFetch(GrGLShaderBuilder* state,
                          const char* fsOutColor,
                          const char* samplerName,
                          const char* swizzle,
                          const char* modulate);

    SamplerMode fSamplerMode;

    const GrProgramStageFactory& fFactory;
};

#endif