1 /*
2  * Copyright (C) 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 package android.opengl;
18 
19 import android.graphics.Bitmap;
20 
21 import javax.microedition.khronos.egl.EGL10;
22 import javax.microedition.khronos.egl.EGL11;
23 
24 /**
25  *
26  * Utility class to help bridging OpenGL ES and Android APIs.
27  *
28  */
29 
30 public final class GLUtils {
31 
GLUtils()32     private GLUtils() {
33     }
34 
35     /**
36      * return the internal format as defined by OpenGL ES of the supplied bitmap.
37      * @param bitmap
38      * @return the internal format of the bitmap.
39      */
getInternalFormat(Bitmap bitmap)40     public static int getInternalFormat(Bitmap bitmap) {
41         if (bitmap == null) {
42             throw new NullPointerException("getInternalFormat can't be used with a null Bitmap");
43         }
44         if (bitmap.isRecycled()) {
45             throw new IllegalArgumentException("bitmap is recycled");
46         }
47         int result = native_getInternalFormat(bitmap);
48         if (result < 0) {
49             throw new IllegalArgumentException("Unknown internalformat");
50         }
51         return result;
52     }
53 
54     /**
55      * Return the type as defined by OpenGL ES of the supplied bitmap, if there
56      * is one. If the bitmap is stored in a compressed format, it may not have
57      * a valid OpenGL ES type.
58      * @throws IllegalArgumentException if the bitmap does not have a type.
59      * @param bitmap
60      * @return the OpenGL ES type of the bitmap.
61      */
getType(Bitmap bitmap)62     public static int getType(Bitmap bitmap) {
63         if (bitmap == null) {
64             throw new NullPointerException("getType can't be used with a null Bitmap");
65         }
66         if (bitmap.isRecycled()) {
67             throw new IllegalArgumentException("bitmap is recycled");
68         }
69         int result = native_getType(bitmap);
70         if (result < 0) {
71             throw new IllegalArgumentException("Unknown type");
72         }
73         return result;
74     }
75 
76     /**
77      * Calls glTexImage2D() on the current OpenGL context. If no context is
78      * current the behavior is the same as calling glTexImage2D() with  no
79      * current context, that is, eglGetError() will return the appropriate
80      * error.
81      * Unlike glTexImage2D() bitmap cannot be null and will raise an exception
82      * in that case.
83      * All other parameters are identical to those used for glTexImage2D().
84      *
85      * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make
86      * sure to set it properly according to the supplied bitmap.
87      *
88      * Whether or not bitmap can have non power of two dimensions depends on
89      * the current OpenGL context. Always check glGetError() some time
90      * after calling this method, just like when using OpenGL directly.
91      *
92      * @param target
93      * @param level
94      * @param internalformat
95      * @param bitmap
96      * @param border
97      */
texImage2D(int target, int level, int internalformat, Bitmap bitmap, int border)98     public static void texImage2D(int target, int level, int internalformat,
99             Bitmap bitmap, int border) {
100         if (bitmap == null) {
101             throw new NullPointerException("texImage2D can't be used with a null Bitmap");
102         }
103         if (bitmap.isRecycled()) {
104             throw new IllegalArgumentException("bitmap is recycled");
105         }
106         if (native_texImage2D(target, level, internalformat, bitmap, -1, border)!=0) {
107             throw new IllegalArgumentException("invalid Bitmap format");
108         }
109     }
110 
111     /**
112      * A version of texImage2D() that takes an explicit type parameter
113      * as defined by the OpenGL ES specification. The actual type and
114      * internalformat of the bitmap must be compatible with the specified
115      * type and internalformat parameters.
116      *
117      * @param target
118      * @param level
119      * @param internalformat
120      * @param bitmap
121      * @param type
122      * @param border
123      */
texImage2D(int target, int level, int internalformat, Bitmap bitmap, int type, int border)124     public static void texImage2D(int target, int level, int internalformat,
125             Bitmap bitmap, int type, int border) {
126         if (bitmap == null) {
127             throw new NullPointerException("texImage2D can't be used with a null Bitmap");
128         }
129         if (bitmap.isRecycled()) {
130             throw new IllegalArgumentException("bitmap is recycled");
131         }
132         if (native_texImage2D(target, level, internalformat, bitmap, type, border)!=0) {
133             throw new IllegalArgumentException("invalid Bitmap format");
134         }
135     }
136 
137     /**
138      * A version of texImage2D that determines the internalFormat and type
139      * automatically.
140      *
141      * @param target
142      * @param level
143      * @param bitmap
144      * @param border
145      */
texImage2D(int target, int level, Bitmap bitmap, int border)146     public static void texImage2D(int target, int level, Bitmap bitmap,
147             int border) {
148         if (bitmap == null) {
149             throw new NullPointerException("texImage2D can't be used with a null Bitmap");
150         }
151         if (bitmap.isRecycled()) {
152             throw new IllegalArgumentException("bitmap is recycled");
153         }
154         if (native_texImage2D(target, level, -1, bitmap, -1, border)!=0) {
155             throw new IllegalArgumentException("invalid Bitmap format");
156         }
157     }
158 
159     /**
160      * Calls glTexSubImage2D() on the current OpenGL context. If no context is
161      * current the behavior is the same as calling glTexSubImage2D() with  no
162      * current context, that is, eglGetError() will return the appropriate
163      * error.
164      * Unlike glTexSubImage2D() bitmap cannot be null and will raise an exception
165      * in that case.
166      * All other parameters are identical to those used for glTexSubImage2D().
167      *
168      * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make
169      * sure to set it properly according to the supplied bitmap.
170      *
171      * Whether or not bitmap can have non power of two dimensions depends on
172      * the current OpenGL context. Always check glGetError() some time
173      * after calling this method, just like when using OpenGL directly.
174      *
175      * @param target
176      * @param level
177      * @param xoffset
178      * @param yoffset
179      * @param bitmap
180      */
texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap)181     public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
182             Bitmap bitmap) {
183         if (bitmap == null) {
184             throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
185         }
186         if (bitmap.isRecycled()) {
187             throw new IllegalArgumentException("bitmap is recycled");
188         }
189         int type = getType(bitmap);
190         if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, -1, type)!=0) {
191             throw new IllegalArgumentException("invalid Bitmap format");
192         }
193     }
194 
195     /**
196      * A version of texSubImage2D() that takes an explicit type parameter
197      * as defined by the OpenGL ES specification.
198      *
199      * @param target
200      * @param level
201      * @param xoffset
202      * @param yoffset
203      * @param bitmap
204      * @param type
205      */
texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap, int format, int type)206     public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
207             Bitmap bitmap, int format, int type) {
208         if (bitmap == null) {
209             throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
210         }
211         if (bitmap.isRecycled()) {
212             throw new IllegalArgumentException("bitmap is recycled");
213         }
214         if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, format, type)!=0) {
215             throw new IllegalArgumentException("invalid Bitmap format");
216         }
217     }
218 
219     /**
220      * Return a string for the EGL error code, or the hex representation
221      * if the error is unknown.
222      *
223      * @param error The EGL error to convert into a String.
224      *
225      * @return An error string corresponding to the EGL error code.
226      */
getEGLErrorString(int error)227     public static String getEGLErrorString(int error) {
228         switch (error) {
229             case EGL10.EGL_SUCCESS:
230                 return "EGL_SUCCESS";
231             case EGL10.EGL_NOT_INITIALIZED:
232                 return "EGL_NOT_INITIALIZED";
233             case EGL10.EGL_BAD_ACCESS:
234                 return "EGL_BAD_ACCESS";
235             case EGL10.EGL_BAD_ALLOC:
236                 return "EGL_BAD_ALLOC";
237             case EGL10.EGL_BAD_ATTRIBUTE:
238                 return "EGL_BAD_ATTRIBUTE";
239             case EGL10.EGL_BAD_CONFIG:
240                 return "EGL_BAD_CONFIG";
241             case EGL10.EGL_BAD_CONTEXT:
242                 return "EGL_BAD_CONTEXT";
243             case EGL10.EGL_BAD_CURRENT_SURFACE:
244                 return "EGL_BAD_CURRENT_SURFACE";
245             case EGL10.EGL_BAD_DISPLAY:
246                 return "EGL_BAD_DISPLAY";
247             case EGL10.EGL_BAD_MATCH:
248                 return "EGL_BAD_MATCH";
249             case EGL10.EGL_BAD_NATIVE_PIXMAP:
250                 return "EGL_BAD_NATIVE_PIXMAP";
251             case EGL10.EGL_BAD_NATIVE_WINDOW:
252                 return "EGL_BAD_NATIVE_WINDOW";
253             case EGL10.EGL_BAD_PARAMETER:
254                 return "EGL_BAD_PARAMETER";
255             case EGL10.EGL_BAD_SURFACE:
256                 return "EGL_BAD_SURFACE";
257             case EGL11.EGL_CONTEXT_LOST:
258                 return "EGL_CONTEXT_LOST";
259             default:
260                 return "0x" + Integer.toHexString(error);
261         }
262     }
263 
native_getInternalFormat(Bitmap bitmap)264     native private static int native_getInternalFormat(Bitmap bitmap);
native_getType(Bitmap bitmap)265     native private static int native_getType(Bitmap bitmap);
native_texImage2D(int target, int level, int internalformat, Bitmap bitmap, int type, int border)266     native private static int native_texImage2D(int target, int level, int internalformat,
267             Bitmap bitmap, int type, int border);
native_texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap, int format, int type)268     native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset,
269             Bitmap bitmap, int format, int type);
270 }
271