summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLES20Canvas.java33
-rw-r--r--core/java/android/view/GLES20DisplayList.java23
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp21
-rw-r--r--libs/hwui/DisplayListRenderer.cpp80
-rw-r--r--libs/hwui/DisplayListRenderer.h10
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