Merge "Reuse of native display list objects" into honeycomb
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user