package com.af.experiments.FxCameraApp.ogles;
import android.opengl.GLSurfaceView;
import android.os.Build;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import static javax.microedition.khronos.egl.EGL10.*;
public class DefaultConfigChooser implements GLSurfaceView.EGLConfigChooser {
private final int[] mConfigSpec;
private final int mRedSize;
private final int mGreenSize;
private final int mBlueSize;
private final int mAlphaSize;
private final int mDepthSize;
private final int mStencilSize;
public DefaultConfigChooser(final int version) {
this(true, version);
}
private static final int JELLY_BEAN_MR1 = 17;
private static final boolean USE_RGB_888 = Integer.parseInt(Build.VERSION.SDK) >= JELLY_BEAN_MR1;
public DefaultConfigChooser(final boolean withDepthBuffer, final int version) {
this(
USE_RGB_888 ? 8 : 5,
USE_RGB_888 ? 8 : 6,
USE_RGB_888 ? 8 : 5,
0,
withDepthBuffer ? 16 : 0,
0,
version
);
}
public DefaultConfigChooser(
final int redSize,
final int greenSize,
final int blueSize,
final int alphaSize,
final int depthSize,
final int stencilSize,
final int version) {
mConfigSpec = filterConfigSpec(new int[]{
EGL_RED_SIZE, redSize,
EGL_GREEN_SIZE, greenSize,
EGL_BLUE_SIZE, blueSize,
EGL_ALPHA_SIZE, alphaSize,
EGL_DEPTH_SIZE, depthSize,
EGL_STENCIL_SIZE, stencilSize,
EGL_NONE
}, version);
mRedSize = redSize;
mGreenSize = greenSize;
mBlueSize = blueSize;
mAlphaSize = alphaSize;
mDepthSize = depthSize;
mStencilSize = stencilSize;
}
private static final int EGL_OPENGL_ES2_BIT = 4;
private int[] filterConfigSpec(final int[] configSpec, final int version) {
if (version != 2) {
return configSpec;
}
/*
* We know none of the subclasses define EGL_RENDERABLE_TYPE.
* And we know the configSpec is well formed.
*/
final int len = configSpec.length;
final int[] newConfigSpec = new int[len + 2];
System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1);
newConfigSpec[len - 1] = EGL_RENDERABLE_TYPE;
newConfigSpec[len] = EGL_OPENGL_ES2_BIT;
newConfigSpec[len + 1] = EGL_NONE;
return newConfigSpec;
}
//////////////////////////////////////////////////////////////////////////
@Override
public EGLConfig chooseConfig(final EGL10 egl, final EGLDisplay display) {
// 要求されている仕様から使用可能な構成の数を抽出します。
final int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
final int config_size = num_config[0];
if (config_size <= 0) {
throw new IllegalArgumentException("No configs match configSpec");
}
// 実際の構成を抽出します。
final EGLConfig[] configs = new EGLConfig[config_size];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, config_size, num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
final EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
}
return config;
}
EGLConfig chooseConfig(final EGL10 egl, final EGLDisplay display, final EGLConfig[] configs) {
for (final EGLConfig config : configs) {
final int d = findConfigAttrib(egl, display, config, EGL_DEPTH_SIZE, 0);
final int s = findConfigAttrib(egl, display, config, EGL_STENCIL_SIZE, 0);
if ((d >= mDepthSize) && (s >= mStencilSize)) {
final int r = findConfigAttrib(egl, display, config, EGL_RED_SIZE, 0);
final int g = findConfigAttrib(egl, display, config, EGL_GREEN_SIZE, 0);
final int b = findConfigAttrib(egl, display, config, EGL_BLUE_SIZE, 0);
final int a = findConfigAttrib(egl, display, config, EGL_ALPHA_SIZE, 0);
if ((r == mRedSize) && (g == mGreenSize) && (b == mBlueSize) && (a == mAlphaSize)) {
return config;
}
}
}
return null;
}
private int findConfigAttrib(final EGL10 egl, final EGLDisplay display, final EGLConfig config, final int attribute, final int defaultValue) {
final int[] value = new int[1];
if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
return value[0];
}
return defaultValue;
}
}