am 8ec8f605: am e591d22b: am f8ac5e31: back port gles fix to api 17

* commit '8ec8f605e13cf601340c75d450fe2af294c2ecbc':
  back port gles fix to api 17
This commit is contained in:
bohu
2015-02-13 20:37:10 +00:00
committed by Android Git Automerger
27 changed files with 494 additions and 293 deletions

View File

@@ -35,6 +35,7 @@ GLClientState::GLClientState(int nLocations)
for (int i = 0; i < m_nLocations; i++) { for (int i = 0; i < m_nLocations; i++) {
m_states[i].enabled = 0; m_states[i].enabled = 0;
m_states[i].enableDirty = false; m_states[i].enableDirty = false;
m_states[i].data = 0;
} }
m_currentArrayVbo = 0; m_currentArrayVbo = 0;
m_currentIndexVbo = 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 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 pixelsize = glUtilsPixelBitSize(format, type) >> 3;
int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment; int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;

View File

@@ -91,6 +91,12 @@ public:
void setActiveTexture(int texUnit) {m_activeTexture = texUnit; }; void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
int getActiveTexture() const { return m_activeTexture; } 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 bindBuffer(GLenum target, GLuint id)
{ {
int err = 0; int err = 0;

View File

@@ -16,10 +16,19 @@
#include "GLSharedGroup.h" #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::BufferData() : m_size(0) {}; 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; void * buffer = NULL;
if (size>0) buffer = m_fixedBuffer.alloc(size); 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) void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type)
{ {
if (index>=m_numIndexes) if (index>=m_numIndexes)
return; return;
m_Indexes[index].base = base; m_Indexes[index].base = base;
@@ -87,7 +96,7 @@ GLuint ProgramData::getIndexForLocation(GLint location)
for (GLuint i=0;i<m_numIndexes;++i) for (GLuint i=0;i<m_numIndexes;++i)
{ {
GLint dist = location - m_Indexes[i].base; GLint dist = location - m_Indexes[i].base;
if (dist >= 0 && if (dist >= 0 &&
(minDist < 0 || dist < minDist)) { (minDist < 0 || dist < minDist)) {
index = i; index = i;
minDist = dist; minDist = dist;
@@ -126,7 +135,7 @@ GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
GLuint index = getIndexForLocation(hostLoc); GLuint index = getIndexForLocation(hostLoc);
if (index<m_numIndexes) { if (index<m_numIndexes) {
if (arrIndex > 0) { if (arrIndex > 0) {
m_Indexes[index].hostLocsPerElement = m_Indexes[index].hostLocsPerElement =
(hostLoc - m_Indexes[index].base) / arrIndex; (hostLoc - m_Indexes[index].base) / arrIndex;
} }
return m_Indexes[index].appBase + arrIndex; return m_Indexes[index].appBase + arrIndex;
@@ -226,12 +235,21 @@ GLSharedGroup::~GLSharedGroup()
{ {
m_buffers.clear(); m_buffers.clear();
m_programs.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) BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
{ {
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
return m_buffers.valueFor(bufferId); return m_buffers.valueFor(bufferId);
} }
void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data) 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) void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
{ {
android::AutoMutex _lock(m_lock); 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) GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
{ {
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
BufferData * buf = m_buffers.valueFor(bufferId); 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 //it's safe to update now
memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size); memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
return GL_NO_ERROR; return GL_NO_ERROR;
} }
void GLSharedGroup::deleteBufferData(GLuint bufferId) void GLSharedGroup::deleteBufferData(GLuint bufferId)
{ {
android::AutoMutex _lock(m_lock); 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) void GLSharedGroup::addProgramData(GLuint program)
{ {
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
ProgramData *pData = m_programs.valueFor(program); ProgramData *pData = m_programs.valueFor(program);
if (pData) if (pData)
{ {
m_programs.removeItem(program); m_programs.removeItem(program);
delete pData; delete pData;
} }
@@ -290,7 +318,7 @@ bool GLSharedGroup::isProgramInitialized(GLuint program)
{ {
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
ProgramData* pData = m_programs.valueFor(program); ProgramData* pData = m_programs.valueFor(program);
if (pData) if (pData)
{ {
return pData->isInitialized(); return pData->isInitialized();
} }
@@ -303,7 +331,7 @@ void GLSharedGroup::deleteProgramData(GLuint program)
ProgramData *pData = m_programs.valueFor(program); ProgramData *pData = m_programs.valueFor(program);
if (pData) if (pData)
delete pData; delete pData;
m_programs.removeItem(program); m_programs.removeItem(program);
} }
void GLSharedGroup::attachShader(GLuint program, GLuint shader) void GLSharedGroup::attachShader(GLuint program, GLuint shader)
@@ -363,7 +391,7 @@ GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
ProgramData* pData = m_programs.valueFor(program); ProgramData* pData = m_programs.valueFor(program);
GLenum type=0; GLenum type=0;
if (pData) if (pData)
{ {
type = pData->getTypeForLocation(location); type = pData->getTypeForLocation(location);
} }

View File

@@ -110,6 +110,7 @@ private:
public: public:
GLSharedGroup(); GLSharedGroup();
~GLSharedGroup(); ~GLSharedGroup();
bool isObject(GLuint obj);
BufferData * getBufferData(GLuint bufferId); BufferData * getBufferData(GLuint bufferId);
void addBufferData(GLuint bufferId, GLsizeiptr size, void * data); void addBufferData(GLuint bufferId, GLsizeiptr size, void * data);
void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data); void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data);

View File

@@ -464,19 +464,19 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
switch(i) { switch(i) {
case GLClientState::VERTEX_LOCATION: case GLClientState::VERTEX_LOCATION:
this->glVertexPointerOffset(this, state->size, state->type, state->stride, this->glVertexPointerOffset(this, state->size, state->type, state->stride,
(GLuint)state->data + firstIndex); (uintptr_t)state->data + firstIndex);
break; break;
case GLClientState::NORMAL_LOCATION: case GLClientState::NORMAL_LOCATION:
this->glNormalPointerOffset(this, state->type, state->stride, this->glNormalPointerOffset(this, state->type, state->stride,
(GLuint) state->data + firstIndex); (uintptr_t)state->data + firstIndex);
break; break;
case GLClientState::POINTSIZE_LOCATION: case GLClientState::POINTSIZE_LOCATION:
this->glPointSizePointerOffset(this, state->type, state->stride, this->glPointSizePointerOffset(this, state->type, state->stride,
(GLuint) state->data + firstIndex); (uintptr_t)state->data + firstIndex);
break; break;
case GLClientState::COLOR_LOCATION: case GLClientState::COLOR_LOCATION:
this->glColorPointerOffset(this, state->size, state->type, state->stride, this->glColorPointerOffset(this, state->size, state->type, state->stride,
(GLuint) state->data + firstIndex); (uintptr_t)state->data + firstIndex);
break; break;
case GLClientState::TEXCOORD0_LOCATION: case GLClientState::TEXCOORD0_LOCATION:
case GLClientState::TEXCOORD1_LOCATION: case GLClientState::TEXCOORD1_LOCATION:
@@ -487,17 +487,17 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
case GLClientState::TEXCOORD6_LOCATION: case GLClientState::TEXCOORD6_LOCATION:
case GLClientState::TEXCOORD7_LOCATION: case GLClientState::TEXCOORD7_LOCATION:
this->glTexCoordPointerOffset(this, state->size, state->type, state->stride, this->glTexCoordPointerOffset(this, state->size, state->type, state->stride,
(GLuint) state->data + firstIndex); (uintptr_t)state->data + firstIndex);
break; break;
case GLClientState::WEIGHT_LOCATION: case GLClientState::WEIGHT_LOCATION:
this->glWeightPointerOffset(this,state->size,state->type,state->stride, this->glWeightPointerOffset(this,state->size,state->type,state->stride,
(GLuint)state->data+firstIndex); (uintptr_t)state->data+firstIndex);
break; break;
case GLClientState::MATRIXINDEX_LOCATION: case GLClientState::MATRIXINDEX_LOCATION:
this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
(GLuint)state->data+firstIndex); (uintptr_t)state->data+firstIndex);
break; break;
} }
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
} }
} else { } else {
@@ -545,14 +545,14 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
if (!has_immediate_arrays) { if (!has_immediate_arrays) {
ctx->sendVertexData(0, count); ctx->sendVertexData(0, count);
ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); 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; adjustIndices = false;
} else { } else {
BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
} }
} }
if (adjustIndices) { if (adjustIndices) {
void *adjustedIndices = (void*)indices; void *adjustedIndices = (void*)indices;
int minIndex = 0, maxIndex = 0; int minIndex = 0, maxIndex = 0;

View File

@@ -79,6 +79,11 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader); m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader);
m_glAttachShader_enc = set_glAttachShader(s_glAttachShader); m_glAttachShader_enc = set_glAttachShader(s_glAttachShader);
m_glDetachShader_enc = set_glDetachShader(s_glDetachShader); 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_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation);
m_glUseProgram_enc = set_glUseProgram(s_glUseProgram); 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_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri); m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv); m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
m_glTexImage2D_enc = set_glTexImage2D(s_glTexImage2D);
} }
GL2Encoder::~GL2Encoder() 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) void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
{ {
GL2Encoder *ctx = (GL2Encoder *) self; 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); GLuint bufferId = ctx->m_state->getBuffer(target);
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
SET_ERROR_IF(size<0, GL_INVALID_VALUE); 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) void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
{ {
GL2Encoder *ctx = (GL2Encoder *) self; 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); GLuint bufferId = ctx->m_state->getBuffer(target);
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 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); SET_ERROR_IF(n<0, GL_INVALID_VALUE);
for (int i=0; i<n; i++) { for (int i=0; i<n; i++) {
ctx->m_shared->deleteBufferData(buffers[i]); ctx->m_shared->deleteBufferData(buffers[i]);
ctx->m_state->unBindBuffer(buffers[i]);
ctx->m_glDeleteBuffers_enc(self,1,&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)) { if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
ctx->m_glGetBooleanv_enc(self, param, ptr); ctx->m_glGetBooleanv_enc(self, param, ptr);
} }
*ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
break; break;
} }
} }
@@ -424,15 +434,15 @@ void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
int stride = state->stride == 0 ? state->elementSize : state->stride; int stride = state->stride == 0 ? state->elementSize : state->stride;
int firstIndex = stride * first; int firstIndex = stride * first;
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
if (state->bufferObject == 0) { if (state->bufferObject == 0) {
this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride, this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
(unsigned char *)state->data + firstIndex, datalen); (unsigned char *)state->data + firstIndex, datalen);
} else { } else {
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride, this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
(GLuint) state->data + firstIndex); (uintptr_t) state->data + firstIndex);
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
} }
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
} else { } else {
this->m_glDisableVertexAttribArray_enc(this, i); 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) { if (!has_immediate_arrays) {
ctx->sendVertexAttributes(0, count); ctx->sendVertexAttributes(0, count);
ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); 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; adjustIndices = false;
} else { } else {
BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
} }
} }
if (adjustIndices) { if (adjustIndices) {
void *adjustedIndices = (void*)indices; void *adjustedIndices = (void*)indices;
int minIndex = 0, maxIndex = 0; int minIndex = 0, maxIndex = 0;
@@ -637,7 +647,9 @@ void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, cons
{ {
GL2Encoder* ctx = (GL2Encoder*)self; GL2Encoder* ctx = (GL2Encoder*)self;
ShaderData* shaderData = ctx->m_shared->getShaderData(shader); 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); int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
char *str = new char[len + 1]; char *str = new char[len + 1];
@@ -686,7 +698,7 @@ void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
GLchar *name = new GLchar[maxLength+1]; GLchar *name = new GLchar[maxLength+1];
GLint location; GLint location;
//for each active uniform, get its size and starting 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); ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
location = ctx->m_glGetUniformLocation_enc(self, program, name); location = ctx->m_glGetUniformLocation_enc(self, program, name);
@@ -746,6 +758,38 @@ GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
return shader; 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) void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
{ {
GL2Encoder *ctx = (GL2Encoder*)self; 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) { if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
return -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, void GL2Encoder::s_glTexParameteriv(void* self,
GLenum target, GLenum pname, const GLint* params) GLenum target, GLenum pname, const GLint* params)
{ {

View File

@@ -74,7 +74,7 @@ private:
glBindBuffer_client_proc_t m_glBindBuffer_enc; glBindBuffer_client_proc_t m_glBindBuffer_enc;
static void s_glBindBuffer(void *self, GLenum target, GLuint id); static void s_glBindBuffer(void *self, GLenum target, GLuint id);
glBufferData_client_proc_t m_glBufferData_enc; glBufferData_client_proc_t m_glBufferData_enc;
static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
glBufferSubData_client_proc_t m_glBufferSubData_enc; glBufferSubData_client_proc_t m_glBufferSubData_enc;
@@ -148,6 +148,22 @@ private:
glDetachShader_client_proc_t m_glDetachShader_enc; glDetachShader_client_proc_t m_glDetachShader_enc;
static void s_glDetachShader(void *self, GLuint program, GLuint shader); 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; glGetUniformLocation_client_proc_t m_glGetUniformLocation_enc;
static int s_glGetUniformLocation(void *self, GLuint program, const GLchar *name); static int s_glGetUniformLocation(void *self, GLuint program, const GLchar *name);
glUseProgram_client_proc_t m_glUseProgram_enc; glUseProgram_client_proc_t m_glUseProgram_enc;
@@ -202,6 +218,7 @@ private:
glTexParameterfv_client_proc_t m_glTexParameterfv_enc; glTexParameterfv_client_proc_t m_glTexParameterfv_enc;
glTexParameteri_client_proc_t m_glTexParameteri_enc; glTexParameteri_client_proc_t m_glTexParameteri_enc;
glTexParameteriv_client_proc_t m_glTexParameteriv_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_glActiveTexture(void* self, GLenum texture);
static void s_glBindTexture(void* self, GLenum target, GLuint 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_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_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_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 #endif

View File

@@ -7,7 +7,7 @@
#include "gl2_types.h" #include "gl2_types.h"
#ifndef gl2_APIENTRY #ifndef gl2_APIENTRY
#define gl2_APIENTRY #define gl2_APIENTRY
#endif #endif
typedef void (gl2_APIENTRY *glActiveTexture_client_proc_t) (void * ctx, GLenum); typedef void (gl2_APIENTRY *glActiveTexture_client_proc_t) (void * ctx, GLenum);
typedef void (gl2_APIENTRY *glAttachShader_client_proc_t) (void * ctx, GLuint, GLuint); typedef void (gl2_APIENTRY *glAttachShader_client_proc_t) (void * ctx, GLuint, GLuint);

View File

@@ -1162,7 +1162,7 @@ void glGetProgramInfoLog_enc(void *self , GLuint program, GLsizei bufsize, GLsiz
gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self; gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
IOStream *stream = ctx->m_stream; IOStream *stream = ctx->m_stream;
const unsigned int __size_length = sizeof(GLsizei); const unsigned int __size_length = ((length != NULL) ? (sizeof(GLsizei)) : 0);
const unsigned int __size_infolog = bufsize; const unsigned int __size_infolog = bufsize;
unsigned char *ptr; unsigned char *ptr;
const size_t packetSize = 8 + 4 + 4 + __size_length + __size_infolog + 2*4; const size_t packetSize = 8 + 4 + 4 + __size_length + __size_infolog + 2*4;
@@ -1174,7 +1174,7 @@ void glGetProgramInfoLog_enc(void *self , GLuint program, GLsizei bufsize, GLsiz
memcpy(ptr, &bufsize, 4); ptr += 4; memcpy(ptr, &bufsize, 4); ptr += 4;
*(unsigned int *)(ptr) = __size_length; ptr += 4; *(unsigned int *)(ptr) = __size_length; ptr += 4;
*(unsigned int *)(ptr) = __size_infolog; ptr += 4; *(unsigned int *)(ptr) = __size_infolog; ptr += 4;
stream->readback(length, __size_length); if (length != NULL) stream->readback(length, __size_length);
stream->readback(infolog, __size_infolog); stream->readback(infolog, __size_infolog);
} }
@@ -1923,7 +1923,7 @@ void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset,
gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self; gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
IOStream *stream = ctx->m_stream; IOStream *stream = ctx->m_stream;
const unsigned int __size_pixels = pixelDataSize(self, width, height, format, type, 0); const unsigned int __size_pixels = ((pixels != NULL) ? pixelDataSize(self, width, height, format, type, 0) : 0);
unsigned char *ptr; unsigned char *ptr;
const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4; const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4); ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
@@ -1940,7 +1940,7 @@ void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset,
memcpy(ptr, &type, 4); ptr += 4; memcpy(ptr, &type, 4); ptr += 4;
stream->flush(); stream->flush();
stream->writeFully(&__size_pixels,4); stream->writeFully(&__size_pixels,4);
stream->writeFully(pixels, __size_pixels); if (pixels != NULL) stream->writeFully(pixels, __size_pixels);
} }
void glUniform1f_enc(void *self , GLint location, GLfloat x) void glUniform1f_enc(void *self , GLint location, GLfloat x)

View File

@@ -231,4 +231,4 @@ extern "C" {
void glShaderString_enc(void *self , GLuint shader, const GLchar* string, GLsizei len); void glShaderString_enc(void *self , GLuint shader, const GLchar* string, GLsizei len);
int glFinishRoundTrip_enc(void *self ); int glFinishRoundTrip_enc(void *self );
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@ QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) :
QemuPipeStream::~QemuPipeStream() QemuPipeStream::~QemuPipeStream()
{ {
if (m_sock >= 0) { if (m_sock >= 0) {
flush();
::close(m_sock); ::close(m_sock);
} }
if (m_buf != NULL) { if (m_buf != NULL) {
@@ -86,6 +87,10 @@ int QemuPipeStream::writeFully(const void *buf, size_t len)
{ {
//DBG(">> QemuPipeStream::writeFully %d\n", len); //DBG(">> QemuPipeStream::writeFully %d\n", len);
if (!valid()) return -1; if (!valid()) return -1;
if (!buf) {
if (len>0) ERR("QemuPipeStream::writeFully failed, buf=NULL, len %d", len);
return 0;
}
size_t res = len; size_t res = len;
int retval = 0; int retval = 0;

View File

@@ -24,6 +24,7 @@ static void tlsDestruct(void *ptr)
EGLThreadInfo *ti = (EGLThreadInfo *)ptr; EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
delete ti->hostConn; delete ti->hostConn;
delete ti; delete ti;
((intptr_t *)__get_tls())[TLS_SLOT_OPENGL] = NULL;
} }
} }

View File

@@ -40,10 +40,10 @@ EGLThreadInfo *slow_getEGLThreadInfo();
// We have a dedicated TLS slot in bionic // We have a dedicated TLS slot in bionic
inline EGLThreadInfo* getEGLThreadInfo() { inline EGLThreadInfo* getEGLThreadInfo() {
EGLThreadInfo *tInfo = EGLThreadInfo *tInfo =
(EGLThreadInfo *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]); (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]);
if (!tInfo) { if (!tInfo) {
tInfo = slow_getEGLThreadInfo(); 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; return tInfo;
} }

View File

@@ -30,13 +30,14 @@
struct cb_handle_t : public native_handle { struct cb_handle_t : public native_handle {
cb_handle_t(int p_fd, int p_ashmemSize, int p_usage, cb_handle_t(int p_fd, int p_ashmemSize, int p_usage,
int p_width, int p_height, int p_format, int p_width, int p_height, int p_frameworkFormat,
int p_glFormat, int p_glType) : int p_format, int p_glFormat, int p_glType) :
fd(p_fd), fd(p_fd),
magic(BUFFER_HANDLE_MAGIC), magic(BUFFER_HANDLE_MAGIC),
usage(p_usage), usage(p_usage),
width(p_width), width(p_width),
height(p_height), height(p_height),
frameworkFormat(p_frameworkFormat),
format(p_format), format(p_format),
glFormat(p_glFormat), glFormat(p_glFormat),
glType(p_glType), glType(p_glType),
@@ -70,8 +71,8 @@ struct cb_handle_t : public native_handle {
numInts = CB_HANDLE_NUM_INTS(numFds); numInts = CB_HANDLE_NUM_INTS(numFds);
} }
static bool validate(cb_handle_t * hnd) { static bool validate(const cb_handle_t* hnd) {
return (hnd && return (hnd &&
hnd->version == sizeof(native_handle) && hnd->version == sizeof(native_handle) &&
hnd->magic == BUFFER_HANDLE_MAGIC && hnd->magic == BUFFER_HANDLE_MAGIC &&
hnd->numInts == CB_HANDLE_NUM_INTS(hnd->numFds)); hnd->numInts == CB_HANDLE_NUM_INTS(hnd->numFds));
@@ -89,12 +90,17 @@ struct cb_handle_t : public native_handle {
int usage; // usage bits the buffer was created with int usage; // usage bits the buffer was created with
int width; // buffer width int width; // buffer width
int height; // buffer height int height; // buffer height
int frameworkFormat; // format requested by the Android framework
int format; // real internal pixel format format int format; // real internal pixel format format
int glFormat; // OpenGL format enum used for host h/w color buffer int glFormat; // OpenGL format enum used for host h/w color buffer
int glType; // OpenGL type enum used when uploading to host int glType; // OpenGL type enum used when uploading to host
int ashmemSize; // ashmem region size for the buffer (0 unless is HW_FB buffer or int ashmemSize; // ashmem region size for the buffer (0 unless is HW_FB buffer or
// s/w access is needed) // s/w access is needed)
int ashmemBase; // CPU address of the mapped ashmem region union {
intptr_t ashmemBase; // CPU address of the mapped ashmem region
uint64_t padding; // enforce same size on 32-bit/64-bit
} __attribute__((aligned(8)));
int ashmemBasePid; // process id which mapped the ashmem region int ashmemBasePid; // process id which mapped the ashmem region
int mappedPid; // process id which succeeded gralloc_register call int mappedPid; // process id which succeeded gralloc_register call
int lockedLeft; // region of buffer locked for s/w write int lockedLeft; // region of buffer locked for s/w write

View File

@@ -86,7 +86,7 @@ const char * eglStrError(EGLint err)
#endif //LOG_EGL_ERRORS #endif //LOG_EGL_ERRORS
#define VALIDATE_CONFIG(cfg,ret) \ #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); \ RETURN_ERROR(ret,EGL_BAD_CONFIG); \
} }
@@ -140,7 +140,9 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* share
versionString(NULL), versionString(NULL),
vendorString(NULL), vendorString(NULL),
rendererString(NULL), rendererString(NULL),
extensionString(NULL) shaderVersionString(NULL),
extensionString(NULL),
deletePending(0)
{ {
flags = 0; flags = 0;
version = 1; version = 1;
@@ -157,6 +159,7 @@ EGLContext_t::~EGLContext_t()
delete [] versionString; delete [] versionString;
delete [] vendorString; delete [] vendorString;
delete [] rendererString; delete [] rendererString;
delete [] shaderVersionString;
delete [] extensionString; delete [] extensionString;
} }
@@ -268,7 +271,7 @@ EGLBoolean egl_window_surface_t::init()
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
getWidth(), getHeight()); getWidth(), getHeight());
if (!rcSurface) { if (!rcSurface) {
ALOGE("rcCreateWindowSurface returned 0"); ALOGE("rcCreateWindowSurface returned 0");
@@ -371,7 +374,7 @@ EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
{ {
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
getWidth(), getHeight()); getWidth(), getHeight());
if (!rcSurface) { if (!rcSurface) {
ALOGE("rcCreateWindowSurface returned 0"); ALOGE("rcCreateWindowSurface returned 0");
@@ -415,6 +418,7 @@ static const char *getGLString(int glEnum)
#define GL_VENDOR 0x1F00 #define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01 #define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02 #define GL_VERSION 0x1F02
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_EXTENSIONS 0x1F03 #define GL_EXTENSIONS 0x1F03
switch(glEnum) { switch(glEnum) {
@@ -427,6 +431,9 @@ static const char *getGLString(int glEnum)
case GL_RENDERER: case GL_RENDERER:
strPtr = &tInfo->currentContext->rendererString; strPtr = &tInfo->currentContext->rendererString;
break; break;
case GL_SHADING_LANGUAGE_VERSION:
strPtr = &tInfo->currentContext->shaderVersionString;
break;
case GL_EXTENSIONS: case GL_EXTENSIONS:
strPtr = &tInfo->currentContext->extensionString; strPtr = &tInfo->currentContext->extensionString;
break; break;
@@ -526,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 // look in gles client api's extensions table
return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname); return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname);
@@ -563,7 +561,7 @@ EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size,
return EGL_TRUE; return EGL_TRUE;
} }
int i=0; uintptr_t i=0;
for (i=0 ; i<numConfigs && i<config_size ; i++) { for (i=0 ; i<numConfigs && i<config_size ; i++) {
*configs++ = (EGLConfig)i; *configs++ = (EGLConfig)i;
} }
@@ -585,9 +583,18 @@ EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig
attribs_size++; //for the terminating EGL_NONE attribs_size++; //for the terminating EGL_NONE
} }
uint32_t* tempConfigs[config_size];
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 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; return EGL_TRUE;
} }
@@ -873,7 +880,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); 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) { if (!rcContext) {
ALOGE("rcCreateContext returned 0"); ALOGE("rcCreateContext returned 0");
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
@@ -897,9 +904,11 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
EGLContext_t * context = static_cast<EGLContext_t*>(ctx); EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
if (getEGLThreadInfo()->currentContext == context) if (!context) return EGL_TRUE;
{
eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); if (getEGLThreadInfo()->currentContext == context) {
getEGLThreadInfo()->currentContext->deletePending = 1;
return EGL_TRUE;
} }
if (context->rcContext) { if (context->rcContext) {
@@ -934,12 +943,21 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
// Nothing to do if no binding change has made // Nothing to do if no binding change has made
// //
EGLThreadInfo *tInfo = getEGLThreadInfo(); EGLThreadInfo *tInfo = getEGLThreadInfo();
if (tInfo->currentContext == context && if (tInfo->currentContext == context &&
(context == NULL || (context == NULL ||
(context && context->draw == draw && context->read == read))) { (context && context->draw == draw && context->read == read))) {
return EGL_TRUE; 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)) { if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
//context is current to another thread //context is current to another thread
setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
@@ -966,7 +984,7 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
} }
} }
else { else if (tInfo->currentContext) {
//release ClientState & SharedGroup //release ClientState & SharedGroup
if (tInfo->currentContext->version == 2) { if (tInfo->currentContext->version == 2) {
hostCon->gl2Encoder()->setClientState(NULL); hostCon->gl2Encoder()->setClientState(NULL);

View File

@@ -39,8 +39,9 @@ struct EGLContext_t {
const char* versionString; const char* versionString;
const char* vendorString; const char* vendorString;
const char* rendererString; const char* rendererString;
const char* shaderVersionString;
const char* extensionString; const char* extensionString;
EGLint deletePending;
GLClientState * getClientState(){ return clientState; } GLClientState * getClientState(){ return clientState; }
GLSharedGroupPtr getSharedGroup(){ return sharedGroup; } GLSharedGroupPtr getSharedGroup(){ return sharedGroup; }
private: private:

View File

@@ -84,9 +84,15 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
// //
// load GLES client API // 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", m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so",
eglIface, eglIface,
&s_gles_lib); &s_gles_lib);
#endif
if (!m_gles_iface) { if (!m_gles_iface) {
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
ALOGE("Failed to load gles1 iface"); ALOGE("Failed to load gles1 iface");
@@ -94,9 +100,15 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
} }
#ifdef WITH_GLES2 #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", m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so",
eglIface, eglIface,
&s_gles2_lib); &s_gles2_lib);
#endif
// Note that if loading gles2 failed, we can still run with no // Note that if loading gles2 failed, we can still run with no
// GLES2 support, having GLES2 is not mandatory. // GLES2 support, having GLES2 is not mandatory.
#endif #endif
@@ -189,7 +201,7 @@ bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
void eglDisplay::processConfigs() void eglDisplay::processConfigs()
{ {
for (int i=0; i<m_numConfigs; i++) { for (intptr_t i=0; i<m_numConfigs; i++) {
EGLConfig config = (EGLConfig)i; EGLConfig config = (EGLConfig)i;
//Setup the EGL_NATIVE_VISUAL_ID attribute //Setup the EGL_NATIVE_VISUAL_ID attribute
PixelFormat format; PixelFormat format;
@@ -401,7 +413,7 @@ EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint
ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
return EGL_FALSE; return EGL_FALSE;
} }
*value = *(m_configs + (int)config*m_numConfigAttribs + attribIdx); *value = *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx);
return EGL_TRUE; return EGL_TRUE;
} }
@@ -434,7 +446,7 @@ EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint
ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
return EGL_FALSE; return EGL_FALSE;
} }
*(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value; *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx) = value;
return EGL_TRUE; return EGL_TRUE;
} }

