diff options
| author | John Reck <jreck@google.com> | 2014-02-14 20:03:38 -0800 |
|---|---|---|
| committer | John Reck <jreck@google.com> | 2014-02-19 10:47:19 -0800 |
| commit | 19b6bcfd83eb7fb92ebd06d2fec89e308311f1d0 (patch) | |
| tree | 617b09881e87d86d03a7486f5c3f05242199210d /core/java/android | |
| parent | 587f43d8725b11632b5d64a0a56a647207f01668 (diff) | |
Support HardwareLayers in RenderThread
Also has a few HardwareLayer lifecycle fixes
Change-Id: I6308cb05f8f199eed72189ace768013a46815941
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 1 | ||||
| -rw-r--r-- | core/java/android/view/GLRenderer.java | 41 | ||||
| -rw-r--r-- | core/java/android/view/HardwareLayer.java | 32 | ||||
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 16 | ||||
| -rw-r--r-- | core/java/android/view/TextureView.java | 26 | ||||
| -rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 89 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 24 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 23 |
8 files changed, 107 insertions, 145 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 30c1e622d346..3258585ad583 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3949,6 +3949,7 @@ public final class ActivityThread { ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); // Cleanup hardware accelerated stuff + // TODO: Do we actually want to do this in response to all config changes? WindowManagerGlobal.getInstance().trimLocalMemory(); freeTextLayoutCachesIfNeeded(configDiff); diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java index c1eb6b771c09..859468aa44ef 100644 --- a/core/java/android/view/GLRenderer.java +++ b/core/java/android/view/GLRenderer.java @@ -477,17 +477,21 @@ public class GLRenderer extends HardwareRenderer { @Override void flushLayerUpdates() { - mGlCanvas.flushLayerUpdates(); + if (validate()) { + mGlCanvas.flushLayerUpdates(); + } } @Override HardwareLayer createTextureLayer() { + validate(); return HardwareLayer.createTextureLayer(this); } @Override public HardwareLayer createDisplayListLayer(int width, int height) { - return HardwareLayer.createRenderLayer(this, width, height); + validate(); + return HardwareLayer.createDisplayListLayer(this, width, height); } @Override @@ -510,6 +514,9 @@ public class GLRenderer extends HardwareRenderer { @Override boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap) { + if (!validate()) { + throw new IllegalStateException("Could not acquire hardware rendering context"); + } layer.flushChanges(); return GLES20Canvas.nCopyLayer(layer.getLayer(), bitmap.mNativeBitmap); } @@ -538,35 +545,6 @@ public class GLRenderer extends HardwareRenderer { } @Override - void destroyLayers(final View view) { - if (view != null) { - safelyRun(new Runnable() { - @Override - public void run() { - if (mCanvas != null) { - mCanvas.clearLayerUpdates(); - } - destroyHardwareLayer(view); - GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); - } - }); - } - } - - private static void destroyHardwareLayer(View view) { - view.destroyLayer(true); - - if (view instanceof ViewGroup) { - ViewGroup group = (ViewGroup) view; - - int count = group.getChildCount(); - for (int i = 0; i < count; i++) { - destroyHardwareLayer(group.getChildAt(i)); - } - } - } - - @Override void destroyHardwareResources(final View view) { if (view != null) { safelyRun(new Runnable() { @@ -1069,7 +1047,6 @@ public class GLRenderer extends HardwareRenderer { return true; } - @Override boolean validate() { return checkRenderContext() != SURFACE_STATE_ERROR; } diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 9bbcf7ce5963..958c0719543a 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -33,7 +33,7 @@ import android.graphics.SurfaceTexture; */ final class HardwareLayer { private static final int LAYER_TYPE_TEXTURE = 1; - private static final int LAYER_TYPE_RENDER = 2; + private static final int LAYER_TYPE_DISPLAY_LIST = 2; private HardwareRenderer mRenderer; private Finalizer mFinalizer; @@ -99,6 +99,10 @@ final class HardwareLayer { doDestroyLayerUpdater(); } + public long getDeferredLayerUpdater() { + return mFinalizer.mDeferredUpdater; + } + /** * Destroys the deferred layer updater but not the backing layer. The * backing layer is instead returned and is the caller's responsibility @@ -120,7 +124,7 @@ final class HardwareLayer { } public DisplayList startRecording() { - assertType(LAYER_TYPE_RENDER); + assertType(LAYER_TYPE_DISPLAY_LIST); if (mDisplayList == null) { mDisplayList = DisplayList.create("HardwareLayer"); @@ -172,9 +176,17 @@ final class HardwareLayer { /** * Indicates that this layer has lost its texture. */ - public void onTextureDestroyed() { + public void detachSurfaceTexture(final SurfaceTexture surface) { assertType(LAYER_TYPE_TEXTURE); - nOnTextureDestroyed(mFinalizer.mDeferredUpdater); + mRenderer.safelyRun(new Runnable() { + @Override + public void run() { + surface.detachFromGLContext(); + // SurfaceTexture owns the texture name and detachFromGLContext + // should have deleted it + nOnTextureDestroyed(mFinalizer.mDeferredUpdater); + } + }); } /** @@ -226,12 +238,20 @@ final class HardwareLayer { return new HardwareLayer(renderer, nCreateTextureLayer(), LAYER_TYPE_TEXTURE); } + static HardwareLayer adoptTextureLayer(HardwareRenderer renderer, long layer) { + return new HardwareLayer(renderer, layer, LAYER_TYPE_TEXTURE); + } + /** * This should only be used by HardwareRenderer! Do not call directly */ - static HardwareLayer createRenderLayer(HardwareRenderer renderer, + static HardwareLayer createDisplayListLayer(HardwareRenderer renderer, int width, int height) { - return new HardwareLayer(renderer, nCreateRenderLayer(width, height), LAYER_TYPE_RENDER); + return new HardwareLayer(renderer, nCreateRenderLayer(width, height), LAYER_TYPE_DISPLAY_LIST); + } + + static HardwareLayer adoptDisplayListLayer(HardwareRenderer renderer, long layer) { + return new HardwareLayer(renderer, layer, LAYER_TYPE_DISPLAY_LIST); } /** This also creates the underlying layer */ diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 93cc9d122ce4..7a943f0a136c 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -234,13 +234,6 @@ public abstract class HardwareRenderer { abstract void updateSurface(Surface surface) throws OutOfResourcesException; /** - * 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. * @@ -257,15 +250,6 @@ public abstract class HardwareRenderer { abstract void invalidate(Surface surface); /** - * This method should be invoked to ensure the hardware renderer is in - * valid state (for instance, to ensure the correct EGL context is bound - * to the current thread.) - * - * @return true if the renderer is now valid, false otherwise - */ - abstract boolean validate(); - - /** * This method ensures the hardware renderer is in a valid state * before executing the specified action. * diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index e78940779fd3..ef0d80d73cde 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -231,26 +231,12 @@ public class TextureView extends View { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (mLayer != null) { - boolean success = executeHardwareAction(new Runnable() { - @Override - public void run() { - destroySurface(); - } - }); - - if (!success) { - Log.w(LOG_TAG, "TextureView was not able to destroy its surface: " + this); - } - } + destroySurface(); } private void destroySurface() { if (mLayer != null) { - mSurface.detachFromGLContext(); - // SurfaceTexture owns the texture name and detachFromGLContext - // should have deleted it - mLayer.onTextureDestroyed(); + mLayer.detachSurfaceTexture(mSurface); boolean shouldRelease = true; if (mListener != null) { @@ -608,14 +594,6 @@ public class TextureView extends View { */ public Bitmap getBitmap(Bitmap bitmap) { if (bitmap != null && isAvailable()) { - AttachInfo info = mAttachInfo; - if (info != null && info.mHardwareRenderer != null && - info.mHardwareRenderer.isEnabled()) { - if (!info.mHardwareRenderer.validate()) { - throw new IllegalStateException("Could not acquire hardware rendering context"); - } - } - applyUpdate(); applyTransformMatrix(); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 1d7e5b296162..e8f5e45fb393 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -76,13 +76,7 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override - void destroyLayers(View view) { - throw new NoSuchMethodError(); - } - - @Override void destroyHardwareResources(View view) { - // TODO: canvas.clearLayerUpdates() destroyResources(view); // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); } @@ -106,12 +100,6 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override - boolean validate() { - // TODO Remove users of this API - return false; - } - - @Override boolean safelyRun(Runnable action) { nRunWithGlContext(mNativeProxy, action); return true; @@ -150,26 +138,6 @@ public class ThreadedRenderer extends HardwareRenderer { return false; } - @Override - void pushLayerUpdate(HardwareLayer layer) { - throw new NoSuchMethodError(); - } - - @Override - void onLayerCreated(HardwareLayer layer) { - throw new NoSuchMethodError(); - } - - @Override - void onLayerDestroyed(HardwareLayer layer) { - throw new NoSuchMethodError(); - } - - @Override - void flushLayerUpdates() { - throw new NoSuchMethodError(); - } - /** * TODO: Remove * Temporary hack to allow RenderThreadTest prototype app to trigger @@ -203,33 +171,63 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override - HardwareLayer createTextureLayer() { - throw new NoSuchMethodError(); + void detachFunctor(long functor) { + nDetachFunctor(mNativeProxy, functor); + } + + @Override + void attachFunctor(AttachInfo attachInfo, long functor) { + nAttachFunctor(mNativeProxy, functor); } @Override HardwareLayer createDisplayListLayer(int width, int height) { - throw new NoSuchMethodError(); + long layer = nCreateDisplayListLayer(mNativeProxy, width, height); + return HardwareLayer.adoptDisplayListLayer(this, layer); } @Override - SurfaceTexture createSurfaceTexture(HardwareLayer layer) { - throw new NoSuchMethodError(); + HardwareLayer createTextureLayer() { + long layer = nCreateTextureLayer(mNativeProxy); + return HardwareLayer.adoptTextureLayer(this, layer); } @Override - boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap) { - throw new NoSuchMethodError(); + SurfaceTexture createSurfaceTexture(final HardwareLayer layer) { + final SurfaceTexture[] ret = new SurfaceTexture[1]; + nRunWithGlContext(mNativeProxy, new Runnable() { + @Override + public void run() { + ret[0] = layer.createSurfaceTexture(); + } + }); + return ret[0]; } @Override - void detachFunctor(long functor) { - nDetachFunctor(mNativeProxy, functor); + boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) { + return nCopyLayerInto(mNativeProxy, + layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap); } @Override - void attachFunctor(AttachInfo attachInfo, long functor) { - nAttachFunctor(mNativeProxy, functor); + void pushLayerUpdate(HardwareLayer layer) { + // TODO: Remove this, it's not needed outside of GLRenderer + } + + @Override + void onLayerCreated(HardwareLayer layer) { + // TODO: Is this actually useful? + } + + @Override + void flushLayerUpdates() { + // TODO: Figure out what this should do or remove it + } + + @Override + void onLayerDestroyed(HardwareLayer layer) { + nDestroyLayer(mNativeProxy, layer.getDeferredLayerUpdater()); } @Override @@ -261,4 +259,9 @@ public class ThreadedRenderer extends HardwareRenderer { private static native void nAttachFunctor(long nativeProxy, long functor); private static native void nDetachFunctor(long nativeProxy, long functor); + + private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height); + private static native long nCreateTextureLayer(long nativeProxy); + private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap); + private static native void nDestroyLayer(long nativeProxy, long layer); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 49dc5728cdb2..9e7046e65fe6 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -13584,19 +13584,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, switch (mLayerType) { case LAYER_TYPE_HARDWARE: - if (attachInfo.mHardwareRenderer != null && - attachInfo.mHardwareRenderer.isEnabled() && - attachInfo.mHardwareRenderer.validate()) { - getHardwareLayer(); - // TODO: We need a better way to handle this case - // If views have registered pre-draw listeners they need - // to be notified before we build the layer. Those listeners - // may however rely on other events to happen first so we - // cannot just invoke them here until they don't cancel the - // current frame - if (!attachInfo.mTreeObserver.hasOnPreDrawListeners()) { - attachInfo.mViewRootImpl.dispatchFlushHardwareLayerUpdates(); - } + getHardwareLayer(); + // TODO: We need a better way to handle this case + // If views have registered pre-draw listeners they need + // to be notified before we build the layer. Those listeners + // may however rely on other events to happen first so we + // cannot just invoke them here until they don't cancel the + // current frame + if (!attachInfo.mTreeObserver.hasOnPreDrawListeners()) { + attachInfo.mViewRootImpl.dispatchFlushHardwareLayerUpdates(); } break; case LAYER_TYPE_SOFTWARE: @@ -13617,8 +13613,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return null; } - if (!mAttachInfo.mHardwareRenderer.validate()) return null; - final int width = mRight - mLeft; final int height = mBottom - mTop; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 11030d984ad2..a68d06ab948c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -631,16 +631,25 @@ public final class ViewRootImpl implements ViewParent, } } else { invalidateDisplayLists(); - if (mAttachInfo.mHardwareRenderer != null && - mAttachInfo.mHardwareRenderer.isEnabled()) { - mAttachInfo.mHardwareRenderer.destroyLayers(mView); + destroyHardwareLayer(mView); + } + } + + private static void destroyHardwareLayer(View view) { + view.destroyLayer(true); + + if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + + int count = group.getChildCount(); + for (int i = 0; i < count; i++) { + destroyHardwareLayer(group.getChildAt(i)); } } } void flushHardwareLayerUpdates() { - if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled() && - mAttachInfo.mHardwareRenderer.validate()) { + if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) { mAttachInfo.mHardwareRenderer.flushLayerUpdates(); } } @@ -2845,10 +2854,6 @@ public final class ViewRootImpl implements ViewParent, void dispatchDetachedFromWindow() { if (mView != null && mView.mAttachInfo != null) { - if (mAttachInfo.mHardwareRenderer != null && - mAttachInfo.mHardwareRenderer.isEnabled()) { - mAttachInfo.mHardwareRenderer.validate(); - } mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false); mView.dispatchDetachedFromWindow(); } |
