Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5977baa1 authored by Chet Haase's avatar Chet Haase
Browse files

Reuse of native display list objects

Change-Id: Ia4553e23930ad20e56c11faa7809be788a1ad4bb
parent 42edf0f8
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -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 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);
+15 −8
Original line number Diff line number Diff line
@@ -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;
+13 −8
Original line number Diff line number Diff line
@@ -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
+47 −33
Original line number Diff line number Diff line
@@ -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);

+6 −4
Original line number Diff line number Diff line
@@ -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