summaryrefslogtreecommitdiff
path: root/core/java/android/view/HardwareRenderer.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-11-15 18:59:59 -0800
committerDianne Hackborn <hackbod@google.com>2011-11-16 14:04:53 -0800
commit717a25dc2a411edb548859cd6870363346c71b01 (patch)
tree69bbc13b92fbef8dd34df6473897d812cea0b4eb /core/java/android/view/HardwareRenderer.java
parent4c6a65bc319feab120d40553d93b160908db2f6d (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.java90
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;
- }
- }
- }
}
}