diff options
| author | Dianne Hackborn <hackbod@google.com> | 2011-11-15 18:59:59 -0800 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2011-11-16 14:04:53 -0800 |
| commit | 717a25dc2a411edb548859cd6870363346c71b01 (patch) | |
| tree | 69bbc13b92fbef8dd34df6473897d812cea0b4eb /core/java/android/view/HardwareRenderer.java | |
| parent | 4c6a65bc319feab120d40553d93b160908db2f6d (diff) | |
Add new ManagedEGLContext class to help apps participate in memory trimming.
This class provides an API for an application to know when it is time to
destroy its EGL context when memory is being trimmed. By having this in
the framework, we can still detect whether it will be useful to destroy
any EGL contexts (because we know if doing so will destroy all of them).
Change-Id: I1eac8d640052778052926b875c7928008f752182
Diffstat (limited to 'core/java/android/view/HardwareRenderer.java')
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index e0167d82bef0..8e39d6edf345 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -22,6 +22,9 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.opengl.GLUtils; +import android.opengl.ManagedEGLContext; +import android.os.Handler; +import android.os.Looper; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Log; @@ -409,7 +412,8 @@ public abstract class HardwareRenderer { static final Object[] sEglLock = new Object[0]; int mWidth = -1, mHeight = -1; - static final ThreadLocal<EGLContext> sEglContextStorage = new ThreadLocal<EGLContext>(); + static final ThreadLocal<Gl20Renderer.MyEGLContext> sEglContextStorage + = new ThreadLocal<Gl20Renderer.MyEGLContext>(); EGLContext mEglContext; Thread mEglThread; @@ -561,12 +565,13 @@ public abstract class HardwareRenderer { } } - mEglContext = sEglContextStorage.get(); + Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get(); + mEglContext = managedContext != null ? managedContext.getContext() : null; mEglThread = Thread.currentThread(); if (mEglContext == null) { mEglContext = createContext(sEgl, sEglDisplay, sEglConfig); - sEglContextStorage.set(mEglContext); + sEglContextStorage.set(new Gl20Renderer.MyEGLContext(mEglContext)); } } @@ -904,6 +909,51 @@ public abstract class HardwareRenderer { private static EGLSurface sPbuffer; private static final Object[] sPbufferLock = new Object[0]; + static class MyEGLContext extends ManagedEGLContext { + final Handler mHandler = new Handler(); + + public MyEGLContext(EGLContext context) { + super(context); + } + + @Override + public void onTerminate(final EGLContext eglContext) { + // Make sure we do this on the correct thread. + if (mHandler.getLooper() != Looper.myLooper()) { + mHandler.post(new Runnable() { + @Override public void run() { + onTerminate(eglContext); + } + }); + return; + } + + synchronized (sEglLock) { + if (sEgl == null) return; + + if (EGLImpl.getInitCount(sEglDisplay) == 1) { + usePbufferSurface(eglContext); + GLES20Canvas.terminateCaches(); + + sEgl.eglDestroyContext(sEglDisplay, eglContext); + sEglContextStorage.remove(); + + sEgl.eglDestroySurface(sEglDisplay, sPbuffer); + sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + sEgl.eglReleaseThread(); + sEgl.eglTerminate(sEglDisplay); + + sEgl = null; + sEglDisplay = null; + sEglConfig = null; + sPbuffer = null; + sEglContextStorage.set(null); + } + } + } + } + Gl20Renderer(boolean translucent) { super(2, translucent); } @@ -1020,12 +1070,12 @@ public abstract class HardwareRenderer { static void trimMemory(int level) { if (sEgl == null || sEglConfig == null) return; - EGLContext eglContext = sEglContextStorage.get(); + Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get(); // We do not have OpenGL objects - if (eglContext == null) { + if (managedContext == null) { return; } else { - usePbufferSurface(eglContext); + usePbufferSurface(managedContext.getContext()); } switch (level) { @@ -1052,33 +1102,5 @@ public abstract class HardwareRenderer { } sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext); } - - static void terminate() { - synchronized (sEglLock) { - if (sEgl == null) return; - - if (EGLImpl.getInitCount(sEglDisplay) == 1) { - EGLContext eglContext = sEglContextStorage.get(); - if (eglContext == null) return; - - usePbufferSurface(eglContext); - GLES20Canvas.terminateCaches(); - - sEgl.eglDestroyContext(sEglDisplay, eglContext); - sEglContextStorage.remove(); - - sEgl.eglDestroySurface(sEglDisplay, sPbuffer); - sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - sEgl.eglReleaseThread(); - sEgl.eglTerminate(sEglDisplay); - - sEgl = null; - sEglDisplay = null; - sEglConfig = null; - sPbuffer = null; - } - } - } } } |
