opengles emulator: cache all buffer on the guest
This is needed to support the rare, but still legal scenario, when glDrawElemets is used with some index array data is stored in VBO's while the actual attributes (vertices) data is in immediate mode. When in immediate mode, we need to process the incodes, in order to know which vertex data to send, which was impossible without the caching. This commit introduces a new class GLSharedGroup, which will hold all data that can be shared by shared contexts (buffers are such data). This also makes the "Jet Cars Stunts" app work properly. Change-Id: Ic937080dae461bc8cdf4d10cf37066a6e847f464
This commit is contained in:
committed by
David 'Digit' Turner
parent
6208854726
commit
e99305dd9f
@@ -8,13 +8,14 @@ $(call emugl-begin-static-library,libOpenglCodecCommon)
|
|||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
GLClientState.cpp \
|
GLClientState.cpp \
|
||||||
|
GLSharedGroup.cpp \
|
||||||
glUtils.cpp \
|
glUtils.cpp \
|
||||||
TcpStream.cpp \
|
TcpStream.cpp \
|
||||||
TimeUtils.cpp
|
TimeUtils.cpp
|
||||||
|
|
||||||
LOCAL_CFLAGS += -DLOG_TAG=\"eglCodecCommon\"
|
LOCAL_CFLAGS += -DLOG_TAG=\"eglCodecCommon\"
|
||||||
|
|
||||||
$(call emugl-export,SHARED_LIBRARIES,libcutils)
|
$(call emugl-export,SHARED_LIBRARIES,libcutils libutils)
|
||||||
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
|
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
|
||||||
$(call emugl-end-module)
|
$(call emugl-end-module)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include "GLSharedGroup.h"
|
||||||
|
|
||||||
|
/**** BufferData ****/
|
||||||
|
|
||||||
|
BufferData::BufferData() : m_size(0) {};
|
||||||
|
BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size)
|
||||||
|
{
|
||||||
|
void * buffer = NULL;
|
||||||
|
if (size>0) buffer = m_fixedBuffer.alloc(size);
|
||||||
|
if (data) memcpy(buffer, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** GLSharedGroup ****/
|
||||||
|
|
||||||
|
GLSharedGroup::GLSharedGroup() :
|
||||||
|
m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GLSharedGroup::~GLSharedGroup()
|
||||||
|
{
|
||||||
|
m_buffers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
|
||||||
|
{
|
||||||
|
android::AutoMutex _lock(m_lock);
|
||||||
|
return m_buffers.valueFor(bufferId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
|
||||||
|
{
|
||||||
|
android::AutoMutex _lock(m_lock);
|
||||||
|
m_buffers.add(bufferId, new BufferData(size, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
|
||||||
|
{
|
||||||
|
android::AutoMutex _lock(m_lock);
|
||||||
|
m_buffers.replaceValueFor(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;
|
||||||
|
|
||||||
|
//it's safe to update now
|
||||||
|
memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
|
||||||
|
return GL_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSharedGroup::deleteBufferData(GLuint bufferId)
|
||||||
|
{
|
||||||
|
android::AutoMutex _lock(m_lock);
|
||||||
|
m_buffers.removeItem(bufferId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef _GL_SHARED_GROUP_H_
|
||||||
|
#define _GL_SHARED_GROUP_H_
|
||||||
|
|
||||||
|
#define GL_API
|
||||||
|
#ifndef ANDROID
|
||||||
|
#define GL_APIENTRY
|
||||||
|
#define GL_APIENTRYP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <GLES/gl.h>
|
||||||
|
#include <GLES/glext.h>
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ErrorLog.h"
|
||||||
|
#include <utils/KeyedVector.h>
|
||||||
|
#include <utils/threads.h>
|
||||||
|
#include "FixedBuffer.h"
|
||||||
|
#include "SmartPtr.h"
|
||||||
|
|
||||||
|
struct BufferData {
|
||||||
|
BufferData();
|
||||||
|
BufferData(GLsizeiptr size, void * data);
|
||||||
|
GLsizeiptr m_size;
|
||||||
|
FixedBuffer m_fixedBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GLSharedGroup {
|
||||||
|
private:
|
||||||
|
android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
|
||||||
|
mutable android::Mutex m_lock;
|
||||||
|
public:
|
||||||
|
GLSharedGroup();
|
||||||
|
~GLSharedGroup();
|
||||||
|
BufferData * getBufferData(GLuint bufferId);
|
||||||
|
void addBufferData(GLuint bufferId, GLsizeiptr size, void * data);
|
||||||
|
void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data);
|
||||||
|
GLenum subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data);
|
||||||
|
void deleteBufferData(GLuint);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr;
|
||||||
|
|
||||||
|
#endif //_GL_SHARED_GROUP_H_
|
||||||
@@ -36,6 +36,19 @@ static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this poin
|
|||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SET_ERROR_IF(condition,err) if((condition)) { \
|
||||||
|
LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
|
||||||
|
ctx->setError(err); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \
|
||||||
|
LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
|
||||||
|
ctx->setError(err); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
GLenum GLEncoder::s_glGetError(void * self)
|
GLenum GLEncoder::s_glGetError(void * self)
|
||||||
{
|
{
|
||||||
GLEncoder *ctx = (GLEncoder *)self;
|
GLEncoder *ctx = (GLEncoder *)self;
|
||||||
@@ -263,6 +276,39 @@ void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
|
|||||||
ctx->m_glBindBuffer_enc(self, target, id);
|
ctx->m_glBindBuffer_enc(self, target, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
|
||||||
|
{
|
||||||
|
GLEncoder *ctx = (GLEncoder *) self;
|
||||||
|
GLuint bufferId = ctx->m_state->getBuffer(target);
|
||||||
|
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
|
||||||
|
SET_ERROR_IF(size<0, GL_INVALID_VALUE);
|
||||||
|
|
||||||
|
ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
|
||||||
|
ctx->m_glBufferData_enc(self, target, size, data, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
|
||||||
|
{
|
||||||
|
GLEncoder *ctx = (GLEncoder *) self;
|
||||||
|
GLuint bufferId = ctx->m_state->getBuffer(target);
|
||||||
|
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
|
||||||
|
|
||||||
|
GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
|
||||||
|
SET_ERROR_IF(res, res);
|
||||||
|
|
||||||
|
ctx->m_glBufferSubData_enc(self, target, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
|
||||||
|
{
|
||||||
|
GLEncoder *ctx = (GLEncoder *) self;
|
||||||
|
SET_ERROR_IF(n<0, GL_INVALID_VALUE);
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
ctx->m_shared->deleteBufferData(buffers[i]);
|
||||||
|
ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
|
void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
|
||||||
{
|
{
|
||||||
assert(m_state != NULL);
|
assert(m_state != NULL);
|
||||||
@@ -331,7 +377,7 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->glBindBuffer(this, GL_ARRAY_BUFFER, state->bufferObject);
|
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
|
||||||
|
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case GLClientState::VERTEX_LOCATION:
|
case GLClientState::VERTEX_LOCATION:
|
||||||
@@ -369,7 +415,8 @@ void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
|
|||||||
this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
|
this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
|
||||||
(GLuint)state->data+firstIndex);
|
(GLuint)state->data+firstIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->m_glDisableClientState_enc(this, state->glConst);
|
this->m_glDisableClientState_enc(this, state->glConst);
|
||||||
@@ -390,6 +437,7 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
|
|||||||
|
|
||||||
GLEncoder *ctx = (GLEncoder *)self;
|
GLEncoder *ctx = (GLEncoder *)self;
|
||||||
assert(ctx->m_state != NULL);
|
assert(ctx->m_state != NULL);
|
||||||
|
SET_ERROR_IF(count<0, GL_INVALID_VALUE);
|
||||||
|
|
||||||
bool has_immediate_arrays = false;
|
bool has_immediate_arrays = false;
|
||||||
bool has_indirect_arrays = false;
|
bool has_indirect_arrays = false;
|
||||||
@@ -410,14 +458,20 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool adjustIndices = true;
|
||||||
if (ctx->m_state->currentIndexVbo() != 0) {
|
if (ctx->m_state->currentIndexVbo() != 0) {
|
||||||
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->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
|
ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
|
||||||
|
adjustIndices = false;
|
||||||
} else {
|
} else {
|
||||||
LOGE("glDrawElements: indirect index arrays, with immidate-mode data array is not supported\n");
|
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);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (adjustIndices) {
|
||||||
void *adjustedIndices = (void*)indices;
|
void *adjustedIndices = (void*)indices;
|
||||||
int minIndex = 0, maxIndex = 0;
|
int minIndex = 0, maxIndex = 0;
|
||||||
|
|
||||||
@@ -487,6 +541,10 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
|
|||||||
m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv);
|
m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv);
|
||||||
|
|
||||||
m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
|
m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
|
||||||
|
m_glBufferData_enc = set_glBufferData(s_glBufferData);
|
||||||
|
m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
|
||||||
|
m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
|
||||||
|
|
||||||
m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState);
|
m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState);
|
||||||
m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState);
|
m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState);
|
||||||
m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled);
|
m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "gl_enc.h"
|
#include "gl_enc.h"
|
||||||
#include "GLClientState.h"
|
#include "GLClientState.h"
|
||||||
|
#include "GLSharedGroup.h"
|
||||||
#include "FixedBuffer.h"
|
#include "FixedBuffer.h"
|
||||||
|
|
||||||
class GLEncoder : public gl_encoder_context_t {
|
class GLEncoder : public gl_encoder_context_t {
|
||||||
@@ -28,6 +29,7 @@ public:
|
|||||||
void setClientState(GLClientState *state) {
|
void setClientState(GLClientState *state) {
|
||||||
m_state = state;
|
m_state = state;
|
||||||
}
|
}
|
||||||
|
void setSharedGroup(GLSharedGroupPtr shared) { m_shared = shared; }
|
||||||
void flush() { m_stream->flush(); }
|
void flush() { m_stream->flush(); }
|
||||||
size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
|
size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
|
||||||
|
|
||||||
@@ -41,6 +43,7 @@ private:
|
|||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
GLClientState *m_state;
|
GLClientState *m_state;
|
||||||
|
GLSharedGroupPtr m_shared;
|
||||||
GLenum m_error;
|
GLenum m_error;
|
||||||
FixedBuffer m_fixedBuffer;
|
FixedBuffer m_fixedBuffer;
|
||||||
GLint *m_compressedTextureFormats;
|
GLint *m_compressedTextureFormats;
|
||||||
@@ -66,6 +69,10 @@ private:
|
|||||||
glWeightPointerOES_client_proc_t m_glWeightPointerOES_enc;
|
glWeightPointerOES_client_proc_t m_glWeightPointerOES_enc;
|
||||||
|
|
||||||
glBindBuffer_client_proc_t m_glBindBuffer_enc;
|
glBindBuffer_client_proc_t m_glBindBuffer_enc;
|
||||||
|
glBufferData_client_proc_t m_glBufferData_enc;
|
||||||
|
glBufferSubData_client_proc_t m_glBufferSubData_enc;
|
||||||
|
glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc;
|
||||||
|
|
||||||
glEnableClientState_client_proc_t m_glEnableClientState_enc;
|
glEnableClientState_client_proc_t m_glEnableClientState_enc;
|
||||||
glDisableClientState_client_proc_t m_glDisableClientState_enc;
|
glDisableClientState_client_proc_t m_glDisableClientState_enc;
|
||||||
glIsEnabled_client_proc_t m_glIsEnabled_enc;
|
glIsEnabled_client_proc_t m_glIsEnabled_enc;
|
||||||
@@ -95,6 +102,11 @@ private:
|
|||||||
static void s_glEnableClientState(void *self, GLenum state);
|
static void s_glEnableClientState(void *self, GLenum state);
|
||||||
static GLboolean s_glIsEnabled(void *self, GLenum cap);
|
static GLboolean s_glIsEnabled(void *self, GLenum cap);
|
||||||
static void s_glBindBuffer(void *self, GLenum target, GLuint id);
|
static void s_glBindBuffer(void *self, GLenum target, GLuint id);
|
||||||
|
static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||||
|
static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||||
|
static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers);
|
||||||
|
|
||||||
|
|
||||||
static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
|
static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
|
||||||
static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
|
static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||||
static void s_glPixelStorei(void *self, GLenum param, GLint value);
|
static void s_glPixelStorei(void *self, GLenum param, GLint value);
|
||||||
|
|||||||
@@ -7,6 +7,20 @@ static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0";
|
|||||||
static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
|
static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
|
||||||
static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
|
static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
|
||||||
|
|
||||||
|
#define SET_ERROR_IF(condition,err) if((condition)) { \
|
||||||
|
LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
|
||||||
|
ctx->setError(err); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \
|
||||||
|
LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
|
||||||
|
ctx->setError(err); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
|
GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
|
||||||
{
|
{
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
@@ -98,6 +112,39 @@ void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
|
|||||||
ctx->m_glBindBuffer_enc(self, target, id);
|
ctx->m_glBindBuffer_enc(self, target, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
|
||||||
|
{
|
||||||
|
GL2Encoder *ctx = (GL2Encoder *) self;
|
||||||
|
GLuint bufferId = ctx->m_state->getBuffer(target);
|
||||||
|
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
|
||||||
|
SET_ERROR_IF(size<0, GL_INVALID_VALUE);
|
||||||
|
|
||||||
|
ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
|
||||||
|
ctx->m_glBufferData_enc(self, target, size, data, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
|
||||||
|
{
|
||||||
|
GL2Encoder *ctx = (GL2Encoder *) self;
|
||||||
|
GLuint bufferId = ctx->m_state->getBuffer(target);
|
||||||
|
SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
|
||||||
|
|
||||||
|
GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
|
||||||
|
SET_ERROR_IF(res, res);
|
||||||
|
|
||||||
|
ctx->m_glBufferSubData_enc(self, target, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
|
||||||
|
{
|
||||||
|
GL2Encoder *ctx = (GL2Encoder *) self;
|
||||||
|
SET_ERROR_IF(n<0, GL_INVALID_VALUE);
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
ctx->m_shared->deleteBufferData(buffers[i]);
|
||||||
|
ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
|
void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
|
||||||
{
|
{
|
||||||
GL2Encoder *ctx = (GL2Encoder *)self;
|
GL2Encoder *ctx = (GL2Encoder *)self;
|
||||||
@@ -234,9 +281,10 @@ void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
|
|||||||
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->glBindBuffer(this, GL_ARRAY_BUFFER, state->bufferObject);
|
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);
|
(GLuint) state->data + firstIndex);
|
||||||
|
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);
|
||||||
@@ -257,6 +305,7 @@ void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
|
|||||||
|
|
||||||
GL2Encoder *ctx = (GL2Encoder *)self;
|
GL2Encoder *ctx = (GL2Encoder *)self;
|
||||||
assert(ctx->m_state != NULL);
|
assert(ctx->m_state != NULL);
|
||||||
|
SET_ERROR_IF(count<0, GL_INVALID_VALUE);
|
||||||
|
|
||||||
bool has_immediate_arrays = false;
|
bool has_immediate_arrays = false;
|
||||||
bool has_indirect_arrays = false;
|
bool has_indirect_arrays = false;
|
||||||
@@ -278,14 +327,20 @@ void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool adjustIndices = true;
|
||||||
if (ctx->m_state->currentIndexVbo() != 0) {
|
if (ctx->m_state->currentIndexVbo() != 0) {
|
||||||
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->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
|
ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
|
||||||
|
adjustIndices = false;
|
||||||
} else {
|
} else {
|
||||||
LOGE("glDrawElements: indirect index arrays, with immidate-mode data array is not supported\n");
|
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);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (adjustIndices) {
|
||||||
void *adjustedIndices = (void*)indices;
|
void *adjustedIndices = (void*)indices;
|
||||||
int minIndex = 0, maxIndex = 0;
|
int minIndex = 0, maxIndex = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "gl2_enc.h"
|
#include "gl2_enc.h"
|
||||||
#include "IOStream.h"
|
#include "IOStream.h"
|
||||||
#include "GLClientState.h"
|
#include "GLClientState.h"
|
||||||
|
#include "GLSharedGroup.h"
|
||||||
#include "FixedBuffer.h"
|
#include "FixedBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ public:
|
|||||||
void setClientState(GLClientState *state) {
|
void setClientState(GLClientState *state) {
|
||||||
m_state = state;
|
m_state = state;
|
||||||
}
|
}
|
||||||
|
void setSharedGroup(GLSharedGroupPtr shared){ m_shared = shared; }
|
||||||
const GLClientState *state() { return m_state; }
|
const GLClientState *state() { return m_state; }
|
||||||
void flush() {
|
void flush() {
|
||||||
gl2_encoder_context_t::m_stream->flush();
|
gl2_encoder_context_t::m_stream->flush();
|
||||||
@@ -44,6 +46,7 @@ private:
|
|||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
GLClientState *m_state;
|
GLClientState *m_state;
|
||||||
|
GLSharedGroupPtr m_shared;
|
||||||
GLenum m_error;
|
GLenum m_error;
|
||||||
|
|
||||||
GLint *m_compressedTextureFormats;
|
GLint *m_compressedTextureFormats;
|
||||||
@@ -69,6 +72,14 @@ 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;
|
||||||
|
static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||||
|
glBufferSubData_client_proc_t m_glBufferSubData_enc;
|
||||||
|
static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||||
|
glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc;
|
||||||
|
static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers);
|
||||||
|
|
||||||
glDrawArrays_client_proc_t m_glDrawArrays_enc;
|
glDrawArrays_client_proc_t m_glDrawArrays_enc;
|
||||||
static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
|
static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <cutils/log.h>
|
#include <cutils/log.h>
|
||||||
#include "gralloc_cb.h"
|
#include "gralloc_cb.h"
|
||||||
#include "GLClientState.h"
|
#include "GLClientState.h"
|
||||||
|
#include "GLSharedGroup.h"
|
||||||
|
|
||||||
#include "GLEncoder.h"
|
#include "GLEncoder.h"
|
||||||
#ifdef WITH_GLES2
|
#ifdef WITH_GLES2
|
||||||
@@ -138,13 +139,14 @@ struct EGLContext_t {
|
|||||||
NEVER_CURRENT = 0x00020000
|
NEVER_CURRENT = 0x00020000
|
||||||
};
|
};
|
||||||
|
|
||||||
EGLContext_t(EGLDisplay dpy, EGLConfig config);
|
EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx);
|
||||||
~EGLContext_t();
|
~EGLContext_t();
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
EGLDisplay dpy;
|
EGLDisplay dpy;
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLSurface read;
|
EGLSurface read;
|
||||||
EGLSurface draw;
|
EGLSurface draw;
|
||||||
|
EGLContext_t * shareCtx;
|
||||||
EGLint version;
|
EGLint version;
|
||||||
uint32_t rcContext;
|
uint32_t rcContext;
|
||||||
const char* versionString;
|
const char* versionString;
|
||||||
@@ -153,15 +155,18 @@ struct EGLContext_t {
|
|||||||
const char* extensionString;
|
const char* extensionString;
|
||||||
|
|
||||||
GLClientState * getClientState(){ return clientState; }
|
GLClientState * getClientState(){ return clientState; }
|
||||||
|
GLSharedGroupPtr getSharedGroup(){ return sharedGroup; }
|
||||||
private:
|
private:
|
||||||
GLClientState * clientState;
|
GLClientState * clientState;
|
||||||
|
GLSharedGroupPtr sharedGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) :
|
EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) :
|
||||||
dpy(dpy),
|
dpy(dpy),
|
||||||
config(config),
|
config(config),
|
||||||
read(EGL_NO_SURFACE),
|
read(EGL_NO_SURFACE),
|
||||||
draw(EGL_NO_SURFACE),
|
draw(EGL_NO_SURFACE),
|
||||||
|
shareCtx(shareCtx),
|
||||||
rcContext(0),
|
rcContext(0),
|
||||||
versionString(NULL),
|
versionString(NULL),
|
||||||
vendorString(NULL),
|
vendorString(NULL),
|
||||||
@@ -171,6 +176,8 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config) :
|
|||||||
flags = 0;
|
flags = 0;
|
||||||
version = 1;
|
version = 1;
|
||||||
clientState = new GLClientState();
|
clientState = new GLClientState();
|
||||||
|
if (shareCtx) sharedGroup = shareCtx->getSharedGroup();
|
||||||
|
else sharedGroup = GLSharedGroupPtr(new GLSharedGroup());
|
||||||
};
|
};
|
||||||
|
|
||||||
EGLContext_t::~EGLContext_t()
|
EGLContext_t::~EGLContext_t()
|
||||||
@@ -931,8 +938,9 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rcShareCtx = 0;
|
uint32_t rcShareCtx = 0;
|
||||||
|
EGLContext_t * shareCtx = NULL;
|
||||||
if (share_context) {
|
if (share_context) {
|
||||||
EGLContext_t * shareCtx = static_cast<EGLContext_t*>(share_context);
|
shareCtx = static_cast<EGLContext_t*>(share_context);
|
||||||
rcShareCtx = shareCtx->rcContext;
|
rcShareCtx = shareCtx->rcContext;
|
||||||
if (shareCtx->dpy != dpy)
|
if (shareCtx->dpy != dpy)
|
||||||
setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
||||||
@@ -945,7 +953,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
|
|||||||
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
|
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLContext_t * context = new EGLContext_t(dpy, config);
|
EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx);
|
||||||
if (!context)
|
if (!context)
|
||||||
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
|
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
|
||||||
|
|
||||||
@@ -1033,10 +1041,24 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
|
|||||||
//set the client state
|
//set the client state
|
||||||
if (context->version == 2) {
|
if (context->version == 2) {
|
||||||
hostCon->gl2Encoder()->setClientState(context->getClientState());
|
hostCon->gl2Encoder()->setClientState(context->getClientState());
|
||||||
|
hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hostCon->glEncoder()->setClientState(context->getClientState());
|
hostCon->glEncoder()->setClientState(context->getClientState());
|
||||||
|
hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//release ClientState & SharedGroup
|
||||||
|
if (tInfo->currentContext->version == 2) {
|
||||||
|
hostCon->gl2Encoder()->setClientState(NULL);
|
||||||
|
hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hostCon->glEncoder()->setClientState(NULL);
|
||||||
|
hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tInfo->currentContext)
|
if (tInfo->currentContext)
|
||||||
|
|||||||
Reference in New Issue
Block a user