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

Commit 35962a04 authored by Lei Ju's avatar Lei Ju Committed by Automerger Merge Worker
Browse files

Merge "Revert "Move Matrix operations multiplyMM and MultiplMV out of jni""...

Merge "Revert "Move Matrix operations multiplyMM and MultiplMV out of jni"" am: ee260c95 am: e11114e1 am: 2cdd1b97

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2382752



Change-Id: Ia8c3347def998e1a8f06ac77f2e0e1b2af044693
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents eca628a7 2cdd1b97
Loading
Loading
Loading
Loading
+87 −0
Original line number Original line Diff line number Diff line
@@ -541,6 +541,87 @@ jint util_visibilityTest(JNIEnv *env, jclass clazz,
            indices.mData, indexCount);
            indices.mData, indexCount);
}
}


#define I(_i, _j) ((_j)+ 4*(_i))

static
void multiplyMM(float* r, const float* lhs, const float* rhs)
{
    for (int i=0 ; i<4 ; i++) {
        const float rhs_i0 = rhs[ I(i,0) ];
        float ri0 = lhs[ I(0,0) ] * rhs_i0;
        float ri1 = lhs[ I(0,1) ] * rhs_i0;
        float ri2 = lhs[ I(0,2) ] * rhs_i0;
        float ri3 = lhs[ I(0,3) ] * rhs_i0;
        for (int j=1 ; j<4 ; j++) {
            const float rhs_ij = rhs[ I(i,j) ];
            ri0 += lhs[ I(j,0) ] * rhs_ij;
            ri1 += lhs[ I(j,1) ] * rhs_ij;
            ri2 += lhs[ I(j,2) ] * rhs_ij;
            ri3 += lhs[ I(j,3) ] * rhs_ij;
        }
        r[ I(i,0) ] = ri0;
        r[ I(i,1) ] = ri1;
        r[ I(i,2) ] = ri2;
        r[ I(i,3) ] = ri3;
    }
}

static
void util_multiplyMM(JNIEnv *env, jclass clazz,
    jfloatArray result_ref, jint resultOffset,
    jfloatArray lhs_ref, jint lhsOffset,
    jfloatArray rhs_ref, jint rhsOffset) {

    FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);

    bool checkOK = resultMat.check() && lhs.check() && rhs.check();

    if ( !checkOK ) {
        return;
    }

    resultMat.bind();
    lhs.bind();
    rhs.bind();

    multiplyMM(resultMat.mData, lhs.mData, rhs.mData);

    resultMat.commitChanges();
}

static
void multiplyMV(float* r, const float* lhs, const float* rhs)
{
    mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
}

static
void util_multiplyMV(JNIEnv *env, jclass clazz,
    jfloatArray result_ref, jint resultOffset,
    jfloatArray lhs_ref, jint lhsOffset,
    jfloatArray rhs_ref, jint rhsOffset) {

    FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);

    bool checkOK = resultV.check() && lhs.check() && rhs.check();

    if ( !checkOK ) {
        return;
    }

    resultV.bind();
    lhs.bind();
    rhs.bind();

    multiplyMV(resultV.mData, lhs.mData, rhs.mData);

    resultV.commitChanges();
}

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