View File

@@ -15,11 +15,7 @@
*/ */
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define #include <limits.h>
# include <asm/page.h>
#else
# include <sys/user.h>
#endif
#include <cutils/ashmem.h> #include <cutils/ashmem.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
@@ -154,6 +150,8 @@ static int gralloc_alloc(alloc_device_t* dev,
bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ; bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ;
bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER; bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
// Keep around original requested format for later validation
int frameworkFormat = format;
// Pick the right concrete pixel format given the endpoints as encoded in // Pick the right concrete pixel format given the endpoints as encoded in
// the usage bits. Every end-point pair needs explicit listing here. // the usage bits. Every end-point pair needs explicit listing here.
if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
@@ -179,7 +177,6 @@ static int gralloc_alloc(alloc_device_t* dev,
return -EINVAL; return -EINVAL;
} }
} }
bool yuv_format = false; bool yuv_format = false;
int ashmem_size = 0; int ashmem_size = 0;
@@ -297,7 +294,8 @@ static int gralloc_alloc(alloc_device_t* dev,
} }
cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage, cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
w, h, format, glFormat, glType); w, h, frameworkFormat, format,
glFormat, glType);
if (ashmem_size > 0) { if (ashmem_size > 0) {
// //
@@ -444,7 +442,7 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
DEFINE_AND_VALIDATE_HOST_CONNECTION; DEFINE_AND_VALIDATE_HOST_CONNECTION;
// increment the post count of the buffer // increment the post count of the buffer
uint32_t *postCountPtr = (uint32_t *)cb->ashmemBase; intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
if (!postCountPtr) { if (!postCountPtr) {
// This should not happen // This should not happen
return -EINVAL; return -EINVAL;
@@ -529,7 +527,7 @@ static int gralloc_register_buffer(gralloc_module_t const* module,
if (cb->hostHandle != 0) { if (cb->hostHandle != 0) {
DEFINE_AND_VALIDATE_HOST_CONNECTION; DEFINE_AND_VALIDATE_HOST_CONNECTION;
D("Opening host ColorBuffer 0x%x\n", cb->hostHandle); D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
rcEnc->rcOpenColorBuffer(rcEnc, cb->hostHandle); rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
} }
// //
@@ -580,7 +578,7 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module,
ERR("gralloc_unregister_buffer(%p): unmap failed", cb); ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
return -EINVAL; return -EINVAL;
} }
cb->ashmemBase = NULL; cb->ashmemBase = 0;
cb->mappedPid = 0; cb->mappedPid = 0;
} }
@@ -630,7 +628,7 @@ static int gralloc_lock(gralloc_module_t const* module,
return -EINVAL; return -EINVAL;
} }
EGLint postCount = 0; intptr_t postCount = 0;
void *cpu_addr = NULL; void *cpu_addr = NULL;
// //
@@ -644,8 +642,8 @@ static int gralloc_lock(gralloc_module_t const* module,
} }
if (cb->canBePosted()) { if (cb->canBePosted()) {
postCount = *((int *)cb->ashmemBase); postCount = *((intptr_t *)cb->ashmemBase);
cpu_addr = (void *)(cb->ashmemBase + sizeof(int)); cpu_addr = (void *)(cb->ashmemBase + sizeof(intptr_t));
} }
else { else {
cpu_addr = (void *)(cb->ashmemBase); cpu_addr = (void *)(cb->ashmemBase);
@@ -916,7 +914,11 @@ fallback_init(void)
return; return;
} }
ALOGD("Emulator without GPU emulation detected."); ALOGD("Emulator without GPU emulation detected.");
#if __LP64__
module = dlopen("/system/lib64/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
#else
module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL); module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
#endif
if (module != NULL) { if (module != NULL) {
sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR)); sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
if (sFallback == NULL) { if (sFallback == NULL) {

View File

@@ -37,6 +37,7 @@ int renderControl_client_context_t::initDispatchByName(void *(*getProc)(const ch
ptr = getProc("rcColorBufferCacheFlush", userData); set_rcColorBufferCacheFlush((rcColorBufferCacheFlush_client_proc_t)ptr); ptr = getProc("rcColorBufferCacheFlush", userData); set_rcColorBufferCacheFlush((rcColorBufferCacheFlush_client_proc_t)ptr);
ptr = getProc("rcReadColorBuffer", userData); set_rcReadColorBuffer((rcReadColorBuffer_client_proc_t)ptr); ptr = getProc("rcReadColorBuffer", userData); set_rcReadColorBuffer((rcReadColorBuffer_client_proc_t)ptr);
ptr = getProc("rcUpdateColorBuffer", userData); set_rcUpdateColorBuffer((rcUpdateColorBuffer_client_proc_t)ptr); ptr = getProc("rcUpdateColorBuffer", userData); set_rcUpdateColorBuffer((rcUpdateColorBuffer_client_proc_t)ptr);
ptr = getProc("rcOpenColorBuffer2", userData); set_rcOpenColorBuffer2((rcOpenColorBuffer2_client_proc_t)ptr);
return 0; return 0;
} }

View File

@@ -33,6 +33,7 @@ struct renderControl_client_context_t {
rcColorBufferCacheFlush_client_proc_t rcColorBufferCacheFlush; rcColorBufferCacheFlush_client_proc_t rcColorBufferCacheFlush;
rcReadColorBuffer_client_proc_t rcReadColorBuffer; rcReadColorBuffer_client_proc_t rcReadColorBuffer;
rcUpdateColorBuffer_client_proc_t rcUpdateColorBuffer; rcUpdateColorBuffer_client_proc_t rcUpdateColorBuffer;
rcOpenColorBuffer2_client_proc_t rcOpenColorBuffer2;
//Accessors //Accessors
virtual rcGetRendererVersion_client_proc_t set_rcGetRendererVersion(rcGetRendererVersion_client_proc_t f) { rcGetRendererVersion_client_proc_t retval = rcGetRendererVersion; rcGetRendererVersion = f; return retval;} virtual rcGetRendererVersion_client_proc_t set_rcGetRendererVersion(rcGetRendererVersion_client_proc_t f) { rcGetRendererVersion_client_proc_t retval = rcGetRendererVersion; rcGetRendererVersion = f; return retval;}
virtual rcGetEGLVersion_client_proc_t set_rcGetEGLVersion(rcGetEGLVersion_client_proc_t f) { rcGetEGLVersion_client_proc_t retval = rcGetEGLVersion; rcGetEGLVersion = f; return retval;} virtual rcGetEGLVersion_client_proc_t set_rcGetEGLVersion(rcGetEGLVersion_client_proc_t f) { rcGetEGLVersion_client_proc_t retval = rcGetEGLVersion; rcGetEGLVersion = f; return retval;}
@@ -59,6 +60,7 @@ struct renderControl_client_context_t {
virtual rcColorBufferCacheFlush_client_proc_t set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_client_proc_t f) { rcColorBufferCacheFlush_client_proc_t retval = rcColorBufferCacheFlush; rcColorBufferCacheFlush = f; return retval;} virtual rcColorBufferCacheFlush_client_proc_t set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_client_proc_t f) { rcColorBufferCacheFlush_client_proc_t retval = rcColorBufferCacheFlush; rcColorBufferCacheFlush = f; return retval;}
virtual rcReadColorBuffer_client_proc_t set_rcReadColorBuffer(rcReadColorBuffer_client_proc_t f) { rcReadColorBuffer_client_proc_t retval = rcReadColorBuffer; rcReadColorBuffer = f; return retval;} virtual rcReadColorBuffer_client_proc_t set_rcReadColorBuffer(rcReadColorBuffer_client_proc_t f) { rcReadColorBuffer_client_proc_t retval = rcReadColorBuffer; rcReadColorBuffer = f; return retval;}
virtual rcUpdateColorBuffer_client_proc_t set_rcUpdateColorBuffer(rcUpdateColorBuffer_client_proc_t f) { rcUpdateColorBuffer_client_proc_t retval = rcUpdateColorBuffer; rcUpdateColorBuffer = f; return retval;} virtual rcUpdateColorBuffer_client_proc_t set_rcUpdateColorBuffer(rcUpdateColorBuffer_client_proc_t f) { rcUpdateColorBuffer_client_proc_t retval = rcUpdateColorBuffer; rcUpdateColorBuffer = f; return retval;}
virtual rcOpenColorBuffer2_client_proc_t set_rcOpenColorBuffer2(rcOpenColorBuffer2_client_proc_t f) { rcOpenColorBuffer2_client_proc_t retval = rcOpenColorBuffer2; rcOpenColorBuffer2 = f; return retval;}
virtual ~renderControl_client_context_t() {} virtual ~renderControl_client_context_t() {}
typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void); typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);

