diff options
author | bohu <bohu@google.com> | 2015-02-03 18:02:30 -0800 |
---|---|---|
committer | bohu <bohu@google.com> | 2015-02-03 18:02:30 -0800 |
commit | d81668725d81d6b3020b08e6fbc72acf3dc1c0c8 (patch) | |
tree | e60befeecf3f3fc5dbf2b9eeb450cd205b7184dd | |
parent | 5afd994147069d77748d5b99791428fc3c0376e3 (diff) | |
download | sdk-d81668725d81d6b3020b08e6fbc72acf3dc1c0c8.zip sdk-d81668725d81d6b3020b08e6fbc72acf3dc1c0c8.tar.gz sdk-d81668725d81d6b3020b08e6fbc72acf3dc1c0c8.tar.bz2 |
back port gles fix to api 16
Following CLs are back ported:
717e625415c4398431b84851ba1b76d8c59ae9cf Add shader version to glGetString
32c30975ea654b9654ad9dade0d25b9856e63f1b Add parameters validation to glShaderSource() API
b0c7cce25bf9323a359800a86c0c7609db2acea4 Fix eglDestroyContext and glTexImage2D
2fc65202c214640c55b52c29bbc9213170d0b533 handles glGetBooleanv when value is nonboolean
beda8027439b9c20475b8a3d379823d09fca3abb Properly initialize GLClientState's m_states
84684ec571a1db94e32a67cb7d154ab562dd0d7f Unbind buffer when buffer is deleted
89b7aac84f8babab93ff5326ad492164d971c421 Handle empty data parameter in glTexSubImage2D_enc
adb0f74f792ba7bca20257b9c0ea41ebda9bb229 Allow glGetProgramInfoLog_enc to have empty length
b31166704ddb7751619cf0bbc4f2f4575c0ad3c4 Guard against negative buffer size
641f35af08a0a4c46586a592ff4e703e866d581a Guard against negative width and height
9d18698dd8da15937f80e5476d73400a011934be Handle empty buffer in QemuPipeStream::writeFully
40a674e0d0acac87aa25eb9de720dc2fb07d9e4f Fix emulator crashes on glDrawElements command
7a2929cd6548693b581c17ba69308a49e03c56be Remove display initialization from eglGetProcAddress API
Change-Id: Ia3c18f714812a8c90593c6a0260c92dc18c56da3
-rw-r--r-- | emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp | 3 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglCodecCommon/GLClientState.h | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp | 56 | ||||
-rwxr-xr-x[-rw-r--r--] | emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h | 1 | ||||
-rw-r--r-- | emulator/opengl/system/GLESv1_enc/GLEncoder.cpp | 20 | ||||
-rw-r--r-- | emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp | 77 | ||||
-rw-r--r-- | emulator/opengl/system/GLESv2_enc/GL2Encoder.h | 23 | ||||
-rw-r--r-- | emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp | 5 | ||||
-rw-r--r-- | emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp | 1 | ||||
-rw-r--r-- | emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h | 4 | ||||
-rw-r--r-- | emulator/opengl/system/egl/egl.cpp | 60 | ||||
-rw-r--r-- | emulator/opengl/system/egl/eglContext.h | 3 | ||||
-rw-r--r-- | emulator/opengl/system/egl/eglDisplay.cpp | 18 |
13 files changed, 216 insertions, 61 deletions
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp index 9795490..0826a14 100644 --- a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp +++ b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp @@ -35,6 +35,7 @@ GLClientState::GLClientState(int nLocations) for (int i = 0; i < m_nLocations; i++) { m_states[i].enabled = 0; m_states[i].enableDirty = false; + m_states[i].data = 0; } m_currentArrayVbo = 0; m_currentIndexVbo = 0; @@ -224,6 +225,8 @@ int GLClientState::setPixelStore(GLenum param, GLint value) size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const { + if (width <= 0 || height <= 0) return 0; + int pixelsize = glUtilsPixelBitSize(format, type) >> 3; int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment; diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h index c86329b..09ee571 100644 --- a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h +++ b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h @@ -91,6 +91,12 @@ public: void setActiveTexture(int texUnit) {m_activeTexture = texUnit; }; int getActiveTexture() const { return m_activeTexture; } + void unBindBuffer(GLuint id) + { + if (m_currentArrayVbo == id) m_currentArrayVbo = 0; + else if (m_currentIndexVbo == id) m_currentIndexVbo = 0; + } + int bindBuffer(GLenum target, GLuint id) { int err = 0; diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp index 8504f7f..b079b6d 100644..100755 --- a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp +++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp @@ -16,10 +16,19 @@ #include "GLSharedGroup.h" +/**** KeyedVector utilities ****/ + +template <typename T> +static void clearObjectMap(android::DefaultKeyedVector<GLuint, T>& v) { + for (size_t i = 0; i < v.size(); i++) + delete v.valueAt(i); + v.clear(); +} + /**** BufferData ****/ BufferData::BufferData() : m_size(0) {}; -BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size) +BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size) { void * buffer = NULL; if (size>0) buffer = m_fixedBuffer.alloc(size); @@ -55,7 +64,7 @@ ProgramData::~ProgramData() } void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type) -{ +{ if (index>=m_numIndexes) return; m_Indexes[index].base = base; @@ -87,7 +96,7 @@ GLuint ProgramData::getIndexForLocation(GLint location) for (GLuint i=0;i<m_numIndexes;++i) { GLint dist = location - m_Indexes[i].base; - if (dist >= 0 && + if (dist >= 0 && (minDist < 0 || dist < minDist)) { index = i; minDist = dist; @@ -126,7 +135,7 @@ GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex) GLuint index = getIndexForLocation(hostLoc); if (index<m_numIndexes) { if (arrIndex > 0) { - m_Indexes[index].hostLocsPerElement = + m_Indexes[index].hostLocsPerElement = (hostLoc - m_Indexes[index].base) / arrIndex; } return m_Indexes[index].appBase + arrIndex; @@ -226,12 +235,21 @@ GLSharedGroup::~GLSharedGroup() { m_buffers.clear(); m_programs.clear(); + clearObjectMap(m_buffers); + clearObjectMap(m_programs); + clearObjectMap(m_shaders); +} + +bool GLSharedGroup::isObject(GLuint obj) +{ + android::AutoMutex _lock(m_lock); + return ((m_shaders.valueFor(obj)!=NULL) || (m_programs.valueFor(obj)!=NULL)); } BufferData * GLSharedGroup::getBufferData(GLuint bufferId) { android::AutoMutex _lock(m_lock); - return m_buffers.valueFor(bufferId); + return m_buffers.valueFor(bufferId); } void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data) @@ -243,32 +261,42 @@ void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data) void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data) { android::AutoMutex _lock(m_lock); - m_buffers.replaceValueFor(bufferId, new BufferData(size, data)); + ssize_t idx = m_buffers.indexOfKey(bufferId); + if (idx >= 0) { + delete m_buffers.valueAt(idx); + m_buffers.editValueAt(idx) = new BufferData(size, data); + } else { + m_buffers.add(bufferId, new BufferData(size, data)); + } } GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data) { android::AutoMutex _lock(m_lock); BufferData * buf = m_buffers.valueFor(bufferId); - if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE; + if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE; //it's safe to update now memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size); - return GL_NO_ERROR; + return GL_NO_ERROR; } void GLSharedGroup::deleteBufferData(GLuint bufferId) { android::AutoMutex _lock(m_lock); - m_buffers.removeItem(bufferId); + ssize_t idx = m_buffers.indexOfKey(bufferId); + if (idx >= 0) { + delete m_buffers.valueAt(idx); + m_buffers.removeItemsAt(idx); + } } void GLSharedGroup::addProgramData(GLuint program) { android::AutoMutex _lock(m_lock); ProgramData *pData = m_programs.valueFor(program); - if (pData) - { + if (pData) + { m_programs.removeItem(program); delete pData; } @@ -290,7 +318,7 @@ bool GLSharedGroup::isProgramInitialized(GLuint program) { android::AutoMutex _lock(m_lock); ProgramData* pData = m_programs.valueFor(program); - if (pData) + if (pData) { return pData->isInitialized(); } @@ -303,7 +331,7 @@ void GLSharedGroup::deleteProgramData(GLuint program) ProgramData *pData = m_programs.valueFor(program); if (pData) delete pData; - m_programs.removeItem(program); + m_programs.removeItem(program); } void GLSharedGroup::attachShader(GLuint program, GLuint shader) @@ -363,7 +391,7 @@ GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location) android::AutoMutex _lock(m_lock); ProgramData* pData = m_programs.valueFor(program); GLenum type=0; - if (pData) + if (pData) { type = pData->getTypeForLocation(location); } diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h index 61b8f00..6dfcd8f 100644..100755 --- a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h +++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h @@ -110,6 +110,7 @@ private: public: GLSharedGroup(); ~GLSharedGroup(); + bool isObject(GLuint obj); BufferData * getBufferData(GLuint bufferId); void addBufferData(GLuint bufferId, GLsizeiptr size, void * data); void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data); diff --git a/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp index 4414f24..989c26f 100644 --- a/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp +++ b/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp @@ -464,19 +464,19 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count) switch(i) { case GLClientState::VERTEX_LOCATION: this->glVertexPointerOffset(this, state->size, state->type, state->stride, - (GLuint)state->data + firstIndex); + (uintptr_t)state->data + firstIndex); break; case GLClientState::NORMAL_LOCATION: this->glNormalPointerOffset(this, state->type, state->stride, - (GLuint) state->data + firstIndex); + (uintptr_t)state->data + firstIndex); break; case GLClientState::POINTSIZE_LOCATION: this->glPointSizePointerOffset(this, state->type, state->stride, - (GLuint) state->data + firstIndex); + (uintptr_t)state->data + firstIndex); break; case GLClientState::COLOR_LOCATION: this->glColorPointerOffset(this, state->size, state->type, state->stride, - (GLuint) state->data + firstIndex); + (uintptr_t)state->data + firstIndex); break; case GLClientState::TEXCOORD0_LOCATION: case GLClientState::TEXCOORD1_LOCATION: @@ -487,17 +487,17 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count) case GLClientState::TEXCOORD6_LOCATION: case GLClientState::TEXCOORD7_LOCATION: this->glTexCoordPointerOffset(this, state->size, state->type, state->stride, - (GLuint) state->data + firstIndex); + (uintptr_t)state->data + firstIndex); break; case GLClientState::WEIGHT_LOCATION: this->glWeightPointerOffset(this,state->size,state->type,state->stride, - (GLuint)state->data+firstIndex); + (uintptr_t)state->data+firstIndex); break; case GLClientState::MATRIXINDEX_LOCATION: this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, - (GLuint)state->data+firstIndex); + (uintptr_t)state->data+firstIndex); break; - } + } this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); } } else { @@ -545,14 +545,14 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum if (!has_immediate_arrays) { ctx->sendVertexData(0, count); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); - ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); + ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices); adjustIndices = false; } else { BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); } - } + } if (adjustIndices) { void *adjustedIndices = (void*)indices; int minIndex = 0, maxIndex = 0; diff --git a/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index d8fedf3..b567f62 100644 --- a/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -79,6 +79,11 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader); m_glAttachShader_enc = set_glAttachShader(s_glAttachShader); m_glDetachShader_enc = set_glDetachShader(s_glDetachShader); + m_glGetAttachedShaders_enc = set_glGetAttachedShaders(s_glGetAttachedShaders); + m_glGetShaderSource_enc = set_glGetShaderSource(s_glGetShaderSource); + m_glGetShaderInfoLog_enc = set_glGetShaderInfoLog(s_glGetShaderInfoLog); + m_glGetProgramInfoLog_enc = set_glGetProgramInfoLog(s_glGetProgramInfoLog); + m_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation); m_glUseProgram_enc = set_glUseProgram(s_glUseProgram); @@ -111,6 +116,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv); m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri); m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv); + m_glTexImage2D_enc = set_glTexImage2D(s_glTexImage2D); } GL2Encoder::~GL2Encoder() @@ -179,6 +185,7 @@ void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id) void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) { GL2Encoder *ctx = (GL2Encoder *) self; + SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM); GLuint bufferId = ctx->m_state->getBuffer(target); SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); SET_ERROR_IF(size<0, GL_INVALID_VALUE); @@ -190,6 +197,7 @@ void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, con void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { GL2Encoder *ctx = (GL2Encoder *) self; + SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM); GLuint bufferId = ctx->m_state->getBuffer(target); SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); @@ -205,6 +213,7 @@ void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffer SET_ERROR_IF(n<0, GL_INVALID_VALUE); for (int i=0; i<n; i++) { ctx->m_shared->deleteBufferData(buffers[i]); + ctx->m_state->unBindBuffer(buffers[i]); ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); } } @@ -348,6 +357,7 @@ void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) { ctx->m_glGetBooleanv_enc(self, param, ptr); } + *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE; break; } } @@ -424,15 +434,15 @@ void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count) int stride = state->stride == 0 ? state->elementSize : state->stride; int firstIndex = stride * first; + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); if (state->bufferObject == 0) { this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride, (unsigned char *)state->data + firstIndex, datalen); } else { - this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride, - (GLuint) state->data + firstIndex); - this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); + (uintptr_t) state->data + firstIndex); } + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); } else { this->m_glDisableVertexAttribArray_enc(this, i); } @@ -479,14 +489,14 @@ void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum if (!has_immediate_arrays) { ctx->sendVertexAttributes(0, count); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); - ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); + ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices); adjustIndices = false; } else { BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); } - } + } if (adjustIndices) { void *adjustedIndices = (void*)indices; int minIndex = 0, maxIndex = 0; @@ -637,7 +647,9 @@ void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, cons { GL2Encoder* ctx = (GL2Encoder*)self; ShaderData* shaderData = ctx->m_shared->getShaderData(shader); - SET_ERROR_IF(!shaderData, GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->m_shared->isObject(shader), GL_INVALID_VALUE); + SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION); + SET_ERROR_IF((count<0), GL_INVALID_VALUE); int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count); char *str = new char[len + 1]; @@ -686,7 +698,7 @@ void GL2Encoder::s_glLinkProgram(void * self, GLuint program) GLchar *name = new GLchar[maxLength+1]; GLint location; //for each active uniform, get its size and starting location. - for (GLint i=0 ; i<numUniforms ; ++i) + for (GLint i=0 ; i<numUniforms ; ++i) { ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name); location = ctx->m_glGetUniformLocation_enc(self, program, name); @@ -746,6 +758,38 @@ GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType) return shader; } +void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount, + GLsizei* count, GLuint* shaders) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE); + ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders); +} + +void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize, + GLsizei* length, GLchar* source) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); + ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source); +} + +void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize, + GLsizei* length, GLchar* infolog) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); + ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog); +} + +void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize, + GLsizei* length, GLchar* infolog) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); + ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog); +} + void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) { GL2Encoder *ctx = (GL2Encoder*)self; @@ -784,7 +828,7 @@ int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) { return -1; } - + } } @@ -1161,6 +1205,23 @@ void GL2Encoder::s_glTexParameteri(void* self, } } +void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid* pixels) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, + height, border, format, type, pixels); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, + height, border, format, type, pixels); + } +} + + void GL2Encoder::s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params) { diff --git a/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/emulator/opengl/system/GLESv2_enc/GL2Encoder.h index f9235d7..a16f490 100644 --- a/emulator/opengl/system/GLESv2_enc/GL2Encoder.h +++ b/emulator/opengl/system/GLESv2_enc/GL2Encoder.h @@ -74,7 +74,7 @@ private: glBindBuffer_client_proc_t m_glBindBuffer_enc; static void s_glBindBuffer(void *self, GLenum target, GLuint id); - + glBufferData_client_proc_t m_glBufferData_enc; static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); glBufferSubData_client_proc_t m_glBufferSubData_enc; @@ -148,6 +148,22 @@ private: glDetachShader_client_proc_t m_glDetachShader_enc; static void s_glDetachShader(void *self, GLuint program, GLuint shader); + glGetAttachedShaders_client_proc_t m_glGetAttachedShaders_enc; + static void s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount, + GLsizei* count, GLuint* shaders); + + glGetShaderSource_client_proc_t m_glGetShaderSource_enc; + static void s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize, + GLsizei* length, GLchar* source); + + glGetShaderInfoLog_client_proc_t m_glGetShaderInfoLog_enc; + static void s_glGetShaderInfoLog(void *self,GLuint shader, + GLsizei bufsize, GLsizei* length, GLchar* infolog); + + glGetProgramInfoLog_client_proc_t m_glGetProgramInfoLog_enc; + static void s_glGetProgramInfoLog(void *self,GLuint program, + GLsizei bufsize, GLsizei* length, GLchar* infolog); + glGetUniformLocation_client_proc_t m_glGetUniformLocation_enc; static int s_glGetUniformLocation(void *self, GLuint program, const GLchar *name); glUseProgram_client_proc_t m_glUseProgram_enc; @@ -202,6 +218,7 @@ private: glTexParameterfv_client_proc_t m_glTexParameterfv_enc; glTexParameteri_client_proc_t m_glTexParameteri_enc; glTexParameteriv_client_proc_t m_glTexParameteriv_enc; + glTexImage2D_client_proc_t m_glTexImage2D_enc; static void s_glActiveTexture(void* self, GLenum texture); static void s_glBindTexture(void* self, GLenum target, GLuint texture); @@ -212,5 +229,9 @@ private: static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params); static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param); static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params); + static void s_glTexImage2D(void* self, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, + const GLvoid* pixels); + }; #endif diff --git a/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp index 50c3d8b..5798370 100644 --- a/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp +++ b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp @@ -40,6 +40,7 @@ QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) : QemuPipeStream::~QemuPipeStream() { if (m_sock >= 0) { + flush(); ::close(m_sock); } if (m_buf != NULL) { @@ -86,6 +87,10 @@ int QemuPipeStream::writeFully(const void *buf, size_t len) { //DBG(">> QemuPipeStream::writeFully %d\n", len); if (!valid()) return -1; + if (!buf) { + if (len>0) ERR("QemuPipeStream::writeFully failed, buf=NULL, len %d", len); + return 0; + } size_t res = len; int retval = 0; diff --git a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp index 75da8f2..f9c8521 100644 --- a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp +++ b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp @@ -24,6 +24,7 @@ static void tlsDestruct(void *ptr) EGLThreadInfo *ti = (EGLThreadInfo *)ptr; delete ti->hostConn; delete ti; + ((intptr_t *)__get_tls())[TLS_SLOT_OPENGL] = NULL; } } diff --git a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h index 0328733..f59ce2a 100644 --- a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h +++ b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h @@ -40,10 +40,10 @@ EGLThreadInfo *slow_getEGLThreadInfo(); // We have a dedicated TLS slot in bionic inline EGLThreadInfo* getEGLThreadInfo() { EGLThreadInfo *tInfo = - (EGLThreadInfo *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]); + (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]); if (!tInfo) { tInfo = slow_getEGLThreadInfo(); - ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)tInfo; + ((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL] = (uintptr_t)tInfo; } return tInfo; } diff --git a/emulator/opengl/system/egl/egl.cpp b/emulator/opengl/system/egl/egl.cpp index ee195ac..586effa 100644 --- a/emulator/opengl/system/egl/egl.cpp +++ b/emulator/opengl/system/egl/egl.cpp @@ -86,7 +86,7 @@ const char * eglStrError(EGLint err) #endif //LOG_EGL_ERRORS #define VALIDATE_CONFIG(cfg,ret) \ - if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \ + if(((intptr_t)cfg<0)||((intptr_t)cfg>s_display.getNumConfigs())) { \ RETURN_ERROR(ret,EGL_BAD_CONFIG); \ } @@ -140,7 +140,9 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* share versionString(NULL), vendorString(NULL), rendererString(NULL), - extensionString(NULL) + shaderVersionString(NULL), + extensionString(NULL), + deletePending(0) { flags = 0; version = 1; @@ -157,6 +159,7 @@ EGLContext_t::~EGLContext_t() delete [] versionString; delete [] vendorString; delete [] rendererString; + delete [] shaderVersionString; delete [] extensionString; } @@ -266,10 +269,9 @@ EGLBoolean egl_window_surface_t::init() if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); } - nativeWindow->lockBuffer(nativeWindow, buffer); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, + rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config, getWidth(), getHeight()); if (!rcSurface) { ALOGE("rcCreateWindowSurface returned 0"); @@ -321,7 +323,6 @@ EGLBoolean egl_window_surface_t::swapBuffers() buffer = NULL; setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); } - nativeWindow->lockBuffer(nativeWindow, buffer); rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle); @@ -373,7 +374,7 @@ EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat) { DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, + rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config, getWidth(), getHeight()); if (!rcSurface) { ALOGE("rcCreateWindowSurface returned 0"); @@ -417,6 +418,7 @@ static const char *getGLString(int glEnum) #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_EXTENSIONS 0x1F03 switch(glEnum) { @@ -429,6 +431,9 @@ static const char *getGLString(int glEnum) case GL_RENDERER: strPtr = &tInfo->currentContext->rendererString; break; + case GL_SHADING_LANGUAGE_VERSION: + strPtr = &tInfo->currentContext->shaderVersionString; + break; case GL_EXTENSIONS: strPtr = &tInfo->currentContext->extensionString; break; @@ -528,15 +533,6 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) } } - // - // Make sure display is initialized before searching in client APIs - // - if (!s_display.initialized()) { - if (!s_display.initialize(&s_eglIface)) { - return NULL; - } - } - // look in gles client api's extensions table return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname); @@ -565,7 +561,7 @@ EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, return EGL_TRUE; } - int i=0; + uintptr_t i=0; for (i=0 ; i<numConfigs && i<config_size ; i++) { *configs++ = (EGLConfig)i; } @@ -587,9 +583,18 @@ EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig attribs_size++; //for the terminating EGL_NONE } + uint32_t* tempConfigs[config_size]; DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size); + *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)tempConfigs, config_size); + if (configs!=NULL) { + EGLint i=0; + for (i=0;i<(*num_config);i++) { + *((uintptr_t*)configs+i) = *((uint32_t*)tempConfigs+i); + } + } + if (*num_config <= 0) + return EGL_FALSE; return EGL_TRUE; } @@ -875,7 +880,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c } DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); - uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version); + uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uintptr_t)config, rcShareCtx, version); if (!rcContext) { ALOGE("rcCreateContext returned 0"); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); @@ -899,9 +904,11 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) EGLContext_t * context = static_cast<EGLContext_t*>(ctx); - if (getEGLThreadInfo()->currentContext == context) - { - eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); + if (!context) return EGL_TRUE; + + if (getEGLThreadInfo()->currentContext == context) { + getEGLThreadInfo()->currentContext->deletePending = 1; + return EGL_TRUE; } if (context->rcContext) { @@ -936,12 +943,21 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC // Nothing to do if no binding change has made // EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (tInfo->currentContext == context && (context == NULL || (context && context->draw == draw && context->read == read))) { return EGL_TRUE; } + if (tInfo->currentContext && tInfo->currentContext->deletePending) { + if (tInfo->currentContext != context) { + EGLContext_t * contextToDelete = tInfo->currentContext; + tInfo->currentContext = 0; + eglDestroyContext(dpy, contextToDelete); + } + } + if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { //context is current to another thread setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); @@ -968,7 +984,7 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); } } - else { + else if (tInfo->currentContext) { //release ClientState & SharedGroup if (tInfo->currentContext->version == 2) { hostCon->gl2Encoder()->setClientState(NULL); diff --git a/emulator/opengl/system/egl/eglContext.h b/emulator/opengl/system/egl/eglContext.h index 2ca6d0c..5b6a428 100644 --- a/emulator/opengl/system/egl/eglContext.h +++ b/emulator/opengl/system/egl/eglContext.h @@ -39,8 +39,9 @@ struct EGLContext_t { const char* versionString; const char* vendorString; const char* rendererString; + const char* shaderVersionString; const char* extensionString; - + EGLint deletePending; GLClientState * getClientState(){ return clientState; } GLSharedGroupPtr getSharedGroup(){ return sharedGroup; } private: diff --git a/emulator/opengl/system/egl/eglDisplay.cpp b/emulator/opengl/system/egl/eglDisplay.cpp index bcb0d4b..96540aa 100644 --- a/emulator/opengl/system/egl/eglDisplay.cpp +++ b/emulator/opengl/system/egl/eglDisplay.cpp @@ -84,9 +84,15 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface) // // load GLES client API // +#if __LP64__ + m_gles_iface = loadGLESClientAPI("/system/lib64/egl/libGLESv1_CM_emulation.so", + eglIface, + &s_gles_lib); +#else m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so", eglIface, &s_gles_lib); +#endif if (!m_gles_iface) { pthread_mutex_unlock(&m_lock); ALOGE("Failed to load gles1 iface"); @@ -94,9 +100,15 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface) } #ifdef WITH_GLES2 +#if __LP64__ + m_gles2_iface = loadGLESClientAPI("/system/lib64/egl/libGLESv2_emulation.so", + eglIface, + &s_gles2_lib); +#else m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so", eglIface, &s_gles2_lib); +#endif // Note that if loading gles2 failed, we can still run with no // GLES2 support, having GLES2 is not mandatory. #endif @@ -189,7 +201,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface) void eglDisplay::processConfigs() { - for (int i=0; i<m_numConfigs; i++) { + for (intptr_t i=0; i<m_numConfigs; i++) { EGLConfig config = (EGLConfig)i; //Setup the EGL_NATIVE_VISUAL_ID attribute PixelFormat format; @@ -401,7 +413,7 @@ EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); return EGL_FALSE; } - *value = *(m_configs + (int)config*m_numConfigAttribs + attribIdx); + *value = *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx); return EGL_TRUE; } @@ -434,7 +446,7 @@ EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); return EGL_FALSE; } - *(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value; + *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx) = value; return EGL_TRUE; } |