GBM上的EGLDisplay

10

我想通过EGL创建一个OpenGL上下文。由于我不需要实际绘制,所以我想与GBM平台一起使用Pbuffers。以下是代码(C99):

#include <stdlib.h>
#include <assert.h>

#include <fcntl.h>
#include <unistd.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <gbm.h>


int main( void )
{
    assert( eglBindAPI( EGL_OPENGL_API ) == EGL_TRUE );

    int fd = open("/dev/dri/card0", O_RDWR);
    struct gbm_device * gbm = gbm_create_device( fd );

    EGLDisplay dpy = eglGetDisplay( gbm );
    eglInitialize( dpy , NULL , NULL );

    EGLConfig config;
    EGLint n_of_configs;
    assert( eglGetConfigs( dpy , &config , 1 , &n_of_configs ) == EGL_TRUE );

    EGLSurface srf = eglCreatePbufferSurface( dpy , config , NULL );
    assert( srf != EGL_NO_SURFACE );

    EGLContext ctx = eglCreateContext( dpy , config , EGL_NO_CONTEXT , NULL );
    assert( ctx != EGL_NO_CONTEXT );

    assert( eglMakeCurrent( dpy , srf , srf , ctx ) == EGL_TRUE );

    eglDestroySurface( dpy , srf );
    eglDestroyContext( dpy , ctx );
    eglTerminate( dpy );

    gbm_device_destroy( gbm );
    close( fd );

    return EXIT_SUCCESS;
}

它会出现以下错误:

test.c: In function ‘main’:
test.c:20:2: error: passing argument 1 of ‘eglGetDisplay’ from incompatible pointer type [-Werror]
  EGLDisplay dpy = eglGetDisplay( gbm );
  ^
In file included from test.c:7:0:
/usr/include/EGL/egl.h:251:31: note: expected ‘EGLNativeDisplayType’ but argument is of type ‘struct gbm_device *’
 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);

这个链接是我用作例子的页面。

我感到惊讶,因为我使用--with-egl-platforms=drm,wayland,x11构建了Mesa,尽管这里声明EGL_DEFAULT_DISPLAY将映射到指定的第一个平台,但在我的系统上它却是_XDisplay *的别名。

--with-egl-platforms
List the platforms (window systems) to support. Its argument is a comma seprated string such as --with-egl-platforms=x11,drm. It decides the platforms a driver may support. The first listed platform is also used by the main library to decide the native platform: the platform the EGL native types such as EGLNativeDisplayType or EGLNativeWindowType defined for.
AFAIK,Weston在GBM基础上创建了EGLDisplay来绘制裸机KMS。我已查看了其代码,并在相关系统头文件中搜索解决方案,但似乎没有找到。

FWIW,我正在使用Radeon HD 3200上的Mesa 10.0,Linux 3.12.6,GCC 4.8.2。

1个回答

7
你说:

我想在GBM平台上使用Pbuffers。

EGL/GBM不支持Pbuffers,也不支持Pixmaps。

要使用EGL/GBM创建离屏表面,你必须将一个gbm_surface传递给eglCreateWindowSurface。 "Window"是一个误称。没有真正的“窗口”被创建。结果缓冲区将保持离屏状态,除非你使用内核的KMS API将其发送到显示器。

但是......这不是你的程序编译失败的原因。在调用eglGetDisplay和eglCreateWindowSurface时,你必须像这样进行转换:

eglGetDisplay((EGLNativeDisplayType)my_gbm_device);
eglCreateWindowSurface(egl_dpy, egl_config,
                       (EGLNativeWindowType)my_gbm_surface, NULL);

如果您正在使用包含提交 468cc86 的 Mesa,则可以通过以下方式使用 eglGetPlatformDisplayEXT 和 eglCreatePlatformWindowSurface 来避免转换:
eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, my_gbm_device, NULL);
eglCreatePlatformWindowSurfaceEXT(egl_dpy, egl_config, my_gbm_surface, NULL);

无论您选择使用原始的EGL函数还是较新的平台EGL函数,都应该参考EGL_MESA_platform_gbm规范中的示例代码作为指南。

1
谢谢提供这些信息!我不知道GBM平台不支持Pbuffers。至于EGL平台扩展,我已经切换到它们了,它们非常适合我的设计。 - djsp
1
你在我回复之前开始使用平台扩展了吗?如果是这样,你是怎么学习到它们的呢?我问这个问题是因为我撰写了平台扩展规范以及它们在 Mesa 中的实现,我想知道像你这样的用户如何了解新的 EGL 功能。 - Chadversary
1
我一直在搜索。很抱歉,我不记得用了哪些搜索词。我在这里提出了一个问题,你回答了我,但是你链接的资源都是我搜索到的那些。 Mesa 代码本身帮助了我。这里有一些好的例子:https://www.khronos.org/registry/egl/sdk/docs/man/html/eglIntro.xhtml http://www.phoronix.com/forums/showthread.php?60486-Any-OpenGL-ES-2-0-with-EGL-example-on-Mesa http://cgit.freedesktop.org/mesa/demos/tree/src/egl/eglut - djsp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接