1 #include "GLSharedGroup.h"
2
3 /**** BufferData ****/
4
BufferData()5 BufferData::BufferData() : m_size(0) {};
BufferData(GLsizeiptr size,void * data)6 BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size)
7 {
8 void * buffer = NULL;
9 if (size>0) buffer = m_fixedBuffer.alloc(size);
10 if (data) memcpy(buffer, data, size);
11 }
12
13 /**** ProgramData ****/
ProgramData()14 ProgramData::ProgramData() : m_numIndexes(0),
15 m_initialized(false),
16 m_locShiftWAR(false)
17 {
18 m_Indexes = NULL;
19 }
20
initProgramData(GLuint numIndexes)21 void ProgramData::initProgramData(GLuint numIndexes)
22 {
23 m_initialized = true;
24 m_numIndexes = numIndexes;
25 delete[] m_Indexes;
26 m_Indexes = new IndexInfo[numIndexes];
27 m_locShiftWAR = false;
28 }
29
isInitialized()30 bool ProgramData::isInitialized()
31 {
32 return m_initialized;
33 }
34
~ProgramData()35 ProgramData::~ProgramData()
36 {
37 delete[] m_Indexes;
38 m_Indexes = NULL;
39 }
40
setIndexInfo(GLuint index,GLint base,GLint size,GLenum type)41 void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type)
42 {
43 if (index>=m_numIndexes)
44 return;
45 m_Indexes[index].base = base;
46 m_Indexes[index].size = size;
47 m_Indexes[index].type = type;
48 if (index > 0) {
49 m_Indexes[index].appBase = m_Indexes[index-1].appBase +
50 m_Indexes[index-1].size;
51 }
52 else {
53 m_Indexes[index].appBase = 0;
54 }
55 m_Indexes[index].hostLocsPerElement = 1;
56 }
57
getIndexForLocation(GLint location)58 GLuint ProgramData::getIndexForLocation(GLint location)
59 {
60 GLuint index = m_numIndexes;
61 GLint minDist = -1;
62 for (GLuint i=0;i<m_numIndexes;++i)
63 {
64 GLint dist = location - m_Indexes[i].base;
65 if (dist >= 0 &&
66 (minDist < 0 || dist < minDist)) {
67 index = i;
68 minDist = dist;
69 }
70 }
71 return index;
72 }
73
getTypeForLocation(GLint location)74 GLenum ProgramData::getTypeForLocation(GLint location)
75 {
76 GLuint index = getIndexForLocation(location);
77 if (index<m_numIndexes) {
78 return m_Indexes[index].type;
79 }
80 return 0;
81 }
82
setupLocationShiftWAR()83 void ProgramData::setupLocationShiftWAR()
84 {
85 m_locShiftWAR = false;
86 for (GLuint i=0; i<m_numIndexes; i++) {
87 if (0 != (m_Indexes[i].base & 0xffff)) {
88 return;
89 }
90 }
91 // if we have one uniform at location 0, we do not need the WAR.
92 if (m_numIndexes > 1) {
93 m_locShiftWAR = true;
94 }
95 }
96
locationWARHostToApp(GLint hostLoc,GLint arrIndex)97 GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
98 {
99 if (!m_locShiftWAR) return hostLoc;
100
101 GLuint index = getIndexForLocation(hostLoc);
102 if (index<m_numIndexes) {
103 if (arrIndex > 0) {
104 m_Indexes[index].hostLocsPerElement =
105 (hostLoc - m_Indexes[index].base) / arrIndex;
106 }
107 return m_Indexes[index].appBase + arrIndex;
108 }
109 return -1;
110 }
111
locationWARAppToHost(GLint appLoc)112 GLint ProgramData::locationWARAppToHost(GLint appLoc)
113 {
114 if (!m_locShiftWAR) return appLoc;
115
116 for(GLuint i=0; i<m_numIndexes; i++) {
117 GLint elemIndex = appLoc - m_Indexes[i].appBase;
118 if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
119 return m_Indexes[i].base +
120 elemIndex * m_Indexes[i].hostLocsPerElement;
121 }
122 }
123 return -1;
124 }
125
126
127 /***** GLSharedGroup ****/
128
GLSharedGroup()129 GLSharedGroup::GLSharedGroup() :
130 m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
131 m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
132 m_shaders(android::List<GLuint>())
133 {
134 }
135
~GLSharedGroup()136 GLSharedGroup::~GLSharedGroup()
137 {
138 m_buffers.clear();
139 m_programs.clear();
140 }
141
getBufferData(GLuint bufferId)142 BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
143 {
144 android::AutoMutex _lock(m_lock);
145 return m_buffers.valueFor(bufferId);
146 }
147
addBufferData(GLuint bufferId,GLsizeiptr size,void * data)148 void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
149 {
150 android::AutoMutex _lock(m_lock);
151 m_buffers.add(bufferId, new BufferData(size, data));
152 }
153
updateBufferData(GLuint bufferId,GLsizeiptr size,void * data)154 void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
155 {
156 android::AutoMutex _lock(m_lock);
157 m_buffers.replaceValueFor(bufferId, new BufferData(size, data));
158 }
159
subUpdateBufferData(GLuint bufferId,GLintptr offset,GLsizeiptr size,void * data)160 GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
161 {
162 android::AutoMutex _lock(m_lock);
163 BufferData * buf = m_buffers.valueFor(bufferId);
164 if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE;
165
166 //it's safe to update now
167 memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
168 return GL_NO_ERROR;
169 }
170
deleteBufferData(GLuint bufferId)171 void GLSharedGroup::deleteBufferData(GLuint bufferId)
172 {
173 android::AutoMutex _lock(m_lock);
174 m_buffers.removeItem(bufferId);
175 }
176
addProgramData(GLuint program)177 void GLSharedGroup::addProgramData(GLuint program)
178 {
179 android::AutoMutex _lock(m_lock);
180 ProgramData *pData = m_programs.valueFor(program);
181 if (pData)
182 {
183 m_programs.removeItem(program);
184 delete pData;
185 }
186
187 m_programs.add(program,new ProgramData());
188 }
189
initProgramData(GLuint program,GLuint numIndexes)190 void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
191 {
192 android::AutoMutex _lock(m_lock);
193 ProgramData *pData = m_programs.valueFor(program);
194 if (pData)
195 {
196 pData->initProgramData(numIndexes);
197 }
198 }
199
isProgramInitialized(GLuint program)200 bool GLSharedGroup::isProgramInitialized(GLuint program)
201 {
202 android::AutoMutex _lock(m_lock);
203 ProgramData* pData = m_programs.valueFor(program);
204 if (pData)
205 {
206 return pData->isInitialized();
207 }
208 return false;
209 }
210
deleteProgramData(GLuint program)211 void GLSharedGroup::deleteProgramData(GLuint program)
212 {
213 android::AutoMutex _lock(m_lock);
214 ProgramData *pData = m_programs.valueFor(program);
215 if (pData)
216 delete pData;
217 m_programs.removeItem(program);
218 }
219
setProgramIndexInfo(GLuint program,GLuint index,GLint base,GLint size,GLenum type)220 void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type)
221 {
222 android::AutoMutex _lock(m_lock);
223 ProgramData* pData = m_programs.valueFor(program);
224 if (pData)
225 {
226 pData->setIndexInfo(index,base,size,type);
227 }
228 }
229
getProgramUniformType(GLuint program,GLint location)230 GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
231 {
232 android::AutoMutex _lock(m_lock);
233 ProgramData* pData = m_programs.valueFor(program);
234 GLenum type=0;
235 if (pData)
236 {
237 type = pData->getTypeForLocation(location);
238 }
239 return type;
240 }
241
isProgram(GLuint program)242 bool GLSharedGroup::isProgram(GLuint program)
243 {
244 android::AutoMutex _lock(m_lock);
245 ProgramData* pData = m_programs.valueFor(program);
246 return (pData!=NULL);
247 }
248
setupLocationShiftWAR(GLuint program)249 void GLSharedGroup::setupLocationShiftWAR(GLuint program)
250 {
251 android::AutoMutex _lock(m_lock);
252 ProgramData* pData = m_programs.valueFor(program);
253 if (pData) pData->setupLocationShiftWAR();
254 }
255
locationWARHostToApp(GLuint program,GLint hostLoc,GLint arrIndex)256 GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
257 {
258 android::AutoMutex _lock(m_lock);
259 ProgramData* pData = m_programs.valueFor(program);
260 if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
261 else return hostLoc;
262 }
263
locationWARAppToHost(GLuint program,GLint appLoc)264 GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
265 {
266 android::AutoMutex _lock(m_lock);
267 ProgramData* pData = m_programs.valueFor(program);
268 if (pData) return pData->locationWARAppToHost(appLoc);
269 else return appLoc;
270 }
271
needUniformLocationWAR(GLuint program)272 bool GLSharedGroup::needUniformLocationWAR(GLuint program)
273 {
274 android::AutoMutex _lock(m_lock);
275 ProgramData* pData = m_programs.valueFor(program);
276 if (pData) return pData->needUniformLocationWAR();
277 return false;
278 }
279
280
addShaderData(GLuint shader)281 void GLSharedGroup::addShaderData(GLuint shader)
282 {
283 android::AutoMutex _lock(m_lock);
284 m_shaders.push_front(shader);
285
286 }
isShader(GLuint shader)287 bool GLSharedGroup::isShader(GLuint shader)
288 {
289 android::AutoMutex _lock(m_lock);
290 android::List<GLuint>::iterator iter;
291 iter = m_shaders.begin();
292 while (iter!=m_shaders.end())
293 {
294 if (*iter==shader)
295 return true;
296 iter++;
297 }
298 return false;
299 }
deleteShaderData(GLuint shader)300 void GLSharedGroup::deleteShaderData(GLuint shader)
301 {
302 android::AutoMutex _lock(m_lock);
303 android::List<GLuint>::iterator iter;
304 iter = m_shaders.begin();
305 while (iter!=m_shaders.end())
306 {
307 if (*iter==shader)
308 {
309 m_shaders.erase(iter);
310 return;
311 }
312 iter++;
313 }
314 }
315