From 70b52f5ce2bbcb09cd4551982d984e0b47b4477f Mon Sep 17 00:00:00 2001 From: Jesse Hall Date: Thu, 7 Mar 2013 09:56:26 -0800 Subject: [PATCH 1/2] Defer destroying surfaces until not current Bug: 8320762 Change-Id: I1320cf87923bcc5b795a86a13193363a49e29653 --- opengl/libagl/egl.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 172ef9571..bc1cf3636 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -147,6 +147,7 @@ struct egl_surface_t EGLDisplay dpy; EGLConfig config; EGLContext ctx; + bool zombie; egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat); virtual ~egl_surface_t(); @@ -173,7 +174,7 @@ protected: egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat) - : magic(MAGIC), dpy(dpy), config(config), ctx(0) + : magic(MAGIC), dpy(dpy), config(config), ctx(0), zombie(false) { depth.version = sizeof(GGLSurface); depth.data = 0; @@ -1580,11 +1581,12 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) if (surface->dpy != dpy) return setError(EGL_BAD_DISPLAY, EGL_FALSE); if (surface->ctx) { - // FIXME: this surface is current check what the spec says + // defer disconnect/delete until no longer current + surface->zombie = true; + } else { surface->disconnect(); - surface->ctx = 0; + delete surface; } - delete surface; } return EGL_TRUE; } @@ -1736,6 +1738,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, if (c->draw) { egl_surface_t* s = reinterpret_cast(c->draw); s->disconnect(); + s->ctx = EGL_NO_CONTEXT; + if (s->zombie) + delete s; } if (c->read) { // FIXME: unlock/disconnect the read surface too @@ -1777,8 +1782,10 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, egl_surface_t* r = (egl_surface_t*)c->read; if (d) { c->draw = 0; - d->ctx = EGL_NO_CONTEXT; d->disconnect(); + d->ctx = EGL_NO_CONTEXT; + if (d->zombie) + delete d; } if (r) { c->read = 0; From f8cbf2c06c8a5b49059d56ae3cea8115d4ff52e0 Mon Sep 17 00:00:00 2001 From: Jesse Hall Date: Thu, 7 Mar 2013 15:14:18 -0800 Subject: [PATCH 2/2] When disconnecting a surface, cancel don't queue the buffer This isn't really right either, but avoids having an extra buffer that the consumer has to drain which it might not be expecting. To be correct, disconnecting a surface from a context should retain the current buffer and continue using it when reconnected. The buffer should only be canceled when the surface is destroyed. That will wait for a later change. Bug: 8320762 Change-Id: I5efa39c741193ca4f5612ea9de001ccbb683b345 --- opengl/libagl/egl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index bc1cf3636..0ed572717 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -420,9 +420,8 @@ void egl_window_surface_v2_t::disconnect() bits = NULL; unlock(buffer); } - // enqueue the last frame - nativeWindow->queueBuffer(nativeWindow, buffer, -1); if (buffer) { + nativeWindow->cancelBuffer(nativeWindow, buffer, -1); buffer->common.decRef(&buffer->common); buffer = 0; }