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

Commit c70f3db8 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Simplify matrix calculations"

parents d951ab23 f7483e3a
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -2967,12 +2967,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private boolean mLastIsOpaque;
    /**
     * Convenience value to check for float values that are close enough to zero to be considered
     * zero.
     */
    private static final float NONZERO_EPSILON = .001f;
    /**
     * The distance in pixels from the left edge of this view's parent
     * to the left edge of this view.
+3 −5
Original line number Diff line number Diff line
@@ -376,7 +376,8 @@ static jboolean android_view_RenderNode_isPivotExplicitlySet(JNIEnv* env,
static jboolean android_view_RenderNode_hasIdentityMatrix(JNIEnv* env,
        jobject clazz, jlong renderNodePtr) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    return renderNode->stagingProperties().getMatrixFlags() == 0;
    renderNode->mutateStagingProperties().updateMatrix();
    return !renderNode->stagingProperties().hasTransformMatrix();
}

// ----------------------------------------------------------------------------
@@ -391,10 +392,7 @@ static void android_view_RenderNode_getTransformMatrix(JNIEnv* env,
    renderNode->mutateStagingProperties().updateMatrix();
    const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();

    if (renderNode->stagingProperties().getMatrixFlags() == TRANSLATION) {
        outMatrix->setTranslate(renderNode->stagingProperties().getTranslationX(),
                renderNode->stagingProperties().getTranslationY());
    } else if (transformMatrix) {
    if (transformMatrix) {
        *outMatrix = *transformMatrix;
    } else {
        outMatrix->setIdentity();
+4 −4
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) {
    } else if (properties().getAnimationMatrix()) {
        renderer.concatMatrix(properties().getAnimationMatrix());
    }
    if (properties().getMatrixFlags() != 0) {
        if (properties().getMatrixFlags() == TRANSLATION) {
    if (properties().hasTransformMatrix()) {
        if (properties().isTransformTranslateOnly()) {
            renderer.translate(properties().getTranslationX(), properties().getTranslationY());
        } else {
            renderer.concatMatrix(*properties().getTransformMatrix());
@@ -214,8 +214,8 @@ void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform)
        mat4 anim(*properties().getAnimationMatrix());
        matrix.multiply(anim);
    }
    if (properties().getMatrixFlags() != 0) {
        if (properties().getMatrixFlags() == TRANSLATION) {
    if (properties().hasTransformMatrix()) {
        if (properties().isTransformTranslateOnly()) {
            matrix.translate(properties().getTranslationX(), properties().getTranslationY(),
                    true3dTransform ? properties().getTranslationZ() : 0.0f);
        } else {
+43 −53
Original line number Diff line number Diff line
@@ -27,6 +27,16 @@

#include "Matrix.h"

/**
 * Convenience value to check for float values that are close enough to zero to be considered
 * zero.
 */
#define NONZERO_EPSILON .001f

static inline bool is_zero(float value) {
    return (value >= -NONZERO_EPSILON) || (value <= NONZERO_EPSILON);
}

