* commit '3a655154d00e5ea67218bc3b5afb09b654a17156': EmuGL: implement OES_EGL_image_external for GLESv1
This commit is contained in:
@@ -21,6 +21,10 @@
|
||||
#include "glUtils.h"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
GLClientState::GLClientState(int nLocations)
|
||||
{
|
||||
if (nLocations < LAST_LOCATION) {
|
||||
@@ -54,6 +58,12 @@ GLClientState::GLClientState(int nLocations)
|
||||
|
||||
m_pixelStore.unpack_alignment = 4;
|
||||
m_pixelStore.pack_alignment = 4;
|
||||
|
||||
memset(m_tex.unit, 0, sizeof(m_tex.unit));
|
||||
m_tex.activeUnit = &m_tex.unit[0];
|
||||
m_tex.textures = NULL;
|
||||
m_tex.numTextures = 0;
|
||||
m_tex.allocTextures = 0;
|
||||
}
|
||||
|
||||
GLClientState::~GLClientState()
|
||||
@@ -230,3 +240,173 @@ size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format
|
||||
return aligned_linesize * height;
|
||||
}
|
||||
|
||||
GLenum GLClientState::setActiveTextureUnit(GLenum texture)
|
||||
{
|
||||
GLuint unit = texture - GL_TEXTURE0;
|
||||
if (unit >= MAX_TEXTURE_UNITS) {
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
m_tex.activeUnit = &m_tex.unit[unit];
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
void GLClientState::enableTextureTarget(GLenum target)
|
||||
{
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
|
||||
break;
|
||||
case GL_TEXTURE_EXTERNAL_OES:
|
||||
m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GLClientState::disableTextureTarget(GLenum target)
|
||||
{
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
|
||||
break;
|
||||
case GL_TEXTURE_EXTERNAL_OES:
|
||||
m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
|
||||
{
|
||||
unsigned int enables = m_tex.activeUnit->enables;
|
||||
if (enables & (1u << TEXTURE_EXTERNAL)) {
|
||||
return GL_TEXTURE_EXTERNAL_OES;
|
||||
} else if (enables & (1u << TEXTURE_2D)) {
|
||||
return GL_TEXTURE_2D;
|
||||
} else {
|
||||
return allDisabled;
|
||||
}
|
||||
}
|
||||
|
||||
int GLClientState::compareTexId(const void* pid, const void* prec)
|
||||
{
|
||||
const GLuint* id = (const GLuint*)pid;
|
||||
const TextureRec* rec = (const TextureRec*)prec;
|
||||
return (GLint)(*id) - (GLint)rec->id;
|
||||
}
|
||||
|
||||
GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
|
||||
GLboolean* firstUse)
|
||||
{
|
||||
GLboolean first = GL_FALSE;
|
||||
TextureRec* texrec = NULL;
|
||||
if (texture != 0) {
|
||||
if (m_tex.textures) {
|
||||
texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
|
||||
m_tex.numTextures, sizeof(TextureRec), compareTexId);
|
||||
}
|
||||
if (!texrec) {
|
||||
if (!(texrec = addTextureRec(texture, target))) {
|
||||
return GL_OUT_OF_MEMORY;
|
||||
}
|
||||
first = GL_TRUE;
|
||||
}
|
||||
if (target != texrec->target) {
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
m_tex.activeUnit->texture[TEXTURE_2D] = texture;
|
||||
break;
|
||||
case GL_TEXTURE_EXTERNAL_OES:
|
||||
m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstUse) {
|
||||
*firstUse = first;
|
||||
}
|
||||
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLClientState::TextureRec* GLClientState::addTextureRec(GLuint id,
|
||||
GLenum target)
|
||||
{
|
||||
if (m_tex.numTextures == m_tex.allocTextures) {
|
||||
const GLuint MAX_TEXTURES = 0xFFFFFFFFu;
|
||||
|
||||
GLuint newAlloc;
|
||||
if (MAX_TEXTURES - m_tex.allocTextures >= m_tex.allocTextures) {
|
||||
newAlloc = MAX(4, 2 * m_tex.allocTextures);
|
||||
} else {
|
||||
if (m_tex.allocTextures == MAX_TEXTURES) {
|
||||
return NULL;
|
||||
}
|
||||
newAlloc = MAX_TEXTURES;
|
||||
}
|
||||
|
||||
TextureRec* newTextures = (TextureRec*)realloc(m_tex.textures,
|
||||
newAlloc * sizeof(TextureRec));
|
||||
if (!newTextures) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_tex.textures = newTextures;
|
||||
m_tex.allocTextures = newAlloc;
|
||||
}
|
||||
|
||||
TextureRec* tex = m_tex.textures + m_tex.numTextures;
|
||||
TextureRec* prev = tex - 1;
|
||||
while (tex != m_tex.textures && id < prev->id) {
|
||||
*tex-- = *prev--;
|
||||
}
|
||||
tex->id = id;
|
||||
tex->target = target;
|
||||
m_tex.numTextures++;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GLuint GLClientState::getBoundTexture(GLenum target) const
|
||||
{
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
return m_tex.activeUnit->texture[TEXTURE_2D];
|
||||
case GL_TEXTURE_EXTERNAL_OES:
|
||||
return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
|
||||
{
|
||||
// Updating the textures array could be made more efficient when deleting
|
||||
// several textures:
|
||||
// - compacting the array could be done in a single pass once the deleted
|
||||
// textures are marked, or
|
||||
// - could swap deleted textures to the end and re-sort.
|
||||
TextureRec* texrec;
|
||||
for (const GLuint* texture = textures; texture != textures + n; texture++) {
|
||||
texrec = (TextureRec*)bsearch(texture, m_tex.textures,
|
||||
m_tex.numTextures, sizeof(TextureRec), compareTexId);
|
||||
if (texrec) {
|
||||
const TextureRec* end = m_tex.textures + m_tex.numTextures;
|
||||
memmove(texrec, texrec + 1,
|
||||
(end - texrec + 1) * sizeof(TextureRec));
|
||||
m_tex.numTextures--;
|
||||
|
||||
for (TextureUnit* unit = m_tex.unit;
|
||||
unit != m_tex.unit + MAX_TEXTURE_UNITS;
|
||||
unit++)
|
||||
{
|
||||
if (unit->texture[TEXTURE_2D] == *texture) {
|
||||
unit->texture[TEXTURE_2D] = 0;
|
||||
} else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
|
||||
unit->texture[TEXTURE_EXTERNAL] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ public:
|
||||
int pack_alignment;
|
||||
} PixelStoreState;
|
||||
|
||||
enum {
|
||||
MAX_TEXTURE_UNITS = 32,
|
||||
};
|
||||
|
||||
public:
|
||||
GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
|
||||
~GLClientState();
|
||||
@@ -123,6 +127,53 @@ public:
|
||||
void setCurrentProgram(GLint program) { m_currentProgram = program; }
|
||||
GLint currentProgram() const { return m_currentProgram; }
|
||||
|
||||
/* OES_EGL_image_external
|
||||
*
|
||||
* These functions manipulate GL state which interacts with the
|
||||
* OES_EGL_image_external extension, to support client-side emulation on
|
||||
* top of host implementations that don't have it.
|
||||
*
|
||||
* Most of these calls should only be used with TEXTURE_2D or
|
||||
* TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
|
||||
* targets should bypass this. An exception is bindTexture(), which should
|
||||
* see all glBindTexture() calls for any target.
|
||||
*/
|
||||
|
||||
// glActiveTexture(GL_TEXTURE0 + i)
|
||||
// Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
|
||||
GLenum setActiveTextureUnit(GLenum texture);
|
||||
|
||||
// glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
|
||||
void enableTextureTarget(GLenum target);
|
||||
|
||||
// glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
|
||||
void disableTextureTarget(GLenum target);
|
||||
|
||||
// Implements the target priority logic:
|
||||
// * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
|
||||
// * Return GL_TEXTURE_2D if enabled, else
|
||||
// * Return the allDisabled value.
|
||||
// For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
|
||||
// simpler; for other cases passing a recognizable enum like GL_ZERO or
|
||||
// GL_INVALID_ENUM is appropriate.
|
||||
GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
|
||||
|
||||
// glBindTexture(GL_TEXTURE_*, ...)
|
||||
// Set the target binding of the active texture unit to texture. Returns
|
||||
// GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
|
||||
// previously been bound to a different target. If firstUse is not NULL,
|
||||
// it is set to indicate whether this is the first use of the texture.
|
||||
// For accurate error detection, bindTexture should be called for *all*
|
||||
// targets, not just 2D and EXTERNAL_OES.
|
||||
GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
|
||||
|
||||
// Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
|
||||
GLuint getBoundTexture(GLenum target) const;
|
||||
|
||||
// glDeleteTextures(...)
|
||||
// Remove references to the to-be-deleted textures.
|
||||
void deleteTextures(GLsizei n, const GLuint* textures);
|
||||
|
||||
private:
|
||||
PixelStoreState m_pixelStore;
|
||||
VertexAttribState *m_states;
|
||||
@@ -133,6 +184,32 @@ private:
|
||||
GLint m_currentProgram;
|
||||
|
||||
bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
|
||||
|
||||
enum TextureTarget {
|
||||
TEXTURE_2D = 0,
|
||||
TEXTURE_EXTERNAL = 1,
|
||||
TEXTURE_TARGET_COUNT
|
||||
};
|
||||
struct TextureUnit {
|
||||
unsigned int enables;
|
||||
GLuint texture[TEXTURE_TARGET_COUNT];
|
||||
};
|
||||
struct TextureRec {
|
||||
GLuint id;
|
||||
GLenum target;
|
||||
};
|
||||
struct TextureState {
|
||||
TextureUnit unit[MAX_TEXTURE_UNITS];
|
||||
TextureUnit* activeUnit;
|
||||
TextureRec* textures;
|
||||
GLuint numTextures;
|
||||
GLuint allocTextures;
|
||||
};
|
||||
TextureState m_tex;
|
||||
|
||||
static int compareTexId(const void* pid, const void* prec);
|
||||
TextureRec* addTextureRec(GLuint id, GLenum target);
|
||||
|
||||
public:
|
||||
void getClientStatePointer(GLenum pname, GLvoid** params);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
//XXX: fix this macro to get the context from fast tls path
|
||||
#define GET_CONTEXT gl_client_context_t * ctx = getEGLThreadInfo()->hostConn->glEncoder();
|
||||
#define GET_CONTEXT GLEncoder * ctx = getEGLThreadInfo()->hostConn->glEncoder();
|
||||
|
||||
#include "gl_entry.cpp"
|
||||
|
||||
@@ -35,7 +35,7 @@ static EGLClient_glesInterface * s_gl = NULL;
|
||||
//GL extensions
|
||||
void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
|
||||
{
|
||||
DBG("glEGLImageTargetTexture2DOES v1 image=0x%x", image);
|
||||
DBG("glEGLImageTargetTexture2DOES v1 target=%#x image=%p", target, image);
|
||||
//TODO: check error - we don't have a way to set gl error
|
||||
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
|
||||
|
||||
@@ -47,15 +47,21 @@ void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES imag
|
||||
return;
|
||||
}
|
||||
|
||||
GET_CONTEXT;
|
||||
DEFINE_AND_VALIDATE_HOST_CONNECTION();
|
||||
rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
|
||||
|
||||
ctx->override2DTextureTarget(target);
|
||||
rcEnc->rcBindTexture(rcEnc,
|
||||
((cb_handle_t *)(native_buffer->handle))->hostHandle);
|
||||
ctx->restore2DTextureTarget();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image)
|
||||
{
|
||||
DBG("glEGLImageTargetRenderbufferStorageOES v1 image=0x%x", image);
|
||||
DBG("glEGLImageTargetRenderbufferStorageOES v1 target=%#x image=%p",
|
||||
target, image);
|
||||
//TODO: check error - we don't have a way to set gl error
|
||||
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
|
||||
|
||||
@@ -67,8 +73,13 @@ void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImag
|
||||
return;
|
||||
}
|
||||
|
||||
GET_CONTEXT;
|
||||
DEFINE_AND_VALIDATE_HOST_CONNECTION();
|
||||
rcEnc->rcBindRenderbuffer(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
|
||||
|
||||
ctx->override2DTextureTarget(target);
|
||||
rcEnc->rcBindRenderbuffer(rcEnc,
|
||||
((cb_handle_t *)(native_buffer->handle))->hostHandle);
|
||||
ctx->restore2DTextureTarget();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,26 +16,19 @@
|
||||
#include "GLEncoder.h"
|
||||
#include "glUtils.h"
|
||||
#include "FixedBuffer.h"
|
||||
#include <private/ui/android_natives_priv.h>
|
||||
#include <cutils/log.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
static GLubyte *gVendorString= (GLubyte *) "Android";
|
||||
static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0";
|
||||
static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0";
|
||||
static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
|
||||
|
||||
#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
|
||||
HostConnection *hostCon = HostConnection::get(); \
|
||||
if (!hostCon) { \
|
||||
LOGE("egl: Failed to get host connection\n"); \
|
||||
return ret; \
|
||||
} \
|
||||
renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
|
||||
if (!rcEnc) { \
|
||||
LOGE("egl: Failed to get renderControl encoder context\n"); \
|
||||
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); \
|
||||
@@ -80,14 +73,37 @@ void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
|
||||
{
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
assert(ctx->m_state != NULL);
|
||||
if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
switch (param) {
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS: {
|
||||
GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
|
||||
if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) {
|
||||
memcpy(ptr, compressedTextureFormats, ctx->m_num_compressedTextureFormats * sizeof(GLint));
|
||||
if (ctx->m_num_compressedTextureFormats > 0 &&
|
||||
compressedTextureFormats != NULL) {
|
||||
memcpy(ptr, compressedTextureFormats,
|
||||
ctx->m_num_compressedTextureFormats * sizeof(GLint));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (!ctx->m_state->getClientStateParameter<GLint>(param,ptr)) {
|
||||
|
||||
case GL_MAX_TEXTURE_UNITS:
|
||||
ctx->m_glGetIntegerv_enc(self, param, ptr);
|
||||
*ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_2D);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_EXTERNAL_OES:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!state->getClientStateParameter<GLint>(param,ptr)) {
|
||||
ctx->m_glGetIntegerv_enc(self, param, ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,16 +111,38 @@ void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
|
||||
{
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
assert(ctx->m_state != NULL);
|
||||
if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
switch (param) {
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS: {
|
||||
GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
|
||||
if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) {
|
||||
if (ctx->m_num_compressedTextureFormats > 0 &&
|
||||
compressedTextureFormats != NULL) {
|
||||
for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
|
||||
ptr[i] = (GLfloat) compressedTextureFormats[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (!ctx->m_state->getClientStateParameter<GLfloat>(param,ptr)) {
|
||||
|
||||
case GL_MAX_TEXTURE_UNITS:
|
||||
ctx->m_glGetFloatv_enc(self, param, ptr);
|
||||
*ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
*ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_EXTERNAL_OES:
|
||||
*ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
|
||||
ctx->m_glGetFloatv_enc(self, param, ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,16 +150,38 @@ void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
|
||||
{
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
assert(ctx->m_state != NULL);
|
||||
if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
switch (param) {
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS: {
|
||||
GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
|
||||
if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) {
|
||||
if (ctx->m_num_compressedTextureFormats > 0 &&
|
||||
compressedTextureFormats != NULL) {
|
||||
for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
|
||||
ptr[i] = compressedTextureFormats[i] << 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (!ctx->m_state->getClientStateParameter<GLfixed>(param,ptr)) {
|
||||
|
||||
case GL_MAX_TEXTURE_UNITS:
|
||||
ctx->m_glGetFixedv_enc(self, param, ptr);
|
||||
*ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_EXTERNAL_OES:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
|
||||
ctx->m_glGetFixedv_enc(self, param, ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,11 +189,34 @@ void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
|
||||
{
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
assert(ctx->m_state != NULL);
|
||||
if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
|
||||
// ignore the command, although we should have generated a GLerror;
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
switch (param) {
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS: {
|
||||
GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
|
||||
if (ctx->m_num_compressedTextureFormats > 0 &&
|
||||
compressedTextureFormats != NULL) {
|
||||
for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
|
||||
ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (!ctx->m_state->getClientStateParameter<GLboolean>(param,ptr)) {
|
||||
ctx->m_glGetBooleanv_enc(self, param, ptr);
|
||||
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BINDING_EXTERNAL_OES:
|
||||
*ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
|
||||
? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
|
||||
ctx->m_glGetBooleanv_enc(self, param, ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +598,273 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
GLClientState* state = ctx->m_state;
|
||||
GLenum err;
|
||||
|
||||
if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
|
||||
LOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
|
||||
ctx->setError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->m_glActiveTexture_enc(ctx, texture);
|
||||
}
|
||||
|
||||
void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
GLClientState* state = ctx->m_state;
|
||||
GLenum err;
|
||||
|
||||
GLboolean firstUse;
|
||||
if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
|
||||
LOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
|
||||
ctx->setError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->m_glBindTexture_enc(ctx, target, texture);
|
||||
return;
|
||||
}
|
||||
|
||||
GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
|
||||
|
||||
if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
|
||||
ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
|
||||
ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if (target != priorityTarget) {
|
||||
ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
|
||||
state->getBoundTexture(GL_TEXTURE_2D));
|
||||
}
|
||||
}
|
||||
|
||||
if (target == priorityTarget) {
|
||||
ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
state->deleteTextures(n, textures);
|
||||
ctx->m_glDeleteTextures_enc(ctx, n, textures);
|
||||
}
|
||||
|
||||
void GLEncoder::s_glDisable(void* self, GLenum cap)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
|
||||
GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
|
||||
state->disableTextureTarget(cap);
|
||||
GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
|
||||
|
||||
if (prevTarget != currTarget) {
|
||||
if (currTarget == GL_INVALID_ENUM) {
|
||||
ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
|
||||
currTarget = GL_TEXTURE_2D;
|
||||
}
|
||||
// maintain the invariant that when TEXTURE_EXTERNAL_OES is
|
||||
// disabled, the TEXTURE_2D binding is active, even if
|
||||
// TEXTURE_2D is also disabled.
|
||||
ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
|
||||
state->getBoundTexture(currTarget));
|
||||
}
|
||||
|
||||
} else {
|
||||
ctx->m_glDisable_enc(ctx, cap);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glEnable(void* self, GLenum cap)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
GLClientState* state = ctx->m_state;
|
||||
|
||||
if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
|
||||
GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
|
||||
state->enableTextureTarget(cap);
|
||||
GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
|
||||
|
||||
if (prevTarget != currTarget) {
|
||||
if (prevTarget == GL_INVALID_ENUM) {
|
||||
ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
|
||||
}
|
||||
if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
|
||||
state->getBoundTexture(currTarget));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ctx->m_glEnable_enc(ctx, cap);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glGetTexParameterfv(void* self,
|
||||
GLenum target, GLenum pname, GLfloat* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glGetTexParameteriv(void* self,
|
||||
GLenum target, GLenum pname, GLint* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glGetTexParameterxv(void* self,
|
||||
GLenum target, GLenum pname, GLfixed* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameterf(void* self,
|
||||
GLenum target, GLenum pname, GLfloat param)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameterf_enc(ctx, target, pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameterfv(void* self,
|
||||
GLenum target, GLenum pname, const GLfloat* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameteri(void* self,
|
||||
GLenum target, GLenum pname, GLint param)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameteri_enc(ctx, target, pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameterx(void* self,
|
||||
GLenum target, GLenum pname, GLfixed param)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameterx_enc(ctx, target, pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameteriv(void* self,
|
||||
GLenum target, GLenum pname, const GLint* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::s_glTexParameterxv(void* self,
|
||||
GLenum target, GLenum pname, const GLfixed* params)
|
||||
{
|
||||
GLEncoder* ctx = (GLEncoder*)self;
|
||||
const GLClientState* state = ctx->m_state;
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
|
||||
ctx->override2DTextureTarget(target);
|
||||
ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
|
||||
ctx->restore2DTextureTarget();
|
||||
} else {
|
||||
ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::override2DTextureTarget(GLenum target)
|
||||
{
|
||||
if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
|
||||
target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
|
||||
m_glBindTexture_enc(this, GL_TEXTURE_2D,
|
||||
m_state->getBoundTexture(target));
|
||||
}
|
||||
}
|
||||
|
||||
void GLEncoder::restore2DTextureTarget()
|
||||
{
|
||||
GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
|
||||
m_glBindTexture_enc(this, GL_TEXTURE_2D,
|
||||
m_state->getBoundTexture(priorityTarget));
|
||||
}
|
||||
|
||||
GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
|
||||
{
|
||||
m_initialized = false;
|
||||
@@ -554,6 +904,20 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
|
||||
set_glFinish(s_glFinish);
|
||||
m_glGetError_enc = set_glGetError(s_glGetError);
|
||||
|
||||
m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture);
|
||||
m_glBindTexture_enc = set_glBindTexture(s_glBindTexture);
|
||||
m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures);
|
||||
m_glDisable_enc = set_glDisable(s_glDisable);
|
||||
m_glEnable_enc = set_glEnable(s_glEnable);
|
||||
m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv);
|
||||
m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv);
|
||||
m_glGetTexParameterxv_enc = set_glGetTexParameterxv(s_glGetTexParameterxv);
|
||||
m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf);
|
||||
m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
|
||||
m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
|
||||
m_glTexParameterx_enc = set_glTexParameterx(s_glTexParameterx);
|
||||
m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
|
||||
m_glTexParameterxv_enc = set_glTexParameterxv(s_glTexParameterxv);
|
||||
}
|
||||
|
||||
GLEncoder::~GLEncoder()
|
||||
@@ -572,4 +936,3 @@ void GLEncoder::s_glFinish(void *self)
|
||||
GLEncoder *ctx = (GLEncoder *)self;
|
||||
ctx->glFinishRoundTrip(self);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ public:
|
||||
virtual void setError(GLenum error){ m_error = error; };
|
||||
virtual GLenum getError() { return m_error; };
|
||||
|
||||
void override2DTextureTarget(GLenum target);
|
||||
void restore2DTextureTarget();
|
||||
|
||||
private:
|
||||
|
||||
bool m_initialized;
|
||||
@@ -80,6 +83,21 @@ private:
|
||||
glDrawElements_client_proc_t m_glDrawElements_enc;
|
||||
glFlush_client_proc_t m_glFlush_enc;
|
||||
|
||||
glActiveTexture_client_proc_t m_glActiveTexture_enc;
|
||||
glBindTexture_client_proc_t m_glBindTexture_enc;
|
||||
glDeleteTextures_client_proc_t m_glDeleteTextures_enc;
|
||||
glDisable_client_proc_t m_glDisable_enc;
|
||||
glEnable_client_proc_t m_glEnable_enc;
|
||||
glGetTexParameterfv_client_proc_t m_glGetTexParameterfv_enc;
|
||||
glGetTexParameteriv_client_proc_t m_glGetTexParameteriv_enc;
|
||||
glGetTexParameterxv_client_proc_t m_glGetTexParameterxv_enc;
|
||||
glTexParameterf_client_proc_t m_glTexParameterf_enc;
|
||||
glTexParameterfv_client_proc_t m_glTexParameterfv_enc;
|
||||
glTexParameteri_client_proc_t m_glTexParameteri_enc;
|
||||
glTexParameterx_client_proc_t m_glTexParameterx_enc;
|
||||
glTexParameteriv_client_proc_t m_glTexParameteriv_enc;
|
||||
glTexParameterxv_client_proc_t m_glTexParameterxv_enc;
|
||||
|
||||
// statics
|
||||
static GLenum s_glGetError(void * self);
|
||||
static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
|
||||
@@ -106,14 +124,26 @@ private:
|
||||
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_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_glFinish(void *self);
|
||||
static void s_glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image);
|
||||
void sendVertexData(unsigned first, unsigned count);
|
||||
|
||||
static void s_glActiveTexture(void* self, GLenum texture);
|
||||
static void s_glBindTexture(void* self, GLenum target, GLuint texture);
|
||||
static void s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures);
|
||||
static void s_glDisable(void* self, GLenum cap);
|
||||
static void s_glEnable(void* self, GLenum cap);
|
||||
static void s_glGetTexParameterfv(void* self, GLenum target, GLenum pname, GLfloat* params);
|
||||
static void s_glGetTexParameteriv(void* self, GLenum target, GLenum pname, GLint* params);
|
||||
static void s_glGetTexParameterxv(void* self, GLenum target, GLenum pname, GLfixed* params);
|
||||
static void s_glTexParameterf(void* self, GLenum target, GLenum pname, GLfloat param);
|
||||
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_glTexParameterx(void* self, GLenum target, GLenum pname, GLfixed param);
|
||||
static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params);
|
||||
static void s_glTexParameterxv(void* self, GLenum target, GLenum pname, const GLfixed* params);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -35,7 +35,7 @@ static EGLClient_glesInterface * s_gl = NULL;
|
||||
//GL extensions
|
||||
void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
|
||||
{
|
||||
DBG("glEGLImageTargetTexture2DOES v2 img=0x%x\n", image);
|
||||
DBG("glEGLImageTargetTexture2DOES v2 img=%p\n", image);
|
||||
//TODO: check error - we don't have a way to set gl error
|
||||
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
|
||||
|
||||
@@ -55,7 +55,7 @@ void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES imag
|
||||
|
||||
void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image)
|
||||
{
|
||||
DBG("glEGLImageTargetRenderbufferStorageOES v2 image=0x%x\n", image);
|
||||
DBG("glEGLImageTargetRenderbufferStorageOES v2 image=%p\n", image);
|
||||
//TODO: check error - we don't have a way to set gl error
|
||||
android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user