From be34f2f3b340196426bdf558b28951359a4d84fa Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 10 Mar 2014 08:58:44 -0700 Subject: DisplayList lifecycle changes Bug: 13360343 Change DisplayList to be more forgiving with weaker lifecycle requirements. Is more self-managed with a strong reference to the renderer it needs Also fix naming mismatch Change-Id: I5c89453a72a52954f6f959f0846199705dbb6476 --- core/java/android/view/DisplayList.java | 34 ++++++++++++++++++++-------- core/java/android/view/GLRenderer.java | 6 ++--- core/java/android/view/HardwareLayer.java | 2 +- core/java/android/view/HardwareRenderer.java | 2 +- core/java/android/view/ThreadedRenderer.java | 6 ++--- core/java/android/view/View.java | 5 ++-- core/java/android/widget/Editor.java | 3 +-- core/jni/android_view_GLRenderer.cpp | 4 ++-- core/jni/android_view_ThreadedRenderer.cpp | 6 ++--- libs/hwui/renderthread/CanvasContext.cpp | 2 +- libs/hwui/renderthread/CanvasContext.h | 2 +- libs/hwui/renderthread/RenderProxy.cpp | 8 +++---- libs/hwui/renderthread/RenderProxy.h | 2 +- 13 files changed, 48 insertions(+), 34 deletions(-) diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 0ae36c1..be6f401 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -122,9 +122,6 @@ import android.graphics.Path; * @hide */ public class DisplayList { - private boolean mValid; - private final long mNativeDisplayList; - /** * Flag used when calling * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)} @@ -175,6 +172,10 @@ public class DisplayList { */ public static final int STATUS_DREW = 0x4; + private boolean mValid; + private final long mNativeDisplayList; + private HardwareRenderer mRenderer; + private DisplayList(String name) { mNativeDisplayList = nCreate(); nSetDisplayListName(mNativeDisplayList, name); @@ -233,7 +234,13 @@ public class DisplayList { GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas; canvas.onPostDraw(); long displayListData = canvas.finishRecording(); - renderer.swapDisplayListData(mNativeDisplayList, displayListData); + if (renderer != mRenderer) { + // If we are changing renderers first destroy with the old + // renderer, then set with the new one + destroyDisplayListData(); + } + mRenderer = renderer; + setDisplayListData(displayListData); canvas.recycle(); mValid = true; } @@ -245,14 +252,22 @@ public class DisplayList { * * @hide */ - public void destroyDisplayListData(HardwareRenderer renderer) { - if (renderer == null) { - throw new IllegalArgumentException("Cannot destroyDisplayListData with a null renderer"); - } - renderer.swapDisplayListData(mNativeDisplayList, 0); + public void destroyDisplayListData() { + if (!mValid) return; + + setDisplayListData(0); + mRenderer = null; mValid = false; } + private void setDisplayListData(long newData) { + if (mRenderer != null) { + mRenderer.setDisplayListData(mNativeDisplayList, newData); + } else { + throw new IllegalStateException("Trying to set data without a renderer! data=" + newData); + } + } + /** * Returns whether the display list is currently usable. If this returns false, * the display list should be re-recorded prior to replaying it. @@ -907,6 +922,7 @@ public class DisplayList { @Override protected void finalize() throws Throwable { try { + destroyDisplayListData(); nDestroyDisplayList(mNativeDisplayList); } finally { super.finalize(); diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java index c90e4b0..81f778d 100644 --- a/core/java/android/view/GLRenderer.java +++ b/core/java/android/view/GLRenderer.java @@ -1196,10 +1196,10 @@ public class GLRenderer extends HardwareRenderer { } } - void swapDisplayListData(long displayList, long newData) { - nSwapDisplayListData(displayList, newData); + void setDisplayListData(long displayList, long newData) { + nSetDisplayListData(displayList, newData); } - private static native void nSwapDisplayListData(long displayList, long newData); + private static native void nSetDisplayListData(long displayList, long newData); private DisplayList buildDisplayList(View view, HardwareCanvas canvas) { if (mDrawDelta <= 0) { diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index c526dd2..46e2690 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -88,7 +88,7 @@ final class HardwareLayer { } if (mDisplayList != null) { - mDisplayList.destroyDisplayListData(mRenderer); + mDisplayList.destroyDisplayListData(); mDisplayList = null; } if (mRenderer != null) { diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index bcc28e3..34efcf5 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -562,7 +562,7 @@ public abstract class HardwareRenderer { mRequested = requested; } - abstract void swapDisplayListData(long displayList, long newData); + abstract void setDisplayListData(long displayList, long newData); /** * Describes a series of frames that should be drawn on screen as a graph. diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 3dcfbb3..a1fb123 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -148,8 +148,8 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override - void swapDisplayListData(long displayList, long newData) { - nSwapDisplayListData(mNativeProxy, displayList, newData); + void setDisplayListData(long displayList, long newData) { + nSetDisplayListData(mNativeProxy, displayList, newData); } @Override @@ -257,7 +257,7 @@ public class ThreadedRenderer extends HardwareRenderer { private static native boolean nInitialize(long nativeProxy, Surface window); private static native void nUpdateSurface(long nativeProxy, Surface window); private static native void nSetup(long nativeProxy, int width, int height); - private static native void nSwapDisplayListData(long nativeProxy, long displayList, + private static native void nSetDisplayListData(long nativeProxy, long displayList, long newData); private static native void nDrawDisplayList(long nativeProxy, long displayList, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 9b45f97..904ec44 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -14062,13 +14062,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private void resetDisplayList() { - HardwareRenderer renderer = getHardwareRenderer(); if (mDisplayList != null && mDisplayList.isValid()) { - mDisplayList.destroyDisplayListData(renderer); + mDisplayList.destroyDisplayListData(); } if (mBackgroundDisplayList != null && mBackgroundDisplayList.isValid()) { - mBackgroundDisplayList.destroyDisplayListData(renderer); + mBackgroundDisplayList.destroyDisplayListData(); } } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 98b43b3..53d9e28 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -287,13 +287,12 @@ public class Editor { } private void destroyDisplayListsData() { - HardwareRenderer renderer = mTextView.getHardwareRenderer(); if (mTextDisplayLists != null) { for (int i = 0; i < mTextDisplayLists.length; i++) { DisplayList displayList = mTextDisplayLists[i] != null ? mTextDisplayLists[i].displayList : null; if (displayList != null && displayList.isValid()) { - displayList.destroyDisplayListData(renderer); + displayList.destroyDisplayListData(); } } } diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp index 5ea8460..b7e795e 100644 --- a/core/jni/android_view_GLRenderer.cpp +++ b/core/jni/android_view_GLRenderer.cpp @@ -140,7 +140,7 @@ static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz, LayerRenderer::destroyLayer(layer); } -static void android_view_GLRenderer_swapDisplayListData(JNIEnv* env, jobject clazz, +static void android_view_GLRenderer_setDisplayListData(JNIEnv* env, jobject clazz, jlong displayListPtr, jlong newDataPtr) { using namespace android::uirenderer; DisplayList* displayList = reinterpret_cast(displayListPtr); @@ -178,7 +178,7 @@ static JNINativeMethod gMethods[] = { { "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime }, { "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer }, - { "nSwapDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_swapDisplayListData }, + { "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData }, #endif { "setupShadersDiskCache", "(Ljava/lang/String;)V", diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 444c8be..2b20758 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -103,12 +103,12 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, proxy->setup(width, height); } -static void android_view_ThreadedRenderer_swapDisplayListData(JNIEnv* env, jobject clazz, +static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz, jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) { RenderProxy* proxy = reinterpret_cast(proxyPtr); DisplayList* displayList = reinterpret_cast(displayListPtr); DisplayListData* newData = reinterpret_cast(newDataPtr); - proxy->swapDisplayListData(displayList, newData); + proxy->setDisplayListData(displayList, newData); } static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz, @@ -191,7 +191,7 @@ static JNINativeMethod gMethods[] = { { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize }, { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup }, - { "nSwapDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_swapDisplayListData }, + { "nSetDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_setDisplayListData }, { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList }, { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas }, { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor }, diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 0568851..ce66d8f 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -373,7 +373,7 @@ void CanvasContext::setup(int width, int height) { mCanvas->setViewport(width, height); } -void CanvasContext::swapDisplayListData(DisplayList* displayList, DisplayListData* newData) { +void CanvasContext::setDisplayListData(DisplayList* displayList, DisplayListData* newData) { displayList->setData(newData); } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 2c9348c..649ffb6 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -63,7 +63,7 @@ public: bool initialize(EGLNativeWindowType window); void updateSurface(EGLNativeWindowType window); void setup(int width, int height); - void swapDisplayListData(DisplayList* displayList, DisplayListData* newData); + void setDisplayListData(DisplayList* displayList, DisplayListData* newData); void processLayerUpdates(const Vector* layerUpdaters); void drawDisplayList(DisplayList* displayList, Rect* dirty); void destroyCanvas(); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index c3bf404..200c21f 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -117,14 +117,14 @@ void RenderProxy::setup(int width, int height) { post(task); } -CREATE_BRIDGE3(swapDisplayListData, CanvasContext* context, DisplayList* displayList, +CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, DisplayList* displayList, DisplayListData* newData) { - args->context->swapDisplayListData(args->displayList, args->newData); + args->context->setDisplayListData(args->displayList, args->newData); return NULL; } -void RenderProxy::swapDisplayListData(DisplayList* displayList, DisplayListData* newData) { - SETUP_TASK(swapDisplayListData); +void RenderProxy::setDisplayListData(DisplayList* displayList, DisplayListData* newData) { + SETUP_TASK(setDisplayListData); args->context = mContext; args->displayList = displayList; args->newData = newData; diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 0934b98..83a8a8f 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -60,7 +60,7 @@ public: ANDROID_API bool initialize(EGLNativeWindowType window); ANDROID_API void updateSurface(EGLNativeWindowType window); ANDROID_API void setup(int width, int height); - ANDROID_API void swapDisplayListData(DisplayList* displayList, DisplayListData* newData); + ANDROID_API void setDisplayListData(DisplayList* displayList, DisplayListData* newData); ANDROID_API void drawDisplayList(DisplayList* displayList, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); ANDROID_API void destroyCanvas(); -- cgit v1.1