创建窗口表面失败:EGL_BAD_MATCH?

2023-11-25

Android 版本是 2.2.1 设备是三星 Galaxy II 完整的崩溃日志是:

java.lang.RuntimeException: createWindowSurface failed: EGL_BAD_MATCH
at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1077)
at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:981)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1304)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)

这是崩溃的相关代码:

@Override 
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                         WindowManager.LayoutParams.FLAG_FULLSCREEN);
    glView = new GLSurfaceView(this);
    glView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
    glView.setRenderer(this);
    setContentView(glView);
    \\etc..............}

我使用了 setEGLConfigChooser() ,因为如果应用程序不在那里,它就会在 API-17 上崩溃,因此对于这个特定的设备,它在我一直在环顾四周,它与设备的 PixelFormat 有关。

我想知道如何使用一些代码,这样就不会在三星 Galaxy II Android 版本 2.2.1 上崩溃,我无法在模拟器中测试它,而且我没有设备来测试它,我只需要确定的代码我不知道如何改变它?


Update:我找到了解决这个问题的方法,实际上它相当简单。

首先:Android的默认EGLConfigChooser实施对某些方面做出了错误的决定 设备。尤其是较旧的 Android 设备似乎会遭受这种情况EGL_BAD_MATCH问题。在调试过程中,我还发现那些较旧的麻烦制造者设备的可用 OpenGL ES 配置非常有限。

造成这种“不匹配”问题的原因不仅仅是 GLSurfaceView 的像素格式与 OpenGL ES 的颜色位深度设置之间的不匹配。总的来说,我们要解决以下几个问题:

  • OpenGL ES API 版本不匹配
  • 请求的目标表面类型不匹配
  • 请求的颜色位深度无法在表面视图上渲染

Android 开发者文档在解释 OpenGL ES API 方面严重缺乏。因此,阅读 Khronos.org 上的原始文档非常重要。特别是关于的文档页面例如选择配置在这里很有帮助。

为了解决上述问题,您必须确保指定以下最低配置:

  • EGL_RENDERABLE_TYPE必须与您正在使用的 OpenGL ES API 版本匹配。在 OpenGL ES 2.x 的可能情况下,您必须将该属性设置为4(see egl.h)
  • EGL_SURFACE_TYPE应该有EGL_WINDOW_BIT set

当然,您还需要设置一个 OpenGL ES 上下文,为您提供正确的颜色、深度和模板缓冲区设置。

不幸的是,不可能以直接的方式挑选这些配置选项。我们必须从任何给定设备上可用的任何内容中进行选择。这就是为什么有必要实施自定义EGLConfigChooser,它会遍历可用配置集的列表,并选择与给定条件最匹配的最合适的配置集。

不管怎样,我为这样的配置选择器创建了一个示例实现:

public class MyConfigChooser implements EGLConfigChooser {
    final private static String TAG = "MyConfigChooser";

    // This constant is not defined in the Android API, so we need to do that here:
    final private static int EGL_OPENGL_ES2_BIT = 4;

    // Our minimum requirements for the graphics context
    private static int[] mMinimumSpec = {
            // We want OpenGL ES 2 (or set it to any other version you wish)
            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,

            // We want to render to a window
            EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,

            // We do not want a translucent window, otherwise the
            // home screen or activity in the background may shine through
            EGL10.EGL_TRANSPARENT_TYPE, EGL10.EGL_NONE, 

            // indicate that this list ends:
            EGL10.EGL_NONE
    };

    private int[] mValue = new int[1];
    protected int mAlphaSize;
    protected int mBlueSize;
    protected int mDepthSize;
    protected int mGreenSize;
    protected int mRedSize;
    protected int mStencilSize;

    /**
    * The constructor lets you specify your minimum pixel format,
    * depth and stencil buffer requirements.
    */
    public MyConfigChooser(int r, int g, int b, int a, int depth, int 
                        stencil) {
        mRedSize = r;
        mGreenSize = g;
        mBlueSize = b;
        mAlphaSize = a;
        mDepthSize = depth;
        mStencilSize = stencil;
    }

