Loading core/java/android/view/HardwareRenderer.java +51 −22 Original line number Diff line number Diff line Loading @@ -162,12 +162,20 @@ 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. Loading Loading @@ -347,15 +355,6 @@ public abstract class HardwareRenderer { Gl20Renderer.trimMemory(level); } /** * 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. * Loading Loading @@ -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; Loading Loading @@ -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)); } } Loading Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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; Loading @@ -1060,6 +1059,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()) { return new Gl20Renderer(translucent); Loading @@ -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; Loading core/java/android/view/TextureView.java +11 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -300,6 +303,14 @@ public class TextureView extends View { return false; } @Override protected void destroyHardwareResources() { super.destroyHardwareResources(); destroySurface(); invalidateParentCaches(); invalidate(true); } @Override HardwareLayer getHardwareLayer() { if (mLayer == null) { Loading core/java/android/view/View.java +20 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -10235,11 +10235,30 @@ 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 Loading core/java/android/view/ViewRootImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 && Loading core/java/android/view/WindowManagerImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
core/java/android/view/HardwareRenderer.java +51 −22 Original line number Diff line number Diff line Loading @@ -162,12 +162,20 @@ 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. Loading Loading @@ -347,15 +355,6 @@ public abstract class HardwareRenderer { Gl20Renderer.trimMemory(level); } /** * 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. * Loading Loading @@ -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; Loading Loading @@ -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)); } } Loading Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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; Loading @@ -1060,6 +1059,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()) { return new Gl20Renderer(translucent); Loading @@ -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; Loading
core/java/android/view/TextureView.java +11 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -300,6 +303,14 @@ public class TextureView extends View { return false; } @Override protected void destroyHardwareResources() { super.destroyHardwareResources(); destroySurface(); invalidateParentCaches(); invalidate(true); } @Override HardwareLayer getHardwareLayer() { if (mLayer == null) { Loading
core/java/android/view/View.java +20 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -10235,11 +10235,30 @@ 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 Loading
core/java/android/view/ViewRootImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 && Loading
core/java/android/view/WindowManagerImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading