xref: /aosp_15_r20/frameworks/rs/driver/rsdShaderCache.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2011-2012 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #include <rs_hal.h>
18*e1eccf28SAndroid Build Coastguard Worker #include <rsContext.h>
19*e1eccf28SAndroid Build Coastguard Worker 
20*e1eccf28SAndroid Build Coastguard Worker #include "rsdShader.h"
21*e1eccf28SAndroid Build Coastguard Worker #include "rsdShaderCache.h"
22*e1eccf28SAndroid Build Coastguard Worker #include "rsdGL.h"
23*e1eccf28SAndroid Build Coastguard Worker 
24*e1eccf28SAndroid Build Coastguard Worker #include <GLES/gl.h>
25*e1eccf28SAndroid Build Coastguard Worker #include <GLES2/gl2.h>
26*e1eccf28SAndroid Build Coastguard Worker 
27*e1eccf28SAndroid Build Coastguard Worker using android::renderscript::Context;
28*e1eccf28SAndroid Build Coastguard Worker 
RsdShaderCache()29*e1eccf28SAndroid Build Coastguard Worker RsdShaderCache::RsdShaderCache() {
30*e1eccf28SAndroid Build Coastguard Worker     mVertexDirty = true;
31*e1eccf28SAndroid Build Coastguard Worker     mFragmentDirty = true;
32*e1eccf28SAndroid Build Coastguard Worker }
33*e1eccf28SAndroid Build Coastguard Worker 
~RsdShaderCache()34*e1eccf28SAndroid Build Coastguard Worker RsdShaderCache::~RsdShaderCache() {
35*e1eccf28SAndroid Build Coastguard Worker     cleanupAll();
36*e1eccf28SAndroid Build Coastguard Worker }
37*e1eccf28SAndroid Build Coastguard Worker 
updateUniformArrayData(const Context * rsc,RsdShader * prog,uint32_t linkedID,UniformData * data,const char * logTag,UniformQueryData ** uniformList,uint32_t uniListSize)38*e1eccf28SAndroid Build Coastguard Worker void RsdShaderCache::updateUniformArrayData(const Context *rsc,
39*e1eccf28SAndroid Build Coastguard Worker                                             RsdShader *prog,
40*e1eccf28SAndroid Build Coastguard Worker                                             uint32_t linkedID,
41*e1eccf28SAndroid Build Coastguard Worker                                             UniformData *data,
42*e1eccf28SAndroid Build Coastguard Worker                                             const char* logTag,
43*e1eccf28SAndroid Build Coastguard Worker                                             UniformQueryData **uniformList,
44*e1eccf28SAndroid Build Coastguard Worker                                             uint32_t uniListSize) {
45*e1eccf28SAndroid Build Coastguard Worker 
46*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < prog->getUniformCount(); ct++) {
47*e1eccf28SAndroid Build Coastguard Worker         if (data[ct].slot >= 0 && data[ct].arraySize > 1) {
48*e1eccf28SAndroid Build Coastguard Worker             //Iterate over the list of active GL uniforms and find highest array index
49*e1eccf28SAndroid Build Coastguard Worker             for (uint32_t ui = 0; ui < uniListSize; ui ++) {
50*e1eccf28SAndroid Build Coastguard Worker                 if (prog->getUniformName(ct) == uniformList[ui]->name) {
51*e1eccf28SAndroid Build Coastguard Worker                     data[ct].arraySize = (uint32_t)uniformList[ui]->arraySize;
52*e1eccf28SAndroid Build Coastguard Worker                     break;
53*e1eccf28SAndroid Build Coastguard Worker                 }
54*e1eccf28SAndroid Build Coastguard Worker             }
55*e1eccf28SAndroid Build Coastguard Worker         }
56*e1eccf28SAndroid Build Coastguard Worker 
57*e1eccf28SAndroid Build Coastguard Worker         if (rsc->props.mLogShaders) {
58*e1eccf28SAndroid Build Coastguard Worker              ALOGV("%s U, %s = %d, arraySize = %d\n", logTag,
59*e1eccf28SAndroid Build Coastguard Worker                    prog->getUniformName(ct).c_str(), data[ct].slot,
60*e1eccf28SAndroid Build Coastguard Worker                    data[ct].arraySize);
61*e1eccf28SAndroid Build Coastguard Worker         }
62*e1eccf28SAndroid Build Coastguard Worker     }
63*e1eccf28SAndroid Build Coastguard Worker }
64*e1eccf28SAndroid Build Coastguard Worker 
populateUniformData(RsdShader * prog,uint32_t linkedID,UniformData * data)65*e1eccf28SAndroid Build Coastguard Worker void RsdShaderCache::populateUniformData(RsdShader *prog, uint32_t linkedID,
66*e1eccf28SAndroid Build Coastguard Worker                                          UniformData *data) {
67*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < prog->getUniformCount(); ct++) {
68*e1eccf28SAndroid Build Coastguard Worker        data[ct].slot = glGetUniformLocation(linkedID,
69*e1eccf28SAndroid Build Coastguard Worker                                             prog->getUniformName(ct).c_str());
70*e1eccf28SAndroid Build Coastguard Worker        data[ct].arraySize = prog->getUniformArraySize(ct);
71*e1eccf28SAndroid Build Coastguard Worker     }
72*e1eccf28SAndroid Build Coastguard Worker }
73*e1eccf28SAndroid Build Coastguard Worker 
hasArrayUniforms(RsdShader * vtx,RsdShader * frag)74*e1eccf28SAndroid Build Coastguard Worker bool RsdShaderCache::hasArrayUniforms(RsdShader *vtx, RsdShader *frag) {
75*e1eccf28SAndroid Build Coastguard Worker     UniformData *data = mCurrent->vtxUniforms;
76*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
77*e1eccf28SAndroid Build Coastguard Worker         if (data[ct].slot >= 0 && data[ct].arraySize > 1) {
78*e1eccf28SAndroid Build Coastguard Worker             return true;
79*e1eccf28SAndroid Build Coastguard Worker         }
80*e1eccf28SAndroid Build Coastguard Worker     }
81*e1eccf28SAndroid Build Coastguard Worker     data = mCurrent->fragUniforms;
82*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < frag->getUniformCount(); ct++) {
83*e1eccf28SAndroid Build Coastguard Worker         if (data[ct].slot >= 0 && data[ct].arraySize > 1) {
84*e1eccf28SAndroid Build Coastguard Worker             return true;
85*e1eccf28SAndroid Build Coastguard Worker         }
86*e1eccf28SAndroid Build Coastguard Worker     }
87*e1eccf28SAndroid Build Coastguard Worker     return false;
88*e1eccf28SAndroid Build Coastguard Worker }
89*e1eccf28SAndroid Build Coastguard Worker 
setup(const Context * rsc)90*e1eccf28SAndroid Build Coastguard Worker bool RsdShaderCache::setup(const Context *rsc) {
91*e1eccf28SAndroid Build Coastguard Worker     if (!mVertexDirty && !mFragmentDirty) {
92*e1eccf28SAndroid Build Coastguard Worker         return true;
93*e1eccf28SAndroid Build Coastguard Worker     }
94*e1eccf28SAndroid Build Coastguard Worker 
95*e1eccf28SAndroid Build Coastguard Worker     if (!link(rsc)) {
96*e1eccf28SAndroid Build Coastguard Worker         return false;
97*e1eccf28SAndroid Build Coastguard Worker     }
98*e1eccf28SAndroid Build Coastguard Worker 
99*e1eccf28SAndroid Build Coastguard Worker     if (mFragmentDirty) {
100*e1eccf28SAndroid Build Coastguard Worker         mFragment->setup(rsc, this);
101*e1eccf28SAndroid Build Coastguard Worker         mFragmentDirty = false;
102*e1eccf28SAndroid Build Coastguard Worker     }
103*e1eccf28SAndroid Build Coastguard Worker     if (mVertexDirty) {
104*e1eccf28SAndroid Build Coastguard Worker         mVertex->setup(rsc, this);
105*e1eccf28SAndroid Build Coastguard Worker         mVertexDirty = false;
106*e1eccf28SAndroid Build Coastguard Worker     }
107*e1eccf28SAndroid Build Coastguard Worker 
108*e1eccf28SAndroid Build Coastguard Worker     return true;
109*e1eccf28SAndroid Build Coastguard Worker }
110*e1eccf28SAndroid Build Coastguard Worker 
link(const Context * rsc)111*e1eccf28SAndroid Build Coastguard Worker bool RsdShaderCache::link(const Context *rsc) {
112*e1eccf28SAndroid Build Coastguard Worker 
113*e1eccf28SAndroid Build Coastguard Worker     RsdShader *vtx = mVertex;
114*e1eccf28SAndroid Build Coastguard Worker     RsdShader *frag = mFragment;
115*e1eccf28SAndroid Build Coastguard Worker 
116*e1eccf28SAndroid Build Coastguard Worker     uint32_t vID = vtx->getStateBasedShaderID(rsc);
117*e1eccf28SAndroid Build Coastguard Worker     uint32_t fID = frag->getStateBasedShaderID(rsc);
118*e1eccf28SAndroid Build Coastguard Worker 
119*e1eccf28SAndroid Build Coastguard Worker     // Don't try to cache if shaders failed to load
120*e1eccf28SAndroid Build Coastguard Worker     if (!vID || !fID) {
121*e1eccf28SAndroid Build Coastguard Worker         return false;
122*e1eccf28SAndroid Build Coastguard Worker     }
123*e1eccf28SAndroid Build Coastguard Worker     uint32_t entryCount = mEntries.size();
124*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < entryCount; ct ++) {
125*e1eccf28SAndroid Build Coastguard Worker         if ((mEntries[ct]->vtx == vID) && (mEntries[ct]->frag == fID)) {
126*e1eccf28SAndroid Build Coastguard Worker             //ALOGV("SC using program %i", mEntries[ct]->program);
127*e1eccf28SAndroid Build Coastguard Worker             glUseProgram(mEntries[ct]->program);
128*e1eccf28SAndroid Build Coastguard Worker             mCurrent = mEntries[ct];
129*e1eccf28SAndroid Build Coastguard Worker             //ALOGV("RsdShaderCache hit, using %i", ct);
130*e1eccf28SAndroid Build Coastguard Worker             rsdGLCheckError(rsc, "RsdShaderCache::link (hit)");
131*e1eccf28SAndroid Build Coastguard Worker             return true;
132*e1eccf28SAndroid Build Coastguard Worker         }
133*e1eccf28SAndroid Build Coastguard Worker     }
134*e1eccf28SAndroid Build Coastguard Worker 
135*e1eccf28SAndroid Build Coastguard Worker     ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
136*e1eccf28SAndroid Build Coastguard Worker                                        vtx->getUniformCount(),
137*e1eccf28SAndroid Build Coastguard Worker                                        frag->getUniformCount());
138*e1eccf28SAndroid Build Coastguard Worker     mEntries.push_back(e);
139*e1eccf28SAndroid Build Coastguard Worker     mCurrent = e;
140*e1eccf28SAndroid Build Coastguard Worker     e->vtx = vID;
141*e1eccf28SAndroid Build Coastguard Worker     e->frag = fID;
142*e1eccf28SAndroid Build Coastguard Worker     e->program = glCreateProgram();
143*e1eccf28SAndroid Build Coastguard Worker     if (e->program) {
144*e1eccf28SAndroid Build Coastguard Worker         GLuint pgm = e->program;
145*e1eccf28SAndroid Build Coastguard Worker         glAttachShader(pgm, vID);
146*e1eccf28SAndroid Build Coastguard Worker         //ALOGE("e1 %x", glGetError());
147*e1eccf28SAndroid Build Coastguard Worker         glAttachShader(pgm, fID);
148*e1eccf28SAndroid Build Coastguard Worker 
149*e1eccf28SAndroid Build Coastguard Worker         glBindAttribLocation(pgm, 0, "ATTRIB_position");
150*e1eccf28SAndroid Build Coastguard Worker         glBindAttribLocation(pgm, 1, "ATTRIB_color");
151*e1eccf28SAndroid Build Coastguard Worker         glBindAttribLocation(pgm, 2, "ATTRIB_normal");
152*e1eccf28SAndroid Build Coastguard Worker         glBindAttribLocation(pgm, 3, "ATTRIB_texture0");
153*e1eccf28SAndroid Build Coastguard Worker 
154*e1eccf28SAndroid Build Coastguard Worker         //ALOGE("e2 %x", glGetError());
155*e1eccf28SAndroid Build Coastguard Worker         glLinkProgram(pgm);
156*e1eccf28SAndroid Build Coastguard Worker         //ALOGE("e3 %x", glGetError());
157*e1eccf28SAndroid Build Coastguard Worker         GLint linkStatus = GL_FALSE;
158*e1eccf28SAndroid Build Coastguard Worker         glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus);
159*e1eccf28SAndroid Build Coastguard Worker         if (linkStatus != GL_TRUE) {
160*e1eccf28SAndroid Build Coastguard Worker             GLint bufLength = 0;
161*e1eccf28SAndroid Build Coastguard Worker             glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength);
162*e1eccf28SAndroid Build Coastguard Worker             if (bufLength) {
163*e1eccf28SAndroid Build Coastguard Worker                 char* buf = (char*) malloc(bufLength);
164*e1eccf28SAndroid Build Coastguard Worker                 if (buf) {
165*e1eccf28SAndroid Build Coastguard Worker                     glGetProgramInfoLog(pgm, bufLength, nullptr, buf);
166*e1eccf28SAndroid Build Coastguard Worker                     rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
167*e1eccf28SAndroid Build Coastguard Worker                     free(buf);
168*e1eccf28SAndroid Build Coastguard Worker                 }
169*e1eccf28SAndroid Build Coastguard Worker             }
170*e1eccf28SAndroid Build Coastguard Worker             glDeleteProgram(pgm);
171*e1eccf28SAndroid Build Coastguard Worker             return false;
172*e1eccf28SAndroid Build Coastguard Worker         }
173*e1eccf28SAndroid Build Coastguard Worker 
174*e1eccf28SAndroid Build Coastguard Worker         for (uint32_t ct=0; ct < e->vtxAttrCount; ct++) {
175*e1eccf28SAndroid Build Coastguard Worker             e->vtxAttrs[ct].slot =
176*e1eccf28SAndroid Build Coastguard Worker                 glGetAttribLocation(pgm, vtx->getAttribName(ct).c_str());
177*e1eccf28SAndroid Build Coastguard Worker             e->vtxAttrs[ct].name = vtx->getAttribName(ct).c_str();
178*e1eccf28SAndroid Build Coastguard Worker             if (rsc->props.mLogShaders) {
179*e1eccf28SAndroid Build Coastguard Worker                 ALOGV("vtx A %i, %s = %d\n", ct,
180*e1eccf28SAndroid Build Coastguard Worker                       vtx->getAttribName(ct).c_str(), e->vtxAttrs[ct].slot);
181*e1eccf28SAndroid Build Coastguard Worker             }
182*e1eccf28SAndroid Build Coastguard Worker         }
183*e1eccf28SAndroid Build Coastguard Worker 
184*e1eccf28SAndroid Build Coastguard Worker         populateUniformData(vtx, pgm, e->vtxUniforms);
185*e1eccf28SAndroid Build Coastguard Worker         populateUniformData(frag, pgm, e->fragUniforms);
186*e1eccf28SAndroid Build Coastguard Worker 
187*e1eccf28SAndroid Build Coastguard Worker         // Only populate this list if we have arrays in our uniforms
188*e1eccf28SAndroid Build Coastguard Worker         UniformQueryData **uniformList = nullptr;
189*e1eccf28SAndroid Build Coastguard Worker         GLint numUniforms = 0;
190*e1eccf28SAndroid Build Coastguard Worker         bool hasArrays = hasArrayUniforms(vtx, frag);
191*e1eccf28SAndroid Build Coastguard Worker         if (hasArrays) {
192*e1eccf28SAndroid Build Coastguard Worker             // Get the number of active uniforms and the length of the longest name
193*e1eccf28SAndroid Build Coastguard Worker             glGetProgramiv(pgm, GL_ACTIVE_UNIFORMS, &numUniforms);
194*e1eccf28SAndroid Build Coastguard Worker             GLint maxNameLength = 0;
195*e1eccf28SAndroid Build Coastguard Worker             glGetProgramiv(pgm, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
196*e1eccf28SAndroid Build Coastguard Worker             if (numUniforms > 0 && maxNameLength > 0) {
197*e1eccf28SAndroid Build Coastguard Worker                 uniformList = new UniformQueryData*[numUniforms];
198*e1eccf28SAndroid Build Coastguard Worker                 // Iterate over all the uniforms and build the list we
199*e1eccf28SAndroid Build Coastguard Worker                 // can later use to match our uniforms to
200*e1eccf28SAndroid Build Coastguard Worker                 for (uint32_t ct = 0; ct < (uint32_t)numUniforms; ct++) {
201*e1eccf28SAndroid Build Coastguard Worker                     uniformList[ct] = new UniformQueryData(maxNameLength);
202*e1eccf28SAndroid Build Coastguard Worker                     glGetActiveUniform(pgm, ct, maxNameLength, &uniformList[ct]->writtenLength,
203*e1eccf28SAndroid Build Coastguard Worker                                        &uniformList[ct]->arraySize, &uniformList[ct]->type,
204*e1eccf28SAndroid Build Coastguard Worker                                        uniformList[ct]->name);
205*e1eccf28SAndroid Build Coastguard Worker                     //ALOGE("GL UNI idx=%u, arraySize=%u, name=%s", ct,
206*e1eccf28SAndroid Build Coastguard Worker                     //     uniformList[ct]->arraySize, uniformList[ct]->name);
207*e1eccf28SAndroid Build Coastguard Worker                 }
208*e1eccf28SAndroid Build Coastguard Worker             }
209*e1eccf28SAndroid Build Coastguard Worker         }
210*e1eccf28SAndroid Build Coastguard Worker 
211*e1eccf28SAndroid Build Coastguard Worker         // We now know the highest index of all of the array uniforms
212*e1eccf28SAndroid Build Coastguard Worker         // and we need to update our cache to reflect that
213*e1eccf28SAndroid Build Coastguard Worker         // we may have declared [n], but only m < n elements are used
214*e1eccf28SAndroid Build Coastguard Worker         updateUniformArrayData(rsc, vtx, pgm, e->vtxUniforms, "vtx",
215*e1eccf28SAndroid Build Coastguard Worker                                uniformList, (uint32_t)numUniforms);
216*e1eccf28SAndroid Build Coastguard Worker         updateUniformArrayData(rsc, frag, pgm, e->fragUniforms, "frag",
217*e1eccf28SAndroid Build Coastguard Worker                                uniformList, (uint32_t)numUniforms);
218*e1eccf28SAndroid Build Coastguard Worker 
219*e1eccf28SAndroid Build Coastguard Worker         // Clean up the uniform data from GL
220*e1eccf28SAndroid Build Coastguard Worker         if (uniformList != nullptr) {
221*e1eccf28SAndroid Build Coastguard Worker             for (uint32_t ct = 0; ct < (uint32_t)numUniforms; ct++) {
222*e1eccf28SAndroid Build Coastguard Worker                 delete uniformList[ct];
223*e1eccf28SAndroid Build Coastguard Worker             }
224*e1eccf28SAndroid Build Coastguard Worker             delete[] uniformList;
225*e1eccf28SAndroid Build Coastguard Worker             uniformList = nullptr;
226*e1eccf28SAndroid Build Coastguard Worker         }
227*e1eccf28SAndroid Build Coastguard Worker     }
228*e1eccf28SAndroid Build Coastguard Worker 
229*e1eccf28SAndroid Build Coastguard Worker     //ALOGV("SC made program %i", e->program);
230*e1eccf28SAndroid Build Coastguard Worker     glUseProgram(e->program);
231*e1eccf28SAndroid Build Coastguard Worker     rsdGLCheckError(rsc, "RsdShaderCache::link (miss)");
232*e1eccf28SAndroid Build Coastguard Worker 
233*e1eccf28SAndroid Build Coastguard Worker     return true;
234*e1eccf28SAndroid Build Coastguard Worker }
235*e1eccf28SAndroid Build Coastguard Worker 
vtxAttribSlot(const std::string & attrName) const236*e1eccf28SAndroid Build Coastguard Worker int32_t RsdShaderCache::vtxAttribSlot(const std::string &attrName) const {
237*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < mCurrent->vtxAttrCount; ct++) {
238*e1eccf28SAndroid Build Coastguard Worker         if (attrName == mCurrent->vtxAttrs[ct].name) {
239*e1eccf28SAndroid Build Coastguard Worker             return mCurrent->vtxAttrs[ct].slot;
240*e1eccf28SAndroid Build Coastguard Worker         }
241*e1eccf28SAndroid Build Coastguard Worker     }
242*e1eccf28SAndroid Build Coastguard Worker     return -1;
243*e1eccf28SAndroid Build Coastguard Worker }
244*e1eccf28SAndroid Build Coastguard Worker 
cleanupVertex(RsdShader * s)245*e1eccf28SAndroid Build Coastguard Worker void RsdShaderCache::cleanupVertex(RsdShader *s) {
246*e1eccf28SAndroid Build Coastguard Worker     int32_t numEntries = (int32_t)mEntries.size();
247*e1eccf28SAndroid Build Coastguard Worker     uint32_t numShaderIDs = s->getStateBasedIDCount();
248*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
249*e1eccf28SAndroid Build Coastguard Worker         uint32_t id = s->getStateBasedID(sId);
250*e1eccf28SAndroid Build Coastguard Worker         for (int32_t ct = 0; ct < numEntries; ct ++) {
251*e1eccf28SAndroid Build Coastguard Worker             if (mEntries[ct]->vtx == id) {
252*e1eccf28SAndroid Build Coastguard Worker                 glDeleteProgram(mEntries[ct]->program);
253*e1eccf28SAndroid Build Coastguard Worker 
254*e1eccf28SAndroid Build Coastguard Worker                 delete mEntries[ct];
255*e1eccf28SAndroid Build Coastguard Worker                 mEntries.erase(mEntries.begin() + ct);
256*e1eccf28SAndroid Build Coastguard Worker                 numEntries = (int32_t)mEntries.size();
257*e1eccf28SAndroid Build Coastguard Worker                 ct --;
258*e1eccf28SAndroid Build Coastguard Worker             }
259*e1eccf28SAndroid Build Coastguard Worker         }
260*e1eccf28SAndroid Build Coastguard Worker     }
261*e1eccf28SAndroid Build Coastguard Worker }
262*e1eccf28SAndroid Build Coastguard Worker 
cleanupFragment(RsdShader * s)263*e1eccf28SAndroid Build Coastguard Worker void RsdShaderCache::cleanupFragment(RsdShader *s) {
264*e1eccf28SAndroid Build Coastguard Worker     int32_t numEntries = (int32_t)mEntries.size();
265*e1eccf28SAndroid Build Coastguard Worker     uint32_t numShaderIDs = s->getStateBasedIDCount();
266*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
267*e1eccf28SAndroid Build Coastguard Worker         uint32_t id = s->getStateBasedID(sId);
268*e1eccf28SAndroid Build Coastguard Worker         for (int32_t ct = 0; ct < numEntries; ct ++) {
269*e1eccf28SAndroid Build Coastguard Worker             if (mEntries[ct]->frag == id) {
270*e1eccf28SAndroid Build Coastguard Worker                 glDeleteProgram(mEntries[ct]->program);
271*e1eccf28SAndroid Build Coastguard Worker 
272*e1eccf28SAndroid Build Coastguard Worker                 delete mEntries[ct];
273*e1eccf28SAndroid Build Coastguard Worker                 mEntries.erase(mEntries.begin() + ct);
274*e1eccf28SAndroid Build Coastguard Worker                 numEntries = (int32_t)mEntries.size();
275*e1eccf28SAndroid Build Coastguard Worker                 ct --;
276*e1eccf28SAndroid Build Coastguard Worker             }
277*e1eccf28SAndroid Build Coastguard Worker         }
278*e1eccf28SAndroid Build Coastguard Worker     }
279*e1eccf28SAndroid Build Coastguard Worker }
280*e1eccf28SAndroid Build Coastguard Worker 
cleanupAll()281*e1eccf28SAndroid Build Coastguard Worker void RsdShaderCache::cleanupAll() {
282*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < mEntries.size(); ct++) {
283*e1eccf28SAndroid Build Coastguard Worker         glDeleteProgram(mEntries[ct]->program);
284*e1eccf28SAndroid Build Coastguard Worker         free(mEntries[ct]);
285*e1eccf28SAndroid Build Coastguard Worker     }
286*e1eccf28SAndroid Build Coastguard Worker     mEntries.clear();
287*e1eccf28SAndroid Build Coastguard Worker }
288