1 #include "GLSharedGroup.h" 2 3 /**** BufferData ****/ 4 5 BufferData::BufferData() : m_size(0) {}; 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 ****/ 14 ProgramData::ProgramData() : m_numIndexes(0), 15 m_initialized(false), 16 m_locShiftWAR(false) 17 { 18 m_Indexes = NULL; 19 } 20 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 30 bool ProgramData::isInitialized() 31 { 32 return m_initialized; 33 } 34 35 ProgramData::~ProgramData() 36 { 37 delete[] m_Indexes; 38 m_Indexes = NULL; 39 } 40 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 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 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 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 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 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 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 136 GLSharedGroup::~GLSharedGroup() 137 { 138 m_buffers.clear(); 139 m_programs.clear(); 140 } 141 142 BufferData * GLSharedGroup::getBufferData(GLuint bufferId) 143 { 144 android::AutoMutex _lock(m_lock); 145 return m_buffers.valueFor(bufferId); 146 } 147 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 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 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 171 void GLSharedGroup::deleteBufferData(GLuint bufferId) 172 { 173 android::AutoMutex _lock(m_lock); 174 m_buffers.removeItem(bufferId); 175 } 176 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 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 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 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 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 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 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 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 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 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 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 281 void GLSharedGroup::addShaderData(GLuint shader) 282 { 283 android::AutoMutex _lock(m_lock); 284 m_shaders.push_front(shader); 285 286 } 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 } 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