util.cpp revision f4faeac3525fe1ce3707ab785a1651aec367589d
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"
19f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck#include "GraphicsJNI.h"
208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dlfcn.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h>
29a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich#include <ETC1/etc1.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31eece0dda56ae29fff6e9003df97594f6ac50b6e2Derek Sollenberger#include <SkBitmap.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef LOG_TAG
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "OpenGLUtil"
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "poly.h"
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass MallocHelper {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    MallocHelper() {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = 0;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
57106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~MallocHelper() {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mData != 0) {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(mData);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
63106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void* alloc(size_t size) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = malloc(size);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mData;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
68106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void* mData;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprint_poly(const char* label, Poly* pPoly) {
776215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("%s: %d verts", label, pPoly->n);
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < pPoly->n; i++) {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Poly_vert* pV = & pPoly->vert[i];
806215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("[%d] %g, %g, %g %g", i, pV->sx, pV->sy, pV->sz, pV->sw);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint visibilityTest(float* pWS, float* pPositions, int positionsLength,
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unsigned short* pIndices, int indexCount) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    MallocHelper mallocHelper;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = POLY_CLIP_OUT;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pTransformed = 0;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int transformedIndexCount = 0;
92106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( indexCount < 3 ) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return POLY_CLIP_OUT;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
96106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Find out how many vertices we need to transform
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We transform every vertex between the min and max indices, inclusive.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This is OK for the data sets we expect to use with this function, but
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // for other loads it might be better to use a more sophisticated vertex
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // cache of some sort.
102106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int minIndex = 65536;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int maxIndex = -1;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < indexCount; i++) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int index = pIndices[i];
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( index < minIndex ) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            minIndex = index;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( index > maxIndex ) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            maxIndex = index;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
114106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( maxIndex * 3 > positionsLength) {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
118106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    transformedIndexCount = maxIndex - minIndex + 1;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float));
121106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pTransformed == 0 ) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -2;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
125106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Transform the vertices
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const float* pSrc = pPositions + 3 * minIndex;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* pDst = pTransformed;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < transformedIndexCount; i++, pSrc += 3, pDst += 4) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS,  pDst);
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
134106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Clip the triangles
136106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Poly poly;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pDest = & poly.vert[0].sx;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < indexCount; i += 3) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        poly.n = 3;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest    , pTransformed + 4 * (pIndices[i    ] - minIndex), 4 * sizeof(float));
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest + 4, pTransformed + 4 * (pIndices[i + 1] - minIndex), 4 * sizeof(float));
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(pDest + 8, pTransformed + 4 * (pIndices[i + 2] - minIndex), 4 * sizeof(float));
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result = poly_clip_to_frustum(&poly);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( result != POLY_CLIP_OUT) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return result;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate<class JArray, class T>
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ArrayHelper {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEnv = env;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRef = ref;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOffset = offset;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinSize = minSize;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBase = 0;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReleaseParam = JNI_ABORT;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~ArrayHelper() {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBase) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
170106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We seperate the bounds check from the initialization because we want to
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // be able to bounds-check multiple arrays, and we can't throw an exception
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // after we've called GetPrimitiveArrayCritical.
174106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Return true if the bounds check succeeded
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Else instruct the runtime to throw an exception
177106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool check() {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( ! mRef) {
1808451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "array == null");
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ( mOffset < 0) {
1848451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "offset < 0");
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLength = mEnv->GetArrayLength(mRef) - mOffset;
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLength < mMinSize ) {
1898451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, "length - offset < n");
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
194106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Bind the array.
196106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void bind() {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mData = mBase + mOffset;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void commitChanges() {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReleaseParam = 0;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
205106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T* mData;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mLength;
208106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T* mBase;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv* mEnv;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JArray mRef;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint mOffset;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint mMinSize;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mReleaseParam;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jfloatArray, float> FloatArrayHelper;
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jintArray, int> IntArrayHelper;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance2(float x, float y, float z) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return x * x + y * y + z * z;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance(float x, float y, float z) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return sqrtf(distance2(x, y, z));
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
230106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_computeBoundingSphere(JNIEnv *env, jclass clazz,
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray positions_ref, jint positionsOffset, jint positionsCount,
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray sphere_ref, jint sphereOffset) {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4);
237106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = positions.check() && sphere.check();
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! checkOK) {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
242106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    positions.bind();
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sphere.bind();
245106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( positionsCount < 1 ) {
2478451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "positionsCount < 1");
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
250106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const float* pSrc = positions.mData;
252106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // find bounding box
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x0 = *pSrc++;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x1 = x0;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y0 = *pSrc++;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y1 = y0;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z0 = *pSrc++;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z1 = z0;
260106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 1; i < positionsCount; i++) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float x = *pSrc++;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (x < x0) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                x0 = x;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (x > x1) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                x1 = x;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float y = *pSrc++;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (y < y0) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                y0 = y;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (y > y1) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                y1 = y;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float z = *pSrc++;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (z < z0) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                z0 = z;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (z > z1) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                z1 = z;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
290106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Because we know our input meshes fit pretty well into bounding boxes,
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // just take the diagonal of the box as defining our sphere.
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pSphere = sphere.mData;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dx = x1 - x0;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dy = y1 - y0;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float dz = z1 - z0;
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = x0 + dx * 0.5f;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = y0 + dy * 0.5f;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = z0 + dz * 0.5f;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *pSphere++ = distance(dx, dy, dz) * 0.5f;
301106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sphere.commitChanges();
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void normalizePlane(float* p) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float rdist = 1.0f / distance(p[0], p[1], p[2]);
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < 4; i++) {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p[i] *= rdist;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return x0 * x1 + y0 * y1 + z0 * z1;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float signedDistance(const float* pPlane, float x, float y, float z) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3];
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Return true if the sphere intersects or is inside the frustum
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float x = pSphere[0];
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float y = pSphere[1];
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float z = pSphere[2];
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float negRadius = -pSphere[3];
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < 6; i++, pFrustum += 4) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (signedDistance(pFrustum, x, y, z) <= negRadius) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void computeFrustum(const float* m, float* f) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m3 = m[3];
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m7 = m[7];
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m11 = m[11];
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float m15 = m[15];
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // right
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[0];
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[4];
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[8];
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[12];
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
348106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    // left
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[0];
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[4];
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[8];
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[12];
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // top
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[1];
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[5];
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[9];
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[13];
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // bottom
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[1];
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[5];
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[9];
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[13];
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // far
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  - m[2];
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  - m[6];
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 - m[10];
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 - m[14];
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f+= 4;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // near
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[0] = m3  + m[2];
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[1] = m7  + m[6];
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[2] = m11 + m[10];
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    f[3] = m15 + m[14];
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalizePlane(f);
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
38936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_frustumCullSpheres(JNIEnv *env, jclass clazz,
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray mvp_ref, jint mvpOffset,
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray spheres_ref, jint spheresOffset, jint spheresCount,
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jintArray results_ref, jint resultsOffset, jint resultsCapacity) {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float frustum[6*4];
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int outputCount;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int* pResults;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float* pSphere;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity);
400106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool initializedOK = mvp.check() && spheres.check() && results.check();
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! initializedOK) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
405106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mvp.bind();
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    spheres.bind();
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    results.bind();
409106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    computeFrustum(mvp.mData, frustum);
411106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Cull the spheres
413106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pSphere = spheres.mData;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pResults = results.mData;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outputCount = 0;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(int i = 0; i < spheresCount; i++, pSphere += 4) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sphereHitsFrustum(frustum, pSphere)) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outputCount < resultsCapacity) {
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *pResults++ = i;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outputCount++;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    results.commitChanges();
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return outputCount;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int visibilityTest(float[] ws, int wsOffset,
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] positions, int positionsOffset,
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] indices, int indicesOffset, int indexCount);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
43636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_visibilityTest(JNIEnv *env, jclass clazz,
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray ws_ref, jint wsOffset,
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloatArray positions_ref, jint positionsOffset,
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jcharArray indices_ref, jint indicesOffset, jint indexCount) {
440106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper ws(env, ws_ref, wsOffset, 16);
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0);
444106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = ws.check() && positions.check() && indices.check();
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (! checkOK) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Return value will be ignored, because an exception has been thrown.
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
450106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (indices.mLength < indexCount) {
4528451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "length < offset + indexCount");
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
455106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ws.bind();
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    positions.bind();
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    indices.bind();
459106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return visibilityTest(ws.mData,
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            positions.mData, positions.mLength,
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            indices.mData, indexCount);
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define I(_i, _j) ((_j)+ 4*(_i))
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMM(float* r, const float* lhs, const float* rhs)
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
47146d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        const float rhs_i0 = rhs[ I(i,0) ];
47246d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        float ri0 = lhs[ I(0,0) ] * rhs_i0;
47346d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        float ri1 = lhs[ I(0,1) ] * rhs_i0;
47446d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        float ri2 = lhs[ I(0,2) ] * rhs_i0;
47546d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        float ri3 = lhs[ I(0,3) ] * rhs_i0;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int j=1 ; j<4 ; j++) {
47746d8444631b4b1253a76bfcc78a29d26014d022fDan Albert            const float rhs_ij = rhs[ I(i,j) ];
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri0 += lhs[ I(j,0) ] * rhs_ij;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri1 += lhs[ I(j,1) ] * rhs_ij;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri2 += lhs[ I(j,2) ] * rhs_ij;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri3 += lhs[ I(j,3) ] * rhs_ij;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,0) ] = ri0;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,1) ] = ri1;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,2) ] = ri2;
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r[ I(i,3) ] = ri3;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMM(JNIEnv *env, jclass clazz,
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray result_ref, jint resultOffset,
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray lhs_ref, jint lhsOffset,
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray rhs_ref, jint rhsOffset) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);
499106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = resultMat.check() && lhs.check() && rhs.check();
501106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( !checkOK ) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
505106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultMat.bind();
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lhs.bind();
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rhs.bind();
509106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    multiplyMM(resultMat.mData, lhs.mData, rhs.mData);
511106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultMat.commitChanges();
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMV(float* r, const float* lhs, const float* rhs)
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMV(JNIEnv *env, jclass clazz,
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray result_ref, jint resultOffset,
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray lhs_ref, jint lhsOffset,
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloatArray rhs_ref, jint rhsOffset) {
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);
530106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool checkOK = resultV.check() && lhs.check() && rhs.check();
532106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( !checkOK ) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
536106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultV.bind();
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lhs.bind();
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rhs.bind();
540106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    multiplyMV(resultV.mData, lhs.mData, rhs.mData);
542106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    resultV.commitChanges();
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54864d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamyextern void setGLDebugLevel(int level);
5490c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamyvoid setTracingLevel(JNIEnv *env, jclass clazz, jint level)
55064d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy{
5510c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy    setGLDebugLevel(level);
55264d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy}
55364d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy
5541103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int checkFormat(SkColorType colorType, int format, int type)
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5561103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
5571103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (format == GL_PALETTE8_RGBA8_OES)
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
5601103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
5611103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type == GL_UNSIGNED_BYTE)
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
5641103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
5651103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (type) {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_4_4_4_4:
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_5_6_5:
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_SHORT_5_5_5_1:
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return 0;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GL_UNSIGNED_BYTE:
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (format == GL_LUMINANCE_ALPHA)
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return 0;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5821103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getInternalFormat(SkColorType colorType)
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5841103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
5851103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_ALPHA;
5871103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGBA;
5891103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGBA;
5911103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_PALETTE8_RGBA8_OES;
5931103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return GL_RGB;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getType(SkColorType colorType)
601708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
6021103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch(colorType) {
6031103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
604708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_BYTE;
6051103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
606708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_SHORT_4_4_4_4;
6071103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
608708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_BYTE;
6091103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
610708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return -1; // No type for compressed data.
6111103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
612708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return GL_UNSIGNED_SHORT_5_6_5;
613708c17b4168404042852e480f25a91a02cf14247Jack Palevich        default:
614708c17b4168404042852e480f25a91a02cf14247Jack Palevich            return -1;
615708c17b4168404042852e480f25a91a02cf14247Jack Palevich    }
616708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
617708c17b4168404042852e480f25a91a02cf14247Jack Palevich
618708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getInternalFormat(JNIEnv *env, jclass clazz,
619708c17b4168404042852e480f25a91a02cf14247Jack Palevich        jobject jbitmap)
620708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
621f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
6221103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return getInternalFormat(nativeBitmap->colorType());
623708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
624708c17b4168404042852e480f25a91a02cf14247Jack Palevich
625708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getType(JNIEnv *env, jclass clazz,
626708c17b4168404042852e480f25a91a02cf14247Jack Palevich        jobject jbitmap)
627708c17b4168404042852e480f25a91a02cf14247Jack Palevich{
628f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
6291103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return getType(nativeBitmap->colorType());
630708c17b4168404042852e480f25a91a02cf14247Jack Palevich}
631708c17b4168404042852e480f25a91a02cf14247Jack Palevich
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texImage2D(JNIEnv *env, jclass clazz,
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint target, jint level, jint internalformat,
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject jbitmap, jint type, jint border)
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
636f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SkBitmap& bitmap(*nativeBitmap);
6381103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    SkColorType colorType = bitmap.colorType();
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (internalformat < 0) {
6401103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        internalformat = getInternalFormat(colorType);
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
642708c17b4168404042852e480f25a91a02cf14247Jack Palevich    if (type < 0) {
6431103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        type = getType(colorType);
644708c17b4168404042852e480f25a91a02cf14247Jack Palevich    }
6451103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    int err = checkFormat(colorType, internalformat, type);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err)
647106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        return err;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.lockPixels();
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int w = bitmap.width();
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int h = bitmap.height();
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* p = bitmap.getPixels();
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (internalformat == GL_PALETTE8_RGBA8_OES) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sizeof(SkPMColor) != sizeof(uint32_t)) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = -1;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto error;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t size = bitmap.getSize();
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t palette_size = 256*sizeof(SkPMColor);
659106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        const size_t imageSize = size + palette_size;
660106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        void* const data = malloc(imageSize);
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (data) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            void* const pixels = (char*)data + palette_size;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkColorTable* ctable = bitmap.getColorTable();
66471487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed            memcpy(data, ctable->readColors(), ctable->count() * sizeof(SkPMColor));
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(pixels, p, size);
666106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich            glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(data);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = -1;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror:
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.unlockPixels();
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texSubImage2D(JNIEnv *env, jclass clazz,
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint target, jint level, jint xoffset, jint yoffset,
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject jbitmap, jint format, jint type)
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
683f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SkBitmap& bitmap(*nativeBitmap);
6851103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    SkColorType colorType = bitmap.colorType();
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (format < 0) {
6871103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        format = getInternalFormat(colorType);
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (format == GL_PALETTE8_RGBA8_OES)
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1; // glCompressedTexSubImage2D() not supported
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6911103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    int err = checkFormat(colorType, format, type);
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err)
693106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich        return err;
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.lockPixels();
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int w = bitmap.width();
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int h = bitmap.height();
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const void* p = bitmap.getPixels();
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p);
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bitmap.unlockPixels();
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
704a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * ETC1 methods.
705a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
706a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
707a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass nioAccessClass;
708a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass bufferClass;
709a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBasePointerID;
710a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayID;
711a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayOffsetID;
712a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID positionID;
713a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID limitID;
714a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID elementSizeShiftID;
715a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
716a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/* Cache method IDs each time the class is loaded. */
717a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
718a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void
719ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas GampenativeClassInitBuffer(JNIEnv *env)
720a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{
721ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass nioAccessClassLocal = FindClassOrDie(env, "java/nio/NIOAccess");
722ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    nioAccessClass = MakeGlobalRefOrDie(env, nioAccessClassLocal);
723ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    getBasePointerID = GetStaticMethodIDOrDie(env, nioAccessClass,
724a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBasePointer", "(Ljava/nio/Buffer;)J");
725ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    getBaseArrayID = GetStaticMethodIDOrDie(env, nioAccessClass,
726a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
727ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    getBaseArrayOffsetID = GetStaticMethodIDOrDie(env, nioAccessClass,
728a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
729ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
730ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass bufferClassLocal = FindClassOrDie(env, "java/nio/Buffer");
731ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    bufferClass = MakeGlobalRefOrDie(env, bufferClassLocal);
732ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    positionID = GetFieldIDOrDie(env, bufferClass, "position", "I");
733ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    limitID = GetFieldIDOrDie(env, bufferClass, "limit", "I");
734ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    elementSizeShiftID = GetFieldIDOrDie(env, bufferClass, "_elementSizeShift", "I");
735a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
736a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
737a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void *
738a6276fdd4253c3a7150ab675678c750473ab6c45Jack PalevichgetPointer(JNIEnv *_env, jobject buffer, jint *remaining)
739a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{
740a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint position;
741a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint limit;
742a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint elementSizeShift;
743a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jlong pointer;
744a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
745a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    position = _env->GetIntField(buffer, positionID);
746a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    limit = _env->GetIntField(buffer, limitID);
747a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
748a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    *remaining = (limit - position) << elementSizeShift;
749a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    pointer = _env->CallStaticLongMethod(nioAccessClass,
750a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            getBasePointerID, buffer);
751a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pointer != 0L) {
75236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        return reinterpret_cast<void *>(pointer);
753a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
754a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return NULL;
755a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
756a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
757a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichclass BufferHelper {
758a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichpublic:
759a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper(JNIEnv *env, jobject buffer) {
760a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mEnv = env;
761a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mBuffer = buffer;
762a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mData = NULL;
763a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        mRemaining = 0;
764a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
765a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
766a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    bool checkPointer(const char* errorMessage) {
767a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (mBuffer) {
768a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            mData = getPointer(mEnv, mBuffer, &mRemaining);
769a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            if (mData == NULL) {
7708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                doThrowIAE(mEnv, errorMessage);
771a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            }
772a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            return mData != NULL;
773a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
7748451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(mEnv, errorMessage);
775a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            return false;
776a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
777a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
778a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
779a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    inline void* getData() {
780a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return mData;
781a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
782a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
783a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    inline jint remaining() {
784a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return mRemaining;
785a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
786a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
787a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichprivate:
788a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    JNIEnv* mEnv;
789a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jobject mBuffer;
790a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    void* mData;
791a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint mRemaining;
792a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich};
793a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
794a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
795a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode a block of pixels.
796a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
797a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in a pointer to a ETC1_DECODED_BLOCK_SIZE array of bytes that represent a
798a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
799a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y).
800a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
801a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether
802a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing.
803a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
804a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out an ETC1 compressed version of the data.
805a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
806a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
807a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeBlock(JNIEnv *env, jclass clazz,
808a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jint validPixelMask, jobject out) {
809a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (validPixelMask < 0 || validPixelMask > 15) {
8108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "validPixelMask");
811a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
812a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
813a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
814a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
815a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
816a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
8178451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE");
818a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
8198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE");
820a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
821a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask,
822a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData());
823a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
824a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
825a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
826a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
827a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
828a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode a block of pixels.
829a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
830a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in an ETC1 compressed version of the data.
831a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *
832a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a
833a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
834a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y).
835a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
836a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeBlock(JNIEnv *env, jclass clazz,
837a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jobject out){
838a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
839a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
840a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
841a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
8428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE");
843a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
8448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE");
845a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
846a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_decode_block((etc1_byte*) inB.getData(),
847a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich                    (etc1_byte*) outB.getData());
848a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
849a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
850a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
851a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
852a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
853a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Return the size of the encoded image data (does not include size of PKM header).
854a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
855a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getEncodedDataSize(JNIEnv *env, jclass clazz,
856a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint width, jint height) {
857a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return etc1_get_encoded_data_size(width, height);
858a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
859a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
860a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
861a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode an entire image.
862a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in pointer to the image data. Formatted such that
863a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *           pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset;
864a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to encoded data. Must be large enough to store entire encoded image.
865a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
866a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeImage(JNIEnv *env, jclass clazz,
867a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject in, jint width, jint height,
868a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint pixelSize, jint stride, jobject out) {
869a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pixelSize < 2 || pixelSize > 3) {
8708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "pixelSize must be 2 or 3");
871a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
872a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
873a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
874a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
875a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
876a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint imageSize = stride * height;
877a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
878a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < imageSize) {
8798451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < image size");
880a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < encodedImageSize) {
8818451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < encoded image size");
882a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
8830f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe            etc1_encode_image((etc1_byte*) inB.getData(), width, height, pixelSize, stride,
8840f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe                              (etc1_byte*) outB.getData());
885a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
886a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
887a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
888a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
889a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
890a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode an entire image.
891a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in the encoded data.
892a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to the image data. Will be written such that
893a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *            pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be
894a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *            large enough to store entire image.
895a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
896a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeImage(JNIEnv *env, jclass clazz,
897a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject  in, jobject out,
898a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint width, jint height,
899a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint pixelSize, jint stride) {
900a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (pixelSize < 2 || pixelSize > 3) {
9018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env, "pixelSize must be 2 or 3");
902a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        return;
903a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
904a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper inB(env, in);
905a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper outB(env, out);
906a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (inB.checkPointer("in") && outB.checkPointer("out")) {
907a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint imageSize = stride * height;
908a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
909a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (inB.remaining() < encodedImageSize) {
9108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "in's remaining data < encoded image size");
911a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else if (outB.remaining() < imageSize) {
9128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "out's remaining data < image size");
913a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
9140f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe            etc1_decode_image((etc1_byte*) inB.getData(), (etc1_byte*) outB.getData(),
9150f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe                              width, height, pixelSize, stride);
916a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
917a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
918a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
919a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
920a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
921a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Format a PKM header
922a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
923a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_formatHeader(JNIEnv *env, jclass clazz,
924a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header, jint width, jint height) {
925a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
926a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
927a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
929a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
930a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height);
931a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
932a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
933a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
934a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
935a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
936a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Check if a PKM header is correctly formatted.
937a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
938a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jboolean etc1_isValid(JNIEnv *env, jclass clazz,
939a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
940a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jboolean result = false;
941a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
942a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
943a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
945a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
946a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_is_valid((etc1_byte*) headerB.getData());
947a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
948a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
94936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
950a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
951a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
952a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
953a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image width from a PKM header
954a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
955a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getWidth(JNIEnv *env, jclass clazz,
956a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
957a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint result = 0;
958a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
959a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
960a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
962a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
963a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_get_width((etc1_byte*) headerB.getData());
964a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
965a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
966a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return result;
967a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
968a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
969a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/**
970a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image height from a PKM header
971a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */
97236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jint etc1_getHeight(JNIEnv *env, jclass clazz,
973a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        jobject header) {
974a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    jint result = 0;
975a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    BufferHelper headerB(env, header);
976a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    if (headerB.checkPointer("header") ){
977a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
9788451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
979a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        } else {
980a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich            result = etc1_pkm_get_height((etc1_byte*) headerB.getData());
981a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich        }
982a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    }
983a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    return result;
984a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}
985a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
986a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/*
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMatrixMethods[] = {
991106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
992106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9958451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesstatic JNINativeMethod gVisibilityMethods[] = {
996106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
998106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gUtilsMethods[] = {
1002106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
1003106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
1004106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
1005106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich    { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
10060c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy    { "setTracingLevel", "(I)V",                        (void*)setTracingLevel },
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic JNINativeMethod gEtc1Methods[] = {
1010a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "encodeBlock", "(Ljava/nio/Buffer;ILjava/nio/Buffer;)V", (void*) etc1_encodeBlock },
1011a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "decodeBlock", "(Ljava/nio/Buffer;Ljava/nio/Buffer;)V", (void*) etc1_decodeBlock },
1012a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getEncodedDataSize", "(II)I", (void*) etc1_getEncodedDataSize },
1013a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "encodeImage", "(Ljava/nio/Buffer;IIIILjava/nio/Buffer;)V", (void*) etc1_encodeImage },
1014a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "decodeImage", "(Ljava/nio/Buffer;Ljava/nio/Buffer;IIII)V", (void*) etc1_decodeImage },
1015a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "formatHeader", "(Ljava/nio/Buffer;II)V", (void*) etc1_formatHeader },
1016a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "isValid", "(Ljava/nio/Buffer;)Z", (void*) etc1_isValid },
1017a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getWidth", "(Ljava/nio/Buffer;)I", (void*) etc1_getWidth },
1018a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    { "getHeight", "(Ljava/nio/Buffer;)I", (void*) etc1_getHeight },
1019a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich};
1020a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct _ClassRegistrationInfo {
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* classPath;
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNINativeMethod* methods;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t methodCount;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} ClassRegistrationInfo;
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ClassRegistrationInfo gClasses[] = {
10288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
10298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
10308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
10318451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_opengl_classes(JNIEnv* env)
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1036a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich    nativeClassInitBuffer(env);
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = 0;
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < NELEM(gClasses); i++) {
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClassRegistrationInfo* cri = &gClasses[i];
1040ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe        result = RegisterMethodsOrDie(env, cri->classPath, cri->methods, cri->methodCount);
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android
1046