4 * GL config chooser. Derived from android ndk gl2jni sample code.
6 * Copyright (c) 2011 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 import android.opengl.GLSurfaceView;
22 import android.util.Log;
24 import javax.microedition.khronos.egl.EGL10;
25 import javax.microedition.khronos.egl.EGLConfig;
26 import javax.microedition.khronos.egl.EGLContext;
27 import javax.microedition.khronos.egl.EGLDisplay;
30 * Copyright (C) 2008,2009 The Android Open Source Project
32 * Licensed under the Apache License, Version 2.0 (the "License");
33 * you may not use this file except in compliance with the License.
34 * You may obtain a copy of the License at
36 * http://www.apache.org/licenses/LICENSE-2.0
38 * Unless required by applicable law or agreed to in writing, software
39 * distributed under the License is distributed on an "AS IS" BASIS,
40 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41 * See the License for the specific language governing permissions and
42 * limitations under the License.
45 class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
46 private final static String TAG = "ConfigChooser";
48 public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
54 mStencilSize = stencil;
57 /* This EGL config specification is used to specify 2.0 rendering.
58 * We use a minimum size of 4 bits for red/green/blue, but will
59 * perform actual matching in chooseConfig() below.
61 private static int EGL_OPENGL_ES2_BIT = 4;
62 private static int[] s_configAttribs2 =
64 EGL10.EGL_RED_SIZE, 4,
65 EGL10.EGL_GREEN_SIZE, 4,
66 EGL10.EGL_BLUE_SIZE, 4,
67 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
71 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
73 /* Get the number of minimally matching EGL configurations
75 int[] num_config = new int[1];
76 egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
78 int numConfigs = num_config[0];
80 if (numConfigs <= 0) {
81 throw new IllegalArgumentException("No configs match configSpec");
84 /* Allocate then read the array of minimally matching EGL configs
86 EGLConfig[] configs = new EGLConfig[numConfigs];
87 egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
89 /* Now return the "best" one
91 return chooseConfig(egl, display, configs);
94 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
95 EGLConfig[] configs) {
96 for(EGLConfig config : configs) {
97 int d = findConfigAttrib(egl, display, config,
98 EGL10.EGL_DEPTH_SIZE, 0);
99 int s = findConfigAttrib(egl, display, config,
100 EGL10.EGL_STENCIL_SIZE, 0);
102 // We need at least mDepthSize and mStencilSize bits
103 if (d < mDepthSize || s < mStencilSize)
106 // We want an *exact* match for red/green/blue/alpha
107 int r = findConfigAttrib(egl, display, config,
108 EGL10.EGL_RED_SIZE, 0);
109 int g = findConfigAttrib(egl, display, config,
110 EGL10.EGL_GREEN_SIZE, 0);
111 int b = findConfigAttrib(egl, display, config,
112 EGL10.EGL_BLUE_SIZE, 0);
113 int a = findConfigAttrib(egl, display, config,
114 EGL10.EGL_ALPHA_SIZE, 0);
116 if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
122 private int findConfigAttrib(EGL10 egl, EGLDisplay display,
123 EGLConfig config, int attribute, int defaultValue) {
125 if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
131 public void printConfigs(EGL10 egl, EGLDisplay display,
132 EGLConfig[] configs) {
133 int numConfigs = configs.length;
134 Log.w(TAG, String.format("%d configurations", numConfigs));
135 for (int i = 0; i < numConfigs; i++) {
136 Log.w(TAG, String.format("Configuration %d:\n", i));
137 printConfig(egl, display, configs[i]);
141 public void printConfig(EGL10 egl, EGLDisplay display,
144 EGL10.EGL_BUFFER_SIZE,
145 EGL10.EGL_ALPHA_SIZE,
147 EGL10.EGL_GREEN_SIZE,
149 EGL10.EGL_DEPTH_SIZE,
150 EGL10.EGL_STENCIL_SIZE,
151 EGL10.EGL_CONFIG_CAVEAT,
154 EGL10.EGL_MAX_PBUFFER_HEIGHT,
155 EGL10.EGL_MAX_PBUFFER_PIXELS,
156 EGL10.EGL_MAX_PBUFFER_WIDTH,
157 EGL10.EGL_NATIVE_RENDERABLE,
158 EGL10.EGL_NATIVE_VISUAL_ID,
159 EGL10.EGL_NATIVE_VISUAL_TYPE,
160 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
162 EGL10.EGL_SAMPLE_BUFFERS,
163 EGL10.EGL_SURFACE_TYPE,
164 EGL10.EGL_TRANSPARENT_TYPE,
165 EGL10.EGL_TRANSPARENT_RED_VALUE,
166 EGL10.EGL_TRANSPARENT_GREEN_VALUE,
167 EGL10.EGL_TRANSPARENT_BLUE_VALUE,
168 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
169 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
170 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
171 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
172 EGL10.EGL_LUMINANCE_SIZE,
173 EGL10.EGL_ALPHA_MASK_SIZE,
174 EGL10.EGL_COLOR_BUFFER_TYPE,
175 EGL10.EGL_RENDERABLE_TYPE,
176 0x3042 // EGL10.EGL_CONFORMANT
189 "EGL_MAX_PBUFFER_HEIGHT",
190 "EGL_MAX_PBUFFER_PIXELS",
191 "EGL_MAX_PBUFFER_WIDTH",
192 "EGL_NATIVE_RENDERABLE",
193 "EGL_NATIVE_VISUAL_ID",
194 "EGL_NATIVE_VISUAL_TYPE",
195 "EGL_PRESERVED_RESOURCES",
197 "EGL_SAMPLE_BUFFERS",
199 "EGL_TRANSPARENT_TYPE",
200 "EGL_TRANSPARENT_RED_VALUE",
201 "EGL_TRANSPARENT_GREEN_VALUE",
202 "EGL_TRANSPARENT_BLUE_VALUE",
203 "EGL_BIND_TO_TEXTURE_RGB",
204 "EGL_BIND_TO_TEXTURE_RGBA",
205 "EGL_MIN_SWAP_INTERVAL",
206 "EGL_MAX_SWAP_INTERVAL",
207 "EGL_LUMINANCE_SIZE",
208 "EGL_ALPHA_MASK_SIZE",
209 "EGL_COLOR_BUFFER_TYPE",
210 "EGL_RENDERABLE_TYPE",
213 int[] value = new int[1];
214 for (int i = 0; i < attributes.length; i++) {
215 int attribute = attributes[i];
216 String name = names[i];
217 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
218 Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
220 // Log.w(TAG, String.format(" %s: failed\n", name));
221 while (egl.eglGetError() != EGL10.EGL_SUCCESS);
226 // Subclasses can adjust these values:
227 protected int mRedSize;
228 protected int mGreenSize;
229 protected int mBlueSize;
230 protected int mAlphaSize;
231 protected int mDepthSize;
232 protected int mStencilSize;
233 private int[] mValue = new int[1];
.