namespace android {
namespace uirenderer {

@@ -42,22 +52,18 @@ RenderProperties::PrimitiveFields::PrimitiveFields()
        , mPivotX(0), mPivotY(0)
        , mLeft(0), mTop(0), mRight(0), mBottom(0)
        , mWidth(0), mHeight(0)
        , mPrevWidth(-1), mPrevHeight(-1)
        , mPivotExplicitlySet(false)
        , mMatrixDirty(false)
        , mMatrixFlags(0)
        , mMatrixOrPivotDirty(false)
        , mCaching(false) {
}

RenderProperties::ComputedFields::ComputedFields()
        : mTransformMatrix(NULL)
        , mTransformMatrix3D(NULL)
        , mClipPath(NULL) {
}

RenderProperties::ComputedFields::~ComputedFields() {
    delete mTransformMatrix;
    delete mTransformMatrix3D;
    delete mClipPath;
}

@@ -82,7 +88,7 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) {
        updateClipPath();

        // Force recalculation of the matrix, since other's dirty bit may be clear
        mPrimitiveFields.mMatrixDirty = true;
        mPrimitiveFields.mMatrixOrPivotDirty = true;
        updateMatrix();
    }
    return *this;
@@ -100,8 +106,8 @@ void RenderProperties::debugOutputProperties(const int level) const {
        ALOGD("%*sConcatMatrix (animation) %p: " SK_MATRIX_STRING,
                level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix));
    }
    if (mPrimitiveFields.mMatrixFlags != 0) {
        if (mPrimitiveFields.mMatrixFlags == TRANSLATION) {
    if (hasTransformMatrix()) {
        if (isTransformTranslateOnly()) {
            ALOGD("%*sTranslate %.2f, %.2f, %.2f",
                    level * 2, "", mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY, mPrimitiveFields.mTranslationZ);
        } else {
@@ -134,52 +140,36 @@ void RenderProperties::debugOutputProperties(const int level) const {
}

void RenderProperties::updateMatrix() {
    if (mPrimitiveFields.mMatrixDirty) {
        // NOTE: mComputedFields.mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
        // to a pure translate. This is safe because the mPrimitiveFields.matrix isn't read in pure translate cases.
        if (mPrimitiveFields.mMatrixFlags && mPrimitiveFields.mMatrixFlags != TRANSLATION) {
    if (mPrimitiveFields.mMatrixOrPivotDirty) {
        if (!mComputedFields.mTransformMatrix) {
            // only allocate a mPrimitiveFields.matrix if we have a complex transform
            mComputedFields.mTransformMatrix = new SkMatrix();
        }
        if (!mPrimitiveFields.mPivotExplicitlySet) {
                if (mPrimitiveFields.mWidth != mPrimitiveFields.mPrevWidth || mPrimitiveFields.mHeight != mPrimitiveFields.mPrevHeight) {
                    mPrimitiveFields.mPrevWidth = mPrimitiveFields.mWidth;
                    mPrimitiveFields.mPrevHeight = mPrimitiveFields.mHeight;
                    mPrimitiveFields.mPivotX = mPrimitiveFields.mPrevWidth / 2.0f;
                    mPrimitiveFields.mPivotY = mPrimitiveFields.mPrevHeight / 2.0f;
                }
            }

            if ((mPrimitiveFields.mMatrixFlags & ROTATION_3D) == 0) {
                mComputedFields.mTransformMatrix->setTranslate(
                        mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY);
                mComputedFields.mTransformMatrix->preRotate(mPrimitiveFields.mRotation,
                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY);
                mComputedFields.mTransformMatrix->preScale(
                        mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY,
                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY);
            mPrimitiveFields.mPivotX = mPrimitiveFields.mWidth / 2.0f;
            mPrimitiveFields.mPivotY = mPrimitiveFields.mHeight / 2.0f;
        }
        SkMatrix* transform = mComputedFields.mTransformMatrix;
        transform->reset();
        if (is_zero(getRotationX()) && is_zero(getRotationY())) {
            transform->setTranslate(getTranslationX(), getTranslationY());
            transform->preRotate(getRotation(), getPivotX(), getPivotY());
            transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
        } else {
                if (!mComputedFields.mTransformMatrix3D) {
                    mComputedFields.mTransformMatrix3D = new SkMatrix();
                }
                mComputedFields.mTransformMatrix->reset();
            SkMatrix transform3D;
            mComputedFields.mTransformCamera.save();
                mComputedFields.mTransformMatrix->preScale(
                        mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY,
                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY);
            transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
            mComputedFields.mTransformCamera.rotateX(mPrimitiveFields.mRotationX);
            mComputedFields.mTransformCamera.rotateY(mPrimitiveFields.mRotationY);
            mComputedFields.mTransformCamera.rotateZ(-mPrimitiveFields.mRotation);
                mComputedFields.mTransformCamera.getMatrix(mComputedFields.mTransformMatrix3D);
                mComputedFields.mTransformMatrix3D->preTranslate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY);
                mComputedFields.mTransformMatrix3D->postTranslate(mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX,
                        mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY);
                mComputedFields.mTransformMatrix->postConcat(*mComputedFields.mTransformMatrix3D);
            mComputedFields.mTransformCamera.getMatrix(&transform3D);
            transform3D.preTranslate(-getPivotX(), -getPivotY());
            transform3D.postTranslate(getPivotX() + getTranslationX(),
                    getPivotY() + getTranslationY());
            transform->postConcat(transform3D);
            mComputedFields.mTransformCamera.restore();
        }
        }
        mPrimitiveFields.mMatrixDirty = false;
        mPrimitiveFields.mMatrixOrPivotDirty = false;
    }
}

+36 −82
Original line number Diff line number Diff line
@@ -28,12 +28,6 @@
#include "RevealClip.h"
#include "Outline.h"

#define TRANSLATION 0x0001
#define ROTATION    0x0002
#define ROTATION_3D 0x0004
#define SCALE       0x0008
#define PIVOT       0x0010

class SkBitmap;
class SkPaint;

@@ -114,7 +108,7 @@ public:
    void setTranslationX(float translationX) {
        if (translationX != mPrimitiveFields.mTranslationX) {
            mPrimitiveFields.mTranslationX = translationX;
            onTranslationUpdate();
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -125,7 +119,7 @@ public:
    void setTranslationY(float translationY) {
        if (translationY != mPrimitiveFields.mTranslationY) {
            mPrimitiveFields.mTranslationY = translationY;
            onTranslationUpdate();
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -136,7 +130,7 @@ public:
    void setTranslationZ(float translationZ) {
        if (translationZ != mPrimitiveFields.mTranslationZ) {
            mPrimitiveFields.mTranslationZ = translationZ;
            onTranslationUpdate();
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -147,12 +141,7 @@ public:
    void setRotation(float rotation) {
        if (rotation != mPrimitiveFields.mRotation) {
            mPrimitiveFields.mRotation = rotation;
            mPrimitiveFields.mMatrixDirty = true;
            if (mPrimitiveFields.mRotation == 0.0f) {
                mPrimitiveFields.mMatrixFlags &= ~ROTATION;
            } else {
                mPrimitiveFields.mMatrixFlags |= ROTATION;
            }
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -163,12 +152,7 @@ public:
    void setRotationX(float rotationX) {
        if (rotationX != mPrimitiveFields.mRotationX) {
            mPrimitiveFields.mRotationX = rotationX;
            mPrimitiveFields.mMatrixDirty = true;
            if (mPrimitiveFields.mRotationX == 0.0f && mPrimitiveFields.mRotationY == 0.0f) {
                mPrimitiveFields.mMatrixFlags &= ~ROTATION_3D;
            } else {
                mPrimitiveFields.mMatrixFlags |= ROTATION_3D;
            }
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -179,12 +163,7 @@ public:
    void setRotationY(float rotationY) {
        if (rotationY != mPrimitiveFields.mRotationY) {
            mPrimitiveFields.mRotationY = rotationY;
            mPrimitiveFields.mMatrixDirty = true;
            if (mPrimitiveFields.mRotationX == 0.0f && mPrimitiveFields.mRotationY == 0.0f) {
                mPrimitiveFields.mMatrixFlags &= ~ROTATION_3D;
            } else {
                mPrimitiveFields.mMatrixFlags |= ROTATION_3D;
            }
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -195,12 +174,7 @@ public:
    void setScaleX(float scaleX) {
        if (scaleX != mPrimitiveFields.mScaleX) {
            mPrimitiveFields.mScaleX = scaleX;
            mPrimitiveFields.mMatrixDirty = true;
            if (mPrimitiveFields.mScaleX == 1.0f && mPrimitiveFields.mScaleY == 1.0f) {
                mPrimitiveFields.mMatrixFlags &= ~SCALE;
            } else {
                mPrimitiveFields.mMatrixFlags |= SCALE;
            }
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -211,12 +185,7 @@ public:
    void setScaleY(float scaleY) {
        if (scaleY != mPrimitiveFields.mScaleY) {
            mPrimitiveFields.mScaleY = scaleY;
            mPrimitiveFields.mMatrixDirty = true;
            if (mPrimitiveFields.mScaleX == 1.0f && mPrimitiveFields.mScaleY == 1.0f) {
                mPrimitiveFields.mMatrixFlags &= ~SCALE;
            } else {
                mPrimitiveFields.mMatrixFlags |= SCALE;
            }
            mPrimitiveFields.mMatrixOrPivotDirty = true;
        }
    }

@@ -226,12 +195,7 @@ public:

    void setPivotX(float pivotX) {
        mPrimitiveFields.mPivotX = pivotX;
        mPrimitiveFields.mMatrixDirty = true;
        if (mPrimitiveFields.mPivotX == 0.0f && mPrimitiveFields.mPivotY == 0.0f) {
            mPrimitiveFields.mMatrixFlags &= ~PIVOT;
        } else {
            mPrimitiveFields.mMatrixFlags |= PIVOT;
        }
        mPrimitiveFields.mMatrixOrPivotDirty = true;
        mPrimitiveFields.mPivotExplicitlySet = true;
    }

@@ -245,12 +209,7 @@ public:

    void setPivotY(float pivotY) {
        mPrimitiveFields.mPivotY = pivotY;
        mPrimitiveFields.mMatrixDirty = true;
        if (mPrimitiveFields.mPivotX == 0.0f && mPrimitiveFields.mPivotY == 0.0f) {
            mPrimitiveFields.mMatrixFlags &= ~PIVOT;
        } else {
            mPrimitiveFields.mMatrixFlags |= PIVOT;
        }
        mPrimitiveFields.mMatrixOrPivotDirty = true;
        mPrimitiveFields.mPivotExplicitlySet = true;
    }

@@ -264,7 +223,7 @@ public:

    void setCameraDistance(float distance) {
        if (distance != getCameraDistance()) {
            mPrimitiveFields.mMatrixDirty = true;
            mPrimitiveFields.mMatrixOrPivotDirty = true;
            mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
        }
    }
@@ -278,8 +237,8 @@ public:
        if (left != mPrimitiveFields.mLeft) {
            mPrimitiveFields.mLeft = left;
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -292,8 +251,8 @@ public:
        if (top != mPrimitiveFields.mTop) {
            mPrimitiveFields.mTop = top;
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -306,8 +265,8 @@ public:
        if (right != mPrimitiveFields.mRight) {
            mPrimitiveFields.mRight = right;
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -320,8 +279,8 @@ public:
        if (bottom != mPrimitiveFields.mBottom) {
            mPrimitiveFields.mBottom = bottom;
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -336,8 +295,8 @@ public:
            mPrimitiveFields.mTop = top;
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -350,8 +309,8 @@ public:
            mPrimitiveFields.mBottom = bottom;
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -360,8 +319,8 @@ public:
        if (offset != 0) {
            mPrimitiveFields.mLeft += offset;
            mPrimitiveFields.mRight += offset;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -370,8 +329,8 @@ public:
        if (offset != 0) {
            mPrimitiveFields.mTop += offset;
            mPrimitiveFields.mBottom += offset;
            if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixDirty = true;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
        }
    }
@@ -392,11 +351,17 @@ public:
        return mAnimationMatrix;
    }

    uint32_t getMatrixFlags() const {
        return mPrimitiveFields.mMatrixFlags;
    bool hasTransformMatrix() const {
        return getTransformMatrix() && !getTransformMatrix()->isIdentity();
    }

    // May only call this if hasTransformMatrix() is true
    bool isTransformTranslateOnly() const {
        return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
    }

    const SkMatrix* getTransformMatrix() const {
        LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
        return mComputedFields.mTransformMatrix;
    }

@@ -452,14 +417,6 @@ public:
    }

private:
    void onTranslationUpdate() {
        mPrimitiveFields.mMatrixDirty = true;
        if (mPrimitiveFields.mTranslationX == 0.0f && mPrimitiveFields.mTranslationY == 0.0f && mPrimitiveFields.mTranslationZ == 0.0f) {
            mPrimitiveFields.mMatrixFlags &= ~TRANSLATION;
        } else {
            mPrimitiveFields.mMatrixFlags |= TRANSLATION;
        }
    }

    // Rendering properties
    struct PrimitiveFields {
@@ -478,10 +435,8 @@ private:
        float mPivotX, mPivotY;
        int mLeft, mTop, mRight, mBottom;
        int mWidth, mHeight;
        int mPrevWidth, mPrevHeight;
        bool mPivotExplicitlySet;
        bool mMatrixDirty;
        uint32_t mMatrixFlags;
        bool mMatrixOrPivotDirty;
        bool mCaching;
    } mPrimitiveFields;

@@ -506,7 +461,6 @@ private:
        SkMatrix* mTransformMatrix;

        Sk3DView mTransformCamera;
        SkMatrix* mTransformMatrix3D;
        SkPath* mClipPath; // TODO: remove this, create new ops for efficient/special case clipping
        SkRegion::Op mClipPathOp;
    } mComputedFields;