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.getNativeInstance());
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.getNativeInstance());
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.getNativeInstance(), -1,
107                 border) != 0) {
108             throw new IllegalArgumentException("invalid Bitmap format");
109         }
110     }
111 
112     /**
113      * A version of texImage2D() that takes an explicit type parameter
114      * as defined by the OpenGL ES specification. The actual type and
115      * internalformat of the bitmap must be compatible with the specified
116      * type and internalformat parameters.
117      *
118      * @param target
119      * @param level
120      * @param internalformat
121      * @param bitmap
122      * @param type
123      * @param border
124      */
texImage2D(int target, int level, int internalformat, Bitmap bitmap, int type, int border)125     public static void texImage2D(int target, int level, int internalformat,
126             Bitmap bitmap, int type, int border) {
127         if (bitmap == null) {
128             throw new NullPointerException("texImage2D can't be used with a null Bitmap");
129         }
130         if (bitmap.isRecycled()) {
131             throw new IllegalArgumentException("bitmap is recycled");
132         }
133         if (native_texImage2D(target, level, internalformat, bitmap.getNativeInstance(), type,
134               border) != 0) {
135             throw new IllegalArgumentException("invalid Bitmap format");
136         }
137     }
138 
139     /**
140      * A version of texImage2D that determines the internalFormat and type
141      * automatically.
142      *
143      * @param target
144      * @param level
145      * @param bitmap
146      * @param border
147      */
texImage2D(int target, int level, Bitmap bitmap, int border)148     public static void texImage2D(int target, int level, Bitmap bitmap,
149             int border) {
150         if (bitmap == null) {
151             throw new NullPointerException("texImage2D can't be used with a null Bitmap");
152         }
153         if (bitmap.isRecycled()) {
154             throw new IllegalArgumentException("bitmap is recycled");
155         }
156         if (native_texImage2D(target, level, -1, bitmap.getNativeInstance(), -1, border) != 0) {
157             throw new IllegalArgumentException("invalid Bitmap format");
158         }
159     }
160 
161     /**
162      * Calls glTexSubImage2D() on the current OpenGL context. If no context is
163      * current the behavior is the same as calling glTexSubImage2D() with  no
164      * current context, that is, eglGetError() will return the appropriate
165      * error.
166      * Unlike glTexSubImage2D() bitmap cannot be null and will raise an exception
167      * in that case.
168      * All other parameters are identical to those used for glTexSubImage2D().
169      *
170      * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make
171      * sure to set it properly according to the supplied bitmap.
172      *
173      * Whether or not bitmap can have non power of two dimensions depends on
174      * the current OpenGL context. Always check glGetError() some time
175      * after calling this method, just like when using OpenGL directly.
176      *
177      * @param target
178      * @param level
179      * @param xoffset
180      * @param yoffset
181      * @param bitmap
182      */
texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap)183     public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
184             Bitmap bitmap) {
185         if (bitmap == null) {
186             throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
187         }
188         if (bitmap.isRecycled()) {
189             throw new IllegalArgumentException("bitmap is recycled");
190         }
191         int type = getType(bitmap);
192         if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap.getNativeInstance(), -1,
193                 type) != 0) {
194             throw new IllegalArgumentException("invalid Bitmap format");
195         }
196     }
197 
198     /**
199      * A version of texSubImage2D() that takes an explicit type parameter
200      * as defined by the OpenGL ES specification.
201      *
202      * @param target
203      * @param level
204      * @param xoffset
205      * @param yoffset
206      * @param bitmap
207      * @param type
208      */
texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap, int format, int type)209     public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
210             Bitmap bitmap, int format, int type) {
211         if (bitmap == null) {
212             throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
213         }
214         if (bitmap.isRecycled()) {
215             throw new IllegalArgumentException("bitmap is recycled");
216         }
217         if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap.getNativeInstance(),
218                 format, type) != 0) {
219             throw new IllegalArgumentException("invalid Bitmap format");
220         }
221     }
222 
223     /**
224      * Return a string for the EGL error code, or the hex representation
225      * if the error is unknown.
226      *
227      * @param error The EGL error to convert into a String.
228      *
229      * @return An error string corresponding to the EGL error code.
230      */
getEGLErrorString(int error)231     public static String getEGLErrorString(int error) {
232         switch (error) {
233             case EGL10.EGL_SUCCESS:
234                 return "EGL_SUCCESS";
235             case EGL10.EGL_NOT_INITIALIZED:
236                 return "EGL_NOT_INITIALIZED";
237             case EGL10.EGL_BAD_ACCESS:
238                 return "EGL_BAD_ACCESS";
239             case EGL10.EGL_BAD_ALLOC:
240                 return "EGL_BAD_ALLOC";
241             case EGL10.EGL_BAD_ATTRIBUTE:
242                 return "EGL_BAD_ATTRIBUTE";
243             case EGL10.EGL_BAD_CONFIG:
244                 return "EGL_BAD_CONFIG";
245             case EGL10.EGL_BAD_CONTEXT:
246                 return "EGL_BAD_CONTEXT";
247             case EGL10.EGL_BAD_CURRENT_SURFACE:
248                 return "EGL_BAD_CURRENT_SURFACE";
249             case EGL10.EGL_BAD_DISPLAY:
250                 return "EGL_BAD_DISPLAY";
251             case EGL10.EGL_BAD_MATCH:
252                 return "EGL_BAD_MATCH";
253             case EGL10.EGL_BAD_NATIVE_PIXMAP:
254                 return "EGL_BAD_NATIVE_PIXMAP";
255             case EGL10.EGL_BAD_NATIVE_WINDOW:
256                 return "EGL_BAD_NATIVE_WINDOW";
257             case EGL10.EGL_BAD_PARAMETER:
258                 return "EGL_BAD_PARAMETER";
259             case EGL10.EGL_BAD_SURFACE:
260                 return "EGL_BAD_SURFACE";
261             case EGL11.EGL_CONTEXT_LOST:
262                 return "EGL_CONTEXT_LOST";
263             default:
264                 return "0x" + Integer.toHexString(error);
265         }
266     }
267 
native_getInternalFormat(long bitmapHandle)268     native private static int native_getInternalFormat(long bitmapHandle);
native_getType(long bitmapHandle)269     native private static int native_getType(long bitmapHandle);
native_texImage2D(int target, int level, int internalformat, long bitmapHandle, int type, int border)270     native private static int native_texImage2D(int target, int level, int internalformat,
271             long bitmapHandle, int type, int border);
native_texSubImage2D(int target, int level, int xoffset, int yoffset, long bitmapHandle, int format, int type)272     native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset,
273             long bitmapHandle, int format, int type);
274 }
275