util.cpp revision 106006cbdedc79ce8746ca5449610c69a2f69655
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 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <nativehelper/jni.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dlfcn.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <core/SkBitmap.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef LOG_TAG 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "OpenGLUtil" 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "poly.h" 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gIAEClass; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gUOEClass; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z + pM[1 + 4 * 3] * w; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z + pM[2 + 4 * 3] * w; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass MallocHelper { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MallocHelper() { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mData = 0; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~MallocHelper() { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mData != 0) { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(mData); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 62106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* alloc(size_t size) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mData = malloc(size); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mData; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 67106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* mData; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprint_poly(const char* label, Poly* pPoly) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("%s: %d verts", label, pPoly->n); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < pPoly->n; i++) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Poly_vert* pV = & pPoly->vert[i]; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("[%d] %g, %g, %g %g", i, pV->sx, pV->sy, pV->sz, pV->sw); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint visibilityTest(float* pWS, float* pPositions, int positionsLength, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short* pIndices, int indexCount) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MallocHelper mallocHelper; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = POLY_CLIP_OUT; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pTransformed = 0; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int transformedIndexCount = 0; 91106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( indexCount < 3 ) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return POLY_CLIP_OUT; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 95106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find out how many vertices we need to transform 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We transform every vertex between the min and max indices, inclusive. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is OK for the data sets we expect to use with this function, but 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for other loads it might be better to use a more sophisticated vertex 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache of some sort. 101106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minIndex = 65536; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int maxIndex = -1; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < indexCount; i++) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = pIndices[i]; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( index < minIndex ) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minIndex = index; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( index > maxIndex ) { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxIndex = index; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 113106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( maxIndex * 3 > positionsLength) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 117106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project transformedIndexCount = maxIndex - minIndex + 1; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float)); 120106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pTransformed == 0 ) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -2; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 124106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Transform the vertices 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* pSrc = pPositions + 3 * minIndex; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pDst = pTransformed; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < transformedIndexCount; i++, pSrc += 3, pDst += 4) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS, pDst); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 133106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Clip the triangles 135106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Poly poly; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pDest = & poly.vert[0].sx; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < indexCount; i += 3) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project poly.n = 3; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(pDest , pTransformed + 4 * (pIndices[i ] - minIndex), 4 * sizeof(float)); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(pDest + 4, pTransformed + 4 * (pIndices[i + 1] - minIndex), 4 * sizeof(float)); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(pDest + 8, pTransformed + 4 * (pIndices[i + 2] - minIndex), 4 * sizeof(float)); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = poly_clip_to_frustum(&poly); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( result != POLY_CLIP_OUT) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate<class JArray, class T> 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ArrayHelper { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv = env; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRef = ref; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset = offset; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinSize = minSize; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBase = 0; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseParam = JNI_ABORT; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~ArrayHelper() { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBase) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 169106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We seperate the bounds check from the initialization because we want to 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be able to bounds-check multiple arrays, and we can't throw an exception 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // after we've called GetPrimitiveArrayCritical. 173106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return true if the bounds check succeeded 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Else instruct the runtime to throw an exception 176106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool check() { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( ! mRef) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv->ThrowNew(gIAEClass, "array == null"); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( mOffset < 0) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv->ThrowNew(gIAEClass, "offset < 0"); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = mEnv->GetArrayLength(mRef) - mOffset; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength < mMinSize ) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnv->ThrowNew(gIAEClass, "length - offset < n"); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 193106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bind the array. 195106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void bind() { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mData = mBase + mOffset; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void commitChanges() { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseParam = 0; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 204106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project T* mData; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLength; 207106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project T* mBase; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* mEnv; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JArray mRef; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint mOffset; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint mMinSize; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mReleaseParam; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jfloatArray, float> FloatArrayHelper; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jintArray, int> IntArrayHelper; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance2(float x, float y, float z) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return x * x + y * y + z * z; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline float distance(float x, float y, float z) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sqrtf(distance2(x, y, z)); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 229106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_computeBoundingSphere(JNIEnv *env, jclass clazz, 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray positions_ref, jint positionsOffset, jint positionsCount, 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray sphere_ref, jint sphereOffset) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4); 236106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = positions.check() && sphere.check(); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! checkOK) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 241106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.bind(); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sphere.bind(); 244106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( positionsCount < 1 ) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ThrowNew(gIAEClass, "positionsCount < 1"); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 249106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* pSrc = positions.mData; 251106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find bounding box 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x0 = *pSrc++; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x1 = x0; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y0 = *pSrc++; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y1 = y0; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z0 = *pSrc++; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z1 = z0; 259106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 1; i < positionsCount; i++) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = *pSrc++; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x < x0) { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = x; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (x > x1) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = *pSrc++; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y < y0) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = y; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (y > y1) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y1 = y; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = *pSrc++; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z < z0) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z0 = z; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (z > z1) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z1 = z; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 289106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Because we know our input meshes fit pretty well into bounding boxes, 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just take the diagonal of the box as defining our sphere. 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pSphere = sphere.mData; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dx = x1 - x0; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dy = y1 - y0; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dz = z1 - z0; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = x0 + dx * 0.5f; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = y0 + dy * 0.5f; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = z0 + dz * 0.5f; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pSphere++ = distance(dx, dy, dz) * 0.5f; 300106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sphere.commitChanges(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void normalizePlane(float* p) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float rdist = 1.0f / distance(p[0], p[1], p[2]); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < 4; i++) { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p[i] *= rdist; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return x0 * x1 + y0 * y1 + z0 * z1; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline float signedDistance(const float* pPlane, float x, float y, float z) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3]; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Return true if the sphere intersects or is inside the frustum 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = pSphere[0]; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = pSphere[1]; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = pSphere[2]; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float negRadius = -pSphere[3]; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 6; i++, pFrustum += 4) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (signedDistance(pFrustum, x, y, z) <= negRadius) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void computeFrustum(const float* m, float* f) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m3 = m[3]; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m7 = m[7]; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m11 = m[11]; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float m15 = m[15]; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // right 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[0]; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[4]; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[8]; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[12]; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 347106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich // left 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[0]; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[4]; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[8]; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[12]; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // top 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[1]; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[5]; 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[9]; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[13]; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // bottom 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[1]; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[5]; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[9]; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[13]; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // far 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 - m[2]; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 - m[6]; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 - m[10]; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 - m[14]; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f+= 4; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // near 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[0] = m3 + m[2]; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[1] = m7 + m[6]; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[2] = m11 + m[10]; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f[3] = m15 + m[14]; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizePlane(f); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint util_frustumCullSpheres(JNIEnv *env, jclass clazz, 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray mvp_ref, jint mvpOffset, 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray spheres_ref, jint spheresOffset, jint spheresCount, 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray results_ref, jint resultsOffset, jint resultsCapacity) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float frustum[6*4]; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int outputCount; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int* pResults; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* pSphere; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity); 399106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool initializedOK = mvp.check() && spheres.check() && results.check(); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! initializedOK) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 404106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mvp.bind(); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spheres.bind(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.bind(); 408106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeFrustum(mvp.mData, frustum); 410106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Cull the spheres 412106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pSphere = spheres.mData; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pResults = results.mData; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputCount = 0; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < spheresCount; i++, pSphere += 4) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sphereHitsFrustum(frustum, pSphere)) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputCount < resultsCapacity) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pResults++ = i; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputCount++; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.commitChanges(); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return outputCount; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int visibilityTest(float[] ws, int wsOffset, 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] positions, int positionsOffset, 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] indices, int indicesOffset, int indexCount); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint util_visibilityTest(JNIEnv *env, jclass clazz, 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray ws_ref, jint wsOffset, 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray positions_ref, jint positionsOffset, 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jcharArray indices_ref, jint indicesOffset, jint indexCount) { 439106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper ws(env, ws_ref, wsOffset, 16); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0); 443106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = ws.check() && positions.check() && indices.check(); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! checkOK) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return value will be ignored, because an exception has been thrown. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 449106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (indices.mLength < indexCount) { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ThrowNew(gIAEClass, "length < offset + indexCount"); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return value will be ignored, because an exception has been thrown. 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 455106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ws.bind(); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.bind(); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices.bind(); 459106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return visibilityTest(ws.mData, 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positions.mData, positions.mLength, 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices.mData, indexCount); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define I(_i, _j) ((_j)+ 4*(_i)) 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMM(float* r, const float* lhs, const float* rhs) 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register const float rhs_i0 = rhs[ I(i,0) ]; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register float ri0 = lhs[ I(0,0) ] * rhs_i0; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register float ri1 = lhs[ I(0,1) ] * rhs_i0; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register float ri2 = lhs[ I(0,2) ] * rhs_i0; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register float ri3 = lhs[ I(0,3) ] * rhs_i0; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=1 ; j<4 ; j++) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register const float rhs_ij = rhs[ I(i,j) ]; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri0 += lhs[ I(j,0) ] * rhs_ij; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri1 += lhs[ I(j,1) ] * rhs_ij; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri2 += lhs[ I(j,2) ] * rhs_ij; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ri3 += lhs[ I(j,3) ] * rhs_ij; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,0) ] = ri0; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,1) ] = ri1; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,2) ] = ri2; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r[ I(i,3) ] = ri3; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMM(JNIEnv *env, jclass clazz, 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray result_ref, jint resultOffset, 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray lhs_ref, jint lhsOffset, 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray rhs_ref, jint rhsOffset) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper resultMat(env, result_ref, resultOffset, 16); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16); 499106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = resultMat.check() && lhs.check() && rhs.check(); 501106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( !checkOK ) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 505106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultMat.bind(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lhs.bind(); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rhs.bind(); 509106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMM(resultMat.mData, lhs.mData, rhs.mData); 511106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultMat.commitChanges(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid multiplyMV(float* r, const float* lhs, const float* rhs) 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid util_multiplyMV(JNIEnv *env, jclass clazz, 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray result_ref, jint resultOffset, 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray lhs_ref, jint lhsOffset, 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray rhs_ref, jint rhsOffset) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper resultV(env, result_ref, resultOffset, 4); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4); 530106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool checkOK = resultV.check() && lhs.check() && rhs.check(); 532106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( !checkOK ) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 536106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultV.bind(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lhs.bind(); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rhs.bind(); 540106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMV(resultV.mData, lhs.mData, rhs.mData); 542106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resultV.commitChanges(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID nativeBitmapID = 0; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid nativeUtilsClassInit(JNIEnv *env, jclass clazz) 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass bitmapClass = env->FindClass("android/graphics/Bitmap"); 553106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich nativeBitmapID = env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int checkFormat(SkBitmap::Config config, int format, int type) 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(config) { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kIndex8_Config: 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_PALETTE8_RGBA8_OES) 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kARGB_8888_Config: 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kA8_Config: 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == GL_UNSIGNED_BYTE) 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kARGB_4444_Config: 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kRGB_565_Config: 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_4_4_4_4: 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_5_6_5: 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_SHORT_5_5_5_1: 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GL_UNSIGNED_BYTE: 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_LUMINANCE_ALPHA) 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int getInternalFormat(SkBitmap::Config config) 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(config) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kA8_Config: 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_ALPHA; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kARGB_4444_Config: 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGBA; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kARGB_8888_Config: 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGBA; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kIndex8_Config: 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_PALETTE8_RGBA8_OES; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SkBitmap::kRGB_565_Config: 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GL_RGB; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 602708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic int getType(SkBitmap::Config config) 603708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 604708c17b4168404042852e480f25a91a02cf14247Jack Palevich switch(config) { 605708c17b4168404042852e480f25a91a02cf14247Jack Palevich case SkBitmap::kA8_Config: 606708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_BYTE; 607708c17b4168404042852e480f25a91a02cf14247Jack Palevich case SkBitmap::kARGB_4444_Config: 608708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_SHORT_4_4_4_4; 609708c17b4168404042852e480f25a91a02cf14247Jack Palevich case SkBitmap::kARGB_8888_Config: 610708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_BYTE; 611708c17b4168404042852e480f25a91a02cf14247Jack Palevich case SkBitmap::kIndex8_Config: 612708c17b4168404042852e480f25a91a02cf14247Jack Palevich return -1; // No type for compressed data. 613708c17b4168404042852e480f25a91a02cf14247Jack Palevich case SkBitmap::kRGB_565_Config: 614708c17b4168404042852e480f25a91a02cf14247Jack Palevich return GL_UNSIGNED_SHORT_5_6_5; 615708c17b4168404042852e480f25a91a02cf14247Jack Palevich default: 616708c17b4168404042852e480f25a91a02cf14247Jack Palevich return -1; 617708c17b4168404042852e480f25a91a02cf14247Jack Palevich } 618708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 619708c17b4168404042852e480f25a91a02cf14247Jack Palevich 620708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getInternalFormat(JNIEnv *env, jclass clazz, 621708c17b4168404042852e480f25a91a02cf14247Jack Palevich jobject jbitmap) 622708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 623708c17b4168404042852e480f25a91a02cf14247Jack Palevich SkBitmap const * nativeBitmap = 624708c17b4168404042852e480f25a91a02cf14247Jack Palevich (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 625708c17b4168404042852e480f25a91a02cf14247Jack Palevich const SkBitmap& bitmap(*nativeBitmap); 626708c17b4168404042852e480f25a91a02cf14247Jack Palevich SkBitmap::Config config = bitmap.getConfig(); 627708c17b4168404042852e480f25a91a02cf14247Jack Palevich return getInternalFormat(config); 628708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 629708c17b4168404042852e480f25a91a02cf14247Jack Palevich 630708c17b4168404042852e480f25a91a02cf14247Jack Palevichstatic jint util_getType(JNIEnv *env, jclass clazz, 631708c17b4168404042852e480f25a91a02cf14247Jack Palevich jobject jbitmap) 632708c17b4168404042852e480f25a91a02cf14247Jack Palevich{ 633708c17b4168404042852e480f25a91a02cf14247Jack Palevich SkBitmap const * nativeBitmap = 634708c17b4168404042852e480f25a91a02cf14247Jack Palevich (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 635708c17b4168404042852e480f25a91a02cf14247Jack Palevich const SkBitmap& bitmap(*nativeBitmap); 636708c17b4168404042852e480f25a91a02cf14247Jack Palevich SkBitmap::Config config = bitmap.getConfig(); 637708c17b4168404042852e480f25a91a02cf14247Jack Palevich return getType(config); 638708c17b4168404042852e480f25a91a02cf14247Jack Palevich} 639708c17b4168404042852e480f25a91a02cf14247Jack Palevich 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texImage2D(JNIEnv *env, jclass clazz, 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint target, jint level, jint internalformat, 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jbitmap, jint type, jint border) 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap const * nativeBitmap = 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkBitmap& bitmap(*nativeBitmap); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap::Config config = bitmap.getConfig(); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (internalformat < 0) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project internalformat = getInternalFormat(config); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 651708c17b4168404042852e480f25a91a02cf14247Jack Palevich if (type < 0) { 652708c17b4168404042852e480f25a91a02cf14247Jack Palevich type = getType(config); 653708c17b4168404042852e480f25a91a02cf14247Jack Palevich } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err = checkFormat(config, internalformat, type); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) 656106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich return err; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.lockPixels(); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int w = bitmap.width(); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int h = bitmap.height(); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* p = bitmap.getPixels(); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (internalformat == GL_PALETTE8_RGBA8_OES) { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sizeof(SkPMColor) != sizeof(uint32_t)) { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = -1; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = bitmap.getSize(); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t palette_size = 256*sizeof(SkPMColor); 668106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich const size_t imageSize = size + palette_size; 669106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich void* const data = malloc(imageSize); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* const pixels = (char*)data + palette_size; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkColorTable* ctable = bitmap.getColorTable(); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor)); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(pixels, p, size); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ctable->unlockColors(false); 676106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(data); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = -1; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror: 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.unlockPixels(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint util_texSubImage2D(JNIEnv *env, jclass clazz, 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint target, jint level, jint xoffset, jint yoffset, 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jbitmap, jint format, jint type) 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap const * nativeBitmap = 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkBitmap& bitmap(*nativeBitmap); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap::Config config = bitmap.getConfig(); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format < 0) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project format = getInternalFormat(config); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (format == GL_PALETTE8_RGBA8_OES) 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; // glCompressedTexSubImage2D() not supported 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err = checkFormat(config, format, type); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err) 704106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich return err; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.lockPixels(); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int w = bitmap.width(); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int h = bitmap.height(); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* p = bitmap.getPixels(); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.unlockPixels(); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectlookupClasses(JNIEnv* env) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gIAEClass = (jclass) env->NewGlobalRef( 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->FindClass("java/lang/IllegalArgumentException")); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gUOEClass = (jclass) env->NewGlobalRef( 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->FindClass("java/lang/UnsupportedOperationException")); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMatrixMethods[] = { 727106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM }, 728106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV }, 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gVisiblityMethods[] = { 732106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere }, 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres }, 734106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest }, 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gUtilsMethods[] = { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeClassInit", "()V", (void*)nativeUtilsClassInit }, 739106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat }, 740106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType }, 741106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D }, 742106006cbdedc79ce8746ca5449610c69a2f69655Jack Palevich { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D }, 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct _ClassRegistrationInfo { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* classPath; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNINativeMethod* methods; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t methodCount; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} ClassRegistrationInfo; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ClassRegistrationInfo gClasses[] = { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)}, 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"android/opengl/Visibility", gVisiblityMethods, NELEM(gVisiblityMethods)}, 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)}, 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_opengl_classes(JNIEnv* env) 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lookupClasses(env); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NELEM(gClasses); i++) { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClassRegistrationInfo* cri = &gClasses[i]; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = AndroidRuntime::registerNativeMethods(env, 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cri->classPath, cri->methods, cri->methodCount); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result < 0) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Failed to register %s: %d", cri->classPath, result); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 775