View File

@@ -34,6 +34,7 @@ typedef void (renderControl_APIENTRY *rcBindRenderbuffer_client_proc_t) (void *
typedef EGLint (renderControl_APIENTRY *rcColorBufferCacheFlush_client_proc_t) (void * ctx, uint32_t, EGLint, int); typedef EGLint (renderControl_APIENTRY *rcColorBufferCacheFlush_client_proc_t) (void * ctx, uint32_t, EGLint, int);
typedef void (renderControl_APIENTRY *rcReadColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*); typedef void (renderControl_APIENTRY *rcReadColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*);
typedef int (renderControl_APIENTRY *rcUpdateColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*); typedef int (renderControl_APIENTRY *rcUpdateColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*);
typedef int (renderControl_APIENTRY *rcOpenColorBuffer2_client_proc_t) (void * ctx, uint32_t);
#endif #endif

View File

@@ -311,6 +311,8 @@ void rcCloseColorBuffer_enc(void *self , uint32_t colorbuffer)
memcpy(ptr, &packetSize, 4); ptr += 4; memcpy(ptr, &packetSize, 4); ptr += 4;
memcpy(ptr, &colorbuffer, 4); ptr += 4; memcpy(ptr, &colorbuffer, 4); ptr += 4;
stream->flush();
} }
void rcSetWindowColorBuffer_enc(void *self , uint32_t windowSurface, uint32_t colorBuffer) void rcSetWindowColorBuffer_enc(void *self , uint32_t windowSurface, uint32_t colorBuffer)
@@ -503,6 +505,25 @@ int rcUpdateColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y,
return retval; return retval;
} }
int rcOpenColorBuffer2_enc(void *self , uint32_t colorbuffer)
{
renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
IOStream *stream = ctx->m_stream;
unsigned char *ptr;
const size_t packetSize = 8 + 4;
ptr = stream->alloc(packetSize);
int tmp = OP_rcOpenColorBuffer2;memcpy(ptr, &tmp, 4); ptr += 4;
memcpy(ptr, &packetSize, 4); ptr += 4;
memcpy(ptr, &colorbuffer, 4); ptr += 4;
int retval;
stream->readback(&retval, 4);
return retval;
}
renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream) renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream)
{ {
m_stream = stream; m_stream = stream;
@@ -532,5 +553,6 @@ renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *strea
set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_enc); set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_enc);
set_rcReadColorBuffer(rcReadColorBuffer_enc); set_rcReadColorBuffer(rcReadColorBuffer_enc);
set_rcUpdateColorBuffer(rcUpdateColorBuffer_enc); set_rcUpdateColorBuffer(rcUpdateColorBuffer_enc);
set_rcOpenColorBuffer2(rcOpenColorBuffer2_enc);
} }

