diff options
| author | Romain Guy <romainguy@google.com> | 2011-11-21 10:55:41 -0800 |
|---|---|---|
| committer | Romain Guy <romainguy@google.com> | 2011-11-21 10:55:41 -0800 |
| commit | 31f2c2e94656530fbf6282803e62edb47e9a894d (patch) | |
| tree | fddc1ff144eccb20909107456ebd37325c86d8be /core/java/android/view/HardwareRenderer.java | |
| parent | 7859c1842c1f2e3c43415dfb5337a0b005bdb1c4 (diff) | |
Notify views when EGL resources are about to be destroyed
Bug #5639899
Change-Id: I7c5d8bebf02294426f5b3ab1358a31c38a4fd064
Diffstat (limited to 'core/java/android/view/HardwareRenderer.java')
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 8e39d6edf345..f77cf7e8398b 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; |
