1dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com/*
2dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com * Copyright 2012 Google Inc.
3dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com *
4dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com * found in the LICENSE file.
6dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com */
7dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
8dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#ifndef GrGLUniformManager_DEFINED
9dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#define GrGLUniformManager_DEFINED
10dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
11dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLShaderVar.h"
12dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLSL.h"
13777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com#include "GrAllocator.h"
14dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
15dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "SkTArray.h"
16dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
179188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.orgclass GrGpuGL;
18d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.comclass SkMatrix;
19dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
20dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com/** Manages a program's uniforms.
21dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com*/
226eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.orgclass GrGLUniformManager : public SkRefCnt {
23dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.compublic:
24dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    // Opaque handle to a uniform
257425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    class UniformHandle {
267425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    public:
277425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        static UniformHandle CreateFromUniformIndex(int i);
287425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
297425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        bool isValid() const { return 0 != fValue; }
307425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
317425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
327425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
337425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        UniformHandle()
347425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org            : fValue(0) {
357425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        }
367425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
377425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    private:
387425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        UniformHandle(int value)
397425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org            : fValue(~value) {
40f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(isValid());
417425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        }
427425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
43f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        int toUniformIndex() const { SkASSERT(isValid()); return ~fValue; }
447425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
457425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        int fValue;
467425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        friend class GrGLUniformManager; // For accessing toUniformIndex().
477425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    };
48dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
49d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    GrGLUniformManager(GrGpuGL* gpu);
50dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
51dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    UniformHandle appendUniform(GrSLType type, int arrayCount = GrGLShaderVar::kNonArray);
52dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
53dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
54d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org     *  array of uniforms. arrayCount must be <= the array count of the uniform.
55dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     */
56dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void setSampler(UniformHandle, GrGLint texUnit) const;
57dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void set1f(UniformHandle, GrGLfloat v0) const;
58d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void set1fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
59dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void set2f(UniformHandle, GrGLfloat, GrGLfloat) const;
60d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void set2fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
61dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const;
62d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void set3fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
63dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const;
64d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void set4fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
65dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    // matrices are column-major, the first three upload a single matrix, the latter three upload
66dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    // arrayCount matrices into a uniform array.
67dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const;
68dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const;
69d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void setMatrix3fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
70d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    void setMatrix4fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
71dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
72d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    // convenience method for uploading a SkMatrix to a 3x3 matrix uniform
73d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    void setSkMatrix(UniformHandle, const SkMatrix&) const;
74d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com
75dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    struct BuilderUniform {
76dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        GrGLShaderVar fVariable;
77dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        uint32_t      fVisibility;
78dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    };
79777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
80777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
81777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    // name strings. Otherwise, we'd have to hand out copies.
82777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    typedef GrTAllocator<BuilderUniform> BuilderUniformArray;
83dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
84dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    /**
85d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org     * Called by the GrGLShaderBuilder to know if the manager is using
86d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org     * BindUniformLocation. In that case getUniformLocations must be called
87d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org     * before the program is linked.
88d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org     */
89d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    bool isUsingBindUniform() const { return fUsingBindUniform; }
90d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org
91d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    /**
92dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     * Called by the GrGLShaderBuilder to get GL locations for all uniforms.
93dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     */
94dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms);
95dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
967425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    /**
977425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org     * Called by the GrGLShaderBuilder to access the array by the handle (index).
987425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org     */
997425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    const BuilderUniform& getBuilderUniform(const BuilderUniformArray&, GrGLUniformManager::UniformHandle) const;
1007425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org
101dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.comprivate:
102dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    enum {
103dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        kUnusedUniform = -1,
104dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    };
105dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
106dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    struct Uniform {
107dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        GrGLint     fVSLocation;
108dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        GrGLint     fFSLocation;
109dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        GrSLType    fType;
110dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        int         fArrayCount;
111dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    };
112dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
113d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org    bool fUsingBindUniform;
114dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    SkTArray<Uniform, true> fUniforms;
1159188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org    GrGpuGL* fGpu;
1166eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
1176eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    typedef SkRefCnt INHERITED;
118dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com};
119dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
120dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#endif
121