    @Override
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        int[] arg = new int[1];
        egl.eglChooseConfig(display, mMinimumSpec, null, 0, arg);
        int numConfigs = arg[0];
        Log.i(TAG, "%d configurations available", numConfigs);

        if(numConfigs <= 0) {
            // Ooops... even the minimum spec is not available here
            return null;
        }

        EGLConfig[] configs = new EGLConfig[numConfigs];
        egl.eglChooseConfig(display, mMinimumSpec, configs,    
            numConfigs, arg);

        // Let's do the hard work now (see next method below)
        EGLConfig chosen = chooseConfig(egl, display, configs);

        if(chosen == null) {
            throw new RuntimeException(
                    "Could not find a matching configuration out of "
                            + configs.length + " available.", 
                configs);
        }

        // Success
        return chosen;
    }

   /**
    * This method iterates through the list of configurations that 
    * fulfill our minimum requirements and tries to pick one that matches best
    * our requested color, depth and stencil buffer requirements that were set using 
    * the constructor of this class.
    */
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
            EGLConfig[] configs) {
        EGLConfig bestMatch = null;
        int bestR = Integer.MAX_VALUE, bestG = Integer.MAX_VALUE, 
            bestB = Integer.MAX_VALUE, bestA = Integer.MAX_VALUE, 
            bestD = Integer.MAX_VALUE, bestS = Integer.MAX_VALUE;

        for(EGLConfig config : configs) {
            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);
            int d = findConfigAttrib(egl, display, config,
                    EGL10.EGL_DEPTH_SIZE, 0);
            int s = findConfigAttrib(egl, display, config,
                    EGL10.EGL_STENCIL_SIZE, 0);

            if(r <= bestR && g <= bestG && b <= bestB && a <= bestA
                    && d <= bestD && s <= bestS && r >= mRedSize
                    && g >= mGreenSize && b >= mBlueSize 
                    && a >= mAlphaSize && d >= mDepthSize 
                    && s >= mStencilSize) {
                bestR = r;
                bestG = g;
                bestB = b;
                bestA = a;
                bestD = d;
                bestS = s;
                bestMatch = config;
            }
        }

        return bestMatch;
    }

    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;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建窗口表面失败:EGL_BAD_MATCH? 的相关文章

随机推荐

  • 从两个日期之间的日期范围中选择数据

    我有一张名为Product Sales它保存这样的数据 Product ID Sold by Qty From date To date 3 12 7 2013 01 05 2013 01 07 6 22 14 2013 01 06 201
  • 如何在 React 中使用 RXJS fromEvent?

    我试图在反应中记录按钮上的点击事件 const InputBox gt const clicky fromEvent document getElementById clickMe click subscribe clickety gt c
  • 如何创建数组的随机排列?

    我已经用 C 编写了这个函数 我希望它创建一个随机排列或从 1 到 n 的数字列表 我很难让它没有重复的数字 因此 如果您有 n 4 我希望它返回一个包含 1 4 的随机数组 每个数组仅一次 例如 1 3 4 2 int random in
  • 如何使用 powershell 为 Windows 10 通用应用程序创建桌面快捷方式?

    我有一个创建的 UWP 应用程序 想要使用 powershell 在桌面上创建快捷方式 创建快捷方式对于 exe 来说很容易 TargetFile Path To MyProgram exe ShortcutFile env USERPRO
  • 访问相关对象键而不在App Engine中获取对象

    一般来说 对给定对象执行单个查询比执行多个查询更好 假设我有一堆 儿子 对象 每个对象都有一个 父亲 我得到了所有 儿子 对象 sons Son all 然后 我想找到那群儿子的所有父亲 我愿意 father keys for son in
  • 如何将GET参数传递给jsFiddle

    如何将GET参数传递给jsFiddle 我试过http jsfiddle net mKwcF id 123但我得到的只是http fiddle jshell net mKwcF show 我的示例 js 在上面给定的链接上很简单 alert
  • 如何让建议组件在 SolrNet 中工作?

    我已经配置了 solrconfig xml 和 schema xml 来查询建议 我可以从网址中获取建议 http localhost 8080 solr collection1 suggest q ha wt xml 我的 SolrCon
  • 现代 n 层 ASP.NET Web 应用程序示例?

    所以我的 asp net 非常非常生锈 我正在尝试回到最佳实践以及其他什么 因此 我快速搜索谷歌并开始寻找示例 示例和教程 但我找到了什么 甚至在石器时代 最新 技术发布之前就已经写了一些陈旧的硬壳东西 当然 这些概念可能仍然有效 但实际执
  • 以 UTC 存储时间总是一个好主意,还是在这种情况下以本地时间存储更好?

    一般来说 最好的做法是用 UTC 存储时间 如中所述here and here 假设有一个重复发生的事件 假设结束时间始终为同一当地时间 假设为 17 00 无论该时区是否启用夏令时 并且还要求在特定时区的 DST 打开或关闭时不要手动更改
  • 在 Android 中调整位图大小

    我使用以下代码调整位图的大小 FileOutputStream out new FileOutputStream sdcard mods png Bitmap bmp Bitmap createScaledBitmap pict int p
  • 将数字限制在某个范围内 (Haskell)

    我公开了一个带有两个参数的函数 一个是最小界限 另一个是最大界限 例如 如何使用类型确保最小界限不大于最大界限 我想避免创建一个智能构造函数并返回 Maybe 因为它会使整个使用更加麻烦 谢谢 这并不能完全回答你的问题 但有时有效的一种方法
  • AWS Cognito - 用户池联合与身份池联合

    Question 为什么 AWS Cognito 有两个位置来联合身份提供商 我认为身份池应该与身份提供商联合 并且想知道为什么用户池也可以 请说明为什么有两个地点的原因 Cognito Identity Pool can federate
  • 清除__m128i的高字节

    我该如何清除16 ia 的高字节 m128i 我已经尝试过这个 它有效 但我想知道是否有更好 更短 更快 的方法 int i 0 lt i lt 16 m128i x m128i mask mm set epi8 0 i gt 14 1 0
  • 如何在 Express js 中使用 cookie 重定向到不同的域

    我正在 Node 上使用 Express 开发一个 Web 应用程序 我正在尝试实现代理登录功能 用户在登录我的网站后直接登录并重定向到另一个网站 在我的路由函数中 我编写了以下代码 res cookie fanws 值 res 重定向 h
  • Hyperv 似乎没有安装

    Hyper V 已启动 操作系统 Windows 10 专业版 内存 4GB Power shell 在管理模式下启动 我已经创建了一个虚拟交换机管理器 然后我正在尝试以下命令 minikube start vm driver hyperv
  • Flutter:让应用程序在后台运行的跨平台方式

    我正在尝试找出一种方法来保持 Flutter 应用程序运行 即使它没有处于焦点状态 例如 无论前台正在运行什么 都可以运行倒计时并在完成时播放警报声 显示通知 有人能指出我正确的方向吗 理想情况下 可以跨平台工作 我找到了这个thread但
  • PHP SimpleXML 换行

    我使用 PHP 的简单 XML 创建了一个 XML 文件 并保存了该文件 使用 fopen 在 php 中打开文件并打印内容时 我的 XML 如下所示 见下文
  • 让 CIColorCube 滤镜在 Swift 中工作

    我正在尝试让 CIColorCube 过滤器正常工作 然而 苹果文档仅提供了一个解释不清的参考示例 Allocate memory const unsigned int size 64 float cubeData float malloc
  • Java 中的 HMAC SHA1 签名

    我正在尝试与 TransUnion Web 服务交互 并且需要提供 HMAC SHA1 签名才能访问它 此示例位于 TransUnion 文档中 输入SampleIntegrationOwner2008 11 18T19 14 40 293
  • 创建窗口表面失败:EGL_BAD_MATCH?

    Android 版本是 2 2 1 设备是三星 Galaxy II 完整的崩溃日志是 java lang RuntimeException createWindowSurface failed EGL BAD MATCH at androi