通过使用 eglExportDMABUFImageQueryMESA 和 GL_RGBA(A 结束)在两个应用程序之间的纹理共享问题

Posted

技术标签:

【中文标题】通过使用 eglExportDMABUFImageQueryMESA 和 GL_RGBA(A 结束)在两个应用程序之间的纹理共享问题【英文标题】:Texture share problem between two apps by use of eglExportDMABUFImageQueryMESA and GL_RGBA (the A on end) 【发布时间】:2020-11-27 19:04:52 【问题描述】:

在一个项目上工作以在两个独立的应用程序之间交换 OpenGL 纹理。

首先我使用这个示例程序https://gitlab.com/blaztinn/dma-buf-texture-sharing/-/tree/master

这是我的一个叉子,用于测试目的https://github.com/AlwinEsch/dma-buf-texture-sharing/tree/own-tries 这将使用完整的图像进行测试(而不是原始图像中的 4 像素)。

在交换 24 位纹理图像 (GL_RGB) 时,这对我来说也完全正确。

但是,如果我切换到我的项目所必需的 32 位 (GL_RGBA),则孩子只会到达垃圾。

Image where shows on left client and on right server

问题:

    这可能与操作系统/硬件错误有关吗? 这在不同 GPU 之间是否会有所不同?如果可以,如何在代码中确定支持? 支持 RGBA 的代码有什么特殊错误? 在两个独立应用之间共享纹理的其他广泛支持的方法?

这里有点十六进制格式:

在服务器上正确:

00000000 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF
00000028 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF │ 38 38 38 FF
...

如果将 Alpha 分配给孩子(带有 GL_BGRA 的 glTexImage2D 格式):

00000000 83 83 8F F3 │ 00 00 0F 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00
00000028 00 00 00 00 │ 00 00 00 00 │ 83 83 8F F3 │ 00 00 0F 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00
...

如果作为 RGB 传递(带有 GL_BGR 的 glTexImage2D 格式,在 RGBA 中作为原始源进行了位交换):

00000000 38 38 38 38 │ 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38 │ 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38 │ 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38
00000028 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38 │ 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38 │ 38 FF 38 FF │ 38 FF 38 38 │ 38 38 38 38 │ 38 FF 38 FF
...

我的硬件:

操作系统:Ubuntu 20.04 CPU:Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz GPU:Intel Corporation UHD Graphics 630(Desktop 9 系列)

我的背景是,我是 Kodi 团队的一员,我希望为 CEF / Chromium 使用的 Kodi 开发一个有效的网络浏览器插件 (https://github.com/AlwinEsch/web.browser.chromium)。 但是,由于 Chromium 有点厚,因此无论执行的应用程序如何,都必须拥有它。

【问题讨论】:

【参考方案1】:

DRM 格式以 little-endian 表示。所以在内存中 DRM_FORMAT_ABGR8888 的像素布局如下:

uint8_t pixel =  R, G, B, A ;

见:

一些 GL 格式和 DRM 格式的表格:https://github.com/swaywm/wlroots/blob/master/render/gles2/pixel_format.c#L5 像素格式指南:https://afrantzis.com/pixel-format-guide/drm.html

【讨论】:

知道并在开始时就想到了与它相关的东西,因为 38 和 83 一样。但似乎来自其他东西,我不知道为什么。如果我提供了其他纹理数据,它有时会部分起作用。只有当一个值太长时,这个垃圾才会出现。【参考方案2】:

可能找到了一个解决方案,无法准确解释它是如何使用它的,也不确定它是否真的正确,但是孩子的渲染然后工作了。

还必须使用“glGenFramebuffers”和“glFramebufferTexture2D”,然后就可以了。

见https://github.com/AlwinEsch/dma-buf-texture-sharing/blob/4e2a4676f9b2dd3029ac2de1efb3f9f196497105/main.cpp#L299-L311

在代码中看起来很恶心,因为那里使用了第二个着色器。

会清理它,看看它如何更清洁。

该错误与 alpha 无关,仅在我的测试中,alpha 值在测试图像中仍然可用,然后当它仅作为 RGB 传输时,它的值几乎不断变化,所以它工作得非常好(即使显示错误)。

【讨论】:

以上是关于通过使用 eglExportDMABUFImageQueryMESA 和 GL_RGBA(A 结束)在两个应用程序之间的纹理共享问题的主要内容,如果未能解决你的问题,请参考以下文章

通过 Join-Where-Group 通过选择查询避免使用临时的正确索引;使用文件排序

如何使用 SLRequest 通过 iOS 更改为通过 <AppName>

使用 mailR 包通过 R 通过 Outlook 发送经过身份验证的邮件

通过使用 pybind11 的虚函数通过引用传递 std::vector 的问题

如何使用 IP 地址(通过 InetAddress)通过 JDBC 与 MySQL 建立连接?

使用通过引用传递的参数(通过指针)优化 OpenCL 函数中的指针访问