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

Commit daf98e94 authored by Chet Haase's avatar Chet Haase
Browse files

Use optimized display lists for all hwaccelerated rendering

Previously, display lists were used only if hardware acceleration
was enabled for an application (hardwareAccelerated=true) *and* if
setDrawingCacheEnabled(true) was called. This change makes the framework
use display lists for all views in an application if hardware acceleration
is enabled.

In addition, display list renderering has been optimized so that
any view's recreation of its own display list (which is necessary whenever
the visuals of that view change) will not cause any other display list
in its parent hierarchy to change. Instead, when there are any visual
changes in the hierarchy, only those views which need to have new
display list content will recreate their display lists.

This optimization works by caching display list references in each
parent display list (so the container of some child will refer to its
child's display list by a reference to the child's display list). Then when
a view needs to recreate its display list, it will do so inside the same
display list object. This will cause the content to get refreshed, but not
the reference to that content. Then when the view hierarchy is redrawn,
it will automatically pick up the new content from the old reference.

This optimization will not necessarily improve performance when applications
need to update the entire view hierarchy or redraw the entire screen, but it does
show significant improvements when redrawing only a portion of the screen,
especially when the regions that are not refreshed are complex and time-
consuming to redraw.

Change-Id: I68d21cac6a224a05703070ec85253220cb001eb4
parent 57ffc002
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -34,11 +34,12 @@ import java.util.List;
 * custom animations, use the {@link LayoutTransition#setAnimator(int, Animator)
 * setAnimator()} method.
 *
 * <p>One of the core concepts of these transition animations is that there are two core
 * <p>One of the core concepts of these transition animations is that there are two types of
 * changes that cause the transition and four different animations that run because of
 * those changes. The changes that trigger the transition are items being added to a container
 * (referred to as an "appearing" transition) or removed from a container (also known as
 * "disappearing"). The animations that run due to those events are one that animates
 * "disappearing"). Setting the visibility of views (between GONE and VISIBLE) will trigger
 * the same add/remove logic. The animations that run due to those events are one that animates
 * items being added, one that animates items being removed, and two that animate the other
 * items in the container that change due to the add/remove occurrence. Users of
 * the transition may want different animations for the changing items depending on whether
@@ -62,6 +63,18 @@ import java.util.List;
 * values when the transition begins. Custom animations will be similarly populated with
 * the target and values being animated, assuming they use ObjectAnimator objects with
 * property names that are known on the target object.</p>
 *
 * <p>This class, and the associated XML flag for containers, animateLayoutChanges="true",
 * provides a simple utility meant for automating changes in straightforward situations.
 * Using LayoutTransition at multiple levels of a nested view hierarchy may not work due to the
 * interrelationship of the various levels of layout. Also, a container that is being scrolled
 * at the same time as items are being added or removed is probably not a good candidate for
 * this utility, because the before/after locations calculated by LayoutTransition
 * may not match the actual locations when the animations finish due to the container
 * being scrolled as the animations are running. You can work around that
 * particular issue by disabling the 'changing' animations by setting the CHANGE_APPEARING
 * and CHANGE_DISAPPEARING animations to null, and setting the startDelay of the
 * other animations appropriately.</p>
 */
public class LayoutTransition {

+4 −2
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@ package android.view;
 * {@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.
 *
 * @hide 
 */
abstract class DisplayList {
public abstract class DisplayList {
    /**
     * Starts recording the display list. All operations performed on the
     * returned canvas are recorded and stored in this display list.
+11 −4
Original line number Diff line number Diff line
@@ -219,6 +219,13 @@ class GLES20Canvas extends HardwareCanvas {

    private native void nAcquireContext(int renderer);

    @Override
    public boolean callDrawGLFunction(int drawGLFunction) {
        return nCallDrawGLFunction(mRenderer, drawGLFunction);
    }

    private native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);

    @Override
    public void releaseContext() {
        if (mContextLocked) {
@@ -246,11 +253,11 @@ class GLES20Canvas extends HardwareCanvas {
    private static native void nDestroyDisplayList(int displayList);

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

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

    ///////////////////////////////////////////////////////////////////////////
    // Hardware layer
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.view;

import java.lang.ref.WeakReference;

/**
 * An implementation of display list for OpenGL ES 2.0.
 */
@@ -27,12 +29,24 @@ class GLES20DisplayList extends DisplayList {
    private boolean mValid = false;

    int mNativeDisplayList;
    WeakReference<View> hostView;

    // The native display list will be destroyed when this object dies.
    // DO NOT overwrite this reference once it is set.
    @SuppressWarnings("unused")
    private DisplayListFinalizer mFinalizer;

    public GLES20DisplayList(View view) {
        hostView = new WeakReference<View>(view);
    }

    public void invalidateView() {
        View v = hostView.get();
        if (v != null) {
            v.invalidate();
        }
    }

    @Override
    HardwareCanvas start() {
        if (mStarted) {
+19 −4
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@ import android.graphics.Paint;

/**
 * Hardware accelerated canvas.
 *
 * @hide 
 */
abstract class HardwareCanvas extends Canvas {
public abstract class HardwareCanvas extends Canvas {
    @Override
    public boolean isHardwareAccelerated() {
        return true;
@@ -49,7 +51,7 @@ abstract class HardwareCanvas extends Canvas {
     * 
     * @param displayList The display list to replay.
     */
    abstract void drawDisplayList(DisplayList displayList);
    abstract boolean drawDisplayList(DisplayList displayList);

    /**
     * Draws the specified layer onto this canvas.
@@ -60,4 +62,17 @@ abstract class HardwareCanvas extends Canvas {
     * @param paint The paint used to draw the layer
     */
    abstract void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint);

    /**
     * Calls the function specified with the drawGLFunction function pointer. This is
     * functionality used by webkit for calling into their renderer from our display lists.
     * This function may return true if an invalidation is needed after the call.
     *
     * @param drawGLFunction A native function pointer
     * @return true if an invalidate is needed after the call, false otherwise
     */
    public boolean callDrawGLFunction(int drawGLFunction) {
        // Noop - this is done in the display list recorder subclass
        return false;
    }
}
Loading