1/*
2 * Copyright 2012 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 GrGLUniformManager_DEFINED
9#define GrGLUniformManager_DEFINED
10
11#include "gl/GrGLShaderVar.h"
12#include "gl/GrGLSL.h"
13#include "GrAllocator.h"
14
15#include "SkTArray.h"
16
17class GrGLContext;
18class SkMatrix;
19
20/** Manages a program's uniforms.
21*/
22class GrGLUniformManager {
23public:
24    // Opaque handle to a uniform
25    typedef int UniformHandle;
26    static const UniformHandle kInvalidUniformHandle = 0;
27
28    GrGLUniformManager(const GrGLContext& context) : fContext(context) {}
29
30    UniformHandle appendUniform(GrSLType type, int arrayCount = GrGLShaderVar::kNonArray);
31
32    /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
33     *  array of uniforms. offset + arrayCount must be <= the array count of the uniform.
34     */
35    void setSampler(UniformHandle, GrGLint texUnit) const;
36    void set1f(UniformHandle, GrGLfloat v0) const;
37    void set1fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const;
38    void set2f(UniformHandle, GrGLfloat, GrGLfloat) const;
39    void set2fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const;
40    void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const;
41    void set3fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const;
42    void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const;
43    void set4fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const;
44    // matrices are column-major, the first three upload a single matrix, the latter three upload
45    // arrayCount matrices into a uniform array.
46    void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const;
47    void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const;
48    void setMatrix3fv(UniformHandle, int offset, int arrayCount, const GrGLfloat matrices[]) const;
49    void setMatrix4fv(UniformHandle, int offset, int arrayCount, const GrGLfloat matrices[]) const;
50
51    // convenience method for uploading a SkMatrix to a 3x3 matrix uniform
52    void setSkMatrix(UniformHandle, const SkMatrix&) const;
53
54    struct BuilderUniform {
55        GrGLShaderVar fVariable;
56        uint32_t      fVisibility;
57    };
58    // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
59    // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
60    // name strings. Otherwise, we'd have to hand out copies.
61    typedef GrTAllocator<BuilderUniform> BuilderUniformArray;
62
63    /**
64     * Called by the GrGLShaderBuilder to get GL locations for all uniforms.
65     */
66    void getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms);
67
68private:
69    enum {
70        kUnusedUniform = -1,
71    };
72
73    struct Uniform {
74        GrGLint     fVSLocation;
75        GrGLint     fFSLocation;
76        GrSLType    fType;
77        int         fArrayCount;
78    };
79
80    SkTArray<Uniform, true> fUniforms;
81    const GrGLContext&  fContext;
82};
83
84#endif
85