summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/HardwareRenderer.java73
-rw-r--r--core/java/android/view/TextureView.java11
-rw-r--r--core/java/android/view/View.java21
-rw-r--r--core/java/android/view/ViewRootImpl.java7
-rw-r--r--core/java/android/view/WindowManagerImpl.java2
-rw-r--r--opengl/java/android/opengl/ManagedEGLContext.java5
6 files changed, 92 insertions, 27 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8e39d6e..f77cf7e 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -162,13 +162,21 @@ public abstract class HardwareRenderer {
abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;
/**
- * Destoys the layers used by the specified view hierarchy.
+ * Destroys the layers used by the specified view hierarchy.
*
* @param view The root of the view hierarchy
*/
abstract void destroyLayers(View view);
/**
+ * Destroys all hardware rendering resources associated with the specified
+ * view hierarchy.
+ *
+ * @param view The root of the view hierarchy
+ */
+ abstract void destroyHardwareResources(View view);
+
+ /**
* This method should be invoked whenever the current hardware renderer
* context should be reset.
*
@@ -348,15 +356,6 @@ public abstract class HardwareRenderer {
}
/**
- * Invoke this method when the system needs to clean up all resources
- * associated with hardware rendering.
- */
- static void terminate() {
- Log.d(LOG_TAG, "Terminating hardware rendering");
- Gl20Renderer.terminate();
- }
-
- /**
* Indicates whether hardware acceleration is currently enabled.
*
* @return True if hardware acceleration is in use, false otherwise.
@@ -412,8 +411,8 @@ public abstract class HardwareRenderer {
static final Object[] sEglLock = new Object[0];
int mWidth = -1, mHeight = -1;
- static final ThreadLocal<Gl20Renderer.MyEGLContext> sEglContextStorage
- = new ThreadLocal<Gl20Renderer.MyEGLContext>();
+ static final ThreadLocal<Gl20Renderer.Gl20RendererEglContext> sEglContextStorage
+ = new ThreadLocal<Gl20Renderer.Gl20RendererEglContext>();
EGLContext mEglContext;
Thread mEglThread;
@@ -565,13 +564,13 @@ public abstract class HardwareRenderer {
}
}
- Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
+ Gl20Renderer.Gl20RendererEglContext managedContext = sEglContextStorage.get();
mEglContext = managedContext != null ? managedContext.getContext() : null;
mEglThread = Thread.currentThread();
if (mEglContext == null) {
mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
- sEglContextStorage.set(new Gl20Renderer.MyEGLContext(mEglContext));
+ sEglContextStorage.set(new Gl20Renderer.Gl20RendererEglContext(mEglContext));
}
}
@@ -909,10 +908,10 @@ public abstract class HardwareRenderer {
private static EGLSurface sPbuffer;
private static final Object[] sPbufferLock = new Object[0];
- static class MyEGLContext extends ManagedEGLContext {
+ static class Gl20RendererEglContext extends ManagedEGLContext {
final Handler mHandler = new Handler();
- public MyEGLContext(EGLContext context) {
+ public Gl20RendererEglContext(EGLContext context) {
super(context);
}
@@ -939,7 +938,8 @@ public abstract class HardwareRenderer {
sEglContextStorage.remove();
sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
sEgl.eglReleaseThread();
sEgl.eglTerminate(sEglDisplay);
@@ -1046,10 +1046,9 @@ public abstract class HardwareRenderer {
}
}
- private void destroyHardwareLayer(View view) {
- if (view.destroyLayer()) {
- view.invalidate(true);
- }
+ private static void destroyHardwareLayer(View view) {
+ view.destroyLayer();
+
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
@@ -1059,6 +1058,36 @@ public abstract class HardwareRenderer {
}
}
}
+
+ @Override
+ void destroyHardwareResources(View view) {
+ if (view != null) {
+ boolean needsContext = true;
+ if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
+
+ if (needsContext) {
+ Gl20RendererEglContext managedContext = sEglContextStorage.get();
+ if (managedContext == null) return;
+ usePbufferSurface(managedContext.getContext());
+ }
+
+ destroyResources(view);
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+ }
+ }
+
+ private static void destroyResources(View view) {
+ view.destroyHardwareResources();
+
+ if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup) view;
+
+ int count = group.getChildCount();
+ for (int i = 0; i < count; i++) {
+ destroyResources(group.getChildAt(i));
+ }
+ }
+ }
static HardwareRenderer create(boolean translucent) {
if (GLES20Canvas.isAvailable()) {
@@ -1070,7 +1099,7 @@ public abstract class HardwareRenderer {
static void trimMemory(int level) {
if (sEgl == null || sEglConfig == null) return;
- Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
+ Gl20RendererEglContext managedContext = sEglContextStorage.get();
// We do not have OpenGL objects
if (managedContext == null) {
return;
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 1697382..3fd2d83 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -203,7 +203,10 @@ public class TextureView extends View {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ destroySurface();
+ }
+ private void destroySurface() {
if (mLayer != null) {
boolean shouldRelease = true;
if (mListener != null) {
@@ -301,6 +304,14 @@ public class TextureView extends View {
}
@Override
+ protected void destroyHardwareResources() {
+ super.destroyHardwareResources();
+ destroySurface();
+ invalidateParentCaches();
+ invalidate(true);
+ }
+
+ @Override
HardwareLayer getHardwareLayer() {
if (mLayer == null) {
if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e2f3919..5002be7 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10073,7 +10073,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
destroyLayer();
- // fall through - unaccelerated views may use software layer mechanism instead
+ // fall through - non-accelerated views may use software layer mechanism instead
case LAYER_TYPE_SOFTWARE:
destroyDrawingCache();
break;
@@ -10235,12 +10235,31 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mHardwareLayer != null) {
mHardwareLayer.destroy();
mHardwareLayer = null;
+
+ invalidate(true);
+ invalidateParentCaches();
+
return true;
}
return false;
}
/**
+ * Destroys all hardware rendering resources. This method is invoked
+ * when the system needs to reclaim resources. Upon execution of this
+ * method, you should free any OpenGL resources created by the view.
+ *
+ * Note: you <strong>must</strong> call
+ * <code>super.destroyHardwareResources()</code> when overriding
+ * this method.
+ *
+ * @hide
+ */
+ protected void destroyHardwareResources() {
+ destroyLayer();
+ }
+
+ /**
* <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
* to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
* bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b15b155..5f70a39 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -576,6 +576,13 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
}
+ void terminateHardwareResources() {
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
+ mAttachInfo.mHardwareRenderer.destroy(false);
+ }
+ }
+
void destroyHardwareLayers() {
if (mThread != Thread.currentThread()) {
if (mAttachInfo.mHardwareRenderer != null &&
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 660e3f4..dfd1d55 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -425,7 +425,7 @@ public class WindowManagerImpl implements WindowManager {
if (mViews == null) return;
int count = mViews.length;
for (int i = 0; i < count; i++) {
- mRoots[i].destroyHardwareResources();
+ mRoots[i].terminateHardwareResources();
}
}
// Terminate the hardware renderer to free all resources
diff --git a/opengl/java/android/opengl/ManagedEGLContext.java b/opengl/java/android/opengl/ManagedEGLContext.java
index d3a3662..1eafbca 100644
--- a/opengl/java/android/opengl/ManagedEGLContext.java
+++ b/opengl/java/android/opengl/ManagedEGLContext.java
@@ -47,8 +47,7 @@ import com.google.android.gles_jni.EGLImpl;
public abstract class ManagedEGLContext {
static final String TAG = "ManagedEGLContext";
- static final ArrayList<ManagedEGLContext> sActive
- = new ArrayList<ManagedEGLContext>();
+ static final ArrayList<ManagedEGLContext> sActive = new ArrayList<ManagedEGLContext>();
final EGLContext mContext;
@@ -127,7 +126,7 @@ public abstract class ManagedEGLContext {
sActive.clear();
}
- for (int i=0; i<active.size(); i++) {
+ for (int i = 0; i < active.size(); i++) {
active.get(i).execTerminate();
}