util.cpp revision ed79ff0026a44741237a6eb5e3810dbf5d765154
18ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis/** 28ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** Copyright 2007, The Android Open Source Project 38ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** 48ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** Licensed under the Apache License, Version 2.0 (the "License"); 58ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** you may not use this file except in compliance with the License. 68ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** You may obtain a copy of the License at 78ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** 88ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** http://www.apache.org/licenses/LICENSE-2.0 98ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** 108ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** Unless required by applicable law or agreed to in writing, software 118ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** distributed under the License is distributed on an "AS IS" BASIS, 128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** See the License for the specific language governing permissions and 148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ** limitations under the License. 158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis */ 168ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 178ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include "jni.h" 188ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include "JNIHelp.h" 198ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 208ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <math.h> 21399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <stdio.h> 228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <stdlib.h> 238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <string.h> 24399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <assert.h> 258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <dlfcn.h> 268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 278ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <GLES/gl.h> 288ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <ETC1/etc1.h> 292adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden 30f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <core/SkBitmap.h> 318ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include "android_runtime/AndroidRuntime.h" 338ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#undef LOG_TAG 358ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define LOG_TAG "OpenGLUtil" 368ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <utils/Log.h> 378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include "utils/misc.h" 389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 39d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza#include "poly.h" 409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisnamespace android { 428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 43eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianstatic inline 44fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennisvoid mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) { 45fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w; 46399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z + pM[1 + 4 * 3] * w; 4729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z + pM[2 + 4 * 3] * w; 489de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w; 49812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 50c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza 51fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosclass MallocHelper { 527dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozapublic: 53ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos MallocHelper() { 543559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mData = 0; 55ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos } 56127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza 5750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza ~MallocHelper() { 58eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos if (mData != 0) { 598ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis free(mData); 608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 612adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden } 628ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 638ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis void* alloc(size_t size) { 642adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden mData = malloc(size); 652adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden return mData; 668ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 678ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 688ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisprivate: 693be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza void* mData; 703be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza}; 717b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 728ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#if 0 732adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatic 748ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisvoid 758a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennisprint_poly(const char* label, Poly* pPoly) { 768a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis ALOGI("%s: %d verts", label, pPoly->n); 778a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis for(int i = 0; i < pPoly->n; i++) { 788a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis Poly_vert* pV = & pPoly->vert[i]; 798ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ALOGI("[%d] %g, %g, %g %g", i, pV->sx, pV->sy, pV->sz, pV->sw); 808ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 817b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 822aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu#endif 832aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu 842aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhustatic 852aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhuint visibilityTest(float* pWS, float* pPositions, int positionsLength, 862aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu unsigned short* pIndices, int indexCount) { 878ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis MallocHelper mallocHelper; 888a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis int result = POLY_CLIP_OUT; 897b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis float* pTransformed = 0; 908ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis int transformedIndexCount = 0; 918ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 92fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ( indexCount < 3 ) { 93fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return POLY_CLIP_OUT; 94fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 95fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 96fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Find out how many vertices we need to transform 97fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // We transform every vertex between the min and max indices, inclusive. 98fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // This is OK for the data sets we expect to use with this function, but 99fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // for other loads it might be better to use a more sophisticated vertex 100fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // cache of some sort. 101fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 102fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos int minIndex = 65536; 103fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos int maxIndex = -1; 104fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos for(int i = 0; i < indexCount; i++) { 105fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos int index = pIndices[i]; 106fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ( index < minIndex ) { 107fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos minIndex = index; 108fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 109fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ( index > maxIndex ) { 110fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos maxIndex = index; 111fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 112fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 113fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 114fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ( maxIndex * 3 > positionsLength) { 115fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return -1; 116fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 117fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 118fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos transformedIndexCount = maxIndex - minIndex + 1; 119fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float)); 120567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos 121567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos if (pTransformed == 0 ) { 1228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return -2; 1232adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden } 1243be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 1253be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza // Transform the vertices 1263be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza { 1273be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza const float* pSrc = pPositions + 3 * minIndex; 1288a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis float* pDst = pTransformed; 1298a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis for (int i = 0; i < transformedIndexCount; i++, pSrc += 3, pDst += 4) { 1308a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS, pDst); 1318a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis } 1328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 133ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian 134ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian // Clip the triangles 1354c00cc11141da7d159eb2323b186ed344115c0f1Jesse Hall 136ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian Poly poly; 137f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall float* pDest = & poly.vert[0].sx; 1388a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis for (int i = 0; i < indexCount; i += 3) { 1398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis poly.n = 3; 1408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis memcpy(pDest , pTransformed + 4 * (pIndices[i ] - minIndex), 4 * sizeof(float)); 1418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis memcpy(pDest + 4, pTransformed + 4 * (pIndices[i + 1] - minIndex), 4 * sizeof(float)); 1429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza memcpy(pDest + 8, pTransformed + 4 * (pIndices[i + 2] - minIndex), 4 * sizeof(float)); 1439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza result = poly_clip_to_frustum(&poly); 1449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if ( result != POLY_CLIP_OUT) { 1459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return result; 1469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return result; 1509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 1519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatic void doThrowIAE(JNIEnv* env, const char* msg) { 1539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza jniThrowException(env, "java/lang/IllegalArgumentException", msg); 154d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 155d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 156d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozatemplate<class JArray, class T> 157d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozaclass ArrayHelper { 158d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozapublic: 159d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) { 160d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mEnv = env; 161d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mRef = ref; 162d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mOffset = offset; 163d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mMinSize = minSize; 164d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mBase = 0; 165d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mReleaseParam = JNI_ABORT; 166d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 167d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 168d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ~ArrayHelper() { 169d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mBase) { 170d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam); 171d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 172d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 173d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 174d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // We seperate the bounds check from the initialization because we want to 175d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // be able to bounds-check multiple arrays, and we can't throw an exception 176d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // after we've called GetPrimitiveArrayCritical. 177d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 178d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // Return true if the bounds check succeeded 179d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // Else instruct the runtime to throw an exception 180d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 181d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza bool check() { 182d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if ( ! mRef) { 183d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza doThrowIAE(mEnv, "array == null"); 184d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return false; 1859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if ( mOffset < 0) { 1879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza doThrowIAE(mEnv, "offset < 0"); 1889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return false; 1899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mLength = mEnv->GetArrayLength(mRef) - mOffset; 1919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mLength < mMinSize ) { 1929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza doThrowIAE(mEnv, "length - offset < n"); 1939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return false; 1949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return true; 1969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 198f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian // Bind the array. 199f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian 2008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis void bind() { 2012adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0); 2028ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis mData = mBase + mOffset; 203c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall } 2048a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis 2058a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis void commitChanges() { 2068a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis mReleaseParam = 0; 2078a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis } 208f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian 2098a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis T* mData; 2108ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis int mLength; 2118ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 2128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisprivate: 213583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos T* mBase; 2148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis JNIEnv* mEnv; 2152adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden JArray mRef; 2168ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jint mOffset; 2171df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis jint mMinSize; 218583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos int mReleaseParam; 219583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos}; 220583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 221583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballostypedef ArrayHelper<jfloatArray, float> FloatArrayHelper; 222583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballostypedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper; 223583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballostypedef ArrayHelper<jintArray, int> IntArrayHelper; 2248ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennistypedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper; 2258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 226eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianinline float distance2(float x, float y, float z) { 227eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian return x * x + y * y + z * z; 2282adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden} 229eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian 2308a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennisinline float distance(float x, float y, float z) { 2318a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis return sqrtf(distance2(x, y, z)); 2328a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis} 2338a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis 234eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianstatic 2358a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennisvoid util_computeBoundingSphere(JNIEnv *env, jclass clazz, 236eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian jfloatArray positions_ref, jint positionsOffset, jint positionsCount, 237eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian jfloatArray sphere_ref, jint sphereOffset) { 238eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 239f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4); 240365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian 241fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis bool checkOK = positions.check() && sphere.check(); 2422adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden if (! checkOK) { 243f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza return; 244f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza } 245097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen 246f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza positions.bind(); 247f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza sphere.bind(); 248f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza 249fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis if ( positionsCount < 1 ) { 250595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian doThrowIAE(env, "positionsCount < 1"); 2518a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis return; 2528a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis } 2538a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis 2548a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis const float* pSrc = positions.mData; 25524202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopian 2568a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis // find bounding box 257fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis float x0 = *pSrc++; 258fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis float x1 = x0; 2598072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian float y0 = *pSrc++; 260fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis float y1 = y0; 261fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis float z0 = *pSrc++; 2622adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden float z1 = z0; 263fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis 2648a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis for(int i = 1; i < positionsCount; i++) { 2658a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis { 2668a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis float x = *pSrc++; 2678a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis if (x < x0) { 2688a29ff2a356816694c695db70460f93c7fb4ae6fJamie Gennis x0 = x; 269fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 270fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis else if (x > x1) { 271399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall x1 = x; 272399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 273399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 274399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall { 275399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall float y = *pSrc++; 276399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (y < y0) { 277399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall y0 = y; 278399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 279399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall else if (y > y1) { 280399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall y1 = y; 281399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 282399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 283399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall { 284399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall float z = *pSrc++; 285399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (z < z0) { 286399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall z0 = z; 28729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 288567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos else if (z > z1) { 2893be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza z1 = z; 29029a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 29129a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 2923be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza } 2933be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 29429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza // Because we know our input meshes fit pretty well into bounding boxes, 2953be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza // just take the diagonal of the box as defining our sphere. 29629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza float* pSphere = sphere.mData; 29729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza float dx = x1 - x0; 29829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza float dy = y1 - y0; 29929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza float dz = z1 - z0; 30029a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza *pSphere++ = x0 + dx * 0.5f; 3019de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza *pSphere++ = y0 + dy * 0.5f; 3029de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza *pSphere++ = z0 + dz * 0.5f; 3039de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza *pSphere++ = distance(dx, dy, dz) * 0.5f; 3049de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 3059de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza sphere.commitChanges(); 3069de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza} 3079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 3089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stozastatic void normalizePlane(float* p) { 3099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza float rdist = 1.0f / distance(p[0], p[1], p[2]); 3109de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza for(int i = 0; i < 4; i++) { 3119de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza p[i] *= rdist; 3129de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 313812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 314812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 315812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stozastatic inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) { 316812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return x0 * x1 + y0 * y1 + z0 * z1; 317812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 318812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 319812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stozastatic inline float signedDistance(const float* pPlane, float x, float y, float z) { 320812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3]; 321812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 322812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 323812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza// Return true if the sphere intersects or is inside the frustum 324c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza 325c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stozastatic bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) { 326c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza float x = pSphere[0]; 327c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza float y = pSphere[1]; 328c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza float z = pSphere[2]; 329c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza float negRadius = -pSphere[3]; 330c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza for (int i = 0; i < 6; i++, pFrustum += 4) { 331c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza if (signedDistance(pFrustum, x, y, z) <= negRadius) { 332c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza return false; 333c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza } 334c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza } 3357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza return true; 3367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza} 3377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 3387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozastatic void computeFrustum(const float* m, float* f) { 3397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza float m3 = m[3]; 3407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza float m7 = m[7]; 3417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza float m11 = m[11]; 3427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza float m15 = m[15]; 3437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // right 3447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza f[0] = m3 - m[0]; 3457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza f[1] = m7 - m[4]; 3467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza f[2] = m11 - m[8]; 347ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos f[3] = m15 - m[12]; 3483559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos normalizePlane(f); 349ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos f+= 4; 350ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 351ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // left 3523559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos f[0] = m3 + m[0]; 3533559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos f[1] = m7 + m[4]; 354ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos f[2] = m11 + m[8]; 355ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos f[3] = m15 + m[12]; 356ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos normalizePlane(f); 357ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos f+= 4; 358ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 359ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // top 360127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f[0] = m3 - m[1]; 361ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[1] = m7 - m[5]; 362ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[2] = m11 - m[9]; 363ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[3] = m15 - m[13]; 364ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos normalizePlane(f); 365ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f+= 4; 366ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos 367ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos // bottom 368ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[0] = m3 + m[1]; 369ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[1] = m7 + m[5]; 370ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[2] = m11 + m[9]; 371ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos f[3] = m15 + m[13]; 372ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos normalizePlane(f); 373127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f+= 4; 374127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza 375127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza // far 376127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f[0] = m3 - m[2]; 377127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f[1] = m7 - m[6]; 378127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f[2] = m11 - m[10]; 379127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f[3] = m15 - m[14]; 380127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza normalizePlane(f); 381127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza f+= 4; 382127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza 383127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza // near 38450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza f[0] = m3 + m[2]; 38550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza f[1] = m7 + m[6]; 3861a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck f[2] = m11 + m[10]; 38750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza f[3] = m15 + m[14]; 38850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza normalizePlane(f); 38950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza} 39050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 39150101d02a8eae555887282a5f761fdec57bdaf30Dan Stozastatic 39250101d02a8eae555887282a5f761fdec57bdaf30Dan Stozaint util_frustumCullSpheres(JNIEnv *env, jclass clazz, 39350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza jfloatArray mvp_ref, jint mvpOffset, 39450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza jfloatArray spheres_ref, jint spheresOffset, jint spheresCount, 39550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza jintArray results_ref, jint resultsOffset, jint resultsCapacity) { 39650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza float frustum[6*4]; 39750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza int outputCount; 39850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza int* pResults; 399ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck float* pSphere; 400ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16); 401ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4); 402ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity); 403ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck 4041a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck bool initializedOK = mvp.check() && spheres.check() && results.check(); 4051a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (! initializedOK) { 4061a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck return -1; 407ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck } 40850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 40950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza mvp.bind(); 41050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza spheres.bind(); 41150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza results.bind(); 41250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 41350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza computeFrustum(mvp.mData, frustum); 41450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 41550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza // Cull the spheres 41650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 41750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza pSphere = spheres.mData; 41850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza pResults = results.mData; 41950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza outputCount = 0; 42050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza for(int i = 0; i < spheresCount; i++, pSphere += 4) { 42150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza if (sphereHitsFrustum(frustum, pSphere)) { 422eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos if (outputCount < resultsCapacity) { 423eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos *pResults++ = i; 424eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } 425eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos outputCount++; 426eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } 427eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } 428eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos results.commitChanges(); 429eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos return outputCount; 430eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos} 431eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos 432eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos/* 433eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos public native int visibilityTest(float[] ws, int wsOffset, 434eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos float[] positions, int positionsOffset, 435eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos char[] indices, int indicesOffset, int indexCount); 436eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos */ 437eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos 438eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballosstatic 439eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballosint util_visibilityTest(JNIEnv *env, jclass clazz, 440eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos jfloatArray ws_ref, jint wsOffset, 4418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jfloatArray positions_ref, jint positionsOffset, 4428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jcharArray indices_ref, jint indicesOffset, jint indexCount) { 4433be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 4443be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza FloatArrayHelper ws(env, ws_ref, wsOffset, 16); 4453be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza FloatArrayHelper positions(env, positions_ref, positionsOffset, 0); 4463be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0); 447466a192d2088f9238d34597d1aa28da41367c1caAndy McFadden 4488ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis bool checkOK = ws.check() && positions.check() && indices.check(); 4498ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (! checkOK) { 4508ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis // Return value will be ignored, because an exception has been thrown. 4512adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden return -1; 4528ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 4538ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4548ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (indices.mLength < indexCount) { 4558ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis doThrowIAE(env, "length < offset + indexCount"); 4562adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden return -1; 4578ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 4587b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 4597b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis ws.bind(); 4608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis positions.bind(); 4618ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis indices.bind(); 4628ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4638ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return visibilityTest(ws.mData, 4647b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis positions.mData, positions.mLength, 4658ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis indices.mData, indexCount); 4663be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza} 467fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 468fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos#define I(_i, _j) ((_j)+ 4*(_i)) 469fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 470fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosstatic 471fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosvoid multiplyMM(float* r, const float* lhs, const float* rhs) 472fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos{ 473fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos for (int i=0 ; i<4 ; i++) { 474fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register const float rhs_i0 = rhs[ I(i,0) ]; 475fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register float ri0 = lhs[ I(0,0) ] * rhs_i0; 476fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register float ri1 = lhs[ I(0,1) ] * rhs_i0; 477fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register float ri2 = lhs[ I(0,2) ] * rhs_i0; 478fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register float ri3 = lhs[ I(0,3) ] * rhs_i0; 479fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos for (int j=1 ; j<4 ; j++) { 480fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos register const float rhs_ij = rhs[ I(i,j) ]; 4818ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis ri0 += lhs[ I(j,0) ] * rhs_ij; 4822adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ri1 += lhs[ I(j,1) ] * rhs_ij; 4833be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza ri2 += lhs[ I(j,2) ] * rhs_ij; 4843be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza ri3 += lhs[ I(j,3) ] * rhs_ij; 4853be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza } 4863be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza r[ I(i,0) ] = ri0; 48712ba0f57d028a9c8f4eb3afddc326b70677d1e0cNaveen Leekha r[ I(i,1) ] = ri1; 488f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall r[ I(i,2) ] = ri2; 489567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos r[ I(i,3) ] = ri3; 490567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos } 4918ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 4921df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 4931df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennisstatic 494ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopianvoid util_multiplyMM(JNIEnv *env, jclass clazz, 495f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall jfloatArray result_ref, jint resultOffset, 4968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jfloatArray lhs_ref, jint lhsOffset, 4979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza jfloatArray rhs_ref, jint rhsOffset) { 4983be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 4999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza FloatArrayHelper resultMat(env, result_ref, resultOffset, 16); 5009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 5019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16); 5029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool checkOK = resultMat.check() && lhs.check() && rhs.check(); 5049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5053be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza if ( !checkOK ) { 506d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return; 507d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 508d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 509d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza resultMat.bind(); 510d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza lhs.bind(); 511d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza rhs.bind(); 512d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 513d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza multiplyMM(resultMat.mData, lhs.mData, rhs.mData); 514d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 515d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza resultMat.commitChanges(); 516d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 517d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 518d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozastatic 519d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozavoid multiplyMV(float* r, const float* lhs, const float* rhs) 520d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza{ 521d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r); 522d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 5233be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 5249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatic 5259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozavoid util_multiplyMV(JNIEnv *env, jclass clazz, 5269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza jfloatArray result_ref, jint resultOffset, 5279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza jfloatArray lhs_ref, jint lhsOffset, 52812ba0f57d028a9c8f4eb3afddc326b70677d1e0cNaveen Leekha jfloatArray rhs_ref, jint rhsOffset) { 5299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza FloatArrayHelper resultV(env, result_ref, resultOffset, 4); 5319f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16); 5328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4); 5333be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 5348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis bool checkOK = resultV.check() && lhs.check() && rhs.check(); 5352adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden 5368ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if ( !checkOK ) { 537c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall return; 538f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian } 539f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian 540f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian resultV.bind(); 541d06421fd37fbb7fd07002e6738fac3a223cb1a62Robert Shih lhs.bind(); 542c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall rhs.bind(); 5438ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 5448ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis multiplyMV(resultV.mData, lhs.mData, rhs.mData); 5453be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza 5468ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis resultV.commitChanges(); 5472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden} 5488ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 5491df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis// --------------------------------------------------------------------------- 5501df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 551583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballosstatic jfieldID nativeBitmapID = 0; 552583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 5538ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisvoid nativeUtilsClassInit(JNIEnv *env, jclass clazz) 5543be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza{ 555eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian jclass bitmapClass = env->FindClass("android/graphics/Bitmap"); 5562adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden nativeBitmapID = env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); 55712ba0f57d028a9c8f4eb3afddc326b70677d1e0cNaveen Leekha} 558eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian 559eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianextern void setGLDebugLevel(int level); 560eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianvoid setTracingLevel(JNIEnv *env, jclass clazz, jint level) 561eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian{ 562eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian setGLDebugLevel(level); 5633be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza} 564fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis 5652adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatic int checkFormat(SkBitmap::Config config, int format, int type) 566f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza{ 567f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza switch(config) { 568f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza case SkBitmap::kIndex8_Config: 569f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (format == GL_PALETTE8_RGBA8_OES) 570fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis return 0; 571595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian case SkBitmap::kARGB_8888_Config: 57224202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopian case SkBitmap::kA8_Config: 57324202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopian if (type == GL_UNSIGNED_BYTE) 57424202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopian return 0; 57593c617fd2a5e7910e0ba5c0ed6da152d30920679Pablo Ceballos case SkBitmap::kARGB_4444_Config: 576f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza case SkBitmap::kRGB_565_Config: 577fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis switch (type) { 578fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case GL_UNSIGNED_SHORT_4_4_4_4: 5793be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza case GL_UNSIGNED_SHORT_5_6_5: 580fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case GL_UNSIGNED_SHORT_5_5_5_1: 5812adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden return 0; 582fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case GL_UNSIGNED_BYTE: 5832773004a83624ed41cf3f94f2b11878cd8521812Mathias Agopian if (format == GL_LUMINANCE_ALPHA) 584fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis return 0; 585fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 5863be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza break; 587399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall default: 588399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall break; 589399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 590399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return -1; 5910ec54e156bed93d59900b742c8e9adcfaee90612Wonsik Kim} 592399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 593399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatic int getInternalFormat(SkBitmap::Config config) 594399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall{ 595399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall switch(config) { 5963be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza case SkBitmap::kA8_Config: 5979de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return GL_ALPHA; 59829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza case SkBitmap::kARGB_4444_Config: 5993be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza return GL_RGBA; 6003be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza case SkBitmap::kARGB_8888_Config: 6013be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza return GL_RGBA; 6023be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza case SkBitmap::kIndex8_Config: 603567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos return GL_PALETTE8_RGBA8_OES; 60429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza case SkBitmap::kRGB_565_Config: 6059de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return GL_RGB; 6069de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza default: 6079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return -1; 6089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 6099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza} 6109de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 6119de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stozastatic int getType(SkBitmap::Config config) 6129de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza{ 613812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza switch(config) { 614812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza case SkBitmap::kA8_Config: 615812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return GL_UNSIGNED_BYTE; 616812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza case SkBitmap::kARGB_4444_Config: 617812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return GL_UNSIGNED_SHORT_4_4_4_4; 618812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza case SkBitmap::kARGB_8888_Config: 619812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return GL_UNSIGNED_BYTE; 620c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza case SkBitmap::kIndex8_Config: 621c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza return -1; // No type for compressed data. 622c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza case SkBitmap::kRGB_565_Config: 623c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza return GL_UNSIGNED_SHORT_5_6_5; 624c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza default: 6257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza return -1; 6267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 6277dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza} 6287dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 6297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozastatic jint util_getInternalFormat(JNIEnv *env, jclass clazz, 6307dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza jobject jbitmap) 6313559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos{ 632ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos SkBitmap const * nativeBitmap = 6333559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 6343559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos const SkBitmap& bitmap(*nativeBitmap); 635ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos SkBitmap::Config config = bitmap.getConfig(); 636ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return getInternalFormat(config); 637ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos} 638ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos 639ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballosstatic jint util_getType(JNIEnv *env, jclass clazz, 640ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos jobject jbitmap) 641ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos{ 642ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos SkBitmap const * nativeBitmap = 643ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 644ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos const SkBitmap& bitmap(*nativeBitmap); 645127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza SkBitmap::Config config = bitmap.getConfig(); 646127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza return getType(config); 647127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza} 648127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza 649127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stozastatic jint util_texImage2D(JNIEnv *env, jclass clazz, 650127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza jint target, jint level, jint internalformat, 651127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza jobject jbitmap, jint type, jint border) 65250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza{ 65350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza SkBitmap const * nativeBitmap = 65450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 65550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza const SkBitmap& bitmap(*nativeBitmap); 6561a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck SkBitmap::Config config = bitmap.getConfig(); 6571a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (internalformat < 0) { 65850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza internalformat = getInternalFormat(config); 65950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza } 66050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza if (type < 0) { 66150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza type = getType(config); 662ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck } 663ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck int err = checkFormat(config, internalformat, type); 664ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck if (err) 665ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck return err; 666ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck bitmap.lockPixels(); 6671a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck const int w = bitmap.width(); 6681a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck const int h = bitmap.height(); 6691a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck const void* p = bitmap.getPixels(); 670ce8e5df3c11616f3eb7867ce89558b530651166cJohn Reck if (internalformat == GL_PALETTE8_RGBA8_OES) { 67150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza if (sizeof(SkPMColor) != sizeof(uint32_t)) { 67250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza err = -1; 67350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza goto error; 67450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza } 67550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza const size_t size = bitmap.getSize(); 67650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza const size_t palette_size = 256*sizeof(SkPMColor); 67750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza const size_t imageSize = size + palette_size; 67850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza void* const data = malloc(imageSize); 67950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza if (data) { 68050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza void* const pixels = (char*)data + palette_size; 68150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza SkColorTable* ctable = bitmap.getColorTable(); 682eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor)); 683eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos memcpy(pixels, p, size); 684eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos ctable->unlockColors(); 685eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data); 686eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos free(data); 687eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } else { 688eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos err = -1; 689eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } 690eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } else { 691eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p); 692eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos } 693eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballoserror: 694eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos bitmap.unlockPixels(); 695eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos return err; 6968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 6978ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 6988ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatic jint util_texSubImage2D(JNIEnv *env, jclass clazz, 6998ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jint target, jint level, jint xoffset, jint yoffset, 7008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis jobject jbitmap, jint format, jint type) 7018ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis{ 7022adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden SkBitmap const * nativeBitmap = 703c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID); 704c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall const SkBitmap& bitmap(*nativeBitmap); 705c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall SkBitmap::Config config = bitmap.getConfig(); 706e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (format < 0) { 707c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall format = getInternalFormat(config); 7083c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden if (format == GL_PALETTE8_RGBA8_OES) 70982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala return -1; // glCompressedTexSubImage2D() not supported 710c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall } 711c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall int err = checkFormat(config, format, type); 712c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall if (err) 7131681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk return err; 7145065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza bitmap.lockPixels(); 7155065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza const int w = bitmap.width(); 716c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall const int h = bitmap.height(); 717c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall const void* p = bitmap.getPixels(); 718e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p); 7191df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis bitmap.unlockPixels(); 720c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall return 0; 721c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall} 722e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 723e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian/* 724c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall * ETC1 methods. 725e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian */ 726e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 727e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatic jclass nioAccessClass; 728e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatic jclass bufferClass; 7293c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFaddenstatic jmethodID getBasePointerID; 73082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvalastatic jmethodID getBaseArrayID; 731e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatic jmethodID getBaseArrayOffsetID; 732e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatic jfieldID positionID; 733e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatic jfieldID limitID; 7341681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkstatic jfieldID elementSizeShiftID; 7355065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza 7365065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza/* Cache method IDs each time the class is loaded. */ 7375065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza 7385065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stozastatic void 7395065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan StozanativeClassInitBuffer(JNIEnv *_env) 740c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall{ 741c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess"); 742e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal); 743e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 744c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall jclass bufferClassLocal = _env->FindClass("java/nio/Buffer"); 745e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal); 746e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 7473c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden getBasePointerID = _env->GetStaticMethodID(nioAccessClass, 74882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala "getBasePointer", "(Ljava/nio/Buffer;)J"); 749e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian getBaseArrayID = _env->GetStaticMethodID(nioAccessClass, 750e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;"); 751e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass, 752567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "getBaseArrayOffset", "(Ljava/nio/Buffer;)I"); 753e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian positionID = _env->GetFieldID(bufferClass, "position", "I"); 754e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian limitID = _env->GetFieldID(bufferClass, "limit", "I"); 755e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian elementSizeShiftID = 756e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian _env->GetFieldID(bufferClass, "_elementSizeShift", "I"); 757e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian} 758e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 7593c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFaddenstatic void * 76082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville TalvalagetPointer(JNIEnv *_env, jobject buffer, jint *remaining) 761e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian{ 762e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian jint position; 763e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian jint limit; 7641681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk jint elementSizeShift; 765e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian jlong pointer; 7661df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis jint offset; 7675065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza void *data; 7685065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza 7695065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza position = _env->GetIntField(buffer, positionID); 7705065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza limit = _env->GetIntField(buffer, limitID); 7715065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID); 772c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall *remaining = (limit - position) << elementSizeShift; 773c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall pointer = _env->CallStaticLongMethod(nioAccessClass, 7748ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis getBasePointerID, buffer); 775 if (pointer != 0L) { 776 return (void *) (jint) pointer; 777 } 778 return NULL; 779} 780 781class BufferHelper { 782public: 783 BufferHelper(JNIEnv *env, jobject buffer) { 784 mEnv = env; 785 mBuffer = buffer; 786 mData = NULL; 787 mRemaining = 0; 788 } 789 790 bool checkPointer(const char* errorMessage) { 791 if (mBuffer) { 792 mData = getPointer(mEnv, mBuffer, &mRemaining); 793 if (mData == NULL) { 794 doThrowIAE(mEnv, errorMessage); 795 } 796 return mData != NULL; 797 } else { 798 doThrowIAE(mEnv, errorMessage); 799 return false; 800 } 801 } 802 803 inline void* getData() { 804 return mData; 805 } 806 807 inline jint remaining() { 808 return mRemaining; 809 } 810 811private: 812 JNIEnv* mEnv; 813 jobject mBuffer; 814 void* mData; 815 jint mRemaining; 816}; 817 818/** 819 * Encode a block of pixels. 820 * 821 * @param in a pointer to a ETC1_DECODED_BLOCK_SIZE array of bytes that represent a 822 * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R 823 * value of pixel (x, y). 824 * 825 * @param validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether 826 * the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing. 827 * 828 * @param out an ETC1 compressed version of the data. 829 * 830 */ 831static void etc1_encodeBlock(JNIEnv *env, jclass clazz, 832 jobject in, jint validPixelMask, jobject out) { 833 if (validPixelMask < 0 || validPixelMask > 15) { 834 doThrowIAE(env, "validPixelMask"); 835 return; 836 } 837 BufferHelper inB(env, in); 838 BufferHelper outB(env, out); 839 if (inB.checkPointer("in") && outB.checkPointer("out")) { 840 if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) { 841 doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE"); 842 } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) { 843 doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE"); 844 } else { 845 etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask, 846 (etc1_byte*) outB.getData()); 847 } 848 } 849} 850 851/** 852 * Decode a block of pixels. 853 * 854 * @param in an ETC1 compressed version of the data. 855 * 856 * @param out a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a 857 * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R 858 * value of pixel (x, y). 859 */ 860static void etc1_decodeBlock(JNIEnv *env, jclass clazz, 861 jobject in, jobject out){ 862 BufferHelper inB(env, in); 863 BufferHelper outB(env, out); 864 if (inB.checkPointer("in") && outB.checkPointer("out")) { 865 if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) { 866 doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE"); 867 } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) { 868 doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE"); 869 } else { 870 etc1_decode_block((etc1_byte*) inB.getData(), 871 (etc1_byte*) outB.getData()); 872 } 873 } 874} 875 876/** 877 * Return the size of the encoded image data (does not include size of PKM header). 878 */ 879static jint etc1_getEncodedDataSize(JNIEnv *env, jclass clazz, 880 jint width, jint height) { 881 return etc1_get_encoded_data_size(width, height); 882} 883 884/** 885 * Encode an entire image. 886 * @param in pointer to the image data. Formatted such that 887 * pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset; 888 * @param out pointer to encoded data. Must be large enough to store entire encoded image. 889 */ 890static void etc1_encodeImage(JNIEnv *env, jclass clazz, 891 jobject in, jint width, jint height, 892 jint pixelSize, jint stride, jobject out) { 893 if (pixelSize < 2 || pixelSize > 3) { 894 doThrowIAE(env, "pixelSize must be 2 or 3"); 895 return; 896 } 897 BufferHelper inB(env, in); 898 BufferHelper outB(env, out); 899 if (inB.checkPointer("in") && outB.checkPointer("out")) { 900 jint imageSize = stride * height; 901 jint encodedImageSize = etc1_get_encoded_data_size(width, height); 902 if (inB.remaining() < imageSize) { 903 doThrowIAE(env, "in's remaining data < image size"); 904 } else if (outB.remaining() < encodedImageSize) { 905 doThrowIAE(env, "out's remaining data < encoded image size"); 906 } else { 907 int result = etc1_encode_image((etc1_byte*) inB.getData(), 908 width, height, pixelSize, 909 stride, 910 (etc1_byte*) outB.getData()); 911 } 912 } 913} 914 915/** 916 * Decode an entire image. 917 * @param in the encoded data. 918 * @param out pointer to the image data. Will be written such that 919 * pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be 920 * large enough to store entire image. 921 */ 922static void etc1_decodeImage(JNIEnv *env, jclass clazz, 923 jobject in, jobject out, 924 jint width, jint height, 925 jint pixelSize, jint stride) { 926 if (pixelSize < 2 || pixelSize > 3) { 927 doThrowIAE(env, "pixelSize must be 2 or 3"); 928 return; 929 } 930 BufferHelper inB(env, in); 931 BufferHelper outB(env, out); 932 if (inB.checkPointer("in") && outB.checkPointer("out")) { 933 jint imageSize = stride * height; 934 jint encodedImageSize = etc1_get_encoded_data_size(width, height); 935 if (inB.remaining() < encodedImageSize) { 936 doThrowIAE(env, "in's remaining data < encoded image size"); 937 } else if (outB.remaining() < imageSize) { 938 doThrowIAE(env, "out's remaining data < image size"); 939 } else { 940 int result = etc1_decode_image((etc1_byte*) inB.getData(), 941 (etc1_byte*) outB.getData(), 942 width, height, pixelSize, 943 stride); 944 } 945 } 946} 947 948/** 949 * Format a PKM header 950 */ 951static void etc1_formatHeader(JNIEnv *env, jclass clazz, 952 jobject header, jint width, jint height) { 953 BufferHelper headerB(env, header); 954 if (headerB.checkPointer("header") ){ 955 if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 956 doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 957 } else { 958 etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height); 959 } 960 } 961} 962 963/** 964 * Check if a PKM header is correctly formatted. 965 */ 966static jboolean etc1_isValid(JNIEnv *env, jclass clazz, 967 jobject header) { 968 jboolean result = false; 969 BufferHelper headerB(env, header); 970 if (headerB.checkPointer("header") ){ 971 if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 972 doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 973 } else { 974 result = etc1_pkm_is_valid((etc1_byte*) headerB.getData()); 975 } 976 } 977 return result; 978} 979 980/** 981 * Read the image width from a PKM header 982 */ 983static jint etc1_getWidth(JNIEnv *env, jclass clazz, 984 jobject header) { 985 jint result = 0; 986 BufferHelper headerB(env, header); 987 if (headerB.checkPointer("header") ){ 988 if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 989 doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 990 } else { 991 result = etc1_pkm_get_width((etc1_byte*) headerB.getData()); 992 } 993 } 994 return result; 995} 996 997/** 998 * Read the image height from a PKM header 999 */ 1000static int etc1_getHeight(JNIEnv *env, jclass clazz, 1001 jobject header) { 1002 jint result = 0; 1003 BufferHelper headerB(env, header); 1004 if (headerB.checkPointer("header") ){ 1005 if (headerB.remaining() < ETC_PKM_HEADER_SIZE) { 1006 doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE"); 1007 } else { 1008 result = etc1_pkm_get_height((etc1_byte*) headerB.getData()); 1009 } 1010 } 1011 return result; 1012} 1013 1014/* 1015 * JNI registration 1016 */ 1017 1018static JNINativeMethod gMatrixMethods[] = { 1019 { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM }, 1020 { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV }, 1021}; 1022 1023static JNINativeMethod gVisibilityMethods[] = { 1024 { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere }, 1025 { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres }, 1026 { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest }, 1027}; 1028 1029static JNINativeMethod gUtilsMethods[] = { 1030 {"nativeClassInit", "()V", (void*)nativeUtilsClassInit }, 1031 { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat }, 1032 { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType }, 1033 { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D }, 1034 { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D }, 1035 { "setTracingLevel", "(I)V", (void*)setTracingLevel }, 1036}; 1037 1038static JNINativeMethod gEtc1Methods[] = { 1039 { "encodeBlock", "(Ljava/nio/Buffer;ILjava/nio/Buffer;)V", (void*) etc1_encodeBlock }, 1040 { "decodeBlock", "(Ljava/nio/Buffer;Ljava/nio/Buffer;)V", (void*) etc1_decodeBlock }, 1041 { "getEncodedDataSize", "(II)I", (void*) etc1_getEncodedDataSize }, 1042 { "encodeImage", "(Ljava/nio/Buffer;IIIILjava/nio/Buffer;)V", (void*) etc1_encodeImage }, 1043 { "decodeImage", "(Ljava/nio/Buffer;Ljava/nio/Buffer;IIII)V", (void*) etc1_decodeImage }, 1044 { "formatHeader", "(Ljava/nio/Buffer;II)V", (void*) etc1_formatHeader }, 1045 { "isValid", "(Ljava/nio/Buffer;)Z", (void*) etc1_isValid }, 1046 { "getWidth", "(Ljava/nio/Buffer;)I", (void*) etc1_getWidth }, 1047 { "getHeight", "(Ljava/nio/Buffer;)I", (void*) etc1_getHeight }, 1048}; 1049 1050typedef struct _ClassRegistrationInfo { 1051 const char* classPath; 1052 JNINativeMethod* methods; 1053 size_t methodCount; 1054} ClassRegistrationInfo; 1055 1056static ClassRegistrationInfo gClasses[] = { 1057 {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)}, 1058 {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)}, 1059 {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)}, 1060 {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)}, 1061}; 1062 1063int register_android_opengl_classes(JNIEnv* env) 1064{ 1065 nativeClassInitBuffer(env); 1066 int result = 0; 1067 for (int i = 0; i < NELEM(gClasses); i++) { 1068 ClassRegistrationInfo* cri = &gClasses[i]; 1069 result = AndroidRuntime::registerNativeMethods(env, 1070 cri->classPath, cri->methods, cri->methodCount); 1071 if (result < 0) { 1072 ALOGE("Failed to register %s: %d", cri->classPath, result); 1073 break; 1074 } 1075 } 1076 return result; 1077} 1078 1079} // namespace android 1080