1 /* 2 * Copyright (C) 2009 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 com.android.gldual; 18 /* 19 * Copyright (C) 2008 The Android Open Source Project 20 * 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 24 * 25 * http://www.apache.org/licenses/LICENSE-2.0 26 * 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. 32 */ 33 34 35 import javax.microedition.khronos.egl.EGL10; 36 import javax.microedition.khronos.egl.EGLConfig; 37 import javax.microedition.khronos.egl.EGLContext; 38 import javax.microedition.khronos.egl.EGLDisplay; 39 import javax.microedition.khronos.opengles.GL10; 40 41 import android.content.Context; 42 import android.opengl.GLSurfaceView; 43 import android.util.AttributeSet; 44 import android.util.Log; 45 46 /** 47 * An implementation of SurfaceView that uses the dedicated surface for 48 * displaying an OpenGL animation. This allows the animation to run in a 49 * separate thread, without requiring that it be driven by the update mechanism 50 * of the view hierarchy. 51 * 52 * The application-specific rendering code is delegated to a GLView.Renderer 53 * instance. 54 */ 55 class GLDualGL2View extends GLSurfaceView { 56 private static String TAG = "GLDualGL2View"; 57 GLDualGL2View(Context context)58 public GLDualGL2View(Context context) { 59 super(context); 60 init(false, 0, 0); 61 } 62 GLDualGL2View(Context context, AttributeSet set)63 public GLDualGL2View(Context context, AttributeSet set) { 64 super(context, set); 65 init(false, 0, 0); 66 } 67 GLDualGL2View(Context context, boolean translucent, int depth, int stencil)68 public GLDualGL2View(Context context, boolean translucent, int depth, int stencil) { 69 super(context); 70 init(translucent, depth, stencil); 71 } 72 init(boolean translucent, int depth, int stencil)73 private void init(boolean translucent, int depth, int stencil) { 74 setEGLContextFactory(new ContextFactory()); 75 setEGLConfigChooser( translucent ? 76 new ConfigChooser(8,8,8,8, depth, stencil) : 77 new ConfigChooser(5,6,5,0, depth, stencil)); 78 setRenderer(new Renderer()); 79 } 80 81 private static class ContextFactory implements GLSurfaceView.EGLContextFactory { 82 private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig)83 public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { 84 Log.w(TAG, "creating OpenGL ES 2.0 context"); 85 checkEglError("Before eglCreateContext", egl); 86 int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 87 EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); 88 checkEglError("After eglCreateContext", egl); 89 return context; 90 } 91 destroyContext(EGL10 egl, EGLDisplay display, EGLContext context)92 public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { 93 egl.eglDestroyContext(display, context); 94 } 95 } 96 checkEglError(String prompt, EGL10 egl)97 private static void checkEglError(String prompt, EGL10 egl) { 98 int error; 99 while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { 100 Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); 101 } 102 } 103 104 private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { 105 private static int EGL_OPENGL_ES2_BIT = 4; 106 private static int[] s_configAttribs2 = 107 { 108 EGL10.EGL_RED_SIZE, 4, 109 EGL10.EGL_GREEN_SIZE, 4, 110 EGL10.EGL_BLUE_SIZE, 4, 111 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 112 EGL10.EGL_NONE 113 }; 114 ConfigChooser(int r, int g, int b, int a, int depth, int stencil)115 public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { 116 mRedSize = r; 117 mGreenSize = g; 118 mBlueSize = b; 119 mAlphaSize = a; 120 mDepthSize = depth; 121 mStencilSize = stencil; 122 } 123 chooseConfig(EGL10 egl, EGLDisplay display)124 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 125 126 int[] num_config = new int[1]; 127 egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); 128 129 int numConfigs = num_config[0]; 130 131 if (numConfigs <= 0) { 132 throw new IllegalArgumentException("No configs match configSpec"); 133 } 134 EGLConfig[] configs = new EGLConfig[numConfigs]; 135 egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); 136 // printConfigs(egl, display, configs); 137 return chooseConfig(egl, display, configs); 138 } 139 chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs)140 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, 141 EGLConfig[] configs) { 142 EGLConfig closestConfig = null; 143 int closestDistance = 1000; 144 for(EGLConfig config : configs) { 145 int d = findConfigAttrib(egl, display, config, 146 EGL10.EGL_DEPTH_SIZE, 0); 147 int s = findConfigAttrib(egl, display, config, 148 EGL10.EGL_STENCIL_SIZE, 0); 149 if (d >= mDepthSize && s>= mStencilSize) { 150 int r = findConfigAttrib(egl, display, config, 151 EGL10.EGL_RED_SIZE, 0); 152 int g = findConfigAttrib(egl, display, config, 153 EGL10.EGL_GREEN_SIZE, 0); 154 int b = findConfigAttrib(egl, display, config, 155 EGL10.EGL_BLUE_SIZE, 0); 156 int a = findConfigAttrib(egl, display, config, 157 EGL10.EGL_ALPHA_SIZE, 0); 158 int distance = Math.abs(r - mRedSize) 159 + Math.abs(g - mGreenSize) 160 + Math.abs(b - mBlueSize) 161 + Math.abs(a - mAlphaSize); 162 if (distance < closestDistance) { 163 closestDistance = distance; 164 closestConfig = config; 165 } 166 } 167 } 168 return closestConfig; 169 } 170 findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue)171 private int findConfigAttrib(EGL10 egl, EGLDisplay display, 172 EGLConfig config, int attribute, int defaultValue) { 173 174 if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { 175 return mValue[0]; 176 } 177 return defaultValue; 178 } 179 printConfigs(EGL10 egl, EGLDisplay display, EGLConfig[] configs)180 private void printConfigs(EGL10 egl, EGLDisplay display, 181 EGLConfig[] configs) { 182 int numConfigs = configs.length; 183 Log.w(TAG, String.format("%d configurations", numConfigs)); 184 for (int i = 0; i < numConfigs; i++) { 185 Log.w(TAG, String.format("Configuration %d:\n", i)); 186 printConfig(egl, display, configs[i]); 187 } 188 } 189 printConfig(EGL10 egl, EGLDisplay display, EGLConfig config)190 private void printConfig(EGL10 egl, EGLDisplay display, 191 EGLConfig config) { 192 int[] attributes = { 193 EGL10.EGL_BUFFER_SIZE, 194 EGL10.EGL_ALPHA_SIZE, 195 EGL10.EGL_BLUE_SIZE, 196 EGL10.EGL_GREEN_SIZE, 197 EGL10.EGL_RED_SIZE, 198 EGL10.EGL_DEPTH_SIZE, 199 EGL10.EGL_STENCIL_SIZE, 200 EGL10.EGL_CONFIG_CAVEAT, 201 EGL10.EGL_CONFIG_ID, 202 EGL10.EGL_LEVEL, 203 EGL10.EGL_MAX_PBUFFER_HEIGHT, 204 EGL10.EGL_MAX_PBUFFER_PIXELS, 205 EGL10.EGL_MAX_PBUFFER_WIDTH, 206 EGL10.EGL_NATIVE_RENDERABLE, 207 EGL10.EGL_NATIVE_VISUAL_ID, 208 EGL10.EGL_NATIVE_VISUAL_TYPE, 209 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, 210 EGL10.EGL_SAMPLES, 211 EGL10.EGL_SAMPLE_BUFFERS, 212 EGL10.EGL_SURFACE_TYPE, 213 EGL10.EGL_TRANSPARENT_TYPE, 214 EGL10.EGL_TRANSPARENT_RED_VALUE, 215 EGL10.EGL_TRANSPARENT_GREEN_VALUE, 216 EGL10.EGL_TRANSPARENT_BLUE_VALUE, 217 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, 218 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, 219 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, 220 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, 221 EGL10.EGL_LUMINANCE_SIZE, 222 EGL10.EGL_ALPHA_MASK_SIZE, 223 EGL10.EGL_COLOR_BUFFER_TYPE, 224 EGL10.EGL_RENDERABLE_TYPE, 225 0x3042 // EGL10.EGL_CONFORMANT 226 }; 227 String[] names = { 228 "EGL_BUFFER_SIZE", 229 "EGL_ALPHA_SIZE", 230 "EGL_BLUE_SIZE", 231 "EGL_GREEN_SIZE", 232 "EGL_RED_SIZE", 233 "EGL_DEPTH_SIZE", 234 "EGL_STENCIL_SIZE", 235 "EGL_CONFIG_CAVEAT", 236 "EGL_CONFIG_ID", 237 "EGL_LEVEL", 238 "EGL_MAX_PBUFFER_HEIGHT", 239 "EGL_MAX_PBUFFER_PIXELS", 240 "EGL_MAX_PBUFFER_WIDTH", 241 "EGL_NATIVE_RENDERABLE", 242 "EGL_NATIVE_VISUAL_ID", 243 "EGL_NATIVE_VISUAL_TYPE", 244 "EGL_PRESERVED_RESOURCES", 245 "EGL_SAMPLES", 246 "EGL_SAMPLE_BUFFERS", 247 "EGL_SURFACE_TYPE", 248 "EGL_TRANSPARENT_TYPE", 249 "EGL_TRANSPARENT_RED_VALUE", 250 "EGL_TRANSPARENT_GREEN_VALUE", 251 "EGL_TRANSPARENT_BLUE_VALUE", 252 "EGL_BIND_TO_TEXTURE_RGB", 253 "EGL_BIND_TO_TEXTURE_RGBA", 254 "EGL_MIN_SWAP_INTERVAL", 255 "EGL_MAX_SWAP_INTERVAL", 256 "EGL_LUMINANCE_SIZE", 257 "EGL_ALPHA_MASK_SIZE", 258 "EGL_COLOR_BUFFER_TYPE", 259 "EGL_RENDERABLE_TYPE", 260 "EGL_CONFORMANT" 261 }; 262 int[] value = new int[1]; 263 for (int i = 0; i < attributes.length; i++) { 264 int attribute = attributes[i]; 265 String name = names[i]; 266 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { 267 Log.w(TAG, String.format(" %s: %d\n", name, value[0])); 268 } else { 269 // Log.w(TAG, String.format(" %s: failed\n", name)); 270 while (egl.eglGetError() != EGL10.EGL_SUCCESS); 271 } 272 } 273 } 274 275 // Subclasses can adjust these values: 276 protected int mRedSize; 277 protected int mGreenSize; 278 protected int mBlueSize; 279 protected int mAlphaSize; 280 protected int mDepthSize; 281 protected int mStencilSize; 282 private int[] mValue = new int[1]; 283 } 284 285 private static class Renderer implements GLSurfaceView.Renderer { onDrawFrame(GL10 gl)286 public void onDrawFrame(GL10 gl) { 287 GLDualLib.step(); 288 } 289 onSurfaceChanged(GL10 gl, int width, int height)290 public void onSurfaceChanged(GL10 gl, int width, int height) { 291 GLDualLib.init(width, height); 292 } 293 onSurfaceCreated(GL10 gl, EGLConfig config)294 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 295 // Do nothing. 296 } 297 } 298 } 299 300