Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 362|回复: 0

java.lang.IllegalArgumentException: No config chosen异常

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-27 14:30:46 | 显示全部楼层 |阅读模式

    针对java.lang.IllegalArgumentException: No config chosen异常,网络上流行的修改办法是:

    在游戏端,调用gLSurfaceView.setEGLConfigChooser(8 8, 8, 8, 16, 0)。

    这样修改,到底修改了什么,如何起作用的?下面分析下源码,看看这个问题。

    EGL 是 OpenGLES 和底层 Native 平台视窗系统之间的接口。对EGL的使用,一般是初始化后,选择恰当的配置。

    下面是选择一个 EGL 配置的函数原型:

    EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint * num_config);

    参数 attrib_list 指定了选择配置时需要参照的属性。参数 configs 将返回一个按照 attrib_list 排序的平台有效的所有 EGL framebuffer 配置列表。参数 config_size 指定了可以返回到 configs 的总配置个数。参数 num_config 返回了实际匹配的配置总数。

    1.异常发生的现场如下:

    <BaseConfigChooser类>

     

    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        int[] num_config = new int[1];
        //第一次调用eglChooseConfig获取有效配置数,mConfigSpec为参考属性,在构造函数中赋值
        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");
        }
        EGLConfig[] configs = new EGLConfig[numConfigs];
        //第二次调用eglChooseConfig获取有效配置列表
        if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
            num_config)) {
            throw new IllegalArgumentException("eglChooseConfig#2 failed");
        }
        //调用另一个重载的chooseConfig函数(为抽象方法,在子类中实现),根据给定的r,g,b,a,depth,stencil选择EGL配置
        EGLConfig config = chooseConfig(egl, display, configs);
        if (config == null) {
            //抛出java.lang.IllegalArgumentException: No config chosen异常
            throw new IllegalArgumentException("No config chosen");  
        }
        return config;
    }
    

     

         

    2.下面来看看chooseConfig(egl, display, configs)何时会返回NULL

    <ComponentSizeChooser类继承自BaseConfigChooser>

     

    private class ComponentSizeChooser extends BaseConfigChooser {
        //构造函数
        public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
                    int alphaSize, int depthSize, int stencilSize) {
                //构造父类,即BaseConfigChooser,设置对应的mConfigSpec
                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;
           }
    
        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;
            }
    

     

        

    该函数遍历所有配置,找到第一个满足如下条件的配置:

    ①Depth和Stencil不小于给定值

    ②R,G,B,Alpha等于给定值

    当没有满足上述条件的EGL配置时,返回NULL。

    这些给定值从和而来?这就是setEGLConfigChooser的工作

     

    3.setEGLConfigChooser都干了些啥

    <GLSurfaceView类>

     

    public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, 
    
                                    int alphaSize, int depthSize, int stencilSize) { 
    
        setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, 
    
                                blueSize, alphaSize, depthSize, stencilSize)); 
    
    } 
    

     

        

    该函数根据给定的r,g,b,a,depth,stencil值创建ComponentSizeChooser实例。ComponentSizeChooser::chooseConfig函数会用到这些值。

     

    从以上源码可知,

    调用gLSurfaceView.setEGLConfigChooser(8 8, 8, 8, 16, 0),

    GLSurfaceView 将根据(r,g,b,a,depth,stencil)-(8 8, 8, 8, 16, 0)去选择EGL配置。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 16:39 , Processed in 0.062998 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表