private static void printConfig(EGLConfig config) { int[] value = new int[1]; Log.d(LOG_TAG, "EGL configuration " + config + ":"); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value); Log.d(LOG_TAG, " RED_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value); Log.d(LOG_TAG, " GREEN_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value); Log.d(LOG_TAG, " BLUE_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value); Log.d(LOG_TAG, " ALPHA_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value); Log.d(LOG_TAG, " DEPTH_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value); Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value); Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value); Log.d(LOG_TAG, " SAMPLES = " + value[0]); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value); Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0])); sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value); Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0])); }
private int findConfigAttrib( EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) { int[] mValue = new int[1]; if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) return mValue[0]; return defaultValue; }
private void logConfig(final EGL10 egl, final EGLDisplay display, final EGLConfig config) { final int value[] = new int[1]; final StringBuilder sb = new StringBuilder(); for (int j = 0; j < ATTR_ID.length; j++) { egl.eglGetConfigAttrib(display, config, ATTR_ID[j], value); sb.append(ATTR_NAME[j] + value[0] + " "); } Log.i(TAG, "Config chosen: " + sb.toString()); }
/*--------- findConfigAttrib -----------------------------------------------------*/ private int findConfigAttrib( EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) { Log.d(TAG + "class ConfigChooser", "findConfigAttrib"); if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { return mValue[0]; } return defaultValue; }
private static EGLConfig chooseConfig() { int[] desiredConfig; int rSize, gSize, bSize; int[] numConfigs = new int[1]; switch (GeckoAppShell.getScreenDepth()) { case 24: desiredConfig = CONFIG_SPEC_24BPP; rSize = gSize = bSize = 8; break; case 16: default: desiredConfig = CONFIG_SPEC_16BPP; rSize = 5; gSize = 6; bSize = 5; break; } if (!sEGL.eglChooseConfig(sEGLDisplay, desiredConfig, null, 0, numConfigs) || numConfigs[0] <= 0) { throw new GLControllerException("No available EGL configurations " + getEGLError()); } EGLConfig[] configs = new EGLConfig[numConfigs[0]]; if (!sEGL.eglChooseConfig(sEGLDisplay, desiredConfig, configs, numConfigs[0], numConfigs)) { throw new GLControllerException( "No EGL configuration for that specification " + getEGLError()); } // Select the first configuration that matches the screen depth. int[] red = new int[1], green = new int[1], blue = new int[1]; for (EGLConfig config : configs) { sEGL.eglGetConfigAttrib(sEGLDisplay, config, EGL10.EGL_RED_SIZE, red); sEGL.eglGetConfigAttrib(sEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green); sEGL.eglGetConfigAttrib(sEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue); if (red[0] == rSize && green[0] == gSize && blue[0] == bSize) { return config; } } throw new GLControllerException("No suitable EGL configuration found"); }
public boolean eglGetConfigAttrib( EGLDisplay display, EGLConfig config, int attribute, int[] value) { begin("eglGetConfigAttrib"); arg("display", display); arg("config", config); arg("attribute", attribute); end(); boolean result = mEgl10.eglGetConfigAttrib(display, config, attribute, value); arg("value", value); returns(result); checkError(); return false; }
/* * OpenGL help */ public static EGLConfig getEglConfig565(EGL10 egl, EGLDisplay display) { int[] version = new int[2]; egl.eglInitialize(display, version); EGLConfig[] conf = new EGLConfig[100]; int[] num_conf = new int[100]; egl.eglGetConfigs(display, conf, 100, num_conf); int[] red = new int[1]; int[] blue = new int[1]; int[] green = new int[1]; for (int i = 0; i < 100; i++) { if (conf[i] == null) break; egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_RED_SIZE, red); egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_BLUE_SIZE, blue); egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_GREEN_SIZE, green); if (red[0] == 5 && green[0] == 6 && blue[0] == 5) { return conf[i]; } } return null; }
private EGLConfig chooseConfig( final EGL10 egl, final EGLDisplay display, final EGLConfig configs[]) { EGLConfig result = null; int minStencil = Integer.MAX_VALUE; final int value[] = new int[1]; // Because we need only one bit of stencil, try to choose a config that // has stencil support but with smallest number of stencil bits. If // none is found, choose any one. for (int i = 0, n = configs.length; i < n; ++i) { if (!ApiHelper.USE_888_PIXEL_FORMAT) { if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RED_SIZE, value)) { // Filter out ARGB 8888 configs. if (value[0] == 8) { continue; } } } if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_STENCIL_SIZE, value)) { if (value[0] == 0) { continue; } if (value[0] < minStencil) { minStencil = value[0]; result = configs[i]; } } else throw new RuntimeException("eglGetConfigAttrib error: " + egl.eglGetError()); } if (result == null) { result = configs[0]; } egl.eglGetConfigAttrib(display, result, EGL10.EGL_STENCIL_SIZE, value); logConfig(egl, display, result); return result; }
private void printConfig(EGL10 egl, EGLDisplay display, EGLConfig config) { int[] attributes = { EGL10.EGL_BUFFER_SIZE, EGL10.EGL_ALPHA_SIZE, EGL10.EGL_BLUE_SIZE, EGL10.EGL_GREEN_SIZE, EGL10.EGL_RED_SIZE, EGL10.EGL_DEPTH_SIZE, EGL10.EGL_STENCIL_SIZE, EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_CONFIG_ID, EGL10.EGL_LEVEL, EGL10.EGL_MAX_PBUFFER_HEIGHT, EGL10.EGL_MAX_PBUFFER_PIXELS, EGL10.EGL_MAX_PBUFFER_WIDTH, EGL10.EGL_NATIVE_RENDERABLE, EGL10.EGL_NATIVE_VISUAL_ID, EGL10.EGL_NATIVE_VISUAL_TYPE, 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, EGL10.EGL_SAMPLES, EGL10.EGL_SAMPLE_BUFFERS, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_TRANSPARENT_TYPE, EGL10.EGL_TRANSPARENT_RED_VALUE, EGL10.EGL_TRANSPARENT_GREEN_VALUE, EGL10.EGL_TRANSPARENT_BLUE_VALUE, 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, EGL10.EGL_LUMINANCE_SIZE, EGL10.EGL_ALPHA_MASK_SIZE, EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RENDERABLE_TYPE, 0x3042 // EGL10.EGL_CONFORMANT }; String[] names = { "EGL_BUFFER_SIZE", "EGL_ALPHA_SIZE", "EGL_BLUE_SIZE", "EGL_GREEN_SIZE", "EGL_RED_SIZE", "EGL_DEPTH_SIZE", "EGL_STENCIL_SIZE", "EGL_CONFIG_CAVEAT", "EGL_CONFIG_ID", "EGL_LEVEL", "EGL_MAX_PBUFFER_HEIGHT", "EGL_MAX_PBUFFER_PIXELS", "EGL_MAX_PBUFFER_WIDTH", "EGL_NATIVE_RENDERABLE", "EGL_NATIVE_VISUAL_ID", "EGL_NATIVE_VISUAL_TYPE", "EGL_PRESERVED_RESOURCES", "EGL_SAMPLES", "EGL_SAMPLE_BUFFERS", "EGL_SURFACE_TYPE", "EGL_TRANSPARENT_TYPE", "EGL_TRANSPARENT_RED_VALUE", "EGL_TRANSPARENT_GREEN_VALUE", "EGL_TRANSPARENT_BLUE_VALUE", "EGL_BIND_TO_TEXTURE_RGB", "EGL_BIND_TO_TEXTURE_RGBA", "EGL_MIN_SWAP_INTERVAL", "EGL_MAX_SWAP_INTERVAL", "EGL_LUMINANCE_SIZE", "EGL_ALPHA_MASK_SIZE", "EGL_COLOR_BUFFER_TYPE", "EGL_RENDERABLE_TYPE", "EGL_CONFORMANT" }; int[] value = new int[1]; for (int i = 0; i < attributes.length; i++) { int attribute = attributes[i]; String name = names[i]; if (egl.eglGetConfigAttrib(display, config, attribute, value)) { Log.w(TAG, String.format(" %s: %d\n", name, value[0])); } else { // Log.w(TAG, String.format(" %s: failed\n", name)); while (egl.eglGetError() != EGL10.EGL_SUCCESS) ; } } }
@Override public EGLConfig chooseConfig(final EGL10 egl, final EGLDisplay display) { final int[] numberConfigs = new int[1]; if (!egl.eglGetConfigs(display, null, 0, numberConfigs)) { throw new IllegalStateException("Unable to retrieve number of egl configs available."); } final EGLConfig[] configs = new EGLConfig[numberConfigs[0]]; if (!egl.eglGetConfigs(display, configs, configs.length, numberConfigs)) { throw new IllegalStateException("Unable to retrieve egl configs available."); } final int[] configAttribs = { EGL10.EGL_ALPHA_SIZE, 8, // need alpha for the multi-pass // timewarp compositor EGL10.EGL_BLUE_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_RED_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_SAMPLES, 0, EGL10.EGL_NONE }; EGLConfig config = null; for (int i = 0; i < numberConfigs[0]; ++i) { final int[] value = new int[1]; final int EGL_OPENGL_ES3_BIT_KHR = 0x0040; if (!egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, value)) { Log.v(TAG, "eglGetConfigAttrib for EGL_RENDERABLE_TYPE failed"); continue; } if ((value[0] & EGL_OPENGL_ES3_BIT_KHR) != EGL_OPENGL_ES3_BIT_KHR) { continue; } if (!egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, value)) { Log.v(TAG, "eglGetConfigAttrib for EGL_SURFACE_TYPE failed"); continue; } if ((value[0] & (EGL10.EGL_WINDOW_BIT | EGL10.EGL_PBUFFER_BIT)) != (EGL10.EGL_WINDOW_BIT | EGL10.EGL_PBUFFER_BIT)) { continue; } int j = 0; for (; configAttribs[j] != EGL10.EGL_NONE; j += 2) { if (!egl.eglGetConfigAttrib(display, configs[i], configAttribs[j], value)) { Log.v(TAG, "eglGetConfigAttrib for " + configAttribs[j] + " failed"); continue; } if (value[0] != configAttribs[j + 1]) { break; } } if (configAttribs[j] == EGL10.EGL_NONE) { config = configs[i]; break; } } return config; }
private int getAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attrib, int defValue) { if (egl.eglGetConfigAttrib(display, config, attrib, value)) { return value[0]; } return defValue; }
// EGL functions public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) { try { EGL10 egl = (EGL10) EGLContext.getEGL(); if (SDLActivity.mEGLDisplay == null) { SDLActivity.mEGLDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2]; egl.eglInitialize(SDLActivity.mEGLDisplay, version); } if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) { // No current GL context exists, we will create a new one. Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); EGLConfig[] configs = new EGLConfig[128]; int[] num_config = new int[1]; if (!egl.eglChooseConfig(SDLActivity.mEGLDisplay, attribs, configs, 1, num_config) || num_config[0] == 0) { Log.e("SDL", "No EGL config available"); return false; } EGLConfig config = null; int bestdiff = -1, bitdiff; int[] value = new int[1]; // eglChooseConfig returns a number of configurations that match or exceed the requested // attribs. // From those, we select the one that matches our requirements more closely Log.v("SDL", "Got " + num_config[0] + " valid modes from egl"); for (int i = 0; i < num_config[0]; i++) { bitdiff = 0; // Go through some of the attributes and compute the bit difference between what we want // and what we get. for (int j = 0; ; j += 2) { if (attribs[j] == EGL10.EGL_NONE) break; if (attribs[j + 1] != EGL10.EGL_DONT_CARE && (attribs[j] == EGL10.EGL_RED_SIZE || attribs[j] == EGL10.EGL_GREEN_SIZE || attribs[j] == EGL10.EGL_BLUE_SIZE || attribs[j] == EGL10.EGL_ALPHA_SIZE || attribs[j] == EGL10.EGL_DEPTH_SIZE || attribs[j] == EGL10.EGL_STENCIL_SIZE)) { egl.eglGetConfigAttrib(SDLActivity.mEGLDisplay, configs[i], attribs[j], value); bitdiff += value[0] - attribs[j + 1]; // value is always >= attrib } } if (bitdiff < bestdiff || bestdiff == -1) { config = configs[i]; bestdiff = bitdiff; } if (bitdiff == 0) break; // we found an exact match! } Log.d("SDL", "Selected mode with a total bit difference of " + bestdiff); SDLActivity.mEGLConfig = config; SDLActivity.mGLMajor = majorVersion; SDLActivity.mGLMinor = minorVersion; } return SDLActivity.createEGLSurface(); } catch (Exception e) { Log.v("SDL", e + ""); for (StackTraceElement s : e.getStackTrace()) { Log.v("SDL", s.toString()); } return false; } }
/** @return OpenGL ES major version 1, 2, or 3 or some non-positive number for error */ private static int getDetectedVersion() { /* * Get all the device configurations and check the EGL_RENDERABLE_TYPE attribute * to determine the highest ES version supported by any config. The * EGL_KHR_create_context extension is required to check for ES3 support; if the * extension is not present this test will fail to detect ES3 support. This * effectively makes the extension mandatory for ES3-capable devices. */ EGL10 egl = (EGL10) EGLContext.getEGL(); EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] numConfigs = new int[1]; if (egl.eglInitialize(display, null)) { try { boolean checkES3 = hasExtension( egl.eglQueryString(display, EGL10.EGL_EXTENSIONS), "EGL_KHR_create_context"); if (egl.eglGetConfigs(display, null, 0, numConfigs)) { EGLConfig[] configs = new EGLConfig[numConfigs[0]]; if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) { int highestEsVersion = 0; int[] value = new int[1]; for (int i = 0; i < numConfigs[0]; i++) { if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, value)) { if (checkES3 && ((value[0] & EGL_OPENGL_ES3_BIT_KHR) == EGL_OPENGL_ES3_BIT_KHR)) { if (highestEsVersion < 3) highestEsVersion = 3; } else if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) { if (highestEsVersion < 2) highestEsVersion = 2; } else if ((value[0] & EGL_OPENGL_ES_BIT) == EGL_OPENGL_ES_BIT) { if (highestEsVersion < 1) highestEsVersion = 1; } } else { Log.w( TAG, "Getting config attribute with " + "EGL10#eglGetConfigAttrib failed " + "(" + i + "/" + numConfigs[0] + "): " + egl.eglGetError()); } } return highestEsVersion; } else { Log.e(TAG, "Getting configs with EGL10#eglGetConfigs failed: " + egl.eglGetError()); return -1; } } else { Log.e( TAG, "Getting number of configs with EGL10#eglGetConfigs failed: " + egl.eglGetError()); return -2; } } finally { egl.eglTerminate(display); } } else { Log.e(TAG, "Couldn't initialize EGL."); return -3; } }