diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-11-17 05:46:34 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-11-17 05:46:34 -0800 |
commit | 77c5f4def49357a89abd9849b0bab950179d71f4 (patch) | |
tree | 0048a35fc889732713233de3723464f86b6128e0 /opengl | |
parent | 7cd2b19a926224dee2b2e12f37c1d71ce658bf97 (diff) | |
parent | 9aa6bd1c34fe3583fe31f283a6415e84fec12567 (diff) | |
download | frameworks_base-77c5f4def49357a89abd9849b0bab950179d71f4.zip frameworks_base-77c5f4def49357a89abd9849b0bab950179d71f4.tar.gz frameworks_base-77c5f4def49357a89abd9849b0bab950179d71f4.tar.bz2 |
am 9aa6bd1c: am 717a25dc: Add new ManagedEGLContext class to help apps participate in memory trimming.
* commit '9aa6bd1c34fe3583fe31f283a6415e84fec12567':
Add new ManagedEGLContext class to help apps participate in memory trimming.
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/java/android/opengl/ManagedEGLContext.java | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/opengl/java/android/opengl/ManagedEGLContext.java b/opengl/java/android/opengl/ManagedEGLContext.java new file mode 100644 index 0000000..d3a3662 --- /dev/null +++ b/opengl/java/android/opengl/ManagedEGLContext.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.opengl; + +import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY; +import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY; + +import java.util.ArrayList; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; + +import android.os.Looper; +import android.util.Log; + +import com.google.android.gles_jni.EGLImpl; + +/** + * The per-process memory overhead of hardware accelerated graphics can + * be quite large on some devices. For small memory devices, being able to + * terminate all EGL contexts so that this graphics driver memory can be + * reclaimed can significant improve the overall behavior of the device. This + * class helps app developers participate in releasing their EGL context + * when appropriate and possible. + * + * <p>To use, simple instantiate this class with the EGLContext you create. + * When you have done this, if the device is getting low on memory and all + * of the currently created EGL contexts in the process are being managed + * through this class, then they will all be asked to terminate through the + * call to {@link #onTerminate}. + */ +public abstract class ManagedEGLContext { + static final String TAG = "ManagedEGLContext"; + + static final ArrayList<ManagedEGLContext> sActive + = new ArrayList<ManagedEGLContext>(); + + final EGLContext mContext; + + /** + * Instantiate to manage the given EGLContext. + */ + public ManagedEGLContext(EGLContext context) { + mContext = context; + synchronized (sActive) { + sActive.add(this); + } + } + + /** + * Retrieve the EGLContext being managed by the class. + */ + public EGLContext getContext() { + return mContext; + } + + /** + * Force-terminate the ManagedEGLContext. This will cause + * {@link #onTerminate(EGLContext)} to be called. You <em>must</em> + * call this when destroying the EGLContext, so that the framework + * knows to stop managing it. + */ + public void terminate() { + execTerminate(); + } + + void execTerminate() { + onTerminate(mContext); + } + + /** + * Override this method to destroy the EGLContext when appropriate. + * <em>Note that this method is always called on the main thread + * of the process.</em> If your EGLContext was created on a different + * thread, you will need to implement this method to hand off the work + * of destroying the context to that thread. + */ + public abstract void onTerminate(EGLContext context); + + /** @hide */ + public static boolean doTerminate() { + ArrayList<ManagedEGLContext> active; + + if (Looper.getMainLooper() != Looper.myLooper()) { + throw new IllegalStateException("Called on wrong thread"); + } + + synchronized (sActive) { + // If there are no active managed contexts, we will not even + // try to terminate. + if (sActive.size() <= 0) { + return false; + } + + // Need to check how many EGL contexts are actually running, + // to compare with how many we are managing. + EGL10 egl = (EGL10) EGLContext.getEGL(); + EGLDisplay display = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); + + if (display == EGL_NO_DISPLAY) { + Log.w(TAG, "doTerminate failed: no display"); + return false; + } + + if (EGLImpl.getInitCount(display) != sActive.size()) { + Log.w(TAG, "doTerminate failed: EGL count is " + EGLImpl.getInitCount(display) + + " but managed count is " + sActive.size()); + return false; + } + + active = new ArrayList<ManagedEGLContext>(sActive); + sActive.clear(); + } + + for (int i=0; i<active.size(); i++) { + active.get(i).execTerminate(); + } + + return true; + } +} |