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

Commit 3758304c authored by John Reck's avatar John Reck Committed by Android Git Automerger
Browse files

am c70f3db8: Merge "Simplify matrix calculations"

* commit 'c70f3db8':
  Simplify matrix calculations
parents 21e13577 c70f3db8
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;