util.cpp revision 1103b3255945d2eb2fa9c191e84e2270b343cca9
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Copyright 2007, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project **
4106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** Licensed under the Apache License, Version 2.0 (the "License");
5106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** you may not use this file except in compliance with the License.
6106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project **
8106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich **     http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project **
10106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** Unless required by applicable law or agreed to in writing, software
11106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** distributed under the License is distributed on an "AS IS" BASIS,
12106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich ** See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
178451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "jni.h"
188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "JNIHelp.h"
198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dlfcn.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h>
28a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich#include <ETC1/etc1.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30eece0dda56ae29fff6e9003df97594f6ac50b6e2Derek Sollenberger#include <SkBitmap.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h"
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef LOG_TAG
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "OpenGLUtil"
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "poly.h"
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z + pM[1 + 4 * 3] * w;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z + pM[2 + 4 * 3] * w;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass MallocHelper {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    MallocHelper() {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = 0;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
56106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~MallocHelper() {
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mData != 0) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(mData);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
62106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void* alloc(size_t size) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = malloc(size);
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mData;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
67106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void* mData;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprint_poly(const char* label, Poly* pPoly) {
766215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("%s: %d verts", label, pPoly->n);
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < pPoly->n; i++) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Poly_vert* pV = & pPoly->vert[i];
796215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("[%d] %g, %g, %g %g", i, pV->sx, pV->sy, pV->sz, pV->sw);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint visibilityTest(float* pWS, float* pPositions, int positionsLength,
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unsigned short* pIndices, int indexCount) {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    MallocHelper mallocHelper;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = POLY_CLIP_OUT;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pTransformed = 0;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int transformedIndexCount = 0;
91106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( indexCount < 3 ) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return POLY_CLIP_OUT;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
95106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Find out how many vertices we need to transform
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We transform every vertex between the min and max indices, inclusive.
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This is OK for the data sets we expect to use with this function, but
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // for other loads it might be better to use a more sophisticated vertex
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // cache of some sort.
101106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int minIndex = 65536;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int maxIndex = -1;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < indexCount; i++) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int index = pIndices[i];
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( index < minIndex ) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            minIndex = index;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( index > maxIndex ) {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            maxIndex = index;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
113106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( maxIndex * 3 > positionsLength) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
117106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    transformedIndexCount = maxIndex - minIndex + 1;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float));
120106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pTransformed == 0 ) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -2;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
124106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Transform the vertices
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const float* pSrc = pPositions + 3 * minIndex;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* pDst = pTransformed;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < transformedIndexCount; i++, pSrc += 3, pDst += 4) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS,  pDst);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
133106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Clip the triangles
135106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Poly poly;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pDest = & poly.vert[0].sx;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < indexCount; i += 3) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        poly.n = 3;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest    , pTransformed + 4 * (pIndices[i    ] - minIndex), 4 * sizeof(float));
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest + 4, pTransformed + 4 * (pIndices[i + 1] - minIndex), 4 * sizeof(float));
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest + 8, pTransformed + 4 * (pIndices[i + 2] - minIndex), 4 * sizeof(float));
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result = poly_clip_to_frustum(&poly);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( result != POLY_CLIP_OUT) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return result;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1528451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesstatic void doThrowIAE(JNIEnv* env, const char* msg) {
1538451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
1548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes}
1558451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate<class JArray, class T>
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ArrayHelper {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEnv = env;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRef = ref;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOffset = offset;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinSize = minSize;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBase = 0;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReleaseParam = JNI_ABORT;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~ArrayHelper() {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBase) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
173106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We seperate the bounds check from the initialization because we want to
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // be able to bounds-check multiple arrays, and we can't throw an exception
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // after we've called GetPrimitiveArrayCritical.
177106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Return true if the bounds check succeeded
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Else instruct the runtime to throw an exception
180106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool check() {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( ! mRef) {
1838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "array == null");
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( mOffset < 0) {
1878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "offset < 0");
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLength = mEnv->GetArrayLength(mRef) - mOffset;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLength < mMinSize ) {
1928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "length - offset < n");
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
197106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Bind the array.
199106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void bind() {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = mBase + mOffset;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void commitChanges() {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReleaseParam = 0;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
208106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T* mData;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mLength;
211106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T* mBase;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv* mEnv;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JArray mRef;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint mOffset;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint mMinSize;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mReleaseParam;
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jfloatArray, float> FloatArrayHelper;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jintArray, int> IntArrayHelper;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance2(float x, float y, float z) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return x * x + y * y + z * z;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance(float x, float y, float z) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return sqrtf(distance2(x, y, z));
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
233106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_computeBoundingSphere(JNIEnv *env, jclass clazz,
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray positions_ref, jint positionsOffset, jint positionsCount,
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray sphere_ref, jint sphereOffset) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4);
240106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = positions.check() && sphere.check();
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! checkOK) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
245106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    positions.bind();
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sphere.bind();
248106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( positionsCount < 1 ) {
2508451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "positionsCount < 1");
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
253106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const float* pSrc = positions.mData;
255106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // find bounding box
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x0 = *pSrc++;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x1 = x0;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y0 = *pSrc++;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y1 = y0;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z0 = *pSrc++;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z1 = z0;
263106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 1; i < positionsCount; i++) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float x = *pSrc++;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (x < x0) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                x0 = x;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (x > x1) {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                x1 = x;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float y = *pSrc++;
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (y < y0) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                y0 = y;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (y > y1) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                y1 = y;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float z = *pSrc++;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (z < z0) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                z0 = z;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (z > z1) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                z1 = z;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
293106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Because we know our input meshes fit pretty well into bounding boxes,
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // just take the diagonal of the box as defining our sphere.
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pSphere = sphere.mData;
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dx = x1 - x0;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dy = y1 - y0;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dz = z1 - z0;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = x0 + dx * 0.5f;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = y0 + dy * 0.5f;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = z0 + dz * 0.5f;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = distance(dx, dy, dz) * 0.5f;
304106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sphere.commitChanges();
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void normalizePlane(float* p) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float rdist = 1.0f / distance(p[0], p[1], p[2]);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < 4; i++) {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p[i] *= rdist;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) {
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return x0 * x1 + y0 * y1 + z0 * z1;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float signedDistance(const float* pPlane, float x, float y, float z) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3];
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Return true if the sphere intersects or is inside the frustum
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x = pSphere[0];
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y = pSphere[1];
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z = pSphere[2];
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float negRadius = -pSphere[3];
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < 6; i++, pFrustum += 4) {
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (signedDistance(pFrustum, x, y, z) <= negRadius) {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void computeFrustum(const float* m, float* f) {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m3 = m[3];
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m7 = m[7];
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m11 = m[11];
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m15 = m[15];
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // right
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[0];
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[4];
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[8];
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[12];
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
351106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    // left
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[0];
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[4];
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[8];
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[12];
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // top
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[1];
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[5];
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[9];
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[13];
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // bottom
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[1];
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[5];
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[9];
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[13];
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // far
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[2];
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[6];
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[10];
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[14];
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // near
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[2];
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[6];
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[10];
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[14];
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
39236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_frustumCullSpheres(JNIEnv *env, jclass clazz,
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray mvp_ref, jint mvpOffset,
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray spheres_ref, jint spheresOffset, jint spheresCount,
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jintArray results_ref, jint resultsOffset, jint resultsCapacity) {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float frustum[6*4];
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int outputCount;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int* pResults;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pSphere;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity);
403106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool initializedOK = mvp.check() && spheres.check() && results.check();
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! initializedOK) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
408106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mvp.bind();
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    spheres.bind();
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    results.bind();
412106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    computeFrustum(mvp.mData, frustum);
414106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Cull the spheres
416106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pSphere = spheres.mData;
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pResults = results.mData;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outputCount = 0;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < spheresCount; i++, pSphere += 4) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sphereHitsFrustum(frustum, pSphere)) {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outputCount < resultsCapacity) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *pResults++ = i;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outputCount++;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    results.commitChanges();
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return outputCount;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int visibilityTest(float[] ws, int wsOffset,
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] positions, int positionsOffset,
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] indices, int indicesOffset, int indexCount);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
43936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_visibilityTest(JNIEnv *env, jclass clazz,
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray ws_ref, jint wsOffset,
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray positions_ref, jint positionsOffset,
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jcharArray indices_ref, jint indicesOffset, jint indexCount) {
443106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper ws(env, ws_ref, wsOffset, 16);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0);
447106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = ws.check() && positions.check() && indices.check();
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (! checkOK) {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Return value will be ignored, because an exception has been thrown.
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
453106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (indices.mLength < indexCount) {
4558451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "length < offset + indexCount");
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
458106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ws.bind();
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    positions.bind();
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    indices.bind();
462106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return visibilityTest(ws.mData,
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            positions.mData, positions.mLength,
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            indices.mData, indexCount);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define I(_i, _j) ((_j)+ 4*(_i))
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMM(float* r, const float* lhs, const float* rhs)
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        register const float rhs_i0 = rhs[ I(i,0) ];
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        register float ri0 = lhs[ I(0,0) ] * rhs_i0;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        register float ri1 = lhs[ I(0,1) ] * rhs_i0;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        register float ri2 = lhs[ I(0,2) ] * rhs_i0;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        register float ri3 = lhs[ I(0,3) ] * rhs_i0;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int j=1 ; j<4 ; j++) {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            register const float rhs_ij = rhs[ I(i,j) ];
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri0 += lhs[ I(j,0) ] * rhs_ij;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri1 += lhs[ I(j,1) ] * rhs_ij;
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri2 += lhs[ I(j,2) ] * rhs_ij;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri3 += lhs[ I(j,3) ] * rhs_ij;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,0) ] = ri0;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,1) ] = ri1;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,2) ] = ri2;
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,3) ] = ri3;
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMM(JNIEnv *env, jclass clazz,
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray result_ref, jint resultOffset,
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray lhs_ref, jint lhsOffset,
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray rhs_ref, jint rhsOffset) {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);
502106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = resultMat.check() && lhs.check() && rhs.check();
504106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( !checkOK ) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
508106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultMat.bind();
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lhs.bind();
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rhs.bind();
512106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    multiplyMM(resultMat.mData, lhs.mData, rhs.mData);
514106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultMat.commitChanges();
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMV(float* r, const float* lhs, const float* rhs)
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMV(JNIEnv *env, jclass clazz,
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray result_ref, jint resultOffset,
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray lhs_ref, jint lhsOffset,
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray rhs_ref, jint rhsOffset) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);
533106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = resultV.check() && lhs.check() && rhs.check();
535106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( !checkOK ) {
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
539106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultV.bind();
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lhs.bind();
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rhs.bind();
543106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    multiplyMV(resultV.mData, lhs.mData, rhs.mData);
545106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultV.commitChanges();
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID nativeBitmapID = 0;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid nativeUtilsClassInit(JNIEnv *env, jclass clazz)
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
55636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    nativeBitmapID = env->GetFieldID(bitmapClass, "mNativeBitmap", "J");
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55964d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamyextern void setGLDebugLevel(int level);
5600c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamyvoid setTracingLevel(JNIEnv *env, jclass clazz, jint level)
56164d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy{
5620c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy    setGLDebugLevel(level);
56364d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy}
56464d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy
5651103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int checkFormat(SkColorType colorType, int format, int type)
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5671103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
5681103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (format == GL_PALETTE8_RGBA8_OES)
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
5711103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
5721103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type == GL_UNSIGNED_BYTE)
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
5751103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
5761103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (type) {
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_4_4_4_4:
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_5_6_5:
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_5_5_5_1:
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return 0;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_BYTE:
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (format == GL_LUMINANCE_ALPHA)
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return 0;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5931103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getInternalFormat(SkColorType colorType)
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5951103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
5961103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_ALPHA;
5981103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGBA;
6001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGBA;
6021103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_PALETTE8_RGBA8_OES;
6041103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGB;
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6111103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getType(SkColorType colorType)
612708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
6131103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
6141103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
615708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_BYTE;
6161103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
617708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_SHORT_4_4_4_4;
6181103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
619708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_BYTE;
6201103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
621708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return -1; // No type for compressed data.
6221103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
623708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_SHORT_5_6_5;
624708c17b4168404042852e480f25a91a02cf14247Jack Palevich        default:
625708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return -1;
626708c17b4168404042852e480f25a91a02cf14247Jack Palevich    }
627708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
628708c17b4168404042852e480f25a91a02cf14247Jack Palevich
629708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getInternalFormat(JNIEnv *env, jclass clazz,
630708c17b4168404042852e480f25a91a02cf14247Jack Palevich        jobject jbitmap)
631708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
632708c17b4168404042852e480f25a91a02cf14247Jack Palevich    SkBitmap const * nativeBitmap =
63336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            (SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
6341103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return getInternalFormat(nativeBitmap->colorType());
635708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
636708c17b4168404042852e480f25a91a02cf14247Jack Palevich
637708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getType(JNIEnv *env, jclass clazz,
638708c17b4168404042852e480f25a91a02cf14247Jack Palevich        jobject jbitmap)
639708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
640708c17b4168404042852e480f25a91a02cf14247Jack Palevich    SkBitmap const * nativeBitmap =
64136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            (SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
6421103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return getType(nativeBitmap->colorType());
643708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
644708c17b4168404042852e480f25a91a02cf14247Jack Palevich
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texImage2D(JNIEnv *env, jclass clazz,
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint target, jint level, jint internalformat,
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject jbitmap, jint type, jint border)
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkBitmap const * nativeBitmap =
65036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            (SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SkBitmap& bitmap(*nativeBitmap);
6521103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    SkColorType colorType = bitmap.colorType();
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (internalformat < 0) {
6541103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        internalformat = getInternalFormat(colorType);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
656708c17b4168404042852e480f25a91a02cf14247Jack Palevich    if (type < 0) {
6571103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        type = getType(colorType);
658708c17b4168404042852e480f25a91a02cf14247Jack Palevich    }
6591103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    int err = checkFormat(colorType, internalformat, type);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err)
661106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        return err;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.lockPixels();
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int w = bitmap.width();
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int h = bitmap.height();
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* p = bitmap.getPixels();
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (internalformat == GL_PALETTE8_RGBA8_OES) {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sizeof(SkPMColor) != sizeof(uint32_t)) {
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = -1;
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto error;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t size = bitmap.getSize();
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t palette_size = 256*sizeof(SkPMColor);
673106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        const size_t imageSize = size + palette_size;
674106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        void* const data = malloc(imageSize);
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (data) {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            void* const pixels = (char*)data + palette_size;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkColorTable* ctable = bitmap.getColorTable();
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(pixels, p, size);
680ed79ff0026a44741237a6eb5e3810dbf5d765154Derek Sollenberger            ctable->unlockColors();
681106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich            glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(data);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = -1;
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror:
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.unlockPixels();
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texSubImage2D(JNIEnv *env, jclass clazz,
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint target, jint level, jint xoffset, jint yoffset,
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject jbitmap, jint format, jint type)
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkBitmap const * nativeBitmap =
69936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            (SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SkBitmap& bitmap(*nativeBitmap);
7011103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    SkColorType colorType = bitmap.colorType();
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (format < 0) {
7031103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        format = getInternalFormat(colorType);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (format == GL_PALETTE8_RGBA8_OES)
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1; // glCompressedTexSubImage2D() not supported
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7071103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    int err = checkFormat(colorType, format, type);
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err)
709106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        return err;
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.lockPixels();
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int w = bitmap.width();
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int h = bitmap.height();
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* p = bitmap.getPixels();
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p);
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.unlockPixels();
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
720a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * ETC1 methods.
721a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
722a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
723a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass nioAccessClass;
724a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass bufferClass;
725a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBasePointerID;
726a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayID;
727a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayOffsetID;
728a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID positionID;
729a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID limitID;
730a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID elementSizeShiftID;
731a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
732a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/* Cache method IDs each time the class is loaded. */
733a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
734a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void
735a6276fdd4253c3a7150ab675678c750473ab6c45Jack PalevichnativeClassInitBuffer(JNIEnv *_env)
736a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{
737a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
738a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
739a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
740a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
741a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
742a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
743a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
744a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBasePointer", "(Ljava/nio/Buffer;)J");
745a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
746a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
747a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
748a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
749a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    positionID = _env->GetFieldID(bufferClass, "position", "I");
750a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    limitID = _env->GetFieldID(bufferClass, "limit", "I");
751a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    elementSizeShiftID =
752a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
753a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
754a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
755a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void *
756a6276fdd4253c3a7150ab675678c750473ab6c45Jack PalevichgetPointer(JNIEnv *_env, jobject buffer, jint *remaining)
757a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{
758a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint position;
759a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint limit;
760a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint elementSizeShift;
761a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jlong pointer;
762a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint offset;
763a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    void *data;
764a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
765a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    position = _env->GetIntField(buffer, positionID);
766a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    limit = _env->GetIntField(buffer, limitID);
767a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
768a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    *remaining = (limit - position) << elementSizeShift;
769a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    pointer = _env->CallStaticLongMethod(nioAccessClass,
770a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            getBasePointerID, buffer);
771a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pointer != 0L) {
77236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        return reinterpret_cast<void *>(pointer);
773a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
774a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return NULL;
775a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
776a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
777a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichclass BufferHelper {
778a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichpublic:
779a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper(JNIEnv *env, jobject buffer) {
780a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mEnv = env;
781a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mBuffer = buffer;
782a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mData = NULL;
783a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mRemaining = 0;
784a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
785a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
786a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    bool checkPointer(const char* errorMessage) {
787a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (mBuffer) {
788a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            mData = getPointer(mEnv, mBuffer, &mRemaining);
789a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            if (mData == NULL) {
7908451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                doThrowIAE(mEnv, errorMessage);
791a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            }
792a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            return mData != NULL;
793a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
7948451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, errorMessage);
795a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            return false;
796a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
797a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
798a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
799a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    inline void* getData() {
800a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return mData;
801a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
802a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
803a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    inline jint remaining() {
804a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return mRemaining;
805a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
806a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
807a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichprivate:
808a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    JNIEnv* mEnv;
809a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jobject mBuffer;
810a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    void* mData;
811a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint mRemaining;
812a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich};
813a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
814a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
815a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode a block of pixels.
816a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
817a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in a pointer to a ETC1_DECODED_BLOCK_SIZE array of bytes that represent a
818a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
819a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y).
820a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
821a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether
822a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing.
823a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
824a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out an ETC1 compressed version of the data.
825a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
826a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
827a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeBlock(JNIEnv *env, jclass clazz,
828a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jint validPixelMask, jobject out) {
829a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (validPixelMask < 0 || validPixelMask > 15) {
8308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "validPixelMask");
831a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
832a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
833a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
834a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
835a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
836a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
8378451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE");
838a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
8398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE");
840a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
841a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask,
842a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData());
843a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
844a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
845a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
846a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
847a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
848a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode a block of pixels.
849a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
850a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in an ETC1 compressed version of the data.
851a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
852a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a
853a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
854a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y).
855a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
856a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeBlock(JNIEnv *env, jclass clazz,
857a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jobject out){
858a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
859a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
860a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
861a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
8628451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE");
863a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
8648451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE");
865a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
866a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_decode_block((etc1_byte*) inB.getData(),
867a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData());
868a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
869a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
870a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
871a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
872a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
873a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Return the size of the encoded image data (does not include size of PKM header).
874a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
875a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getEncodedDataSize(JNIEnv *env, jclass clazz,
876a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint width, jint height) {
877a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return etc1_get_encoded_data_size(width, height);
878a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
879a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
880a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
881a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode an entire image.
882a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in pointer to the image data. Formatted such that
883a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *           pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset;
884a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to encoded data. Must be large enough to store entire encoded image.
885a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
886a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeImage(JNIEnv *env, jclass clazz,
887a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jint width, jint height,
888a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint pixelSize, jint stride, jobject out) {
889a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pixelSize < 2 || pixelSize > 3) {
8908451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "pixelSize must be 2 or 3");
891a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
892a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
893a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
894a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
895a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
896a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint imageSize = stride * height;
897a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
898a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < imageSize) {
8998451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < image size");
900a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < encodedImageSize) {
9018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < encoded image size");
902a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
903a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            int result = etc1_encode_image((etc1_byte*) inB.getData(),
904a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    width, height, pixelSize,
905a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    stride,
906a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData());
907a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
908a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
909a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
910a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
911a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
912a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode an entire image.
913a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in the encoded data.
914a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to the image data. Will be written such that
915a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *            pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be
916a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *            large enough to store entire image.
917a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
918a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeImage(JNIEnv *env, jclass clazz,
919a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject  in, jobject out,
920a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint width, jint height,
921a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint pixelSize, jint stride) {
922a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pixelSize < 2 || pixelSize > 3) {
9238451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "pixelSize must be 2 or 3");
924a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
925a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
926a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
927a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
928a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
929a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint imageSize = stride * height;
930a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
931a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < encodedImageSize) {
9328451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < encoded image size");
933a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < imageSize) {
9348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < image size");
935a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
936a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            int result = etc1_decode_image((etc1_byte*) inB.getData(),
937a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData(),
938a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    width, height, pixelSize,
939a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    stride);
940a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
941a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
942a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
943a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
944a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
945a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Format a PKM header
946a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
947a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_formatHeader(JNIEnv *env, jclass clazz,
948a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header, jint width, jint height) {
949a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
950a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
951a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9528451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
953a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
954a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height);
955a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
956a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
957a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
958a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
959a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
960a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Check if a PKM header is correctly formatted.
961a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
962a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jboolean etc1_isValid(JNIEnv *env, jclass clazz,
963a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
964a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jboolean result = false;
965a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
966a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
967a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9688451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
969a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
970a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_is_valid((etc1_byte*) headerB.getData());
971a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
972a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
97336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
974a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
975a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
976a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
977a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image width from a PKM header
978a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
979a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getWidth(JNIEnv *env, jclass clazz,
980a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
981a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint result = 0;
982a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
983a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
984a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9858451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
986a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
987a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_get_width((etc1_byte*) headerB.getData());
988a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
989a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
990a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return result;
991a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
992a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
993a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
994a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image height from a PKM header
995a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
99636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jint etc1_getHeight(JNIEnv *env, jclass clazz,
997a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
998a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint result = 0;
999a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
1000a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
1001a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
10028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
1003a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
1004a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_get_height((etc1_byte*) headerB.getData());
1005a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
1006a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
1007a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return result;
1008a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
1009a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
1010a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/*
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMatrixMethods[] = {
1015106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
1016106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesstatic JNINativeMethod gVisibilityMethods[] = {
1020106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
1022106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gUtilsMethods[] = {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"nativeClassInit", "()V",                          (void*)nativeUtilsClassInit },
1027106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
1028106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
1029106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
1030106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
10310c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy    { "setTracingLevel", "(I)V",                        (void*)setTracingLevel },
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1034a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic JNINativeMethod gEtc1Methods[] = {
1035a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "encodeBlock", "(Ljava/nio/Buffer;ILjava/nio/Buffer;)V", (void*) etc1_encodeBlock },
1036a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "decodeBlock", "(Ljava/nio/Buffer;Ljava/nio/Buffer;)V", (void*) etc1_decodeBlock },
1037a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getEncodedDataSize", "(II)I", (void*) etc1_getEncodedDataSize },
1038a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "encodeImage", "(Ljava/nio/Buffer;IIIILjava/nio/Buffer;)V", (void*) etc1_encodeImage },
1039a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "decodeImage", "(Ljava/nio/Buffer;Ljava/nio/Buffer;IIII)V", (void*) etc1_decodeImage },
1040a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "formatHeader", "(Ljava/nio/Buffer;II)V", (void*) etc1_formatHeader },
1041a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "isValid", "(Ljava/nio/Buffer;)Z", (void*) etc1_isValid },
1042a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getWidth", "(Ljava/nio/Buffer;)I", (void*) etc1_getWidth },
1043a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getHeight", "(Ljava/nio/Buffer;)I", (void*) etc1_getHeight },
1044a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich};
1045a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct _ClassRegistrationInfo {
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* classPath;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNINativeMethod* methods;
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t methodCount;
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} ClassRegistrationInfo;
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ClassRegistrationInfo gClasses[] = {
10538451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
10548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
10558451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
10568451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_opengl_classes(JNIEnv* env)
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1061a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    nativeClassInitBuffer(env);
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = 0;
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < NELEM(gClasses); i++) {
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClassRegistrationInfo* cri = &gClasses[i];
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result = AndroidRuntime::registerNativeMethods(env,
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cri->classPath, cri->methods, cri->methodCount);
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result < 0) {
10683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("Failed to register %s: %d", cri->classPath, result);
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android
1076