c - GBM 上的 EGLDsplay

标签 c egl mesa

我想通过 EGL 创建一个 OpenGL 上下文。由于我不会实际绘制,所以我想将 Pbuffers 与 GBM 平台结合使用。这是代码 (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);

This是我拿来举例的页面。

我很惊讶,因为我用 --with-egl-platforms=drm,wayland,x11 构建了 Mesa,而且,即使它被声明为 here 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.

据我所知,Weston 在 GBM 之上创建了一个 EGLDisplay,用于在裸 KMS 上绘图。我查看了它的代码,并搜索了相关的系统 header 以寻找解决方案,但似乎不存在。

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

最佳答案

你说

I want to use Pbuffers in conjunction with the GBM platform.

EGL/GBM 不支持 Pbuffers。它也不支持像素图。

要使用 EGL/GBM 创建离屏表面,您必须将 gbm_surface 传递给 eglCreateWindowSurface。 “窗口”用词不当。没有创建真正的“窗口”。生成的缓冲区将保持在屏幕外,除非您使用内核的 KMS API 将其发布到显示器上。

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

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

如果您使用的 Mesa 包含提交 468cc86 ,那么您可以通过使用 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 中的示例代码规范作为指导。

关于c - GBM 上的 EGLDsplay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20816844/

相关文章:

c - 为结构化指针分配内存

c - 111-D 返回 0 时无法访问语句

opengl - 带有 EGL 的 Vulkan 接头

android - GLSurfaceView 如何使用我的 EGLDisplay、EGLContext 和 eglSurface?

opengl - 如何判断计算机是否支持 OpenGL 2.0? (我想写着色器)

linux - 没有 X 的 Tegra Mesa GLES

opengl - 找不到 glXCreateContextAttribsARB

c - 防止断言失败时崩溃(alsa 未正确配置)

在 STM32F4 发现上配置 SPI

linux - xlib/egl 如何在 eglSwapBuffers 上获取 VSync/swapInterval