2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gl2jni;
19 * Copyright (C) 2008 The Android Open Source Project
21 * Licensed under the Apache License, Version 2.0 (the "License");
22 * you may not use this file except in compliance with the License.
23 * You may obtain a copy of the License at
25 * http://www.apache.org/licenses/LICENSE-2.0
27 * Unless required by applicable law or agreed to in writing, software
28 * distributed under the License is distributed on an "AS IS" BASIS,
29 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30 * See the License for the specific language governing permissions and
31 * limitations under the License.
35 import android.content.Context;
36 import android.opengl.GLSurfaceView;
37 import android.util.AttributeSet;
38 import android.util.Log;
39 import android.view.KeyEvent;
40 import android.view.MotionEvent;
42 import javax.microedition.khronos.egl.EGL10;
43 import javax.microedition.khronos.egl.EGLConfig;
44 import javax.microedition.khronos.egl.EGLContext;
45 import javax.microedition.khronos.egl.EGLDisplay;
46 import javax.microedition.khronos.opengles.GL10;
49 * An implementation of SurfaceView that uses the dedicated surface for
50 * displaying an OpenGL animation. This allows the animation to run in a
51 * separate thread, without requiring that it be driven by the update mechanism
52 * of the view hierarchy.
54 * The application-specific rendering code is delegated to a GLView.Renderer
57 class GL2JNIView extends GLSurfaceView {
58 private static String TAG = "GL2JNIView";
60 public GL2JNIView(Context context) {
65 public GL2JNIView(Context context, boolean translucent, int depth, int stencil) {
67 init(translucent, depth, stencil);
70 private void init(boolean translucent, int depth, int stencil) {
71 setEGLContextFactory(new ContextFactory());
72 setEGLConfigChooser( translucent ?
73 new ConfigChooser(8,8,8,8, depth, stencil) :
74 new ConfigChooser(5,6,5,0, depth, stencil));
75 setRenderer(new Renderer());
78 private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
79 private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
80 public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
81 Log.w(TAG, "creating OpenGL ES 2.0 context");
82 checkEglError("Before eglCreateContext", egl);
83 int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
84 EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
85 checkEglError("After eglCreateContext", egl);
89 public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
90 egl.eglDestroyContext(display, context);
94 private static void checkEglError(String prompt, EGL10 egl) {
96 while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
97 Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
101 private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
102 private static int EGL_OPENGL_ES2_BIT = 4;
103 private static int[] s_configAttribs2 =
105 EGL10.EGL_RED_SIZE, 4,
106 EGL10.EGL_GREEN_SIZE, 4,
107 EGL10.EGL_BLUE_SIZE, 4,
108 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
112 public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
118 mStencilSize = stencil;
121 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
123 int[] num_config = new int[1];
124 egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
126 int numConfigs = num_config[0];
128 if (numConfigs <= 0) {
129 throw new IllegalArgumentException("No configs match configSpec");
131 EGLConfig[] configs = new EGLConfig[numConfigs];
132 egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
133 // printConfigs(egl, display, configs);
134 return chooseConfig(egl, display, configs);
137 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
138 EGLConfig[] configs) {
139 EGLConfig closestConfig = null;
140 int closestDistance = 1000;
141 for(EGLConfig config : configs) {
142 int d = findConfigAttrib(egl, display, config,
143 EGL10.EGL_DEPTH_SIZE, 0);
144 int s = findConfigAttrib(egl, display, config,
145 EGL10.EGL_STENCIL_SIZE, 0);
146 if (d >= mDepthSize && s>= mStencilSize) {
147 int r = findConfigAttrib(egl, display, config,
148 EGL10.EGL_RED_SIZE, 0);
149 int g = findConfigAttrib(egl, display, config,
150 EGL10.EGL_GREEN_SIZE, 0);
151 int b = findConfigAttrib(egl, display, config,
152 EGL10.EGL_BLUE_SIZE, 0);
153 int a = findConfigAttrib(egl, display, config,
154 EGL10.EGL_ALPHA_SIZE, 0);
155 int distance = Math.abs(r - mRedSize)
156 + Math.abs(g - mGreenSize)
157 + Math.abs(b - mBlueSize)
158 + Math.abs(a - mAlphaSize);
159 if (distance < closestDistance) {
160 closestDistance = distance;
161 closestConfig = config;
165 return closestConfig;
168 private int findConfigAttrib(EGL10 egl, EGLDisplay display,
169 EGLConfig config, int attribute, int defaultValue) {
171 if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
177 private void printConfigs(EGL10 egl, EGLDisplay display,
178 EGLConfig[] configs) {
179 int numConfigs = configs.length;
180 Log.w(TAG, String.format("%d configurations", numConfigs));
181 for (int i = 0; i < numConfigs; i++) {
182 Log.w(TAG, String.format("Configuration %d:\n", i));
183 printConfig(egl, display, configs[i]);
187 private void printConfig(EGL10 egl, EGLDisplay display,
190 EGL10.EGL_BUFFER_SIZE,
191 EGL10.EGL_ALPHA_SIZE,
193 EGL10.EGL_GREEN_SIZE,
195 EGL10.EGL_DEPTH_SIZE,
196 EGL10.EGL_STENCIL_SIZE,
197 EGL10.EGL_CONFIG_CAVEAT,
200 EGL10.EGL_MAX_PBUFFER_HEIGHT,
201 EGL10.EGL_MAX_PBUFFER_PIXELS,
202 EGL10.EGL_MAX_PBUFFER_WIDTH,
203 EGL10.EGL_NATIVE_RENDERABLE,
204 EGL10.EGL_NATIVE_VISUAL_ID,
205 EGL10.EGL_NATIVE_VISUAL_TYPE,
206 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
208 EGL10.EGL_SAMPLE_BUFFERS,
209 EGL10.EGL_SURFACE_TYPE,
210 EGL10.EGL_TRANSPARENT_TYPE,
211 EGL10.EGL_TRANSPARENT_RED_VALUE,
212 EGL10.EGL_TRANSPARENT_GREEN_VALUE,
213 EGL10.EGL_TRANSPARENT_BLUE_VALUE,
214 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
215 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
216 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
217 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
218 EGL10.EGL_LUMINANCE_SIZE,
219 EGL10.EGL_ALPHA_MASK_SIZE,
220 EGL10.EGL_COLOR_BUFFER_TYPE,
221 EGL10.EGL_RENDERABLE_TYPE,
222 0x3042 // EGL10.EGL_CONFORMANT
235 "EGL_MAX_PBUFFER_HEIGHT",
236 "EGL_MAX_PBUFFER_PIXELS",
237 "EGL_MAX_PBUFFER_WIDTH",
238 "EGL_NATIVE_RENDERABLE",
239 "EGL_NATIVE_VISUAL_ID",
240 "EGL_NATIVE_VISUAL_TYPE",
241 "EGL_PRESERVED_RESOURCES",
243 "EGL_SAMPLE_BUFFERS",
245 "EGL_TRANSPARENT_TYPE",
246 "EGL_TRANSPARENT_RED_VALUE",
247 "EGL_TRANSPARENT_GREEN_VALUE",
248 "EGL_TRANSPARENT_BLUE_VALUE",
249 "EGL_BIND_TO_TEXTURE_RGB",
250 "EGL_BIND_TO_TEXTURE_RGBA",
251 "EGL_MIN_SWAP_INTERVAL",
252 "EGL_MAX_SWAP_INTERVAL",
253 "EGL_LUMINANCE_SIZE",
254 "EGL_ALPHA_MASK_SIZE",
255 "EGL_COLOR_BUFFER_TYPE",
256 "EGL_RENDERABLE_TYPE",
259 int[] value = new int[1];
260 for (int i = 0; i < attributes.length; i++) {
261 int attribute = attributes[i];
262 String name = names[i];
263 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
264 Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
266 // Log.w(TAG, String.format(" %s: failed\n", name));
267 while (egl.eglGetError() != EGL10.EGL_SUCCESS);
272 // Subclasses can adjust these values:
273 protected int mRedSize;
274 protected int mGreenSize;
275 protected int mBlueSize;
276 protected int mAlphaSize;
277 protected int mDepthSize;
278 protected int mStencilSize;
279 private int[] mValue = new int[1];
282 private static class Renderer implements GLSurfaceView.Renderer {
283 public void onDrawFrame(GL10 gl) {
287 public void onSurfaceChanged(GL10 gl, int width, int height) {
288 GL2JNILib.init(width, height);
291 public void onSurfaceCreated(GL10 gl, EGLConfig config) {