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 
20 #include <string>
21 #include <vector>
22 
23 namespace android {
24 namespace renderscript {
25 
26 class Context;
27 
28 } // namespace renderscript
29 } // namespace android
30 
31 class RsdShader;
32 
33 // ---------------------------------------------------------------------------
34 
35 // An element is a group of Components that occupies one cell in a structure.
36 class RsdShaderCache {
37 public:
38     RsdShaderCache();
39     virtual ~RsdShaderCache();
40 
setActiveVertex(RsdShader * pv)41     void setActiveVertex(RsdShader *pv) {
42         mVertexDirty = true;
43         mVertex = pv;
44     }
45 
setActiveFragment(RsdShader * pf)46     void setActiveFragment(RsdShader *pf) {
47         mFragmentDirty = true;
48         mFragment = pf;
49     }
50 
51     bool setup(const android::renderscript::Context *rsc);
52 
53     void cleanupVertex(RsdShader *s);
54     void cleanupFragment(RsdShader *s);
55 
56     void cleanupAll();
57 
58     int32_t vtxAttribSlot(const std::string &attrName) const;
vtxUniformSlot(uint32_t a)59     int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->vtxUniforms[a].slot;}
vtxUniformSize(uint32_t a)60     uint32_t vtxUniformSize(uint32_t a) const {return mCurrent->vtxUniforms[a].arraySize;}
fragUniformSlot(uint32_t a)61     int32_t fragUniformSlot(uint32_t a) const {return mCurrent->fragUniforms[a].slot;}
fragUniformSize(uint32_t a)62     uint32_t fragUniformSize(uint32_t a) const {return mCurrent->fragUniforms[a].arraySize;}
63 
64 protected:
65     bool link(const android::renderscript::Context *rsc);
66     bool mFragmentDirty;
67     bool mVertexDirty;
68     RsdShader *mVertex;
69     RsdShader *mFragment;
70 
71     struct UniformQueryData {
72         char *name;
73         uint32_t nameLength;
74         int32_t writtenLength;
75         int32_t arraySize;
76         uint32_t type;
UniformQueryDataUniformQueryData77         explicit UniformQueryData(uint32_t maxName) {
78             name = nullptr;
79             nameLength = maxName;
80             if (nameLength > 0 ) {
81                 name = new char[nameLength];
82             }
83         }
~UniformQueryDataUniformQueryData84         ~UniformQueryData() {
85             if (name != nullptr) {
86                 delete[] name;
87                 name = nullptr;
88             }
89         }
90     };
91     struct UniformData {
92         int32_t slot;
93         uint32_t arraySize;
94     };
95     struct AttrData {
96         int32_t slot;
97         const char* name;
98     };
99     struct ProgramEntry {
ProgramEntryProgramEntry100         ProgramEntry(uint32_t numVtxAttr, uint32_t numVtxUnis,
101                      uint32_t numFragUnis) : vtx(0), frag(0), program(0), vtxAttrCount(0),
102                                              vtxAttrs(0), vtxUniforms(0), fragUniforms(0),
103                                              fragUniformIsSTO(0) {
104             vtxAttrCount = numVtxAttr;
105             if (numVtxAttr) {
106                 vtxAttrs = new AttrData[numVtxAttr];
107             }
108             if (numVtxUnis) {
109                 vtxUniforms = new UniformData[numVtxUnis];
110             }
111             if (numFragUnis) {
112                 fragUniforms = new UniformData[numFragUnis];
113                 fragUniformIsSTO = new bool[numFragUnis];
114             }
115         }
~ProgramEntryProgramEntry116         ~ProgramEntry() {
117             if (vtxAttrs) {
118                 delete[] vtxAttrs;
119                 vtxAttrs = nullptr;
120             }
121             if (vtxUniforms) {
122                 delete[] vtxUniforms;
123                 vtxUniforms = nullptr;
124             }
125             if (fragUniforms) {
126                 delete[] fragUniforms;
127                 fragUniforms = nullptr;
128             }
129             if (fragUniformIsSTO) {
130                 delete[] fragUniformIsSTO;
131                 fragUniformIsSTO = nullptr;
132             }
133         }
134         uint32_t vtx;
135         uint32_t frag;
136         uint32_t program;
137         uint32_t vtxAttrCount;
138         AttrData *vtxAttrs;
139         UniformData *vtxUniforms;
140         UniformData *fragUniforms;
141         bool *fragUniformIsSTO;
142     };
143     std::vector<ProgramEntry*> mEntries;
144     ProgramEntry *mCurrent;
145 
146     bool hasArrayUniforms(RsdShader *vtx, RsdShader *frag);
147     void populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data);
148     void updateUniformArrayData(const android::renderscript::Context *rsc,
149                                 RsdShader *prog, uint32_t linkedID,
150                                 UniformData *data, const char* logTag,
151                                 UniformQueryData **uniformList, uint32_t uniListSize);
152 };
153 
154 
155 #endif //ANDROID_RSD_SHADER_CACHE_H
156 
157 
158 
159 
160