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

Commit b051e895 authored by Romain Guy's avatar Romain Guy
Browse files

Add display lists caching.

Change-Id: Iac3a248a81ed8cb076a83ef9d186b8ebba685b4c
parent 5a86c4c3
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

/**
 * A display lists records a series of graphics related operation and can replay
 * them later. Display lists are usually built by recording operations on a
 * {@link android.graphics.Canvas}. Replaying the operations from a display list
 * avoids executing views drawing code on every frame, and is thus much more
 * efficient. 
 */
abstract class DisplayList {
    /**
     * Starts recording the display list. All operations performed on the
     * returned canvas are recorded and stored in this display list.
     * 
     * @return A canvas to record drawing operations.
     */
    abstract HardwareCanvas start();

    /**
     * Ends the recording for this display list. A display list cannot be
     * replayed if recording is not finished. 
     */
    abstract void end();

    /**
     * Frees resources taken by this display list. This method must be called
     * before releasing all references.
     */
    abstract void destroy();

    /**
     * Indicates whether this display list can be replayed or not.
     * 
     * @return True if the display list can be replayed, false otherwise.
     * 
     * @see android.view.HardwareCanvas#drawDisplayList(DisplayList) 
     */
    abstract boolean isReady();
}
+42 −29
Original line number Diff line number Diff line
@@ -35,14 +35,10 @@ import android.text.SpannableString;
import android.text.SpannedString;
import android.text.TextUtils;

import javax.microedition.khronos.opengles.GL;

/**
 * An implementation of Canvas on top of OpenGL ES 2.0.
 */
class GLES20Canvas extends Canvas {
    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
    private final GL mGl;
class GLES20Canvas extends HardwareCanvas {
    private final boolean mOpaque;
    private int mRenderer;
    
@@ -73,26 +69,28 @@ class GLES20Canvas extends Canvas {
    // Constructors
    ///////////////////////////////////////////////////////////////////////////

    GLES20Canvas(GL gl, boolean translucent) {
        mGl = gl;
    GLES20Canvas(boolean translucent) {
        this(false, translucent);
    }
    
    GLES20Canvas(boolean record, boolean translucent) {
        mOpaque = !translucent;

        if (record) {
            mRenderer = nCreateDisplayListRenderer();
        } else {
            mRenderer = nCreateRenderer();
        }
       
        if (mRenderer == 0) {
            throw new IllegalStateException("Could not create GLES20Canvas renderer");
        }
    }

    private native int nCreateRenderer();    
    private native int nCreateDisplayListRenderer();    

    /**
     * This method <strong>must</strong> be called before releasing a
     * reference to a GLES20Canvas. This method is responsible for freeing
     * native resources associated with the hardware. Not invoking this
     * method properly can result in memory leaks.
     * 
     * @hide
     */
    @Override
    public synchronized void destroy() {
        if (mRenderer != 0) {
            nDestroyRenderer(mRenderer);
@@ -106,16 +104,6 @@ class GLES20Canvas extends Canvas {
    // Canvas management
    ///////////////////////////////////////////////////////////////////////////

    @Override
    public boolean isHardwareAccelerated() {
        return true;
    }

    @Override
    public void setBitmap(Bitmap bitmap) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isOpaque() {
        return mOpaque;
@@ -145,12 +133,14 @@ class GLES20Canvas extends Canvas {
    
    private native void nSetViewport(int renderer, int width, int height);

    @Override
    void onPreDraw() {
        nPrepare(mRenderer);
    }

    private native void nPrepare(int renderer);

    @Override
    void onPostDraw() {
        nFinish(mRenderer);
    }
@@ -178,6 +168,29 @@ class GLES20Canvas extends Canvas {

    private native void nReleaseContext(int renderer);
    
    ///////////////////////////////////////////////////////////////////////////
    // Display list
    ///////////////////////////////////////////////////////////////////////////

    int getDisplayList() {
        return nCreateDisplayList(mRenderer);
    }

    private native int nCreateDisplayList(int renderer);
    
    void destroyDisplayList(int displayList) {
        nDestroyDisplayList(displayList);
    }

    private native void nDestroyDisplayList(int displayList);

    @Override
    public void drawDisplayList(DisplayList displayList) {
        nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
    }

    private native void nDrawDisplayList(int renderer, int displayList);

    ///////////////////////////////////////////////////////////////////////////
    // Clipping
    ///////////////////////////////////////////////////////////////////////////
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

/**
 * An implementation of display list for OpenGL ES 2.0.
 */
class GLES20DisplayList extends DisplayList {
    private GLES20Canvas mCanvas;

    private boolean mStarted = false;
    private boolean mRecorded = false;

    int mNativeDisplayList;

    @Override
    HardwareCanvas start() {
        if (mStarted) {
            throw new IllegalStateException("Recording has already started");
        }

        destroyCanvas();

        mCanvas = new GLES20Canvas(true, true);
        mStarted = true;
        mRecorded = false;

        return mCanvas;
    }

    private void destroyCanvas() {
        if (mCanvas != null) {
            mCanvas.destroyDisplayList(mNativeDisplayList);
            mCanvas.destroy();

            mCanvas = null;
            mNativeDisplayList = 0;
        }
    }

    @Override
    void end() {
        if (mCanvas != null) {
            mStarted = false;
            mRecorded = true;

            mNativeDisplayList = mCanvas.getDisplayList();
        }
    }

    @Override
    void destroy() {
        destroyCanvas();
    }

    @Override
    boolean isReady() {
        return !mStarted && mRecorded;
    }
}
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.graphics.Bitmap;
import android.graphics.Canvas;

/**
 * Hardware accelerated canvas. 
 */
abstract class HardwareCanvas extends Canvas {
    @Override
    public boolean isHardwareAccelerated() {
        return true;
    }

    @Override
    public void setBitmap(Bitmap bitmap) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method <strong>must</strong> be called before releasing a
     * reference to a hardware canvas. This method is responsible for
     * freeing native resources associated with the hardware. Not
     * invoking this method properly can result in memory leaks.
     */    
    public abstract void destroy();

    /**
     * Invoked before any drawing operation is performed in this canvas.
     */
    abstract void onPreDraw();

    /**
     * Invoked after all drawing operation have been performed.
     */
    abstract void onPostDraw();
    
    /**
     * Draws the specified display list onto this canvas.
     * 
     * @param displayList The display list to replay.
     */
    public abstract void drawDisplayList(DisplayList displayList);
}
+14 −1
Original line number Diff line number Diff line
@@ -102,6 +102,14 @@ public abstract class HardwareRenderer {
     */
    abstract void draw(View view, View.AttachInfo attachInfo, int yOffset);

    /**
     * Creates a new canvas that can be used to record drawing operations
     * in the specified display list.
     * 
     * @return A new recording canvas.
     */
    abstract DisplayList createDisplayList();

    /**
     * Initializes the hardware renderer for the specified surface and setup the
     * renderer for drawing, if needed. This is invoked when the ViewRoot has
@@ -577,7 +585,7 @@ public abstract class HardwareRenderer {

        @Override
        GLES20Canvas createCanvas() {
            return mGlCanvas = new GLES20Canvas(mGl, true);
            return mGlCanvas = new GLES20Canvas(true);
        }

        @Override
@@ -590,6 +598,11 @@ public abstract class HardwareRenderer {
            mGlCanvas.onPostDraw();
        }

        @Override
        DisplayList createDisplayList() {
            return new GLES20DisplayList();
        }

        static HardwareRenderer create(boolean translucent) {
            if (GLES20Canvas.isAvailable()) {
                return new Gl20Renderer(translucent);
Loading