diff options
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 33 | ||||
-rw-r--r-- | core/java/android/view/GLES20DisplayList.java | 23 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 80 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 10 |
5 files changed, 100 insertions, 67 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 67b22fa..311002c 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -85,7 +85,7 @@ class GLES20Canvas extends HardwareCanvas { protected void setupRenderer(boolean record) { if (record) { - mRenderer = nCreateDisplayListRenderer(); + mRenderer = nGetDisplayListRenderer(mRenderer); } else { mRenderer = nCreateRenderer(); } @@ -93,28 +93,33 @@ class GLES20Canvas extends HardwareCanvas { if (mRenderer == 0) { throw new IllegalStateException("Could not create GLES20Canvas renderer"); } else { - if (mFinalizer == null) { - mFinalizer = new CanvasFinalizer(mRenderer); - } else { - mFinalizer.replaceNativeObject(mRenderer); - } + mFinalizer = CanvasFinalizer.getFinalizer(mFinalizer, mRenderer); } } - private native int nCreateRenderer(); - private native int nCreateDisplayListRenderer(); - + private native int nCreateRenderer(); + private static native int nGetDisplayListRenderer(int renderer); private static native void nDestroyRenderer(int renderer); private static class CanvasFinalizer { int mRenderer; - CanvasFinalizer(int renderer) { + // Factory method returns new instance if old one is null, or old instance + // otherwise, destroying native renderer along the way as necessary + static CanvasFinalizer getFinalizer(CanvasFinalizer oldFinalizer, int renderer) { + if (oldFinalizer == null) { + return new CanvasFinalizer(renderer); + } + oldFinalizer.replaceNativeObject(renderer); + return oldFinalizer; + } + + private CanvasFinalizer(int renderer) { mRenderer = renderer; } - void replaceNativeObject(int newRenderer) { - if (mRenderer != 0) { + private void replaceNativeObject(int newRenderer) { + if (mRenderer != 0 && newRenderer != mRenderer) { nDestroyRenderer(mRenderer); } mRenderer = newRenderer; @@ -199,10 +204,10 @@ class GLES20Canvas extends HardwareCanvas { /////////////////////////////////////////////////////////////////////////// int getDisplayList() { - return nCreateDisplayList(mRenderer); + return nGetDisplayList(mRenderer); } - private native int nCreateDisplayList(int renderer); + private native int nGetDisplayList(int renderer); static void destroyDisplayList(int displayList) { nDestroyDisplayList(displayList); diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index bd18fdd..c548659 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -70,11 +70,7 @@ class GLES20DisplayList extends DisplayList { mRecorded = true; mNativeDisplayList = mCanvas.getDisplayList(); - if (mFinalizer == null) { - mFinalizer = new DisplayListFinalizer(mNativeDisplayList); - } else { - mFinalizer.replaceNativeObject(mNativeDisplayList); - } + mFinalizer = DisplayListFinalizer.getFinalizer(mFinalizer, mNativeDisplayList); } } @@ -86,12 +82,23 @@ class GLES20DisplayList extends DisplayList { private static class DisplayListFinalizer { int mNativeDisplayList; - DisplayListFinalizer(int nativeDisplayList) { + // Factory method returns new instance if old one is null, or old instance + // otherwise, destroying native display list along the way as necessary + static DisplayListFinalizer getFinalizer(DisplayListFinalizer oldFinalizer, + int nativeDisplayList) { + if (oldFinalizer == null) { + return new DisplayListFinalizer(nativeDisplayList); + } + oldFinalizer.replaceNativeObject(nativeDisplayList); + return oldFinalizer; + } + + private DisplayListFinalizer(int nativeDisplayList) { mNativeDisplayList = nativeDisplayList; } - void replaceNativeObject(int newNativeDisplayList) { - if (mNativeDisplayList != 0) { + private void replaceNativeObject(int newNativeDisplayList) { + if (mNativeDisplayList != 0 && mNativeDisplayList != newNativeDisplayList) { GLES20Canvas.destroyDisplayList(mNativeDisplayList); } mNativeDisplayList = newNativeDisplayList; diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index c3d3572..b4c868f 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -417,16 +417,21 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas, // Display lists // ---------------------------------------------------------------------------- -static OpenGLRenderer* android_view_GLES20Canvas_createDisplayListRenderer( - JNIEnv* env, jobject canvas) { - return new DisplayListRenderer; -} - -static DisplayList* android_view_GLES20Canvas_createDisplayList(JNIEnv* env, +static DisplayList* android_view_GLES20Canvas_getDisplayList(JNIEnv* env, jobject canvas, DisplayListRenderer* renderer) { return renderer->getDisplayList(); } +static OpenGLRenderer* android_view_GLES20Canvas_getDisplayListRenderer(JNIEnv* env, + jobject clazz, DisplayListRenderer* renderer) { + if (renderer == NULL) { + renderer = new DisplayListRenderer; + } else { + renderer->reset(); + } + return renderer; +} + static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env, jobject clazz, DisplayList* displayList) { delete displayList; @@ -517,9 +522,9 @@ static JNINativeMethod gMethods[] = { { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds }, - { "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer }, - { "nCreateDisplayList", "(I)I", (void*) android_view_GLES20Canvas_createDisplayList }, + { "nGetDisplayList", "(I)I", (void*) android_view_GLES20Canvas_getDisplayList }, { "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList }, + { "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer }, { "nDrawDisplayList", "(II)V", (void*) android_view_GLES20Canvas_drawDisplayList }, #endif diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 77d628a..afb82bf 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -82,6 +82,43 @@ void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const { /////////////////////////////////////////////////////////////////////////////// DisplayList::DisplayList(const DisplayListRenderer& recorder) { + initFromDisplayListRenderer(recorder); +} + +DisplayList::~DisplayList() { + sk_free((void*) mReader.base()); + + Caches& caches = Caches::getInstance(); + + for (size_t i = 0; i < mBitmapResources.size(); i++) { + caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); + } + mBitmapResources.clear(); + + for (size_t i = 0; i < mShaderResources.size(); i++) { + caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i)); + } + mShaderResources.clear(); + + for (size_t i = 0; i < mPaints.size(); i++) { + delete mPaints.itemAt(i); + } + mPaints.clear(); + + for (size_t i = 0; i < mMatrices.size(); i++) { + delete mMatrices.itemAt(i); + } + mMatrices.clear(); + + if (mPathHeap) { + for (int i = 0; i < mPathHeap->count(); i++) { + caches.pathCache.removeDeferred(&(*mPathHeap)[i]); + } + mPathHeap->safeUnref(); + } +} + +void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) { const SkWriter32& writer = recorder.writeStream(); init(); @@ -132,39 +169,6 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) { } } -DisplayList::~DisplayList() { - sk_free((void*) mReader.base()); - - Caches& caches = Caches::getInstance(); - - for (size_t i = 0; i < mBitmapResources.size(); i++) { - caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); - } - mBitmapResources.clear(); - - for (size_t i = 0; i < mShaderResources.size(); i++) { - caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i)); - } - mShaderResources.clear(); - - for (size_t i = 0; i < mPaints.size(); i++) { - delete mPaints.itemAt(i); - } - mPaints.clear(); - - for (size_t i = 0; i < mMatrices.size(); i++) { - delete mMatrices.itemAt(i); - } - mMatrices.clear(); - - if (mPathHeap) { - for (int i = 0; i < mPathHeap->count(); i++) { - caches.pathCache.removeDeferred(&(*mPathHeap)[i]); - } - mPathHeap->safeUnref(); - } -} - void DisplayList::init() { mPathHeap = NULL; } @@ -327,6 +331,7 @@ void DisplayList::replay(OpenGLRenderer& renderer) { DisplayListRenderer::DisplayListRenderer(): mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) { mPathHeap = NULL; + mDisplayList = NULL; } DisplayListRenderer::~DisplayListRenderer() { @@ -367,6 +372,15 @@ void DisplayListRenderer::reset() { // Operations /////////////////////////////////////////////////////////////////////////////// +DisplayList* DisplayListRenderer::getDisplayList() { + if (mDisplayList == NULL) { + mDisplayList = new DisplayList(*this); + } else { + mDisplayList->initFromDisplayListRenderer(*this); + } + return mDisplayList; +} + void DisplayListRenderer::setViewport(int width, int height) { mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index b608381..fedb174 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -110,6 +110,8 @@ public: SetupShadow }; + void initFromDisplayListRenderer(const DisplayListRenderer& recorder); + void replay(OpenGLRenderer& renderer); private: @@ -216,6 +218,8 @@ public: DisplayListRenderer(); ~DisplayListRenderer(); + DisplayList* getDisplayList(); + void setViewport(int width, int height); void prepare(bool opaque); @@ -266,10 +270,6 @@ public: void reset(); - DisplayList* getDisplayList() const { - return new DisplayList(*this); - } - const SkWriter32& writeStream() const { return mWriter; } @@ -422,6 +422,8 @@ private: SkRefCntRecorder mRCRecorder; SkRefCntRecorder mTFRecorder; + DisplayList *mDisplayList; + friend class DisplayList; }; // class DisplayListRenderer |