Merge "Reuse of native display list objects" into honeycomb

This commit is contained in:
Chet Haase
2011-01-06 15:02:51 -08:00
committed by Android (Google) Code Review
5 changed files with 100 additions and 67 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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