GLCHeader.cpp revision c96812cb27ca2fbfe4456c8297e2c77d23d790f1
1**
2** Copyright 2006, The Android Open Source Project
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8**     http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
14** limitations under the License.
15*/
16
17// This source file is automatically generated
18
19#include <android_runtime/AndroidRuntime.h>
20#include <utils/misc.h>
21
22#include <assert.h>
23#include <GLES/gl.h>
24#include <GLES/glext.h>
25
26/* special calls implemented in Android's GLES wrapper used to more
27 * efficiently bound-check passed arrays */
28extern "C" {
29GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
30        const GLvoid *ptr, GLsizei count);
31GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
32        const GLvoid *pointer, GLsizei count);
33GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
34        GLsizei stride, const GLvoid *pointer, GLsizei count);
35GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
36        GLsizei stride, const GLvoid *pointer, GLsizei count);
37}
38
39static int initialized = 0;
40
41static jclass nioAccessClass;
42static jclass bufferClass;
43static jclass OOMEClass;
44static jclass UOEClass;
45static jclass IAEClass;
46static jclass AIOOBEClass;
47static jclass G11ImplClass;
48static jmethodID getBasePointerID;
49static jmethodID getBaseArrayID;
50static jmethodID getBaseArrayOffsetID;
51static jmethodID allowIndirectBuffersID;
52static jfieldID positionID;
53static jfieldID limitID;
54static jfieldID elementSizeShiftID;
55
56/* Cache method IDs each time the class is loaded. */
57
58static void
59nativeClassInitBuffer(JNIEnv *_env)
60{
61    jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
62    nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
63
64    jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
65    bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
66
67    jclass g11impClassLocal = _env->FindClass("com/google/android/gles_jni/GLImpl");
68    G11ImplClass = (jclass) _env->NewGlobalRef(g11impClassLocal);
69
70    getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
71            "getBasePointer", "(Ljava/nio/Buffer;)J");
72    getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
73            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
74    getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
75            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
76    allowIndirectBuffersID = _env->GetStaticMethodID(g11impClassLocal,
77            "allowIndirectBuffers", "(Ljava/lang/String;)Z");
78    positionID = _env->GetFieldID(bufferClass, "position", "I");
79    limitID = _env->GetFieldID(bufferClass, "limit", "I");
80    elementSizeShiftID =
81        _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
82}
83
84static void
85nativeClassInit(JNIEnv *_env, jclass glImplClass)
86{
87    nativeClassInitBuffer(_env);
88
89    jclass IAEClassLocal =
90        _env->FindClass("java/lang/IllegalArgumentException");
91    jclass OOMEClassLocal =
92         _env->FindClass("java/lang/OutOfMemoryError");
93    jclass UOEClassLocal =
94         _env->FindClass("java/lang/UnsupportedOperationException");
95    jclass AIOOBEClassLocal =
96         _env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
97
98    IAEClass = (jclass) _env->NewGlobalRef(IAEClassLocal);
99    OOMEClass = (jclass) _env->NewGlobalRef(OOMEClassLocal);
100    UOEClass = (jclass) _env->NewGlobalRef(UOEClassLocal);
101    AIOOBEClass = (jclass) _env->NewGlobalRef(AIOOBEClassLocal);
102}
103
104static void *
105getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
106{
107    jint position;
108    jint limit;
109    jint elementSizeShift;
110    jlong pointer;
111    jint offset;
112    void *data;
113
114    position = _env->GetIntField(buffer, positionID);
115    limit = _env->GetIntField(buffer, limitID);
116    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
117    *remaining = (limit - position) << elementSizeShift;
118    pointer = _env->CallStaticLongMethod(nioAccessClass,
119            getBasePointerID, buffer);
120    if (pointer != 0L) {
121        *array = NULL;
122        return (void *) (jint) pointer;
123    }
124
125    *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
126            getBaseArrayID, buffer);
127    if (*array == NULL) {
128        return (void*) NULL;
129    }
130    offset = _env->CallStaticIntMethod(nioAccessClass,
131            getBaseArrayOffsetID, buffer);
132    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
133
134    return (void *) ((char *) data + offset);
135}
136
137static void
138releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
139{
140    _env->ReleasePrimitiveArrayCritical(array, data,
141					   commit ? 0 : JNI_ABORT);
142}
143
144extern "C" {
145extern char*  __progname;
146}
147
148static bool
149allowIndirectBuffers(JNIEnv *_env) {
150    static jint sIndirectBufferCompatability;
151    if (sIndirectBufferCompatability == 0) {
152        jobject appName = _env->NewStringUTF(::__progname);
153        sIndirectBufferCompatability = _env->CallStaticBooleanMethod(G11ImplClass, allowIndirectBuffersID, appName) ? 2 : 1;
154    }
155    return sIndirectBufferCompatability == 2;
156}
157
158static void *
159getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
160    if (!buffer) {
161        return NULL;
162    }
163    void* buf = _env->GetDirectBufferAddress(buffer);
164    if (buf) {
165        jint position = _env->GetIntField(buffer, positionID);
166        jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
167        buf = ((char*) buf) + (position << elementSizeShift);
168    } else {
169        if (allowIndirectBuffers(_env)) {
170            jarray array = 0;
171            jint remaining;
172            buf = getPointer(_env, buffer, &array, &remaining);
173            if (array) {
174                releasePointer(_env, array, buf, 0);
175            }
176        } else {
177            _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
178        }
179    }
180    return buf;
181}
182
183static int
184getNumCompressedTextureFormats() {
185    int numCompressedTextureFormats = 0;
186    glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedTextureFormats);
187    return numCompressedTextureFormats;
188}
189
190// --------------------------------------------------------------------------
191
192