View File

@@ -47,5 +47,6 @@ extern "C" {
EGLint rcColorBufferCacheFlush_enc(void *self , uint32_t colorbuffer, EGLint postCount, int forRead); EGLint rcColorBufferCacheFlush_enc(void *self , uint32_t colorbuffer, EGLint postCount, int forRead);
void rcReadColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels); void rcReadColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
int rcUpdateColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels); int rcUpdateColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
int rcOpenColorBuffer2_enc(void *self , uint32_t colorbuffer);
}; };
#endif #endif

View File

@@ -31,6 +31,7 @@ extern "C" {
EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead); EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead);
void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels); void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
int rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels); int rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
int rcOpenColorBuffer2(uint32_t colorbuffer);
}; };
#endif #endif
@@ -190,3 +191,9 @@ int rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLi
return ctx->rcUpdateColorBuffer(ctx, colorbuffer, x, y, width, height, format, type, pixels); return ctx->rcUpdateColorBuffer(ctx, colorbuffer, x, y, width, height, format, type, pixels);
} }
int rcOpenColorBuffer2(uint32_t colorbuffer)
{
GET_CONTEXT;
return ctx->rcOpenColorBuffer2(ctx, colorbuffer);
}

View File

@@ -33,6 +33,7 @@ static struct _renderControl_funcs_by_name {
{"rcColorBufferCacheFlush", (void*)rcColorBufferCacheFlush}, {"rcColorBufferCacheFlush", (void*)rcColorBufferCacheFlush},
{"rcReadColorBuffer", (void*)rcReadColorBuffer}, {"rcReadColorBuffer", (void*)rcReadColorBuffer},
{"rcUpdateColorBuffer", (void*)rcUpdateColorBuffer}, {"rcUpdateColorBuffer", (void*)rcUpdateColorBuffer},
{"rcOpenColorBuffer2", (void*)rcOpenColorBuffer2},
}; };
static int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name); static int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);

View File

@@ -28,7 +28,8 @@
#define OP_rcColorBufferCacheFlush 10022 #define OP_rcColorBufferCacheFlush 10022
#define OP_rcReadColorBuffer 10023 #define OP_rcReadColorBuffer 10023
#define OP_rcUpdateColorBuffer 10024 #define OP_rcUpdateColorBuffer 10024
#define OP_last 10025 #define OP_rcOpenColorBuffer2 10025
#define OP_last 10026
#endif #endif