// The internal format is no longer the same as pixel format, per Table 2 in
// The internal format is no longer the same as pixel format, per Table 2 in
@@ -933,6 +1014,11 @@ static jint etc1_getHeight(JNIEnv *env, jclass clazz,
 * JNI registration
 * JNI registration
 */
 */


static const JNINativeMethod gMatrixMethods[] = {
    { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
    { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
};

static const JNINativeMethod gVisibilityMethods[] = {
static const JNINativeMethod gVisibilityMethods[] = {
    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
@@ -965,6 +1051,7 @@ typedef struct _ClassRegistrationInfo {
} ClassRegistrationInfo;
} ClassRegistrationInfo;


static const ClassRegistrationInfo gClasses[] = {
static const ClassRegistrationInfo gClasses[] = {
    {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
+26 −193
Original line number Original line Diff line number Diff line
@@ -40,11 +40,7 @@ import androidx.annotation.NonNull;
public class Matrix {
public class Matrix {


    /** Temporary memory for operations that need temporary matrix data. */
    /** Temporary memory for operations that need temporary matrix data. */
    private static final ThreadLocal<float[]> ThreadTmp = new ThreadLocal() {
    private final static float[] sTemp = new float[32];
        @Override protected float[] initialValue() {
            return new float[32];
        }
    };


    /**
    /**
     * @deprecated All methods are static, do not instantiate this class.
     * @deprecated All methods are static, do not instantiate this class.
@@ -52,40 +48,6 @@ public class Matrix {
    @Deprecated
    @Deprecated
    public Matrix() {}
    public Matrix() {}


    private static boolean overlap(
            float[] a, int aStart, int aLength, float[] b, int bStart, int bLength) {
        if (a != b) {
            return false;
        }

        if (aStart == bStart) {
            return true;
        }

        int aEnd = aStart + aLength;
        int bEnd = bStart + bLength;

        if (aEnd == bEnd) {
            return true;
        }

        if (aStart < bStart && bStart < aEnd) {
            return true;
        }
        if (aStart < bEnd   && bEnd   < aEnd) {
            return true;
        }

        if (bStart < aStart && aStart < bEnd) {
            return true;
        }
        if (bStart < aEnd   && aEnd   < bEnd) {
            return true;
        }

        return false;
    }

    /**
    /**
     * Multiplies two 4x4 matrices together and stores the result in a third 4x4
     * Multiplies two 4x4 matrices together and stores the result in a third 4x4
     * matrix. In matrix notation: result = lhs x rhs. Due to the way
     * matrix. In matrix notation: result = lhs x rhs. Due to the way
@@ -93,9 +55,9 @@ public class Matrix {
     * effect as first multiplying by the rhs matrix, then multiplying by
     * effect as first multiplying by the rhs matrix, then multiplying by
     * the lhs matrix. This is the opposite of what you might expect.
     * the lhs matrix. This is the opposite of what you might expect.
     * <p>
     * <p>
     * The same float array may be passed for result, lhs, and/or rhs. This
     * The same float array may be passed for result, lhs, and/or rhs. However,
     * operation is expected to do the correct thing if the result elements
     * the result element values are undefined if the result elements overlap
     * overlap with either of the lhs or rhs elements.
     * either the lhs or rhs elements.
     *
     *
     * @param result The float array that holds the result.
     * @param result The float array that holds the result.
     * @param resultOffset The offset into the result array where the result is
     * @param resultOffset The offset into the result array where the result is
@@ -105,101 +67,20 @@ public class Matrix {
     * @param rhs The float array that holds the right-hand-side matrix.
     * @param rhs The float array that holds the right-hand-side matrix.
     * @param rhsOffset The offset into the rhs array where the rhs is stored.
     * @param rhsOffset The offset into the rhs array where the rhs is stored.
     *
     *
     * @throws IllegalArgumentException under any of the following conditions:
     * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
     * result, lhs, or rhs are null;
     * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
     * resultOffset + 16 > result.length
     * rhsOffset + 16 > rhs.length.
     * or lhsOffset + 16 > lhs.length
     * or rhsOffset + 16 > rhs.length;
     * resultOffset < 0 or lhsOffset < 0 or rhsOffset < 0
     */
     */
    public static void multiplyMM(float[] result, int resultOffset,
    public static native void multiplyMM(float[] result, int resultOffset,
            float[] lhs, int lhsOffset, float[] rhs, int rhsOffset) {
            float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);
        // error checking
        if (result == null) {
            throw new IllegalArgumentException("result == null");
        }
        if (lhs == null) {
            throw new IllegalArgumentException("lhs == null");
        }
        if (rhs == null) {
            throw new IllegalArgumentException("rhs == null");
        }
        if (resultOffset < 0) {
            throw new IllegalArgumentException("resultOffset < 0");
        }
        if (lhsOffset < 0) {
            throw new IllegalArgumentException("lhsOffset < 0");
        }
        if (rhsOffset < 0) {
            throw new IllegalArgumentException("rhsOffset < 0");
        }
        if (result.length < resultOffset + 16) {
            throw new IllegalArgumentException("result.length < resultOffset + 16");
        }
        if (lhs.length < lhsOffset + 16) {
            throw new IllegalArgumentException("lhs.length < lhsOffset + 16");
        }
        if (rhs.length < rhsOffset + 16) {
            throw new IllegalArgumentException("rhs.length < rhsOffset + 16");
        }

        // Check for overlap between rhs and result or lhs and result
        if ( overlap(result, resultOffset, 16, lhs, lhsOffset, 16)
                || overlap(result, resultOffset, 16, rhs, rhsOffset, 16) ) {
            float[] tmp = ThreadTmp.get();
            for (int i=0; i<4; i++) {
                final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
                float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
                float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
                float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
                float ri3 = lhs[ 3 + 16 ] * rhs_i0;
                for (int j=1; j<4; j++) {
                    final float rhs_ij = rhs[ 4*i + j + rhsOffset];
                    ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
                    ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
                    ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
                    ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
                }
                tmp[ 4*i + 0 ] = ri0;
                tmp[ 4*i + 1 ] = ri1;
                tmp[ 4*i + 2 ] = ri2;
                tmp[ 4*i + 3 ] = ri3;
            }

            // copy from tmp to result
            for (int i=0; i < 16; i++) {
                result[ i + resultOffset ] = tmp[ i ];
            }

        } else {
            for (int i=0; i<4; i++) {
                final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
                float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
                float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
                float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
                float ri3 = lhs[ 3 + lhsOffset ] * rhs_i0;
                for (int j=1; j<4; j++) {
                    final float rhs_ij = rhs[ 4*i + j + rhsOffset];
                    ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
                    ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
                    ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
                    ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
                }
                result[ 4*i + 0 + resultOffset ] = ri0;
                result[ 4*i + 1 + resultOffset ] = ri1;
                result[ 4*i + 2 + resultOffset ] = ri2;
                result[ 4*i + 3 + resultOffset ] = ri3;
            }
        }
    }


    /**
    /**
     * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
     * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
     * 4-element column vector. In matrix notation: result = lhs x rhs
     * 4-element column vector. In matrix notation: result = lhs x rhs
     * <p>
     * <p>
     * The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
     * The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
     * This operation is expected to do the correct thing if the result elements
     * However, the resultVec element values are undefined if the resultVec
     * overlap with either of the lhs or rhs elements.
     * elements overlap either the lhsMat or rhsVec elements.
     *
     *
     * @param resultVec The float array that holds the result vector.
     * @param resultVec The float array that holds the result vector.
     * @param resultVecOffset The offset into the result array where the result
     * @param resultVecOffset The offset into the result array where the result
@@ -210,67 +91,14 @@ public class Matrix {
     * @param rhsVecOffset The offset into the rhs vector where the rhs vector
     * @param rhsVecOffset The offset into the rhs vector where the rhs vector
     *        is stored.
     *        is stored.
     *
     *
     * @throws IllegalArgumentException under any of the following conditions:
     * @throws IllegalArgumentException if resultVec, lhsMat,
     * resultVec, lhsMat, or rhsVec are null;
     * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
     * resultVecOffset + 4  > resultVec.length
     * or lhsMatOffset + 16 > lhsMat.length or
     * or lhsMatOffset + 16 > lhsMat.length
     * rhsVecOffset + 4 > rhsVec.length.
     * or rhsVecOffset + 4  > rhsVec.length;
     * resultVecOffset < 0 or lhsMatOffset < 0 or rhsVecOffset < 0
     */
     */
    public static void multiplyMV(float[] resultVec,
    public static native void multiplyMV(float[] resultVec,
            int resultVecOffset, float[] lhsMat, int lhsMatOffset,
            int resultVecOffset, float[] lhsMat, int lhsMatOffset,
            float[] rhsVec, int rhsVecOffset) {
            float[] rhsVec, int rhsVecOffset);
        // error checking
        if (resultVec == null) {
            throw new IllegalArgumentException("resultVec == null");
        }
        if (lhsMat == null) {
            throw new IllegalArgumentException("lhsMat == null");
        }
        if (rhsVec == null) {
            throw new IllegalArgumentException("rhsVec == null");
        }
        if (resultVecOffset < 0) {
            throw new IllegalArgumentException("resultVecOffset < 0");
        }
        if (lhsMatOffset < 0) {
            throw new IllegalArgumentException("lhsMatOffset < 0");
        }
        if (rhsVecOffset < 0) {
            throw new IllegalArgumentException("rhsVecOffset < 0");
        }
        if (resultVec.length < resultVecOffset + 4) {
            throw new IllegalArgumentException("resultVec.length < resultVecOffset + 4");
        }
        if (lhsMat.length < lhsMatOffset + 16) {
            throw new IllegalArgumentException("lhsMat.length < lhsMatOffset + 16");
        }
        if (rhsVec.length < rhsVecOffset + 4) {
            throw new IllegalArgumentException("rhsVec.length < rhsVecOffset + 4");
        }

        float tmp0 = lhsMat[0 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
                     lhsMat[0 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
                     lhsMat[0 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
                     lhsMat[0 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
        float tmp1 = lhsMat[1 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
                     lhsMat[1 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
                     lhsMat[1 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
                     lhsMat[1 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
        float tmp2 = lhsMat[2 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
                     lhsMat[2 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
                     lhsMat[2 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
                     lhsMat[2 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
        float tmp3 = lhsMat[3 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
                     lhsMat[3 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
                     lhsMat[3 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
                     lhsMat[3 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];

        resultVec[ 0 + resultVecOffset ] = tmp0;
        resultVec[ 1 + resultVecOffset ] = tmp1;
        resultVec[ 2 + resultVecOffset ] = tmp2;
        resultVec[ 3 + resultVecOffset ] = tmp3;
    }


    /**
    /**
     * Transposes a 4 x 4 matrix.
     * Transposes a 4 x 4 matrix.
@@ -711,9 +539,10 @@ public class Matrix {
    public static void rotateM(float[] rm, int rmOffset,
    public static void rotateM(float[] rm, int rmOffset,
            float[] m, int mOffset,
            float[] m, int mOffset,
            float a, float x, float y, float z) {
            float a, float x, float y, float z) {
        float[] tmp = ThreadTmp.get();
        synchronized(sTemp) {
        setRotateM(tmp, 16, a, x, y, z);
            setRotateM(sTemp, 0, a, x, y, z);
        multiplyMM(rm, rmOffset, m, mOffset, tmp, 16);
            multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);
        }
    }
    }


    /**
    /**
@@ -729,7 +558,11 @@ public class Matrix {
     */
     */
    public static void rotateM(float[] m, int mOffset,
    public static void rotateM(float[] m, int mOffset,
            float a, float x, float y, float z) {
            float a, float x, float y, float z) {
        rotateM(m, mOffset, m, mOffset, a, x, y, z);
        synchronized(sTemp) {
            setRotateM(sTemp, 0, a, x, y, z);
            multiplyMM(sTemp, 16, m, mOffset, sTemp, 0);
            System.arraycopy(sTemp, 16, m, mOffset, 16);
        }
    }
    }


    /**
    /**