Home | History | Annotate | Download | only in OpenglCodecCommon
      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