【问题标题】:java.lang.RuntimeException with EGLConfigChooser on PowerVR G6200PowerVR G6200 上带有 EGLConfigChooser 的 java.lang.RuntimeException
【发布时间】:2017-10-11 14:18:15
【问题描述】:

在使用 PowerVR G6200 GPU 的设备(例如 Sony Xperia M5 (E5603) 和 Xiaomi Redmi Note 3 (hennessy))上,创建使用 OpenGL ES 2 进行渲染的 EGL 上下文失败,而它在我测试过的所有其他设备上都可以使用:

java.lang.RuntimeException: 
  at android.opengl.GLSurfaceView$EglHelper.throwEglException (GLSurfaceView.java:1233)
  at android.opengl.GLSurfaceView$EglHelper.throwEglException (GLSurfaceView.java:1224)
  at android.opengl.GLSurfaceView$EglHelper.start (GLSurfaceView.java:1074)
  at android.opengl.GLSurfaceView$GLThread.guardedRun (GLSurfaceView.java:1447)
  at android.opengl.GLSurfaceView$GLThread.run (GLSurfaceView.java:1286)

配置选择器是这样实现的:

class CustomEGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        EGLConfig [] configs = new EGLConfig[1];
        int [] num_config = new int[1];
        int [] attrib_list  = new int[] {
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_ALPHA_SIZE, 8,
            EGL10.EGL_DEPTH_SIZE, 24,
            EGL10.EGL_STENCIL_SIZE, 8,
            EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
            EGL10.EGL_NONE,
        };

        boolean res = egl.eglChooseConfig(display, attrib_list, configs, configs.length, num_config);
        if (res && num_config[0] > 0) {
            return configs[0];
        }   

        return null;
    }   
}   

配置选择器从 GLSurfaceView 子类中使用,如下所示:

public class GameView extends GLSurfaceView {
    public GameView (Context context, ClientConfig clientConfig) {
        super(context);
        setEGLContextClientVersion(2);
        setEGLConfigChooser(new CustomEGLConfigChooser());
    }
}

【问题讨论】:

    标签: java android opengl-es-2.0 glsurfaceview egl


    【解决方案1】:

    通过比较运行此代码的设备 (Nexus 5x EGL configs) 和非工作设备 (Xiaomi Redmi Note 3 EGL configs) 上的 EGL 配置列表,我发现虽然有匹配的配置,但它们在一个属性上有所不同,即EGL_RENDERABLE_TYPE.

    第一个匹配的 Nexus 5x EGL 配置:

    EGL_CONFIG_ID:  11
    [...]
    EGL_ALPHA_SIZE: 8
    EGL_BLUE_SIZE:  8
    EGL_GREEN_SIZE: 8
    EGL_RED_SIZE:   8
    EGL_DEPTH_SIZE: 24
    EGL_STENCIL_SIZE:   8
    [...]
    EGL_RENDERABLE_TYPE:    OpenGL_ES OpenGL_ES_2 (5)
    

    第一个匹配的小米红米 Note 3 EGL 配置:

    EGL_CONFIG_ID:  1
    [...]
    EGL_ALPHA_SIZE: 8
    EGL_BLUE_SIZE:  8
    EGL_GREEN_SIZE: 8
    EGL_RED_SIZE:   8
    EGL_DEPTH_SIZE: 24
    EGL_STENCIL_SIZE:   8
    [...]
    EGL_RENDERABLE_TYPE:    OpenGL_ES (1)
    

    请注意,Nexus 5x 支持EGL_RENDERABLE_TYPEEGL_OPENGL_ES2_BIT(此外还支持具有相同配置的EGL_OPENGL_ES_BIT),所以我们很幸运现有设备上的所有配置都支持这两种可渲染类型.

    小米红米 Note 3 还有一个支持 ES2 可渲染类型的配置,但这并不是第一个匹配的配置:

    EGL_CONFIG_ID:  23
    [...]
    EGL_ALPHA_SIZE: 8
    EGL_BLUE_SIZE:  8
    EGL_GREEN_SIZE: 8
    EGL_RED_SIZE:   8
    EGL_DEPTH_SIZE: 24
    EGL_STENCIL_SIZE:   8
    [...]
    EGL_RENDERABLE_TYPE:    OpenGL_ES_2 (4)
    

    尝试在 ES2 渲染上下文中使用第一个(配置 ID 1)显然是行不通的,因为该配置不支持 ES2 可渲染对象。解决方法是显式请求可渲染类型作为 EGL 配置选择器的一部分,如下所示修改问题中的示例:

            int [] attrib_list  = new int[] {
                EGL10.EGL_RED_SIZE, 8,
                EGL10.EGL_GREEN_SIZE, 8,
                EGL10.EGL_BLUE_SIZE, 8,
                EGL10.EGL_ALPHA_SIZE, 8,
                EGL10.EGL_DEPTH_SIZE, 24,
                EGL10.EGL_STENCIL_SIZE, 8,
                EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
                EGL10.EGL_RENDERABLE_TYPE, EGL10. EGL_OPENGL_ES2_BIT,
                EGL10.EGL_NONE,
            };
    

    请注意,在只需要请求 RGBA + 深度/模板值的情况下,另一种选择是使用 setEGLConfigChooser(int, int, int, int, int, int) 而不是自定义实现,这将处理基于请求 EGL_RENDERABLE_TYPEsetEGLContextClientVersion() 中设置的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-19
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      相关资源
      最近更新 更多