Merge "Notify views when EGL resources are about to be destroyed Bug #5639899" into ics-mr1
This commit is contained in:
@ -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.
|
||||
@ -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.
|
||||
*
|
||||
@ -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;
|
||||
|
@ -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) {
|
||||
@ -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) {
|
||||
|
@ -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,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
|
||||
|
@ -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 &&
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user