summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
authorbohu <bohu@google.com>2014-11-25 16:50:37 -0800
committerbohu <bohu@google.com>2014-11-26 14:31:35 -0800
commit4f9ec3916ac526dca9ddf2781d26340fe1f18015 (patch)
tree0c31a968e124cdba798eda6a34530c02603b492a /opengl
parentc2f8474518a220b3c1b86b6d4f9fa28ed9bb734a (diff)
downloadandroid_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.cpp18
-rw-r--r--opengl/system/GLESv2_enc/GL2Encoder.h5
-rw-r--r--opengl/system/egl/egl.cpp22
-rw-r--r--opengl/system/egl/eglContext.h2
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: