解决Android OpenGl 因 配置EGLConfigChooser 错误造成的 EGL_BAD_CONFIG error,导致打开摄像头后黑屏问题。

自动选择最好的EGLConfig。

        EGL10 egl = (EGL10) EGLContext.getEGL();        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);        int[] version = new int[3];        if (egl.eglInitialize(display, version) == true) {            logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});        }        try {            // Create a config chooser            AndroidConfigChooser configChooser = new AndroidConfigChooser(ConfigType.BEST);            // Init chooser            if (!configChooser.findConfig(egl, display)) {                Log.e("yl","Unable to find suitable EGL config");            }            clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();            if (clientOpenGLESVersion < 2) {            Log.e("yl","OpenGL ES 2.0 is not supported on this device");           }            // Requesting client version from GLSurfaceView which is extended by            // AndroidInput.            this.setEGLContextClientVersion(clientOpenGLESVersion);            this.setEGLConfigChooser(configChooser);        } finally {            if (display != null) {                egl.eglTerminate(display);            }        }

AndroidConfigChooser.java

import android.graphics.PixelFormat;import android.opengl.GLSurfaceView.EGLConfigChooser;import java.util.logging.Level;import java.util.logging.Logger;import javax.microedition.khronos.egl.EGL10;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.egl.EGLDisplay;/** * AndroidConfigChooser is used to determine the best suited EGL Config * * @author larynx */public class AndroidConfigChooser implements EGLConfigChooser {    private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());    protected int clientOpenGLESVersion = 0;    protected EGLConfig bestConfig = null;    protected EGLConfig fastestConfig = null;    protected EGLConfig choosenConfig = null;    protected ConfigType type;    protected int pixelFormat;    protected boolean verbose = false;    private final static int EGL_OPENGL_ES2_BIT = 4;    public enum ConfigType {        /**         * RGB565, 0 alpha, 16 depth, 0 stencil         */        FASTEST,        /**         * RGB???, 0 alpha, >=16 depth, 0 stencil         */        BEST,        /**         * Turn off config chooser and use hardcoded         * setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16,         * 0);         */        LEGACY    }    public AndroidConfigChooser(ConfigType type) {        this.type = type;    }    /**     * Gets called by the GLSurfaceView class to return the best config     */    @Override    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {        logger.info("GLSurfaceView asks for egl config, returning: ");        logEGLConfig(choosenConfig, display, egl);        return choosenConfig;    }    /**     * findConfig is used to locate the best config and init the chooser with     *     * @param egl     * @param display     * @return true if successfull, false if no config was found     */    public boolean findConfig(EGL10 egl, EGLDisplay display) {        if (type == ConfigType.BEST) {            ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);            choosenConfig = compChooser.chooseConfig(egl, display);            if (choosenConfig == null) {                compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0);                choosenConfig = compChooser.chooseConfig(egl, display);                if (choosenConfig == null) {                    compChooser = new ComponentSizeChooser(8, 8, 8, 8, 16, 0);                    choosenConfig = compChooser.chooseConfig(egl, display);                    if (choosenConfig == null) {                        compChooser = new ComponentSizeChooser(8, 8, 8, 0, 16, 0);                        choosenConfig = compChooser.chooseConfig(egl, display);                    }                }            }            logger.info("JME3 using best EGL configuration available here: ");        } else {            ComponentSizeChooser compChooser = new ComponentSizeChooser(5, 6, 5, 0, 16, 0);            choosenConfig = compChooser.chooseConfig(egl, display);            logger.info("JME3 using fastest EGL configuration available here: ");        }        if (choosenConfig != null) {            logger.info("JME3 using choosen config: ");            logEGLConfig(choosenConfig, display, egl);            pixelFormat = getPixelFormat(choosenConfig, display, egl);            clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);            return true;        } else {            logger.severe("###ERROR### Unable to get a valid OpenGL ES 2.0 config, nether Fastest nor Best found! Bug. Please report this.");            clientOpenGLESVersion = 1;            pixelFormat = PixelFormat.UNKNOWN;            return false;        }    }    private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) {        int[] value = new int[1];        int result = PixelFormat.RGB_565;        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);        if (value[0] == 8) {            result = PixelFormat.RGBA_8888;            /*            egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);            if (value[0] == 8)            {                result = PixelFormat.RGBA_8888;            }            else            {                result = PixelFormat.RGB_888;            }*/        }        if (verbose) {            logger.log(Level.INFO, "Using PixelFormat {0}", result);        }        //return result; TODO Test pixelformat        return PixelFormat.TRANSPARENT;    }    private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) {        int[] value = new int[1];        int result = 1;        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);        // Check if conf is OpenGL ES 2.0        if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) {            result = 2;        }        return result;    }    /**     * log output with egl config details     *     * @param conf     * @param display     * @param egl     */    public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl) {        int[] value = new int[1];        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);        logger.info(String.format("EGL_RED_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0]));        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);        logger.info(String.format("EGL_SURFACE_TYPE  = %d", value[0]));    }    public int getClientOpenGLESVersion() {        return clientOpenGLESVersion;    }    public void setClientOpenGLESVersion(int clientOpenGLESVersion) {        this.clientOpenGLESVersion = clientOpenGLESVersion;    }    public int getPixelFormat() {        return pixelFormat;    }    private abstract class BaseConfigChooser implements EGLConfigChooser {        private boolean bClientOpenGLESVersionSet;        public BaseConfigChooser(int[] configSpec) {            bClientOpenGLESVersionSet = false;            mConfigSpec = filterConfigSpec(configSpec);        }        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {            int[] num_config = new int[1];            if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,                    num_config)) {                throw new IllegalArgumentException("eglChooseConfig failed");            }            int numConfigs = num_config[0];            if (numConfigs <= 0) {                //throw new IllegalArgumentException("No configs match configSpec");                return null;            }            EGLConfig[] configs = new EGLConfig[numConfigs];            if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,                    num_config)) {                throw new IllegalArgumentException("eglChooseConfig#2 failed");            }            EGLConfig config = chooseConfig(egl, display, configs);            //if (config == null) {            //    throw new IllegalArgumentException("No config chosen");            //}            return config;        }        abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,                EGLConfig[] configs);        protected int[] mConfigSpec;        private int[] filterConfigSpec(int[] configSpec) {            if (bClientOpenGLESVersionSet == true) {                return configSpec;            }            /*             * We know none of the subclasses define EGL_RENDERABLE_TYPE. And we             * know the configSpec is well formed.             */            int len = configSpec.length;            int[] newConfigSpec = new int[len + 2];            System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1);            newConfigSpec[len - 1] = EGL10.EGL_RENDERABLE_TYPE;            newConfigSpec[len] = 4; /*             * EGL_OPENGL_ES2_BIT             */            newConfigSpec[len + 1] = EGL10.EGL_NONE;            bClientOpenGLESVersionSet = true;            return newConfigSpec;        }    }    /**     * Choose a configuration with exactly the specified r,g,b,a sizes, and at     * least the specified depth and stencil sizes.     */    private class ComponentSizeChooser extends BaseConfigChooser {        private int[] mValue;        // Subclasses can adjust these values:        protected int mRedSize;        protected int mGreenSize;        protected int mBlueSize;        protected int mAlphaSize;        protected int mDepthSize;        protected int mStencilSize;                public ComponentSizeChooser(int redSize, int greenSize, int blueSize,                int alphaSize, int depthSize, int stencilSize) {            super(new int[]{                        EGL10.EGL_RED_SIZE, redSize,                        EGL10.EGL_GREEN_SIZE, greenSize,                        EGL10.EGL_BLUE_SIZE, blueSize,                        EGL10.EGL_ALPHA_SIZE, alphaSize,                        EGL10.EGL_DEPTH_SIZE, depthSize,                        EGL10.EGL_STENCIL_SIZE, stencilSize,                        EGL10.EGL_NONE});            mValue = new int[1];            mRedSize = redSize;            mGreenSize = greenSize;            mBlueSize = blueSize;            mAlphaSize = alphaSize;            mDepthSize = depthSize;            mStencilSize = stencilSize;        }        @Override        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {            for (EGLConfig config : configs) {                int d = findConfigAttrib(egl, display, config,                        EGL10.EGL_DEPTH_SIZE, 0);                int s = findConfigAttrib(egl, display, config,                        EGL10.EGL_STENCIL_SIZE, 0);                if ((d >= mDepthSize) && (s >= mStencilSize)) {                    int r = findConfigAttrib(egl, display, config,                            EGL10.EGL_RED_SIZE, 0);                    int g = findConfigAttrib(egl, display, config,                            EGL10.EGL_GREEN_SIZE, 0);                    int b = findConfigAttrib(egl, display, config,                            EGL10.EGL_BLUE_SIZE, 0);                    int a = findConfigAttrib(egl, display, config,                            EGL10.EGL_ALPHA_SIZE, 0);                    if ((r == mRedSize) && (g == mGreenSize)                            && (b == mBlueSize) && (a == mAlphaSize)) {                        return config;                    }                }            }            return null;        }        private int findConfigAttrib(EGL10 egl, EGLDisplay display,                EGLConfig config, int attribute, int defaultValue) {            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {                return mValue[0];            }            return defaultValue;        }    }}




更多相关文章

  1. Android前置摄像头视频录制失败(MediaRecorder: start failed: -1
  2. android 从横屏到竖屏状态出现黑屏
  3. Android(安卓)Studio 报错集合解决方案
  4. 在Ubuntu12.10-32bit上构建、测试WebRTC之Android示例WebRTCDemo
  5. Android常见错误之[email&#160;protected] that was originally
  6. Android中调用startActivity结果导致:java.lang.RuntimeException
  7. Android的Face++Demo错误1302
  8. Android(安卓)make sdk 错误解决方案
  9. DDM dispatch reg wait timeout , Can't dispatch DDM chunk 解

随机推荐

  1. android 常用第三方插件收藏
  2. Android的冷启动优化
  3. android存取数据(基础)
  4. 从屏幕底部弹出PopupWindow
  5. Android自定义弹窗效果
  6. Android(安卓)Design Support Library之T
  7. Flutter Android(安卓)Studio打包安卓apk
  8. android 2.1 监听电话状态并自动接听来电
  9. Win10下编译Android(安卓)Ogre3d 1.12.6
  10. Animation Android(安卓)( 一)