util.cpp revision 5b406cb7b548443b589f0acb235c8a7465ffb82b
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 1535b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass ByteArrayGetter { 1545b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1555b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) { 1565b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetByteArrayElements(array, is_copy); 1575b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1585b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1595b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass BooleanArrayGetter { 1605b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1615b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) { 1625b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetBooleanArrayElements(array, is_copy); 1635b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1645b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1655b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass CharArrayGetter { 1665b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1675b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) { 1685b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetCharArrayElements(array, is_copy); 1695b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1705b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1715b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass ShortArrayGetter { 1725b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1735b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) { 1745b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetShortArrayElements(array, is_copy); 1755b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1765b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1775b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass IntArrayGetter { 1785b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1795b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) { 1805b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetIntArrayElements(array, is_copy); 1815b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1825b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1835b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass LongArrayGetter { 1845b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1855b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) { 1865b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetLongArrayElements(array, is_copy); 1875b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1885b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1895b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass FloatArrayGetter { 1905b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1915b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) { 1925b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetFloatArrayElements(array, is_copy); 1935b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 1945b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 1955b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass DoubleArrayGetter { 1965b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 1975b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) { 1985b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi return _env->GetDoubleArrayElements(array, is_copy); 1995b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2005b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2015b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi 2025b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass ByteArrayReleaser { 2035b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2045b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jint mode) { 2055b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseByteArrayElements(array, data, mode); 2065b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2075b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2085b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass BooleanArrayReleaser { 2095b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2105b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jint mode) { 2115b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseBooleanArrayElements(array, data, mode); 2125b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2135b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2145b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass CharArrayReleaser { 2155b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2165b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jcharArray array, jchar* data, jint mode) { 2175b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseCharArrayElements(array, data, mode); 2185b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2195b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2205b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass ShortArrayReleaser { 2215b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2225b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jshortArray array, jshort* data, jint mode) { 2235b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseShortArrayElements(array, data, mode); 2245b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2255b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2265b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass IntArrayReleaser { 2275b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2285b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jintArray array, jint* data, jint mode) { 2295b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseIntArrayElements(array, data, mode); 2305b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2315b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2325b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass LongArrayReleaser { 2335b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2345b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jlongArray array, jlong* data, jint mode) { 2355b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseLongArrayElements(array, data, mode); 2365b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2375b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2385b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass FloatArrayReleaser { 2395b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2405b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jint mode) { 2415b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseFloatArrayElements(array, data, mode); 2425b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2435b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2445b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchiclass DoubleArrayReleaser { 2455b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchipublic: 2465b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jint mode) { 2475b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi _env->ReleaseDoubleArrayElements(array, data, mode); 2485b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi } 2495b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi}; 2505b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi 2515b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchitemplate<class JArray, class T, class ArrayGetter, class ArrayReleaser> 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ArrayHelper { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv = env; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRef = ref; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset = offset; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinSize = minSize; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBase = 0; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseParam = JNI_ABORT; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~ArrayHelper() { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBase) { 2655b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi ArrayReleaser::Release(mEnv, mRef, mBase, mReleaseParam); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 268106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We seperate the bounds check from the initialization because we want to 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be able to bounds-check multiple arrays, and we can't throw an exception 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // after we've called GetPrimitiveArrayCritical. 272106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return true if the bounds check succeeded 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Else instruct the runtime to throw an exception 275106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool check() { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( ! mRef) { 2788451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(mEnv, "array == null"); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( mOffset < 0) { 2828451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(mEnv, "offset < 0"); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = mEnv->GetArrayLength(mRef) - mOffset; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength < mMinSize ) { 2878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(mEnv, "length - offset < n"); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 292106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bind the array. 294106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void bind() { 2965b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchi mBase = (T*) ArrayGetter::Get(mEnv, mRef, (jboolean *) 0); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mData = mBase + mOffset; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void commitChanges() { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseParam = 0; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 303106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project T* mData; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLength; 306106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project T* mBase; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* mEnv; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JArray mRef; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint mOffset; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint mMinSize; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mReleaseParam; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3165b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchitypedef ArrayHelper<jfloatArray, float, FloatArrayGetter, FloatArrayReleaser> FloatArrayHelper; 3175b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchitypedef ArrayHelper<jcharArray, unsigned short, CharArrayGetter, CharArrayReleaser> UnsignedShortArrayHelper; 3185b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchitypedef ArrayHelper<jintArray, int, IntArrayGetter, IntArrayReleaser> IntArrayHelper; 3195b406cb7b548443b589f0acb235c8a7465ffb82bHiroshi Yamauchitypedef ArrayHelper<jbyteArray, unsigned char, ByteArrayGetter, ByteArrayReleaser> ByteArrayHelper; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance2(float x, float y, float z) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return x * x + y * y + z * z; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance(float x, float y, float z) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sqrtf(distance2(x, y, z)); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 328106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_computeBoundingSphere(JNIEnv *env, jclass clazz, 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray positions_ref, jint positionsOffset, jint positionsCount, 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray sphere_ref, jint sphereOffset) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4); 335106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = positions.check() && sphere.check(); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! checkOK) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 340106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.bind(); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sphere.bind(); 343106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( positionsCount < 1 ) { 3458451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "positionsCount < 1"); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 348106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* pSrc = positions.mData; 350106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find bounding box 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x0 = *pSrc++; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x1 = x0; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y0 = *pSrc++; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y1 = y0; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z0 = *pSrc++; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z1 = z0; 358106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 1; i < positionsCount; i++) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = *pSrc++; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x < x0) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = x; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (x > x1) { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = *pSrc++; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y < y0) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = y; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (y > y1) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y1 = y; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = *pSrc++; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z < z0) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z0 = z; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (z > z1) { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z1 = z; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 388106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Because we know our input meshes fit pretty well into bounding boxes, 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just take the diagonal of the box as defining our sphere. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pSphere = sphere.mData; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dx = x1 - x0; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dy = y1 - y0; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dz = z1 - z0; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = x0 + dx * 0.5f; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = y0 + dy * 0.5f; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = z0 + dz * 0.5f; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = distance(dx, dy, dz) * 0.5f; 399106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sphere.commitChanges(); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void normalizePlane(float* p) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float rdist = 1.0f / distance(p[0], p[1], p[2]); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < 4; i++) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p[i] *= rdist; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return x0 * x1 + y0 * y1 + z0 * z1; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float signedDistance(const float* pPlane, float x, float y, float z) { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3]; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Return true if the sphere intersects or is inside the frustum 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = pSphere[0]; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = pSphere[1]; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = pSphere[2]; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float negRadius = -pSphere[3]; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 6; i++, pFrustum += 4) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (signedDistance(pFrustum, x, y, z) <= negRadius) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void computeFrustum(const float* m, float* f) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m3 = m[3]; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m7 = m[7]; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m11 = m[11]; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m15 = m[15]; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // right 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[0]; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[4]; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[8]; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[12]; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 446106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich // left 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[0]; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[4]; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[8]; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[12]; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // top 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[1]; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[5]; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[9]; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[13]; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // bottom 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[1]; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[5]; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[9]; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[13]; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // far 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[2]; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[6]; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[10]; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[14]; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // near 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[2]; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[6]; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[10]; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[14]; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 48736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_frustumCullSpheres(JNIEnv *env, jclass clazz, 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray mvp_ref, jint mvpOffset, 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray spheres_ref, jint spheresOffset, jint spheresCount, 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray results_ref, jint resultsOffset, jint resultsCapacity) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float frustum[6*4]; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int outputCount; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int* pResults; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pSphere; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity); 498106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool initializedOK = mvp.check() && spheres.check() && results.check(); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! initializedOK) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 503106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mvp.bind(); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spheres.bind(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.bind(); 507106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeFrustum(mvp.mData, frustum); 509106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Cull the spheres 511106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pSphere = spheres.mData; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pResults = results.mData; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputCount = 0; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < spheresCount; i++, pSphere += 4) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sphereHitsFrustum(frustum, pSphere)) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputCount < resultsCapacity) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pResults++ = i; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputCount++; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.commitChanges(); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return outputCount; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int visibilityTest(float[] ws, int wsOffset, 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] positions, int positionsOffset, 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] indices, int indicesOffset, int indexCount); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 53436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatjint util_visibilityTest(JNIEnv *env, jclass clazz, 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray ws_ref, jint wsOffset, 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray positions_ref, jint positionsOffset, 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jcharArray indices_ref, jint indicesOffset, jint indexCount) { 538106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper ws(env, ws_ref, wsOffset, 16); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0); 542106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = ws.check() && positions.check() && indices.check(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! checkOK) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return value will be ignored, because an exception has been thrown. 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 548106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (indices.mLength < indexCount) { 5508451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "length < offset + indexCount"); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 553106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ws.bind(); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.bind(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices.bind(); 557106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return visibilityTest(ws.mData, 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.mData, positions.mLength, 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices.mData, indexCount); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define I(_i, _j) ((_j)+ 4*(_i)) 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMM(float* r, const float* lhs, const float* rhs) 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 56946d8444631b4b1253a76bfcc78a29d26014d022fDan Albert const float rhs_i0 = rhs[ I(i,0) ]; 57046d8444631b4b1253a76bfcc78a29d26014d022fDan Albert float ri0 = lhs[ I(0,0) ] * rhs_i0; 57146d8444631b4b1253a76bfcc78a29d26014d022fDan Albert float ri1 = lhs[ I(0,1) ] * rhs_i0; 57246d8444631b4b1253a76bfcc78a29d26014d022fDan Albert float ri2 = lhs[ I(0,2) ] * rhs_i0; 57346d8444631b4b1253a76bfcc78a29d26014d022fDan Albert float ri3 = lhs[ I(0,3) ] * rhs_i0; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=1 ; j<4 ; j++) { 57546d8444631b4b1253a76bfcc78a29d26014d022fDan Albert const float rhs_ij = rhs[ I(i,j) ]; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri0 += lhs[ I(j,0) ] * rhs_ij; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri1 += lhs[ I(j,1) ] * rhs_ij; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri2 += lhs[ I(j,2) ] * rhs_ij; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri3 += lhs[ I(j,3) ] * rhs_ij; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,0) ] = ri0; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,1) ] = ri1; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,2) ] = ri2; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,3) ] = ri3; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMM(JNIEnv *env, jclass clazz, 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray result_ref, jint resultOffset, 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray lhs_ref, jint lhsOffset, 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray rhs_ref, jint rhsOffset) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper resultMat(env, result_ref, resultOffset, 16); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16); 597106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = resultMat.check() && lhs.check() && rhs.check(); 599106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( !checkOK ) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 603106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultMat.bind(); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lhs.bind(); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rhs.bind(); 607106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMM(resultMat.mData, lhs.mData, rhs.mData); 609106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultMat.commitChanges(); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMV(float* r, const float* lhs, const float* rhs) 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMV(JNIEnv *env, jclass clazz, 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray result_ref, jint resultOffset, 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray lhs_ref, jint lhsOffset, 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray rhs_ref, jint rhsOffset) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper resultV(env, result_ref, resultOffset, 4); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4); 628106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = resultV.check() && lhs.check() && rhs.check(); 630106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( !checkOK ) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 634106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultV.bind(); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lhs.bind(); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rhs.bind(); 638106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMV(resultV.mData, lhs.mData, rhs.mData); 640106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultV.commitChanges(); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64664d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamyextern void setGLDebugLevel(int level); 6470c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamyvoid setTracingLevel(JNIEnv *env, jclass clazz, jint level) 64864d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy{ 6490c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy setGLDebugLevel(level); 65064d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy} 65164d10a1da0a702ffeb086ad9c4a632f2712f1dadSiva Velusamy 6521103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int checkFormat(SkColorType colorType, int format, int type) 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6541103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed switch(colorType) { 6551103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kIndex_8_SkColorType: 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_PALETTE8_RGBA8_OES) 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6581103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kN32_SkColorType: 6591103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kAlpha_8_SkColorType: 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == GL_UNSIGNED_BYTE) 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6621103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kARGB_4444_SkColorType: 6631103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kRGB_565_SkColorType: 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_4_4_4_4: 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_5_6_5: 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_5_5_5_1: 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_BYTE: 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_LUMINANCE_ALPHA) 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6801103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getInternalFormat(SkColorType colorType) 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6821103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed switch(colorType) { 6831103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kAlpha_8_SkColorType: 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_ALPHA; 6851103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kARGB_4444_SkColorType: 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGBA; 6871103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kN32_SkColorType: 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGBA; 6891103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kIndex_8_SkColorType: 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_PALETTE8_RGBA8_OES; 6911103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kRGB_565_SkColorType: 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGB; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6981103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedstatic int getType(SkColorType colorType) 699708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 7001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed switch(colorType) { 7011103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kAlpha_8_SkColorType: 702708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_BYTE; 7031103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kARGB_4444_SkColorType: 704708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_SHORT_4_4_4_4; 7051103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kN32_SkColorType: 706708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_BYTE; 7071103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kIndex_8_SkColorType: 708708c17b4168404042852e480f25a91a02cf14247Jack Palevich return -1; // No type for compressed data. 7091103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed case kRGB_565_SkColorType: 710708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_SHORT_5_6_5; 711708c17b4168404042852e480f25a91a02cf14247Jack Palevich default: 712708c17b4168404042852e480f25a91a02cf14247Jack Palevich return -1; 713708c17b4168404042852e480f25a91a02cf14247Jack Palevich } 714708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 715708c17b4168404042852e480f25a91a02cf14247Jack Palevich 716708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getInternalFormat(JNIEnv *env, jclass clazz, 717708c17b4168404042852e480f25a91a02cf14247Jack Palevich jobject jbitmap) 718708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 719ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck SkBitmap nativeBitmap; 720ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap); 721ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck return getInternalFormat(nativeBitmap.colorType()); 722708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 723708c17b4168404042852e480f25a91a02cf14247Jack Palevich 724708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getType(JNIEnv *env, jclass clazz, 725708c17b4168404042852e480f25a91a02cf14247Jack Palevich jobject jbitmap) 726708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 727ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck SkBitmap nativeBitmap; 728ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap); 729ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck return getType(nativeBitmap.colorType()); 730708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 731708c17b4168404042852e480f25a91a02cf14247Jack Palevich 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texImage2D(JNIEnv *env, jclass clazz, 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint target, jint level, jint internalformat, 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jbitmap, jint type, jint border) 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 736ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck SkBitmap bitmap; 737ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); 7381103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = bitmap.colorType(); 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (internalformat < 0) { 7401103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed internalformat = getInternalFormat(colorType); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 742708c17b4168404042852e480f25a91a02cf14247Jack Palevich if (type < 0) { 7431103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed type = getType(colorType); 744708c17b4168404042852e480f25a91a02cf14247Jack Palevich } 7451103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed int err = checkFormat(colorType, internalformat, type); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) 747106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich return err; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.lockPixels(); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int w = bitmap.width(); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int h = bitmap.height(); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* p = bitmap.getPixels(); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (internalformat == GL_PALETTE8_RGBA8_OES) { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sizeof(SkPMColor) != sizeof(uint32_t)) { 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = -1; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = bitmap.getSize(); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t palette_size = 256*sizeof(SkPMColor); 759106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich const size_t imageSize = size + palette_size; 760106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich void* const data = malloc(imageSize); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data) { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* const pixels = (char*)data + palette_size; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkColorTable* ctable = bitmap.getColorTable(); 76471487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed memcpy(data, ctable->readColors(), ctable->count() * sizeof(SkPMColor)); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(pixels, p, size); 766106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(data); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = -1; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror: 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.unlockPixels(); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texSubImage2D(JNIEnv *env, jclass clazz, 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint target, jint level, jint xoffset, jint yoffset, 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jbitmap, jint format, jint type) 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 783ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck SkBitmap bitmap; 784ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); 7851103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = bitmap.colorType(); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format < 0) { 7871103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed format = getInternalFormat(colorType); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_PALETTE8_RGBA8_OES) 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; // glCompressedTexSubImage2D() not supported 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7911103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed int err = checkFormat(colorType, format, type); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) 793106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich return err; 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.lockPixels(); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int w = bitmap.width(); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int h = bitmap.height(); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* p = bitmap.getPixels(); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.unlockPixels(); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 804a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * ETC1 methods. 805a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 806a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 807a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass nioAccessClass; 808a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jclass bufferClass; 809a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBasePointerID; 810a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayID; 811a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jmethodID getBaseArrayOffsetID; 812a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID positionID; 813a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID limitID; 814a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jfieldID elementSizeShiftID; 815a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 816a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/* Cache method IDs each time the class is loaded. */ 817a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 818a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void 819ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas GampenativeClassInitBuffer(JNIEnv *env) 820a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{ 821ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass nioAccessClassLocal = FindClassOrDie(env, "java/nio/NIOAccess"); 822ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe nioAccessClass = MakeGlobalRefOrDie(env, nioAccessClassLocal); 823ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe getBasePointerID = GetStaticMethodIDOrDie(env, nioAccessClass, 824a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich "getBasePointer", "(Ljava/nio/Buffer;)J"); 825ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe getBaseArrayID = GetStaticMethodIDOrDie(env, nioAccessClass, 826a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;"); 827ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe getBaseArrayOffsetID = GetStaticMethodIDOrDie(env, nioAccessClass, 828a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich "getBaseArrayOffset", "(Ljava/nio/Buffer;)I"); 829ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 830ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe jclass bufferClassLocal = FindClassOrDie(env, "java/nio/Buffer"); 831ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe bufferClass = MakeGlobalRefOrDie(env, bufferClassLocal); 832ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe positionID = GetFieldIDOrDie(env, bufferClass, "position", "I"); 833ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe limitID = GetFieldIDOrDie(env, bufferClass, "limit", "I"); 834ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe elementSizeShiftID = GetFieldIDOrDie(env, bufferClass, "_elementSizeShift", "I"); 835a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 836a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 837a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void * 838a6276fdd4253c3a7150ab675678c750473ab6c45Jack PalevichgetPointer(JNIEnv *_env, jobject buffer, jint *remaining) 839a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich{ 840a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint position; 841a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint limit; 842a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint elementSizeShift; 843a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jlong pointer; 844a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 845a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich position = _env->GetIntField(buffer, positionID); 846a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich limit = _env->GetIntField(buffer, limitID); 847a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID); 848a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich *remaining = (limit - position) << elementSizeShift; 849a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich pointer = _env->CallStaticLongMethod(nioAccessClass, 850a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich getBasePointerID, buffer); 851a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (pointer != 0L) { 85236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<void *>(pointer); 853a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 854a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return NULL; 855a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 856a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 857a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichclass BufferHelper { 858a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichpublic: 859a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper(JNIEnv *env, jobject buffer) { 860a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich mEnv = env; 861a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich mBuffer = buffer; 862a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich mData = NULL; 863a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich mRemaining = 0; 864a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 865a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 866a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich bool checkPointer(const char* errorMessage) { 867a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (mBuffer) { 868a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich mData = getPointer(mEnv, mBuffer, &mRemaining); 869a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (mData == NULL) { 8708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(mEnv, errorMessage); 871a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 872a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return mData != NULL; 873a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 8748451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(mEnv, errorMessage); 875a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return false; 876a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 877a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 878a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 879a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich inline void* getData() { 880a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return mData; 881a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 882a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 883a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich inline jint remaining() { 884a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return mRemaining; 885a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 886a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 887a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichprivate: 888a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich JNIEnv* mEnv; 889a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject mBuffer; 890a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich void* mData; 891a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint mRemaining; 892a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}; 893a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 894a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 895a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode a block of pixels. 896a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 897a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in a pointer to a ETC1_DECODED_BLOCK_SIZE array of bytes that represent a 898a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R 899a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y). 900a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 901a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether 902a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing. 903a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 904a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out an ETC1 compressed version of the data. 905a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 906a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 907a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeBlock(JNIEnv *env, jclass clazz, 908a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject in, jint validPixelMask, jobject out) { 909a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (validPixelMask < 0 || validPixelMask > 15) { 9108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "validPixelMask"); 911a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return; 912a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 913a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper inB(env, in); 914a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper outB(env, out); 915a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.checkPointer("in") && outB.checkPointer("out")) { 916a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) { 9178451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE"); 918a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) { 9198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE"); 920a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 921a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask, 922a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich (etc1_byte*) outB.getData()); 923a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 924a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 925a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 926a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 927a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 928a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode a block of pixels. 929a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 930a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in an ETC1 compressed version of the data. 931a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 932a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a 933a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R 934a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * value of pixel (x, y). 935a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 936a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeBlock(JNIEnv *env, jclass clazz, 937a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject in, jobject out){ 938a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper inB(env, in); 939a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper outB(env, out); 940a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.checkPointer("in") && outB.checkPointer("out")) { 941a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) { 9428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE"); 943a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) { 9448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE"); 945a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 946a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich etc1_decode_block((etc1_byte*) inB.getData(), 947a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich (etc1_byte*) outB.getData()); 948a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 949a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 950a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 951a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 952a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 953a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Return the size of the encoded image data (does not include size of PKM header). 954a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 955a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getEncodedDataSize(JNIEnv *env, jclass clazz, 956a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint width, jint height) { 957a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return etc1_get_encoded_data_size(width, height); 958a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 959a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 960a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 961a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Encode an entire image. 962a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in pointer to the image data. Formatted such that 963a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset; 964a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to encoded data. Must be large enough to store entire encoded image. 965a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 966a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_encodeImage(JNIEnv *env, jclass clazz, 967a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject in, jint width, jint height, 968a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint pixelSize, jint stride, jobject out) { 969a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (pixelSize < 2 || pixelSize > 3) { 9708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "pixelSize must be 2 or 3"); 971a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return; 972a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 973a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper inB(env, in); 974a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper outB(env, out); 975a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.checkPointer("in") && outB.checkPointer("out")) { 976a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint imageSize = stride * height; 977a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint encodedImageSize = etc1_get_encoded_data_size(width, height); 978a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.remaining() < imageSize) { 9798451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "in's remaining data < image size"); 980a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else if (outB.remaining() < encodedImageSize) { 9818451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "out's remaining data < encoded image size"); 982a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 9830f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe etc1_encode_image((etc1_byte*) inB.getData(), width, height, pixelSize, stride, 9840f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe (etc1_byte*) outB.getData()); 985a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 986a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 987a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 988a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 989a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 990a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Decode an entire image. 991a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param in the encoded data. 992a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * @param out pointer to the image data. Will be written such that 993a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be 994a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * large enough to store entire image. 995a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 996a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_decodeImage(JNIEnv *env, jclass clazz, 997a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject in, jobject out, 998a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint width, jint height, 999a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint pixelSize, jint stride) { 1000a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (pixelSize < 2 || pixelSize > 3) { 10018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "pixelSize must be 2 or 3"); 1002a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return; 1003a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1004a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper inB(env, in); 1005a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper outB(env, out); 1006a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.checkPointer("in") && outB.checkPointer("out")) { 1007a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint imageSize = stride * height; 1008a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint encodedImageSize = etc1_get_encoded_data_size(width, height); 1009a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (inB.remaining() < encodedImageSize) { 10108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "in's remaining data < encoded image size"); 1011a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else if (outB.remaining() < imageSize) { 10128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "out's remaining data < image size"); 1013a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 10140f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe etc1_decode_image((etc1_byte*) inB.getData(), (etc1_byte*) outB.getData(), 10150f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe width, height, pixelSize, stride); 1016a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1017a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1018a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 1019a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 1020a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 1021a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Format a PKM header 1022a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 1023a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic void etc1_formatHeader(JNIEnv *env, jclass clazz, 1024a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject header, jint width, jint height) { 1025a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper headerB(env, header); 1026a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.checkPointer("header") ){ 1027a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 10288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 1029a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 1030a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height); 1031a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1032a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1033a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 1034a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 1035a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 1036a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Check if a PKM header is correctly formatted. 1037a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 1038a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jboolean etc1_isValid(JNIEnv *env, jclass clazz, 1039a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject header) { 1040a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jboolean result = false; 1041a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper headerB(env, header); 1042a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.checkPointer("header") ){ 1043a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 10448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 1045a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 1046a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich result = etc1_pkm_is_valid((etc1_byte*) headerB.getData()); 1047a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1048a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 104936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return result ? JNI_TRUE : JNI_FALSE; 1050a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 1051a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 1052a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 1053a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image width from a PKM header 1054a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 1055a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic jint etc1_getWidth(JNIEnv *env, jclass clazz, 1056a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject header) { 1057a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint result = 0; 1058a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper headerB(env, header); 1059a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.checkPointer("header") ){ 1060a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 10618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 1062a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 1063a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich result = etc1_pkm_get_width((etc1_byte*) headerB.getData()); 1064a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1065a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1066a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return result; 1067a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 1068a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 1069a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/** 1070a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich * Read the image height from a PKM header 1071a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich */ 107236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jint etc1_getHeight(JNIEnv *env, jclass clazz, 1073a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jobject header) { 1074a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich jint result = 0; 1075a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich BufferHelper headerB(env, header); 1076a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.checkPointer("header") ){ 1077a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 10788451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 1079a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } else { 1080a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich result = etc1_pkm_get_height((etc1_byte*) headerB.getData()); 1081a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1082a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich } 1083a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich return result; 1084a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich} 1085a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 1086a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich/* 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMatrixMethods[] = { 1091106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM }, 1092106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV }, 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10958451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesstatic JNINativeMethod gVisibilityMethods[] = { 1096106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere }, 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres }, 1098106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest }, 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gUtilsMethods[] = { 1102106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat }, 1103106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType }, 1104106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D }, 1105106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D }, 11060c1761bd37815c3776608a19c8e11d862b3e910cSiva Velusamy { "setTracingLevel", "(I)V", (void*)setTracingLevel }, 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevichstatic JNINativeMethod gEtc1Methods[] = { 1110a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "encodeBlock", "(Ljava/nio/Buffer;ILjava/nio/Buffer;)V", (void*) etc1_encodeBlock }, 1111a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "decodeBlock", "(Ljava/nio/Buffer;Ljava/nio/Buffer;)V", (void*) etc1_decodeBlock }, 1112a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "getEncodedDataSize", "(II)I", (void*) etc1_getEncodedDataSize }, 1113a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "encodeImage", "(Ljava/nio/Buffer;IIIILjava/nio/Buffer;)V", (void*) etc1_encodeImage }, 1114a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "decodeImage", "(Ljava/nio/Buffer;Ljava/nio/Buffer;IIII)V", (void*) etc1_decodeImage }, 1115a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "formatHeader", "(Ljava/nio/Buffer;II)V", (void*) etc1_formatHeader }, 1116a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "isValid", "(Ljava/nio/Buffer;)Z", (void*) etc1_isValid }, 1117a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "getWidth", "(Ljava/nio/Buffer;)I", (void*) etc1_getWidth }, 1118a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich { "getHeight", "(Ljava/nio/Buffer;)I", (void*) etc1_getHeight }, 1119a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich}; 1120a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct _ClassRegistrationInfo { 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* classPath; 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNINativeMethod* methods; 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t methodCount; 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} ClassRegistrationInfo; 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ClassRegistrationInfo gClasses[] = { 11288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)}, 11298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)}, 11308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)}, 11318451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)}, 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_opengl_classes(JNIEnv* env) 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1136a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich nativeClassInitBuffer(env); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NELEM(gClasses); i++) { 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClassRegistrationInfo* cri = &gClasses[i]; 1140ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe result = RegisterMethodsOrDie(env, cri->classPath, cri->methods, cri->methodCount); 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 1146