createWindowSurface失败:EGL_BAD_MATCH? [英] createWindowSurface failed: EGL_BAD_MATCH?

查看:1912
本文介绍了createWindowSurface失败:EGL_BAD_MATCH?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

the version android is 2.2.1 the device is a samsung galaxy II the full crash log is:

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)

这是有关code到崩溃:

this is the relevant code to the crash:

@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的设备这个特定的设备。wasnt

i used setEGLConfigChooser() because the app would crash on API-17 if it wasnt in there so for this specific device that it is crashing on i been looking around and it has something to do with the PixelFormat for the device.

什么即时知道是我如何可以用一些code所以这将在三星Galaxy II的Andr​​oid 2.2.1版本没有崩溃,我不能在模拟器测试这一点,我没有将设备进行测试,我只是需要确保code和林不知道如何去改变它呢?

What im wondering is how can i use some code so this will not crash on the samsung galaxy II android version 2.2.1, i cant test this in an emulator and i dont have the device to test it in, i just need for sure code and im not sure how to change it up?

推荐答案

更新:我找到了一种方法来解决这个问题,它实际上是相当简单的。

Update: I found a way to work around this issue and actually it is fairly straightforward.

首先:Android的默认 EGLConfigChooser 的实施,使得一些糟糕的决定 设备。尤其是较旧的Andr​​oid设备似乎受此 EGL_BAD_MATCH 的问题。在我的调试会话我还发现,那些年龄较大的麻烦制造者设备有相当一组可用的OpenGL ES配置有限的。

First of all: Android's default EGLConfigChooser implementation makes bad decisions on some devices. Especially the older Android devices seem to suffer this EGL_BAD_MATCH issue. During my debugging sessions I also discovered that those older troublemaker devices had quite a limited set of available OpenGL ES configurations.

这个坏匹配的问题的原因不仅仅是GLSurfaceView的像素格式和OpenGL ES的色彩位深的设置不匹配。整体而言,我们必须处理以下问题:

The cause of this "bad match" problem is more than just a mismatch between the GLSurfaceView's pixel format and the color bit depth settings of OpenGL ES. Overall we have to deal with the following issues:

  • 的OpenGL ES的API版本不匹配
  • 请求的目标表面类型的不匹配
  • 在所要求的色位深度不能在表面视图渲染

Android的开发者文档,严重缺乏时,它涉及到解释的OpenGL ES API。因此,重要的阅读原始文件在上Khronos.org。特别是有关 eglChooseConfig 的文档页面是有帮助这里

The Android developer documentation is severely lacking when it comes to explaining the OpenGL ES API. It is therefore important to read the original documentation over at Khronos.org. Especially the doc page about eglChooseConfig is helpful here.

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

In order to remedy above listed problems you have to make sure to specify the following minimum configuration:

  • EGL_RENDERABLE_TYPE 必须要使用的OpenGL ES的API版本相匹配。在OpenGL ES的2.X可能的情况下,你必须设置该属性为 4 (见的 egl.h
  • EGL_SURFACE_TYPE 应具备的 EGL_WINDOW_BIT 设置
  • EGL_RENDERABLE_TYPE must match the OpenGL ES API version you are using. In the likely case of OpenGL ES 2.x you must set that attribute to 4(see egl.h)
  • EGL_SURFACE_TYPE should have the EGL_WINDOW_BIT set

当然,你也想设置一个OpenGL ES环境,为您提供正确的颜色,深度和模板缓冲区设置。

And of course you also want to set up an OpenGL ES context that provides you with the correct color, depth and stencil buffer settings.

不幸的是,不可能对挑拣以直接的方式将这些配置选项。我们无论从任何可在任何给定的设备上进行选择。这就是为什么要实现自定义 EGLConfigChooser <有必要/ code> ,即经过现有的配置集列表,并挑选最适合的匹配最好的给定条件。

Unfortunately it is not possible to cherry-pick these configuration options in a straightforward way. We have to choose from whatever is available on any given device. That's why it is necessary to implement a custom EGLConfigChooser, that goes through the list of available configuration sets and picks the most suitable one that matches best the given criteria.

不管怎样,我掀起了一个样本实现这样的配置选择器:

Anyway, I whipped up a sample implementation for such a config chooser:

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;
    }
}

这篇关于createWindowSurface失败:EGL_BAD_MATCH?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