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