diff options
author | bohu <bohu@google.com> | 2014-11-25 16:50:37 -0800 |
---|---|---|
committer | bohu <bohu@google.com> | 2014-11-26 14:31:35 -0800 |
commit | 4f9ec3916ac526dca9ddf2781d26340fe1f18015 (patch) | |
tree | 0c31a968e124cdba798eda6a34530c02603b492a /opengl | |
parent | c2f8474518a220b3c1b86b6d4f9fa28ed9bb734a (diff) | |
download | android_device_generic_goldfish-4f9ec3916ac526dca9ddf2781d26340fe1f18015.tar.gz android_device_generic_goldfish-4f9ec3916ac526dca9ddf2781d26340fe1f18015.tar.bz2 android_device_generic_goldfish-4f9ec3916ac526dca9ddf2781d26340fe1f18015.zip |
Fix eglDestroyContext and glTexImage2D
1. When destroy context that is in use, EGL spec says:
"If the EGL rendering context context is not current to any thread,
eglDestroyContext destroys it immediately. Otherwise, context is
destroyed when it becomes not current to any thread."
2. When calling glTexImage2D, should bind the correct texture first.
Change-Id: I6c779b71d1e6002b8a484477921ba323acbd986e
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/system/GLESv2_enc/GL2Encoder.cpp | 18 | ||||
-rw-r--r-- | opengl/system/GLESv2_enc/GL2Encoder.h | 5 | ||||
-rw-r--r-- | opengl/system/egl/egl.cpp | 22 | ||||
-rw-r--r-- | opengl/system/egl/eglContext.h | 2 |
4 files changed, 41 insertions, 6 deletions
diff --git a/opengl/system/GLESv2_enc/GL2Encoder.cpp b/opengl/system/GLESv2_enc/GL2Encoder.cpp index 0575935..80a2cda 100644 --- a/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -121,6 +121,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) OVERRIDE(glTexParameterfv); OVERRIDE(glTexParameteri); OVERRIDE(glTexParameteriv); + OVERRIDE(glTexImage2D); } GL2Encoder::~GL2Encoder() @@ -1211,6 +1212,23 @@ void GL2Encoder::s_glTexParameteri(void* self, } } +void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid* pixels) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, + height, border, format, type, pixels); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, + height, border, format, type, pixels); + } +} + + void GL2Encoder::s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params) { diff --git a/opengl/system/GLESv2_enc/GL2Encoder.h b/opengl/system/GLESv2_enc/GL2Encoder.h index 2a19c3a..5f255d1 100644 --- a/opengl/system/GLESv2_enc/GL2Encoder.h +++ b/opengl/system/GLESv2_enc/GL2Encoder.h @@ -218,6 +218,7 @@ private: glTexParameterfv_client_proc_t m_glTexParameterfv_enc; glTexParameteri_client_proc_t m_glTexParameteri_enc; glTexParameteriv_client_proc_t m_glTexParameteriv_enc; + glTexImage2D_client_proc_t m_glTexImage2D_enc; static void s_glActiveTexture(void* self, GLenum texture); static void s_glBindTexture(void* self, GLenum target, GLuint texture); @@ -228,5 +229,9 @@ private: static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params); static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param); static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params); + static void s_glTexImage2D(void* self, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, + const GLvoid* pixels); + }; #endif diff --git a/opengl/system/egl/egl.cpp b/opengl/system/egl/egl.cpp index 1ad91ff..8499229 100644 --- a/opengl/system/egl/egl.cpp +++ b/opengl/system/egl/egl.cpp @@ -140,7 +140,8 @@ EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* share versionString(NULL), vendorString(NULL), rendererString(NULL), - extensionString(NULL) + extensionString(NULL), + deletePending(0) { flags = 0; version = 1; @@ -915,9 +916,11 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) EGLContext_t * context = static_cast<EGLContext_t*>(ctx); - if (getEGLThreadInfo()->currentContext == context) - { - eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); + if (!context) return EGL_TRUE; + + if (getEGLThreadInfo()->currentContext == context) { + getEGLThreadInfo()->currentContext->deletePending = 1; + return EGL_TRUE; } if (context->rcContext) { @@ -952,12 +955,21 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC // Nothing to do if no binding change has made // EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (tInfo->currentContext == context && (context == NULL || (context && context->draw == draw && context->read == read))) { return EGL_TRUE; } + if (tInfo->currentContext && tInfo->currentContext->deletePending) { + if (tInfo->currentContext != context) { + EGLContext_t * contextToDelete = tInfo->currentContext; + tInfo->currentContext = 0; + eglDestroyContext(dpy, contextToDelete); + } + } + if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { //context is current to another thread setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); @@ -984,7 +996,7 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); } } - else { + else if (tInfo->currentContext) { //release ClientState & SharedGroup if (tInfo->currentContext->version == 2) { hostCon->gl2Encoder()->setClientState(NULL); diff --git a/opengl/system/egl/eglContext.h b/opengl/system/egl/eglContext.h index 2ca6d0c..16a2780 100644 --- a/opengl/system/egl/eglContext.h +++ b/opengl/system/egl/eglContext.h @@ -40,7 +40,7 @@ struct EGLContext_t { const char* vendorString; const char* rendererString; const char* extensionString; - + EGLint deletePending; GLClientState * getClientState(){ return clientState; } GLSharedGroupPtr getSharedGroup(){ return sharedGroup; } private: |