1/*
2 * Copyright (C) 2011-2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_RSD_SHADER_CACHE_H
18#define ANDROID_RSD_SHADER_CACHE_H
19
20namespace android {
21namespace renderscript {
22
23class Context;
24
25}
26}
27
28#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
29#include <utils/String8.h>
30#include <utils/Vector.h>
31#else
32#include "rsUtils.h"
33#endif
34class RsdShader;
35
36// ---------------------------------------------------------------------------
37
38// An element is a group of Components that occupies one cell in a structure.
39class RsdShaderCache {
40public:
41    RsdShaderCache();
42    virtual ~RsdShaderCache();
43
44    void setActiveVertex(RsdShader *pv) {
45        mVertexDirty = true;
46        mVertex = pv;
47    }
48
49    void setActiveFragment(RsdShader *pf) {
50        mFragmentDirty = true;
51        mFragment = pf;
52    }
53
54    bool setup(const android::renderscript::Context *rsc);
55
56    void cleanupVertex(RsdShader *s);
57    void cleanupFragment(RsdShader *s);
58
59    void cleanupAll();
60
61    int32_t vtxAttribSlot(const android::String8 &attrName) const;
62    int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->vtxUniforms[a].slot;}
63    uint32_t vtxUniformSize(uint32_t a) const {return mCurrent->vtxUniforms[a].arraySize;}
64    int32_t fragUniformSlot(uint32_t a) const {return mCurrent->fragUniforms[a].slot;}
65    uint32_t fragUniformSize(uint32_t a) const {return mCurrent->fragUniforms[a].arraySize;}
66
67protected:
68    bool link(const android::renderscript::Context *rsc);
69    bool mFragmentDirty;
70    bool mVertexDirty;
71    RsdShader *mVertex;
72    RsdShader *mFragment;
73
74    struct UniformQueryData {
75        char *name;
76        uint32_t nameLength;
77        int32_t writtenLength;
78        int32_t arraySize;
79        uint32_t type;
80        UniformQueryData(uint32_t maxName) {
81            name = NULL;
82            nameLength = maxName;
83            if (nameLength > 0 ) {
84                name = new char[nameLength];
85            }
86        }
87        ~UniformQueryData() {
88            if (name != NULL) {
89                delete[] name;
90                name = NULL;
91            }
92        }
93    };
94    struct UniformData {
95        int32_t slot;
96        uint32_t arraySize;
97    };
98    struct AttrData {
99        int32_t slot;
100        const char* name;
101    };
102    struct ProgramEntry {
103        ProgramEntry(uint32_t numVtxAttr, uint32_t numVtxUnis,
104                     uint32_t numFragUnis) : vtx(0), frag(0), program(0), vtxAttrCount(0),
105                                             vtxAttrs(0), vtxUniforms(0), fragUniforms(0),
106                                             fragUniformIsSTO(0) {
107            vtxAttrCount = numVtxAttr;
108            if (numVtxAttr) {
109                vtxAttrs = new AttrData[numVtxAttr];
110            }
111            if (numVtxUnis) {
112                vtxUniforms = new UniformData[numVtxUnis];
113            }
114            if (numFragUnis) {
115                fragUniforms = new UniformData[numFragUnis];
116                fragUniformIsSTO = new bool[numFragUnis];
117            }
118        }
119        ~ProgramEntry() {
120            if (vtxAttrs) {
121                delete[] vtxAttrs;
122                vtxAttrs = NULL;
123            }
124            if (vtxUniforms) {
125                delete[] vtxUniforms;
126                vtxUniforms = NULL;
127            }
128            if (fragUniforms) {
129                delete[] fragUniforms;
130                fragUniforms = NULL;
131            }
132            if (fragUniformIsSTO) {
133                delete[] fragUniformIsSTO;
134                fragUniformIsSTO = NULL;
135            }
136        }
137        uint32_t vtx;
138        uint32_t frag;
139        uint32_t program;
140        uint32_t vtxAttrCount;
141        AttrData *vtxAttrs;
142        UniformData *vtxUniforms;
143        UniformData *fragUniforms;
144        bool *fragUniformIsSTO;
145    };
146    android::Vector<ProgramEntry*> mEntries;
147    ProgramEntry *mCurrent;
148
149    bool hasArrayUniforms(RsdShader *vtx, RsdShader *frag);
150    void populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data);
151    void updateUniformArrayData(const android::renderscript::Context *rsc,
152                                RsdShader *prog, uint32_t linkedID,
153                                UniformData *data, const char* logTag,
154                                UniformQueryData **uniformList, uint32_t uniListSize);
155};
156
157
158#endif //ANDROID_RSD_SHADER_CACHE_H
159
160
161
162
163