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 package com.android.gallery3d.ui; 17 18 import android.opengl.GLSurfaceView.EGLConfigChooser; 19 20 import javax.microedition.khronos.egl.EGL10; 21 import javax.microedition.khronos.egl.EGLConfig; 22 import javax.microedition.khronos.egl.EGLDisplay; 23 24 /* 25 * The code is copied/adapted from 26 * <code>android.opengl.GLSurfaceView.BaseConfigChooser</code>. Here we try to 27 * choose a configuration that support RGBA_8888 format and if possible, 28 * with stencil buffer, but is not required. 29 */ 30 class GalleryEGLConfigChooser implements EGLConfigChooser { 31 32 private static final String TAG = "GalleryEGLConfigChooser"; 33 private int mStencilBits; 34 35 private final int mConfigSpec[] = new int[] { 36 EGL10.EGL_RED_SIZE, 5, 37 EGL10.EGL_GREEN_SIZE, 6, 38 EGL10.EGL_BLUE_SIZE, 5, 39 EGL10.EGL_ALPHA_SIZE, 0, 40 EGL10.EGL_NONE 41 }; 42 43 public int getStencilBits() { 44 return mStencilBits; 45 } 46 47 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 48 int[] numConfig = new int[1]; 49 if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, numConfig)) { 50 throw new RuntimeException("eglChooseConfig failed"); 51 } 52 53 if (numConfig[0] <= 0) { 54 throw new RuntimeException("No configs match configSpec"); 55 } 56 57 EGLConfig[] configs = new EGLConfig[numConfig[0]]; 58 if (!egl.eglChooseConfig(display, 59 mConfigSpec, configs, configs.length, numConfig)) { 60 throw new RuntimeException(); 61 } 62 63 return chooseConfig(egl, display, configs); 64 } 65 66 private EGLConfig chooseConfig( 67 EGL10 egl, EGLDisplay display, EGLConfig configs[]) { 68 69 EGLConfig result = null; 70 int minStencil = Integer.MAX_VALUE; 71 int value[] = new int[1]; 72 73 // Because we need only one bit of stencil, try to choose a config that 74 // has stencil support but with smallest number of stencil bits. If 75 // none is found, choose any one. 76 for (int i = 0, n = configs.length; i < n; ++i) { 77 if (egl.eglGetConfigAttrib( 78 display, configs[i], EGL10.EGL_RED_SIZE, value)) { 79 // Filter out ARGB 8888 configs. 80 if (value[0] == 8) continue; 81 } 82 if (egl.eglGetConfigAttrib( 83 display, configs[i], EGL10.EGL_STENCIL_SIZE, value)) { 84 if (value[0] == 0) continue; 85 if (value[0] < minStencil) { 86 minStencil = value[0]; 87 result = configs[i]; 88 } 89 } else { 90 throw new RuntimeException( 91 "eglGetConfigAttrib error: " + egl.eglGetError()); 92 } 93 } 94 if (result == null) result = configs[0]; 95 egl.eglGetConfigAttrib( 96 display, result, EGL10.EGL_STENCIL_SIZE, value); 97 mStencilBits = value[0]; 98 logConfig(egl, display, result); 99 return result; 100 } 101 102 private static final int[] ATTR_ID = { 103 EGL10.EGL_RED_SIZE, 104 EGL10.EGL_GREEN_SIZE, 105 EGL10.EGL_BLUE_SIZE, 106 EGL10.EGL_ALPHA_SIZE, 107 EGL10.EGL_DEPTH_SIZE, 108 EGL10.EGL_STENCIL_SIZE, 109 EGL10.EGL_CONFIG_ID, 110 EGL10.EGL_CONFIG_CAVEAT 111 }; 112 113 private static final String[] ATTR_NAME = { 114 "R", "G", "B", "A", "D", "S", "ID", "CAVEAT" 115 }; 116 117 private void logConfig(EGL10 egl, EGLDisplay display, EGLConfig config) { 118 int value[] = new int[1]; 119 StringBuilder sb = new StringBuilder(); 120 for (int j = 0; j < ATTR_ID.length; j++) { 121 egl.eglGetConfigAttrib(display, config, ATTR_ID[j], value); 122 sb.append(ATTR_NAME[j] + value[0] + " "); 123 } 124 Log.i(TAG, "Config chosen: " + sb.toString()); 125 } 126 } 127