summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-07-18 16:06:31 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-18 16:06:31 -0700
commitf40aa3834d92bfb516e0f865375103d81e3de71d (patch)
treecd061368ccc161d3e9bb7250c056e54efc3f5bfb
parent822036d00eecd5fb7c48260bdb7f649f627efbd2 (diff)
parentbdf7609867a3f886455c51dba91623a86cceb6e2 (diff)
downloadframeworks_base-f40aa3834d92bfb516e0f865375103d81e3de71d.zip
frameworks_base-f40aa3834d92bfb516e0f865375103d81e3de71d.tar.gz
frameworks_base-f40aa3834d92bfb516e0f865375103d81e3de71d.tar.bz2
Merge "Trim OpenGLRenderer's memory usage whenever possible"
-rw-r--r--core/java/android/app/ActivityThread.java1
-rw-r--r--core/java/android/view/GLES20Canvas.java32
-rw-r--r--core/java/android/view/HardwareRenderer.java24
-rw-r--r--core/java/android/view/WindowManagerImpl.java23
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp8
-rw-r--r--libs/hwui/Caches.cpp34
-rw-r--r--libs/hwui/Caches.h12
-rw-r--r--libs/hwui/Debug.h3
8 files changed, 128 insertions, 9 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c6a746b..86161da 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3558,6 +3558,7 @@ public final class ActivityThread {
}
final void handleTrimMemory(int level) {
+ WindowManagerImpl.getDefault().trimMemory(level);
}
private final void handleBindApplication(AppBindData data) {
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 4987e2f..80244bb 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -286,6 +286,38 @@ class GLES20Canvas extends HardwareCanvas {
private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Memory
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @see #flushCaches(int)
+ */
+ public static final int FLUSH_CACHES_MODERATE = 0;
+
+ /**
+ * @see #flushCaches(int)
+ */
+ public static final int FLUSH_CACHES_FULL = 1;
+
+ /**
+ * Flush caches to reclaim as much memory as possible. The amount of memory
+ * to reclaim is indicate by the level parameter.
+ *
+ * The level can be one of {@link #FLUSH_CACHES_MODERATE} or
+ * {@link #FLUSH_CACHES_FULL}.
+ *
+ * @param level Hint about the amount of memory to reclaim
+ *
+ * @hide
+ */
+ public static void flushCaches(int level) {
+ nFlushCaches(level);
+ }
+
+ private static native void nFlushCaches(int level);
+
///////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 011e44c..9a2564f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,6 +17,7 @@
package android.view;
+import android.content.ComponentCallbacks;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@@ -263,6 +264,18 @@ public abstract class HardwareRenderer {
}
/**
+ * Invoke this method when the system is running out of memory. This
+ * method will attempt to recover as much memory as possible, based on
+ * the specified hint.
+ *
+ * @param level Hint about the amount of memory that should be trimmed,
+ * see {@link android.content.ComponentCallbacks}
+ */
+ static void trimMemory(int level) {
+ Gl20Renderer.flushCaches(level);
+ }
+
+ /**
* Indicates whether hardware acceleration is currently enabled.
*
* @return True if hardware acceleration is in use, false otherwise.
@@ -858,5 +871,16 @@ public abstract class HardwareRenderer {
}
return null;
}
+
+ static void flushCaches(int level) {
+ switch (level) {
+ case ComponentCallbacks.TRIM_MEMORY_MODERATE:
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
+ break;
+ case ComponentCallbacks.TRIM_MEMORY_COMPLETE:
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+ break;
+ }
+ }
}
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 54e7c04..4e9531b 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,18 +16,16 @@
package android.view;
-import java.util.HashMap;
-
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.AndroidRuntimeException;
import android.util.Log;
-import android.util.Slog;
-import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
+import java.util.HashMap;
+
final class WindowLeaked extends AndroidRuntimeException {
public WindowLeaked(String msg) {
super(msg);
@@ -402,7 +400,16 @@ public class WindowManagerImpl implements WindowManager {
}
}
}
-
+
+ /**
+ * @param level See {@link android.content.ComponentCallbacks}
+ */
+ public void trimMemory(int level) {
+ if (HardwareRenderer.isAvailable()) {
+ HardwareRenderer.trimMemory(level);
+ }
+ }
+
public void setStoppedState(IBinder token, boolean stopped) {
synchronized (this) {
if (mViews == null)
@@ -456,8 +463,7 @@ public class WindowManagerImpl implements WindowManager {
return new Display(Display.DEFAULT_DISPLAY, null);
}
- private static void removeItem(Object[] dst, Object[] src, int index)
- {
+ private static void removeItem(Object[] dst, Object[] src, int index) {
if (dst.length > 0) {
if (index > 0) {
System.arraycopy(src, 0, dst, 0, index);
@@ -468,8 +474,7 @@ public class WindowManagerImpl implements WindowManager {
}
}
- private int findViewLocked(View view, boolean required)
- {
+ private int findViewLocked(View view, boolean required) {
synchronized (this) {
final int count = mViews != null ? mViews.length : 0;
for (int i=0; i<count; i++) {
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e201964..b0c2f2c 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -127,6 +127,13 @@ static void android_view_GLES20Canvas_disableVsync(JNIEnv* env, jobject clazz) {
}
}
+static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
+ Caches::FlushMode mode) {
+ if (Caches::hasInstance()) {
+ Caches::getInstance().flush(mode);
+ }
+}
+
// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
@@ -735,6 +742,7 @@ static JNINativeMethod gMethods[] = {
{ "nIsBackBufferPreserved", "()Z", (void*) android_view_GLES20Canvas_isBackBufferPreserved },
{ "nPreserveBackBuffer", "()Z", (void*) android_view_GLES20Canvas_preserveBackBuffer },
{ "nDisableVsync", "()V", (void*) android_view_GLES20Canvas_disableVsync },
+ { "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches },
{ "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
{ "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index e232ddd..7114b6a 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -33,6 +33,16 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Caches);
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
+// Macros
+///////////////////////////////////////////////////////////////////////////////
+
+#if DEBUG_CACHE_FLUSH
+ #define FLUSH_LOGD(...) LOGD(__VA_ARGS__)
+#else
+ #define FLUSH_LOGD(...)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -150,6 +160,30 @@ void Caches::deleteLayerDeferred(Layer* layer) {
mLayerGarbage.push(layer);
}
+void Caches::flush(FlushMode mode) {
+ FLUSH_LOGD("Flushing caches (mode %d)", mode);
+
+ clearGarbage();
+
+ switch (mode) {
+ case kFlushMode_Full:
+ textureCache.clear();
+ patchCache.clear();
+ dropShadowCache.clear();
+ gradientCache.clear();
+ // fall through
+ case kFlushMode_Moderate:
+ layerCache.clear();
+ pathCache.clear();
+ roundRectShapeCache.clear();
+ circleShapeCache.clear();
+ ovalShapeCache.clear();
+ rectShapeCache.clear();
+ arcShapeCache.clear();
+ break;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// VBO
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e64d8ac..76dff4b 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -100,6 +100,18 @@ class Caches: public Singleton<Caches> {
Vector<Layer*> mLayerGarbage;
public:
+ enum FlushMode {
+ kFlushMode_Moderate = 0,
+ kFlushMode_Full
+ };
+
+ /**
+ * Flush the cache.
+ *
+ * @param mode Indicates how much of the cache should be flushed
+ */
+ void flush(FlushMode mode);
+
/**
* Indicates whether the renderer is in debug mode.
* This debug mode provides limited information to app developers.
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 2cdc8c3..5db73db 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -26,6 +26,9 @@
// Turn on to enable memory usage summary on each frame
#define DEBUG_MEMORY_USAGE 0
+// Turn on to enable debugging of cache flushes
+#define DEBUG_CACHE_FLUSH 1
+
// Turn on to enable layers debugging when rendered as regions
#define DEBUG_LAYERS_AS_REGIONS 0