GLCHeader.cpp revision 9875750593aae7c2a62f33c620809d49162393eb
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 "jni.h"
20#include "JNIHelp.h"
21#include <android_runtime/AndroidRuntime.h>
22#include <utils/misc.h>
23
24#include <assert.h>
25#include <GLES/gl.h>
26#include <GLES/glext.h>
27
28// Work around differences between the generated name and the actual name.
29
30#define glBlendEquation glBlendEquationOES
31#define glBlendEquationSeparate glBlendEquationSeparateOES
32#define glBlendFuncSeparate glBlendFuncSeparateOES
33#define glGetTexGenfv glGetTexGenfvOES
34#define glGetTexGeniv glGetTexGenivOES
35#define glGetTexGenxv glGetTexGenxvOES
36#define glTexGenf glTexGenfOES
37#define glTexGenfv glTexGenfvOES
38#define glTexGeni glTexGeniOES
39#define glTexGeniv glTexGenivOES
40#define glTexGenx glTexGenxOES
41#define glTexGenxv glTexGenxvOES
42
43
44
45/* special calls implemented in Android's GLES wrapper used to more
46 * efficiently bound-check passed arrays */
47extern "C" {
48GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
49        const GLvoid *ptr, GLsizei count);
50GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
51        const GLvoid *pointer, GLsizei count);
52GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
53        GLsizei stride, const GLvoid *pointer, GLsizei count);
54GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
55        GLsizei stride, const GLvoid *pointer, GLsizei count);
56GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
57        GLsizei stride, const GLvoid *pointer, GLsizei count);
58GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
59        GLsizei stride, const GLvoid *pointer, GLsizei count);
60GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
61        GLsizei stride, const GLvoid *pointer, GLsizei count);
62}
63
64static int initialized = 0;
65
66static jclass nioAccessClass;
67static jclass bufferClass;
68static jclass G11ImplClass;
69static jmethodID getBasePointerID;
70static jmethodID getBaseArrayID;
71static jmethodID getBaseArrayOffsetID;
72static jmethodID allowIndirectBuffersID;
73static jfieldID positionID;
74static jfieldID limitID;
75static jfieldID elementSizeShiftID;
76static jfieldID haveCheckedExtensionsID;
77static jfieldID have_OES_blend_equation_separateID;
78static jfieldID have_OES_blend_subtractID;
79static jfieldID have_OES_framebuffer_objectID;
80static jfieldID have_OES_texture_cube_mapID;
81
82/* Cache method IDs each time the class is loaded. */
83
84static void
85nativeClassInit(JNIEnv *_env, jclass glImplClass)
86{
87    jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
88    nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
89
90    jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
91    bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
92
93    jclass g11impClassLocal = _env->FindClass("com/google/android/gles_jni/GLImpl");
94    G11ImplClass = (jclass) _env->NewGlobalRef(g11impClassLocal);
95    haveCheckedExtensionsID =  _env->GetFieldID(G11ImplClass, "haveCheckedExtensions", "Z");
96    have_OES_blend_equation_separateID =  _env->GetFieldID(G11ImplClass, "have_OES_blend_equation_separate", "Z");
97    have_OES_blend_subtractID =  _env->GetFieldID(G11ImplClass, "have_OES_blend_subtract", "Z");
98    have_OES_framebuffer_objectID =  _env->GetFieldID(G11ImplClass, "have_OES_framebuffer_object", "Z");
99    have_OES_texture_cube_mapID =  _env->GetFieldID(G11ImplClass, "have_OES_texture_cube_map", "Z");
100
101    getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
102            "getBasePointer", "(Ljava/nio/Buffer;)J");
103    getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
104            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
105    getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
106            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
107    allowIndirectBuffersID = _env->GetStaticMethodID(g11impClassLocal,
108            "allowIndirectBuffers", "(Ljava/lang/String;)Z");
109    positionID = _env->GetFieldID(bufferClass, "position", "I");
110    limitID = _env->GetFieldID(bufferClass, "limit", "I");
111    elementSizeShiftID =
112        _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
113}
114
115static void *
116getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
117{
118    jint position;
119    jint limit;
120    jint elementSizeShift;
121    jlong pointer;
122    jint offset;
123    void *data;
124
125    position = _env->GetIntField(buffer, positionID);
126    limit = _env->GetIntField(buffer, limitID);
127    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
128    *remaining = (limit - position) << elementSizeShift;
129    pointer = _env->CallStaticLongMethod(nioAccessClass,
130            getBasePointerID, buffer);
131    if (pointer != 0L) {
132        *array = NULL;
133        return (void *) (jint) pointer;
134    }
135
136    *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
137            getBaseArrayID, buffer);
138    if (*array == NULL) {
139        return (void*) NULL;
140    }
141    offset = _env->CallStaticIntMethod(nioAccessClass,
142            getBaseArrayOffsetID, buffer);
143    data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
144
145    return (void *) ((char *) data + offset);
146}
147
148static void
149releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
150{
151    _env->ReleasePrimitiveArrayCritical(array, data,
152					   commit ? 0 : JNI_ABORT);
153}
154
155extern "C" {
156extern char*  __progname;
157}
158
159static bool
160allowIndirectBuffers(JNIEnv *_env) {
161    static jint sIndirectBufferCompatability;
162    if (sIndirectBufferCompatability == 0) {
163        jobject appName = _env->NewStringUTF(::__progname);
164        sIndirectBufferCompatability = _env->CallStaticBooleanMethod(G11ImplClass, allowIndirectBuffersID, appName) ? 2 : 1;
165    }
166    return sIndirectBufferCompatability == 2;
167}
168
169static void *
170getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
171    if (!buffer) {
172        return NULL;
173    }
174    void* buf = _env->GetDirectBufferAddress(buffer);
175    if (buf) {
176        jint position = _env->GetIntField(buffer, positionID);
177        jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
178        buf = ((char*) buf) + (position << elementSizeShift);
179    } else {
180        if (allowIndirectBuffers(_env)) {
181            jarray array = 0;
182            jint remaining;
183            buf = getPointer(_env, buffer, &array, &remaining);
184            if (array) {
185                releasePointer(_env, array, buf, 0);
186            }
187        } else {
188            jniThrowException(_env, "java/lang/IllegalArgumentException",
189                              "Must use a native order direct Buffer");
190        }
191    }
192    return buf;
193}
194
195static int
196getNumCompressedTextureFormats() {
197    int numCompressedTextureFormats = 0;
198    glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedTextureFormats);
199    return numCompressedTextureFormats;
200}
201
202// Check if the extension at the head of pExtensions is pExtension. Note that pExtensions is
203// terminated by either 0 or space, while pExtension is terminated by 0.
204
205static bool
206extensionEqual(const GLubyte* pExtensions, const GLubyte* pExtension) {
207    while (true) {
208        char a = *pExtensions++;
209        char b = *pExtension++;
210        bool aEnd = a == '\0' || a == ' ';
211        bool bEnd = b == '\0';
212        if ( aEnd || bEnd) {
213            return aEnd == bEnd;
214        }
215        if ( a != b ) {
216            return false;
217        }
218    }
219}
220
221static const GLubyte*
222nextExtension(const GLubyte* pExtensions) {
223    while (true) {
224        char a = *pExtensions++;
225        if ( a == '\0') {
226            return pExtensions-1;
227        } else if ( a == ' ') {
228            return pExtensions;
229        }
230    }
231}
232
233static bool
234checkForExtension(const GLubyte* pExtensions, const GLubyte* pExtension) {
235    for (;*pExtensions != '\0'; pExtensions = nextExtension(pExtensions)) {
236        if (extensionEqual(pExtensions, pExtension)) {
237            return true;
238        }
239    }
240    return false;
241}
242
243static bool
244supportsExtension(JNIEnv *_env, jobject impl, jfieldID fieldId) {
245    if (!_env->GetBooleanField(impl, haveCheckedExtensionsID)) {
246        _env->SetBooleanField(impl, haveCheckedExtensionsID, true);
247        const GLubyte* sExtensions = glGetString(GL_EXTENSIONS);
248        _env->SetBooleanField(impl, have_OES_blend_equation_separateID,
249            checkForExtension(sExtensions, (const GLubyte*) "GL_OES_blend_equation_separate"));
250        _env->SetBooleanField(impl, have_OES_blend_subtractID,
251            checkForExtension(sExtensions, (const GLubyte*) "GL_OES_blend_subtract"));
252        _env->SetBooleanField(impl, have_OES_framebuffer_objectID,
253            checkForExtension(sExtensions, (const GLubyte*) "GL_OES_framebuffer_object"));
254        _env->SetBooleanField(impl, have_OES_texture_cube_mapID,
255            checkForExtension(sExtensions, (const GLubyte*) "GL_OES_texture_cube_map"));
256    }
257    return _env->GetBooleanField(impl, fieldId);
258}
259
260// --------------------------------------------------------------------------
261