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

Commit 9420abd5 authored by Chet Haase's avatar Chet Haase
Browse files

Re-enable DisplayList properties.

Re-enabling DisplayList properties last week caused some app
errors due to the way that some transforms were being handled (specifically,
those coming from the old Animations and ViewGroup's childStaticTransformation
field). This change pushes *all* transform/alpha data from View.draw() into
the view's DisplayList, making DisplayLists more encapsulated (and correct).

Change-Id: Ia702c6aae050784bb3ed505aa87553113f8a1938
parent 1d601335
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.view;

import android.graphics.Matrix;

/**
 * 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
@@ -117,12 +119,26 @@ public abstract class DisplayList {
    public abstract void setClipChildren(boolean clipChildren);

    /**
     * Set the application scale on the DisplayList. This scale is incurred by applications that
     * are auto-scaled for compatibility reasons. By default, the value is 1 (unscaled).
     * Set the static matrix on the DisplayList. This matrix exists if a custom ViewGroup
     * overrides
     * {@link ViewGroup#getChildStaticTransformation(View, android.view.animation.Transformation)}
     * and also has {@link ViewGroup#setStaticTransformationsEnabled(boolean)} set to true.
     * This matrix will be concatenated with any other matrices in the DisplayList to position
     * the view appropriately.
     *
     * @param matrix The matrix
     */
    public abstract void setStaticMatrix(Matrix matrix);

    /**
     * Set the Animation matrix on the DisplayList. This matrix exists if an Animation is
     * currently playing on a View, and is set on the DisplayList during at draw() time. When
     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
     * for the matrix parameter.
     *
     * @param scale The scaling factor
     * @param matrix The matrix, null indicates that the matrix should be cleared.
     */
    public abstract void setApplicationScale(float scale);
    public abstract void setAnimationMatrix(Matrix matrix);

    /**
     * Sets the alpha value for the DisplayList
+14 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.graphics.Bitmap;
import android.graphics.Matrix;

import java.util.ArrayList;

@@ -119,9 +120,18 @@ class GLES20DisplayList extends DisplayList {
    }

    @Override
    public void setApplicationScale(float scale) {
    public void setStaticMatrix(Matrix matrix) {
        try {
            nSetApplicationScale(getNativeDisplayList(), scale);
            nSetStaticMatrix(getNativeDisplayList(), matrix.native_instance);
        } catch (IllegalStateException e) {
            // invalid DisplayList okay: we'll set current values the next time we render to it
        }
    }

    @Override
    public void setAnimationMatrix(Matrix matrix) {
        try {
            nSetAnimationMatrix(getNativeDisplayList(), matrix.native_instance);
        } catch (IllegalStateException e) {
            // invalid DisplayList okay: we'll set current values the next time we render to it
        }
@@ -335,6 +345,8 @@ class GLES20DisplayList extends DisplayList {
    private static native void nSetTransformationInfo(int displayList, float alpha,
            float translationX, float translationY, float rotation, float rotationX,
            float rotationY, float scaleX, float scaleY);
    private static native void nSetStaticMatrix(int displayList, int nativeMatrix);
    private static native void nSetAnimationMatrix(int displayList, int animationMatrix);


    ///////////////////////////////////////////////////////////////////////////
+60 −16
Original line number Diff line number Diff line
@@ -11529,12 +11529,34 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                displayList.setClipChildren(
                        (((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
            }
            if (mAttachInfo != null && mAttachInfo.mScalingRequired &&
                    mAttachInfo.mApplicationScale != 1.0f) {
                displayList.setApplicationScale(1f / mAttachInfo.mApplicationScale);
            float alpha = 1;
            if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
                    ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
                ViewGroup parentVG = (ViewGroup) mParent;
                final boolean hasTransform =
                        parentVG.getChildStaticTransformation(this, parentVG.mChildTransformation);
                if (hasTransform) {
                    Transformation transform = parentVG.mChildTransformation;
                    final int transformType = parentVG.mChildTransformation.getTransformationType();
                    if (transformType != Transformation.TYPE_IDENTITY) {
                        if ((transformType & Transformation.TYPE_ALPHA) != 0) {
                            alpha = transform.getAlpha();
                        }
                        if ((transformType & Transformation.TYPE_MATRIX) != 0) {
                            displayList.setStaticMatrix(transform.getMatrix());
                        }
                    }
                }
            }
            if (mTransformationInfo != null) {
                displayList.setTransformationInfo(mTransformationInfo.mAlpha,
                alpha *= mTransformationInfo.mAlpha;
                if (alpha < 1) {
                    final int multipliedAlpha = (int) (255 * alpha);
                    if (onSetAlpha(multipliedAlpha)) {
                        alpha = 1;
                    }
                }
                displayList.setTransformationInfo(alpha,
                        mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY,
                        mTransformationInfo.mRotation, mTransformationInfo.mRotationX,
                        mTransformationInfo.mRotationY, mTransformationInfo.mScaleX,
@@ -11548,6 +11570,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                    displayList.setPivotX(getPivotX());
                    displayList.setPivotY(getPivotY());
                }
            } else if (alpha < 1) {
                displayList.setAlpha(alpha);
            }
        }
    }
@@ -11580,6 +11604,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
                (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
            caching = true;
            // Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
            if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
        } else {
            caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
@@ -11590,7 +11615,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            more = drawAnimation(parent, drawingTime, a, scalingRequired);
            concatMatrix = a.willChangeTransformationMatrix();
            transformToApply = parent.mChildTransformation;
        } else if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
        } else if (!useDisplayListProperties &&
                (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
            final boolean hasTransform =
                    parent.getChildStaticTransformation(this, parent.mChildTransformation);
            if (hasTransform) {
@@ -11658,6 +11684,17 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            }
        }
        useDisplayListProperties &= hasDisplayList;
        if (useDisplayListProperties) {
            displayList = getDisplayList();
            if (!displayList.isValid()) {
                // Uncommon, but possible. If a view is removed from the hierarchy during the call
                // to getDisplayList(), the display list will be marked invalid and we should not
                // try to use it again.
                displayList = null;
                hasDisplayList = false;
                useDisplayListProperties = false;
            }
        }
        final boolean hasNoCache = cache == null || hasDisplayList;
        final boolean offsetForScroll = cache == null && !hasDisplayList &&
@@ -11675,6 +11712,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            }
            if (scalingRequired) {
                if (useDisplayListProperties) {
                    // TODO: Might not need this if we put everything inside the DL
                    restoreTo = canvas.save();
                }
                // mAttachInfo cannot be null, otherwise scalingRequired == false
@@ -11684,7 +11722,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        }
        float alpha = useDisplayListProperties ? 1 : getAlpha();
        if (transformToApply != null || alpha < 1.0f || !hasIdentityMatrix()) {
        if (transformToApply != null || alpha < 1 || !hasIdentityMatrix()) {
            if (transformToApply != null || !childHasIdentityMatrix) {
                int transX = 0;
                int transY = 0;
@@ -11696,16 +11734,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                if (transformToApply != null) {
                    if (concatMatrix) {
                        if (useDisplayListProperties) {
                            displayList.setAnimationMatrix(transformToApply.getMatrix());
                        } else {
                            // Undo the scroll translation, apply the transformation matrix,
                            // then redo the scroll translate to get the correct result.
                            canvas.translate(-transX, -transY);
                            canvas.concat(transformToApply.getMatrix());
                            canvas.translate(transX, transY);
                        }
                        parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
                    }
                    float transformAlpha = transformToApply.getAlpha();
                    if (transformAlpha < 1.0f) {
                    if (transformAlpha < 1) {
                        alpha *= transformToApply.getAlpha();
                        parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
                    }
@@ -11718,7 +11760,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                }
            }
            if (alpha < 1.0f) {
            if (alpha < 1) {
                parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
                if (hasNoCache) {
                    final int multipliedAlpha = (int) (255 * alpha);
@@ -11728,7 +11770,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                                layerType != LAYER_TYPE_NONE) {
                            layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
                        }
                        if (layerType == LAYER_TYPE_NONE) {
                        if (useDisplayListProperties) {
                            displayList.setAlpha(alpha * getAlpha());
                        } else  if (layerType == LAYER_TYPE_NONE) {
                            final int scrollX = hasDisplayList ? 0 : sx;
                            final int scrollY = hasDisplayList ? 0 : sy;
                            canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft,
@@ -11758,7 +11802,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            }
        }
        if (hasDisplayList) {
        if (!useDisplayListProperties && hasDisplayList) {
            displayList = getDisplayList();
            if (!displayList.isValid()) {
                // Uncommon, but possible. If a view is removed from the hierarchy during the call
@@ -11815,7 +11859,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                    cachePaint.setDither(false);
                    parent.mCachePaint = cachePaint;
                }
                if (alpha < 1.0f) {
                if (alpha < 1) {
                    cachePaint.setAlpha((int) (alpha * 255));
                    parent.mGroupFlags |= ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
                } else if  ((flags & ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE) != 0) {
+32 −28
Original line number Diff line number Diff line
@@ -45,9 +45,14 @@ static void android_view_GLES20DisplayList_setCaching(JNIEnv* env,
    displayList->setCaching(caching);
}

static void android_view_GLES20DisplayList_setApplicationScale(JNIEnv* env,
        jobject clazz, DisplayList* displayList, float scale) {
    displayList->setApplicationScale(scale);
static void android_view_GLES20DisplayList_setStaticMatrix(JNIEnv* env,
        jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
    displayList->setStaticMatrix(matrix);
}

static void android_view_GLES20DisplayList_setAnimationMatrix(JNIEnv* env,
        jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
    displayList->setAnimationMatrix(matrix);
}

static void android_view_GLES20DisplayList_setClipChildren(JNIEnv* env,
@@ -176,8 +181,8 @@ const char* const kClassPathName = "android/view/GLES20DisplayList";
static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
    { "nSetCaching",           "(IZ)V",  (void*) android_view_GLES20DisplayList_setCaching },
    { "nSetApplicationScale",    "(IF)V",
            (void*) android_view_GLES20DisplayList_setApplicationScale },
    { "nSetStaticMatrix",      "(II)V",  (void*) android_view_GLES20DisplayList_setStaticMatrix },
    { "nSetAnimationMatrix",   "(II)V",  (void*) android_view_GLES20DisplayList_setAnimationMatrix },
    { "nSetClipChildren",      "(IZ)V",  (void*) android_view_GLES20DisplayList_setClipChildren },
    { "nSetAlpha",             "(IF)V",  (void*) android_view_GLES20DisplayList_setAlpha },
    { "nSetTranslationX",      "(IF)V",  (void*) android_view_GLES20DisplayList_setTranslationX },
@@ -191,8 +196,7 @@ static JNINativeMethod gMethods[] = {
            (void*) android_view_GLES20DisplayList_setTransformationInfo },
    { "nSetPivotX",            "(IF)V",  (void*) android_view_GLES20DisplayList_setPivotX },
    { "nSetPivotY",            "(IF)V",  (void*) android_view_GLES20DisplayList_setPivotY },
    { "nSetCameraDistance",      "(IF)V",
            (void*) android_view_GLES20DisplayList_setCameraDistance },
    { "nSetCameraDistance",    "(IF)V",  (void*) android_view_GLES20DisplayList_setCameraDistance },
    { "nSetLeft",              "(II)V",  (void*) android_view_GLES20DisplayList_setLeft },
    { "nSetTop",               "(II)V",  (void*) android_view_GLES20DisplayList_setTop },
    { "nSetRight",             "(II)V",  (void*) android_view_GLES20DisplayList_setRight },
+52 −24
Original line number Diff line number Diff line
@@ -94,7 +94,8 @@ void DisplayList::outputLogBuffer(int fd) {
}

DisplayList::DisplayList(const DisplayListRenderer& recorder) :
    mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL) {
    mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
    mStaticMatrix(NULL), mAnimationMatrix(NULL) {

    initFromDisplayListRenderer(recorder);
}
@@ -108,7 +109,6 @@ void DisplayList::initProperties() {
    mTop = 0;
    mRight = 0;
    mBottom = 0;
    mApplicationScale = -1;
    mClipChildren = true;
    mAlpha = 1;
    mMultipliedAlpha = 255;
@@ -143,18 +143,16 @@ void DisplayList::clearResources() {
    sk_free((void*) mReader.base());

    if (USE_DISPLAY_LIST_PROPERTIES) {
        if (mTransformMatrix) {
        delete mTransformMatrix;
            mTransformMatrix = NULL;
        }
        if (mTransformCamera) {
        delete mTransformCamera;
            mTransformCamera = NULL;
        }
        if (mTransformMatrix3D) {
        delete mTransformMatrix3D;
        delete mStaticMatrix;
        delete mAnimationMatrix;
        mTransformMatrix = NULL;
        mTransformCamera = NULL;
        mTransformMatrix3D = NULL;
        }
        mStaticMatrix = NULL;
        mAnimationMatrix = NULL;
    }

    Caches& caches = Caches::getInstance();
@@ -667,12 +665,26 @@ void DisplayList::updateMatrix() {
void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
    if (USE_DISPLAY_LIST_PROPERTIES) {
        updateMatrix();
        if (mApplicationScale >= 0) {
            ALOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
                    mApplicationScale, mApplicationScale);
        }
        if (mLeft != 0 || mTop != 0) {
            ALOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
            ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
        }
        if (mStaticMatrix) {
            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
                    indent, "ConcatMatrix (static)", mStaticMatrix,
                    mStaticMatrix->get(0), mStaticMatrix->get(1),
                    mStaticMatrix->get(2), mStaticMatrix->get(3),
                    mStaticMatrix->get(4), mStaticMatrix->get(5),
                    mStaticMatrix->get(6), mStaticMatrix->get(7),
                    mStaticMatrix->get(8));
        }
        if (mAnimationMatrix) {
            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
                    indent, "ConcatMatrix (animation)", mAnimationMatrix,
                    mAnimationMatrix->get(0), mAnimationMatrix->get(1),
                    mAnimationMatrix->get(2), mAnimationMatrix->get(3),
                    mAnimationMatrix->get(4), mAnimationMatrix->get(5),
                    mAnimationMatrix->get(6), mAnimationMatrix->get(7),
                    mAnimationMatrix->get(8));
        }
        if (mMatrixFlags != 0) {
            if (mMatrixFlags == TRANSLATION) {
@@ -719,13 +731,29 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, ui
#endif
        updateMatrix();
        if (mLeft != 0 || mTop != 0) {
            DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
            DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
            renderer.translate(mLeft, mTop);
        }
        if (mApplicationScale >= 0) {
            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
                    mApplicationScale, mApplicationScale);
            renderer.scale(mApplicationScale, mApplicationScale);
        if (mStaticMatrix) {
            DISPLAY_LIST_LOGD(
                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
                    indent, "ConcatMatrix (static)", mStaticMatrix,
                    mStaticMatrix->get(0), mStaticMatrix->get(1),
                    mStaticMatrix->get(2), mStaticMatrix->get(3),
                    mStaticMatrix->get(4), mStaticMatrix->get(5),
                    mStaticMatrix->get(6), mStaticMatrix->get(7),
                    mStaticMatrix->get(8));
            renderer.concatMatrix(mStaticMatrix);
        } else if (mAnimationMatrix) {
            DISPLAY_LIST_LOGD(
                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
                    indent, "ConcatMatrix (animation)", mAnimationMatrix,
                    mAnimationMatrix->get(0), mAnimationMatrix->get(1),
                    mAnimationMatrix->get(2), mAnimationMatrix->get(3),
                    mAnimationMatrix->get(4), mAnimationMatrix->get(5),
                    mAnimationMatrix->get(6), mAnimationMatrix->get(7),
                    mAnimationMatrix->get(8));
            renderer.concatMatrix(mAnimationMatrix);
        }
        if (mMatrixFlags != 0) {
            if (mMatrixFlags == TRANSLATION) {
Loading