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

Commit ee260c95 authored by Lei Ju's avatar Lei Ju Committed by Gerrit Code Review
Browse files

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

parents 4ab85d92 89fe5f3e
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
@@ -541,6 +541,87 @@ jint util_visibilityTest(JNIEnv *env, jclass clazz,
            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
@@ -928,6 +1009,11 @@ static jint etc1_getHeight(JNIEnv *env, jclass clazz,
 * 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[] = {
    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
@@ -960,6 +1046,7 @@ typedef struct _ClassRegistrationInfo {
} ClassRegistrationInfo;

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

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

    /**
     * @deprecated All methods are static, do not instantiate this class.
@@ -52,40 +48,6 @@ public class Matrix {
    @Deprecated
    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
     * 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
     * the lhs matrix. This is the opposite of what you might expect.
     * <p>
     * The same float array may be passed for result, lhs, and/or rhs. This
     * operation is expected to do the correct thing if the result elements
     * overlap with either of the lhs or rhs elements.
     * The same float array may be passed for result, lhs, and/or rhs. However,
     * the result element values are undefined if the result elements overlap
     * either the lhs or rhs elements.
     *
     * @param result The float array that holds the result.
     * @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 rhsOffset The offset into the rhs array where the rhs is stored.
     *
     * @throws IllegalArgumentException under any of the following conditions:
     * result, lhs, or rhs are null;
     * resultOffset + 16 > result.length
     * or lhsOffset + 16 > lhs.length
     * or rhsOffset + 16 > rhs.length;
     * resultOffset < 0 or lhsOffset < 0 or rhsOffset < 0
     * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
     * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
     * rhsOffset + 16 > rhs.length.
     */
    public static void multiplyMM(float[] result, int resultOffset,
            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;
            }
        }
    }
    public static native void multiplyMM(float[] result, int resultOffset,
            float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);

    /**
     * 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
     * <p>
     * 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
     * overlap with either of the lhs or rhs elements.
     * However, the resultVec element values are undefined if the resultVec
     * elements overlap either the lhsMat or rhsVec elements.
     *
     * @param resultVec The float array that holds the result vector.
     * @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
     *        is stored.
     *
     * @throws IllegalArgumentException under any of the following conditions:
     * resultVec, lhsMat, or rhsVec are null;
     * resultVecOffset + 4  > resultVec.length
     * or lhsMatOffset + 16 > lhsMat.length
     * or rhsVecOffset + 4  > rhsVec.length;
     * resultVecOffset < 0 or lhsMatOffset < 0 or rhsVecOffset < 0
     * @throws IllegalArgumentException if resultVec, lhsMat,
     * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
     * or lhsMatOffset + 16 > lhsMat.length or
     * rhsVecOffset + 4 > rhsVec.length.
     */
    public static void multiplyMV(float[] resultVec,
    public static native void multiplyMV(float[] resultVec,
            int resultVecOffset, float[] lhsMat, int lhsMatOffset,
            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;
    }
            float[] rhsVec, int rhsVecOffset);

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

    /**
@@ -729,7 +558,11 @@ public class Matrix {
     */
    public static void rotateM(float[] m, int mOffset,
            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);
        }
    }

    /**