1

一部のopengl ESドライバーで問題に直面しています。Pbufferに対してglReadPixelsを呼び出すと、一部のデバイスはメッセージなしでアプリを強制終了します。他の人は私に次のトレースを提供し、アプリを強制終了する前に約 10 秒間フリーズします。

Unable to Find Phys Addr for 0

これまでのところ、問題が再現可能な影響を受けるデバイスは次のとおりです。

Galaxy Y, Galaxy Ace, Galaxy Mini, Galaxy Young

また、次のデバイスでコードをテストしましたが、期待どおりに正しく動作し、まったく問題はありません。

Nexy 4, Nexus 7, Nexus Galaxy, SGI, SGII, SGIII, Motorola Mini-Defy, and some others more.

問題を再現する簡単なテスト機能をまとめました。多分誰かが問題を見つけることができます。これは単なるテスト方法です。バグをテストできるようにまとめただけなので、レビューは必要ありません。何か見逃した場合はお知らせください。

private static void bugTest()
{
    EGL10 egl = (EGL10)EGLContext.getEGL();
    EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

    // Initialize
    int[] version = new int[2];
    egl.eglInitialize(eglDisplay, version);

    // Query total number of configurations
    int[] totalConfigurations = new int[1];
    egl.eglGetConfigs(eglDisplay, null, 0, totalConfigurations);

    EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
    int attribs[] = { EGL10.EGL_RENDERABLE_TYPE, 4 /* EGL_OPENGL_ES2_BIT */, EGL10.EGL_RED_SIZE, 1, EGL10.EGL_GREEN_SIZE, 1, EGL10.EGL_BLUE_SIZE, 1, EGL10.EGL_NONE };

    if (egl.eglChooseConfig(eglDisplay, attribs, configurationsList, 1, totalConfigurations) == false)
    {
        Log.e(TAG, "Could not find config for GLES2");          
        egl.eglTerminate(eglDisplay);
        return;
    }

    // Create the PBuffer

    EGLSurface eglSurface = null;
    final int surfaceWidth = 512;
    final int surfaceHeight = 512;

    try
    {
        int[] attribList = new int[] { EGL10.EGL_WIDTH, surfaceWidth, EGL10.EGL_HEIGHT, surfaceHeight, EGL10.EGL_NONE };
        eglSurface = egl.eglCreatePbufferSurface(eglDisplay, configurationsList[0], attribList);
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Failed to create surface");             
        egl.eglTerminate(eglDisplay);
        return;
    }

    // BUG Test for glReadPixels

    if (eglSurface != null)
    {
        // Create context

        final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
        final int GLES_VERSION = 2;
        int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL10.EGL_NONE };
        EGLContext eglContext = egl.eglCreateContext(eglDisplay, configurationsList[0], EGL10.EGL_NO_CONTEXT, attribList);

        if (eglContext != null)
        {
            // Attach context to surface

            if (egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) == true)
            {
                // Perform the actual bug test

                GL10 gl = (GL10)eglContext.getGL();
                int buffer[] = new int[surfaceWidth * surfaceHeight];
                IntBuffer wrappedBuffer = IntBuffer.wrap(buffer);
                wrappedBuffer.position(0);

                // BUG: Line of failure
                gl.glReadPixels(0, 0, surfaceWidth, surfaceHeight, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, wrappedBuffer);

                // Also fails when using RGBA 
                //gl.glReadPixels(0, 0, surfaceWidth, surfaceHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, wrappedBuffer);
            }

            egl.eglDestroyContext(eglDisplay, eglContext);
        }

        egl.eglDestroySurface(display, eglSurface);
    }

    egl.eglTerminate(eglDisplay);
}
4

1 に答える 1

0

Pbuffers は、Nvidia Tegra GPU を搭載したデバイスではサポートされていません。問題は、コードではなく、EGL ドライバーにあります。しかし、とにかく pbuffers を使用する正当な理由はありません。それらは時代遅れです。特に Android では、代わりに FBO を使用する必要があります。この記事では、その理由について詳しく説明します。

http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

Android でオフスクリーン サーフェスを作成する最良の方法は、新しい SurfaceTexture() を構築し、それを eglCreateWindowSurface() に渡すことです。

于 2013-09-06T17:37:47.527 に答える