• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2009, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 // This source file is automatically generated
19 
20 #include <GLES/gl.h>
21 #include <GLES/glext.h>
22 
23 #include "jni.h"
24 #include "JNIHelp.h"
25 #include <android_runtime/AndroidRuntime.h>
26 #include <utils/misc.h>
27 #include <assert.h>
28 
29 static int initialized = 0;
30 
31 static jclass nioAccessClass;
32 static jclass bufferClass;
33 static jmethodID getBasePointerID;
34 static jmethodID getBaseArrayID;
35 static jmethodID getBaseArrayOffsetID;
36 static jfieldID positionID;
37 static jfieldID limitID;
38 static jfieldID elementSizeShiftID;
39 
40 
41 /* special calls implemented in Android's GLES wrapper used to more
42  * efficiently bound-check passed arrays */
43 extern "C" {
44 #ifdef GL_VERSION_ES_CM_1_1
45 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
46         const GLvoid *ptr, GLsizei count);
47 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
48         const GLvoid *pointer, GLsizei count);
49 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
50         GLsizei stride, const GLvoid *pointer, GLsizei count);
51 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
52         GLsizei stride, const GLvoid *pointer, GLsizei count);
53 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
54         GLsizei stride, const GLvoid *pointer, GLsizei count);
55 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
56         GLsizei stride, const GLvoid *pointer, GLsizei count);
57 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
58         GLsizei stride, const GLvoid *pointer, GLsizei count);
59 #endif
60 #ifdef GL_ES_VERSION_2_0
glVertexAttribPointerBounds(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * pointer,GLsizei count)61 static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
62         GLboolean normalized, GLsizei stride, const GLvoid *pointer, GLsizei count) {
63     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
64 }
65 #endif
66 }
67 
68 /* Cache method IDs each time the class is loaded. */
69 
70 static void
nativeClassInit(JNIEnv * _env,jclass glImplClass)71 nativeClassInit(JNIEnv *_env, jclass glImplClass)
72 {
73     jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
74     nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
75 
76     jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
77     bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
78 
79     getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
80             "getBasePointer", "(Ljava/nio/Buffer;)J");
81     getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
82             "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
83     getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
84             "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
85 
86     positionID = _env->GetFieldID(bufferClass, "position", "I");
87     limitID = _env->GetFieldID(bufferClass, "limit", "I");
88     elementSizeShiftID =
89         _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
90 }
91 
92 static void *
getPointer(JNIEnv * _env,jobject buffer,jarray * array,jint * remaining,jint * offset)93 getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
94 {
95     jint position;
96     jint limit;
97     jint elementSizeShift;
98     jlong pointer;
99 
100     position = _env->GetIntField(buffer, positionID);
101     limit = _env->GetIntField(buffer, limitID);
102     elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
103     *remaining = (limit - position) << elementSizeShift;
104     pointer = _env->CallStaticLongMethod(nioAccessClass,
105             getBasePointerID, buffer);
106     if (pointer != 0L) {
107         *array = NULL;
108         return (void *) (jint) pointer;
109     }
110 
111     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
112             getBaseArrayID, buffer);
113     *offset = _env->CallStaticIntMethod(nioAccessClass,
114             getBaseArrayOffsetID, buffer);
115 
116     return NULL;
117 }
118 
119 static void
releasePointer(JNIEnv * _env,jarray array,void * data,jboolean commit)120 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
121 {
122     _env->ReleasePrimitiveArrayCritical(array, data,
123                        commit ? 0 : JNI_ABORT);
124 }
125 
126 static void *
getDirectBufferPointer(JNIEnv * _env,jobject buffer)127 getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
128     char* buf = (char*) _env->GetDirectBufferAddress(buffer);
129     if (buf) {
130         jint position = _env->GetIntField(buffer, positionID);
131         jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
132         buf += position << elementSizeShift;
133     } else {
134         jniThrowException(_env, "java/lang/IllegalArgumentException",
135                           "Must use a native order direct Buffer");
136     }
137     return (void*) buf;
138 }
139 
140 // --------------------------------------------------------------------------
141 
142 /*
143  * returns the number of values glGet returns for a given pname.
144  *
145  * The code below is written such that pnames requiring only one values
146  * are the default (and are not explicitely tested for). This makes the
147  * checking code much shorter/readable/efficient.
148  *
149  * This means that unknown pnames (e.g.: extensions) will default to 1. If
150  * that unknown pname needs more than 1 value, then the validation check
151  * is incomplete and the app may crash if it passed the wrong number params.
152  */
getNeededCount(GLint pname)153 static int getNeededCount(GLint pname) {
154     int needed = 1;
155 #ifdef GL_ES_VERSION_2_0
156     // GLES 2.x pnames
157     switch (pname) {
158         case GL_ALIASED_LINE_WIDTH_RANGE:
159         case GL_ALIASED_POINT_SIZE_RANGE:
160             needed = 2;
161             break;
162 
163         case GL_BLEND_COLOR:
164         case GL_COLOR_CLEAR_VALUE:
165         case GL_COLOR_WRITEMASK:
166         case GL_SCISSOR_BOX:
167         case GL_VIEWPORT:
168             needed = 4;
169             break;
170 
171         case GL_COMPRESSED_TEXTURE_FORMATS:
172             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
173             break;
174 
175         case GL_SHADER_BINARY_FORMATS:
176             glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &needed);
177             break;
178     }
179 #endif
180 
181 #ifdef GL_VERSION_ES_CM_1_1
182     // GLES 1.x pnames
183     switch (pname) {
184         case GL_ALIASED_LINE_WIDTH_RANGE:
185         case GL_ALIASED_POINT_SIZE_RANGE:
186         case GL_DEPTH_RANGE:
187         case GL_SMOOTH_LINE_WIDTH_RANGE:
188         case GL_SMOOTH_POINT_SIZE_RANGE:
189             needed = 2;
190             break;
191 
192         case GL_CURRENT_NORMAL:
193         case GL_POINT_DISTANCE_ATTENUATION:
194             needed = 3;
195             break;
196 
197         case GL_COLOR_CLEAR_VALUE:
198         case GL_COLOR_WRITEMASK:
199         case GL_CURRENT_COLOR:
200         case GL_CURRENT_TEXTURE_COORDS:
201         case GL_FOG_COLOR:
202         case GL_LIGHT_MODEL_AMBIENT:
203         case GL_SCISSOR_BOX:
204         case GL_VIEWPORT:
205             needed = 4;
206             break;
207 
208         case GL_MODELVIEW_MATRIX:
209         case GL_PROJECTION_MATRIX:
210         case GL_TEXTURE_MATRIX:
211             needed = 16;
212             break;
213 
214         case GL_COMPRESSED_TEXTURE_FORMATS:
215             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
216             break;
217     }
218 #endif
219     return needed;
220 }
221 
222 template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
223 static void
get(JNIEnv * _env,jobject _this,jint pname,JTYPEARRAY params_ref,jint offset)224 get
225   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
226     jint _exception = 0;
227     const char * _exceptionType;
228     const char * _exceptionMessage;
229     CTYPE *params_base = (CTYPE *) 0;
230     jint _remaining;
231     CTYPE *params = (CTYPE *) 0;
232     int _needed = 0;
233 
234     if (!params_ref) {
235         _exception = 1;
236         _exceptionType = "java/lang/IllegalArgumentException";
237         _exceptionMessage = "params == null";
238         goto exit;
239     }
240     if (offset < 0) {
241         _exception = 1;
242         _exceptionType = "java/lang/IllegalArgumentException";
243         _exceptionMessage = "offset < 0";
244         goto exit;
245     }
246     _remaining = _env->GetArrayLength(params_ref) - offset;
247     _needed = getNeededCount(pname);
248     // if we didn't find this pname, we just assume the user passed
249     // an array of the right size -- this might happen with extensions
250     // or if we forget an enum here.
251     if (_remaining < _needed) {
252         _exception = 1;
253         _exceptionType = "java/lang/IllegalArgumentException";
254         _exceptionMessage = "length - offset < needed";
255         goto exit;
256     }
257     params_base = (CTYPE *)
258         _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
259     params = params_base + offset;
260 
261     GET(
262         (GLenum)pname,
263         (CTYPE *)params
264     );
265 
266 exit:
267     if (params_base) {
268         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
269             _exception ? JNI_ABORT: 0);
270     }
271     if (_exception) {
272         jniThrowException(_env, _exceptionType, _exceptionMessage);
273     }
274 }
275 
276 
277 template <typename CTYPE, void GET(GLenum, CTYPE*)>
278 static void
getarray(JNIEnv * _env,jobject _this,jint pname,jobject params_buf)279 getarray
280   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
281     jint _exception = 0;
282     const char * _exceptionType;
283     const char * _exceptionMessage;
284     jarray _array = (jarray) 0;
285     jint _bufferOffset = (jint) 0;
286     jint _remaining;
287     CTYPE *params = (CTYPE *) 0;
288     int _needed = 0;
289 
290     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
291     _needed = getNeededCount(pname);
292     // if we didn't find this pname, we just assume the user passed
293     // an array of the right size -- this might happen with extensions
294     // or if we forget an enum here.
295     if (_needed>0 && _remaining < _needed) {
296         _exception = 1;
297         _exceptionType = "java/lang/IllegalArgumentException";
298         _exceptionMessage = "remaining() < needed";
299         goto exit;
300     }
301     if (params == NULL) {
302         char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
303         params = (CTYPE *) (_paramsBase + _bufferOffset);
304     }
305     GET(
306         (GLenum)pname,
307         (CTYPE *)params
308     );
309 
310 exit:
311     if (_array) {
312         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
313     }
314     if (_exception) {
315         jniThrowException(_env, _exceptionType, _exceptionMessage);
316     }
317 }
318 
319 // --------------------------------------------------------------------------
320 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
321 static jint
android_glQueryMatrixxOES___3II_3II(JNIEnv * _env,jobject _this,jintArray mantissa_ref,jint mantissaOffset,jintArray exponent_ref,jint exponentOffset)322 android_glQueryMatrixxOES___3II_3II
323   (JNIEnv *_env, jobject _this, jintArray mantissa_ref, jint mantissaOffset, jintArray exponent_ref, jint exponentOffset) {
324     jint _exception = 0;
325     const char * _exceptionType = NULL;
326     const char * _exceptionMessage = NULL;
327     GLbitfield _returnValue = -1;
328     GLfixed *mantissa_base = (GLfixed *) 0;
329     jint _mantissaRemaining;
330     GLfixed *mantissa = (GLfixed *) 0;
331     GLint *exponent_base = (GLint *) 0;
332     jint _exponentRemaining;
333     GLint *exponent = (GLint *) 0;
334 
335     if (!mantissa_ref) {
336         _exception = 1;
337         _exceptionType = "java/lang/IllegalArgumentException";
338         _exceptionMessage = "mantissa == null";
339         goto exit;
340     }
341     if (mantissaOffset < 0) {
342         _exception = 1;
343         _exceptionType = "java/lang/IllegalArgumentException";
344         _exceptionMessage = "mantissaOffset < 0";
345         goto exit;
346     }
347     _mantissaRemaining = _env->GetArrayLength(mantissa_ref) - mantissaOffset;
348     if (_mantissaRemaining < 16) {
349         _exception = 1;
350         _exceptionType = "java/lang/IllegalArgumentException";
351         _exceptionMessage = "length - mantissaOffset < 16 < needed";
352         goto exit;
353     }
354     mantissa_base = (GLfixed *)
355         _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
356     mantissa = mantissa_base + mantissaOffset;
357 
358     if (!exponent_ref) {
359         _exception = 1;
360         _exceptionType = "java/lang/IllegalArgumentException";
361         _exceptionMessage = "exponent == null";
362         goto exit;
363     }
364     if (exponentOffset < 0) {
365         _exception = 1;
366         _exceptionType = "java/lang/IllegalArgumentException";
367         _exceptionMessage = "exponentOffset < 0";
368         goto exit;
369     }
370     _exponentRemaining = _env->GetArrayLength(exponent_ref) - exponentOffset;
371     if (_exponentRemaining < 16) {
372         _exception = 1;
373         _exceptionType = "java/lang/IllegalArgumentException";
374         _exceptionMessage = "length - exponentOffset < 16 < needed";
375         goto exit;
376     }
377     exponent_base = (GLint *)
378         _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
379     exponent = exponent_base + exponentOffset;
380 
381     _returnValue = glQueryMatrixxOES(
382         (GLfixed *)mantissa,
383         (GLint *)exponent
384     );
385 
386 exit:
387     if (exponent_base) {
388         _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
389             _exception ? JNI_ABORT: 0);
390     }
391     if (mantissa_base) {
392         _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
393             _exception ? JNI_ABORT: 0);
394     }
395     if (_exception) {
396         jniThrowException(_env, _exceptionType, _exceptionMessage);
397     }
398     return _returnValue;
399 }
400 
401 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
402 static jint
android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2(JNIEnv * _env,jobject _this,jobject mantissa_buf,jobject exponent_buf)403 android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
404   (JNIEnv *_env, jobject _this, jobject mantissa_buf, jobject exponent_buf) {
405     jint _exception = 0;
406     const char * _exceptionType = NULL;
407     const char * _exceptionMessage = NULL;
408     jarray _mantissaArray = (jarray) 0;
409     jint _mantissaBufferOffset = (jint) 0;
410     jarray _exponentArray = (jarray) 0;
411     jint _exponentBufferOffset = (jint) 0;
412     GLbitfield _returnValue = -1;
413     jint _mantissaRemaining;
414     GLfixed *mantissa = (GLfixed *) 0;
415     jint _exponentRemaining;
416     GLint *exponent = (GLint *) 0;
417 
418     mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
419     if (_mantissaRemaining < 16) {
420         _exception = 1;
421         _exceptionType = "java/lang/IllegalArgumentException";
422         _exceptionMessage = "remaining() < 16 < needed";
423         goto exit;
424     }
425     exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
426     if (_exponentRemaining < 16) {
427         _exception = 1;
428         _exceptionType = "java/lang/IllegalArgumentException";
429         _exceptionMessage = "remaining() < 16 < needed";
430         goto exit;
431     }
432     if (mantissa == NULL) {
433         char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
434         mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
435     }
436     if (exponent == NULL) {
437         char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
438         exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
439     }
440     _returnValue = glQueryMatrixxOES(
441         (GLfixed *)mantissa,
442         (GLint *)exponent
443     );
444 
445 exit:
446     if (_exponentArray) {
447         releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
448     }
449     if (_mantissaArray) {
450         releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
451     }
452     if (_exception) {
453         jniThrowException(_env, _exceptionType, _exceptionMessage);
454     }
455     return _returnValue;
456 }
457 
458 static const char *classPathName = "android/opengl/GLES10Ext";
459 
460 static JNINativeMethod methods[] = {
461 {"_nativeClassInit", "()V", (void*)nativeClassInit },
462 {"glQueryMatrixxOES", "([II[II)I", (void *) android_glQueryMatrixxOES___3II_3II },
463 {"glQueryMatrixxOES", "(Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;)I", (void *) android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2 },
464 };
465 
register_android_opengl_jni_GLES10Ext(JNIEnv * _env)466 int register_android_opengl_jni_GLES10Ext(JNIEnv *_env)
467 {
468     int err;
469     err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));
470     return err;
471 }
472