当前位置: 首页 > news >正文

wayland(xdg_wm_base) + egl + opengles——dma_buf 作为纹理数据源(五)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、EGL dma_buf import 相关的数据结构和函数
    • 1. EGLImageKHR
    • 2. eglCreateImageKHR()
    • 3. glEGLImageTargetTexture2DOES()
  • 二、egl 中 import dma_buf 作为纹理的代码实例
    • 1. egl_wayland_dmabuf_texture 代码实例
      • 1.1 基于opengles2.0 相关接口的egl_wayland_dmabuf_texture2_0.c
      • 1.2 基于opengles3.0 相关接口的egl_wayland_dmabuf_texture3_0.c
    • 2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
    • 3. 编译
    • 4. 运行
  • 总结
  • 参考资料


前言

`本文主要描述如何在一个wayland client 中将一个 dma_buf import 作为一个 opengles texture 数据源
软硬件环境
硬件:aarch64
软件:linux5.10 opengles2.0/3.0 egl1.5


一、EGL dma_buf import 相关的数据结构和函数

如下图所示,EGL 中 import dma_buf 作为 opengles texture ,主要是使用数据结构EGLImageKHR,函数eglCreateImageKHR()和glEGLImageTargetTexture2DOES()
在这里插入图片描述

1. EGLImageKHR

EGLImageKHR 是 EGL (嵌入式系统图形库) 扩展 API 中的一种数据类型。它表示一个 EGL 图像对象的句柄,可用于在不同的图形 API 或上下文之间共享图像数据。 EGLImageKHR 对象通常使用 eglCreateImageKHR 函数创建。这个函数接受诸如 EGL 显示、客户端 API 类型(例如,用于 OpenGL 纹理的 EGL _ GL _ TEXTURE _ 2D _ KHR)和客户端 API 图像源代码句柄等参数。它返回一个 EGLImageKHR 句柄,该句柄以可共享的格式表示图像数据。一旦有了 EGLImageKHR 句柄,就可以将其与其他 EGL 或图形 API 函数一起使用,以便对图像数据执行操作。例如,您可以使用 glEGLImageTargetTexture2DOES 功能将 EGLImageKHR 绑定到 OpenGL 中的纹理对象。 EGLImageKHR 是对核心 EGL 规范的扩展,其可用性和使用可能会根据您正在使用的平台和版本而有所不同。

2. eglCreateImageKHR()

eglCreateImageKHR 函数是 EGL 扩展 API 的一部分,它代表“嵌入式系统图形库”此函数用于从现有的客户端 API 映像源创建 EGLImage。EGLImage 可以被看作是一个句柄,它引用图像数据的格式可以在不同的图形 API 之间共享。

3. glEGLImageTargetTexture2DOES()

函数 glEGLImageTargetTexture2DOES 是 OpenGL ES 中的一个扩展函数,它允许您将 EGLImage 绑定为纹理目标。它将一个 EGLImage 与 OpenGLES 中的纹理对象关联起来,使您能够使用 EGLImage 作为纹理数据源。

二、egl 中 import dma_buf 作为纹理的代码实例

1. egl_wayland_dmabuf_texture 代码实例

本实例是以 /dev/dma_heap/linux,cma 节点作为dmabuf export ,得到dma_fd
在这里插入图片描述

1.1 基于opengles2.0 相关接口的egl_wayland_dmabuf_texture2_0.c

#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/dma-heap.h>
#include <linux/dma-buf.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <drm/drm_fourcc.h>
#include "xdg-shell-client-protocol.h"#define WIDTH 800
#define HEIGHT 600struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct xdg_wm_base *wm_base = NULL;
struct wl_registry *registry = NULL;
GLuint texture;
GLint textureLocation;PFNEGLCREATEIMAGEKHRPROC create_image;
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;struct window {struct wl_surface *surface;struct xdg_surface *xdg_surface;struct xdg_toplevel *xdg_toplevel;struct wl_egl_window *egl_window;
};// Index to bind the attributes to vertex shaders
const unsigned int VertexArray = 0;static void
xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
{xdg_wm_base_pong(shell, serial);
}/*for xdg_wm_base listener*/
static const struct xdg_wm_base_listener wm_base_listener = {xdg_wm_base_ping,
};/*for registry listener*/
static void registry_add_object(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 
{if (!strcmp(interface, "wl_compositor")) {compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);} else if (strcmp(interface, "xdg_wm_base") == 0) {wm_base = wl_registry_bind(registry, name,&xdg_wm_base_interface, 1);xdg_wm_base_add_listener(wm_base, &wm_base_listener, NULL);}
}void registry_remove_object(void *data, struct wl_registry *registry, uint32_t name) 
{}static struct wl_registry_listener registry_listener = {registry_add_object, registry_remove_object};static void
handle_surface_configure(void *data, struct xdg_surface *surface,uint32_t serial)
{//struct window *window = data;xdg_surface_ack_configure(surface, serial);//window->wait_for_configure = false;
}static const struct xdg_surface_listener xdg_surface_listener = {handle_surface_configure
};static void
handle_toplevel_configure(void *data, struct xdg_toplevel *toplevel,int32_t width, int32_t height,struct wl_array *states)
{
}static void
handle_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
{
}static const struct xdg_toplevel_listener xdg_toplevel_listener = {handle_toplevel_configure,handle_toplevel_close,
};bool initWaylandConnection()
{	if ((display = wl_display_connect(NULL)) == NULL){printf("Failed to connect to Wayland display!\n");return false;}if ((registry = wl_display_get_registry(display)) == NULL){printf("Faield to get Wayland registry!\n");return false;}wl_registry_add_listener(registry, &registry_listener, NULL);wl_display_dispatch(display);if (!compositor){printf("Could not bind Wayland protocols!\n");return false;}return true;
}bool initializeWindow(struct window *window)
{initWaylandConnection();window->surface = wl_compositor_create_surface (compositor);window->xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, window->surface);if (window->xdg_surface == NULL){printf("Failed to get Wayland xdg surface\n");return false;} else {xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window);window->xdg_toplevel =xdg_surface_get_toplevel(window->xdg_surface);xdg_toplevel_add_listener(window->xdg_toplevel,&xdg_toplevel_listener, window);xdg_toplevel_set_title(window->xdg_toplevel, "egl_wayland_texture");}return true;
}void releaseWaylandConnection(struct window *window)
{if(window->xdg_toplevel)xdg_toplevel_destroy(window->xdg_toplevel);if(window->xdg_surface)xdg_surface_destroy(window->xdg_surface);wl_surface_destroy(window->surface);xdg_wm_base_destroy(wm_base);wl_compositor_destroy(compositor);wl_registry_destroy(registry);wl_display_disconnect(display);
}bool createEGLSurface(EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface *eglSurface, struct window *window)
{window->egl_window = wl_egl_window_create(window->surface, WIDTH, HEIGHT);if (window->egl_window == EGL_NO_SURFACE) { printf("Can't create egl window\n"); return false;} else {printf("Created wl egl window\n");}*eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, window->egl_window, NULL);return true;
}bool dmabuf_texture_create(EGLImageKHR egl_image)
{//GLuint texture;glGenTextures(1, &texture);glBindTexture(GL_TEXTURE_2D, texture);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);image_target_texture_2d(GL_TEXTURE_2D, egl_image);return true;
}bool opengles_init(GLuint *shaderProgram, EGLImageKHR egl_image)
{GLuint fragmentShader = 0;GLuint vertexShader = 0;char msg[1000];GLsizei len;const char* const fragmentShaderSource = "precision mediump float;\n""varying vec2 vTexCoord; \n""uniform sampler2D uTexture; \n""void main()\n""{\n""   gl_FragColor = texture2D(uTexture, vTexCoord);\n""}\n";// Create a fragment shader objectfragmentShader = glCreateShader(GL_FRAGMENT_SHADER);// Load the source code into itglShaderSource(fragmentShader, 1, (const char**)&fragmentShaderSource, NULL);// Compile the source codeglCompileShader(fragmentShader);// Check that the shader compiledGLint isShaderCompiled;glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isShaderCompiled);if (!isShaderCompiled){// If an error happened, first retrieve the length of the log messageglGetShaderInfoLog(fragmentShader, sizeof msg, &len, msg)
http://www.lryc.cn/news/300656.html

相关文章:

  • 【VTKExamples::PolyData】第二十八期 LinearExtrusion
  • Linux操作系统基础(五):Linux的目录结构
  • SolidWorks如何在一个零件的基础上绘制另一个零件
  • gin(结)
  • JavaScript 设计模式之桥接模式
  • B3651 [语言月赛202208] 数组调整
  • MessageQueue --- RabbitMQ
  • WordPress作者页面链接的用户名自动变成16位字符串串插件Smart User Slug Hider
  • Nvidia 携手 RTX 推出的本地运行 AI 聊天机器人
  • 年假作业day2
  • HTML-多媒体嵌入-MDN文档学习笔记
  • openJudge | 距离排序 C语言
  • 【教程】MySQL数据库学习笔记(三)——数据定义语言DDL(持续更新)
  • [leetcode]买卖股票的最佳时机 (动态规划)
  • 隐函数的求导【高数笔记】
  • SG3225EEN晶体振荡器规格书
  • ESP8266 常用AT指令
  • esbuild 构建工具为什么很快?
  • 解决vscode报错,在赋值前使用了变量“XXX“
  • python自动定时任务schedule库的使用方法
  • 用机器学习方法重构期货商品板块
  • 51单片机项目(29)——基于51单片机的避障跟随小车
  • 人工智能学习与实训笔记(六):百度飞桨套件使用方法
  • Linux第一个小程序-进度条
  • YoloV8改进策略:Block改进|Mamba-UNet改进YoloV8,打造全新的Yolo-Mamba网络
  • 数据分析基础之《pandas(8)—综合案例》
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • define和typedef
  • SpringCloud之Nacos用法笔记
  • 【c++】拷贝构造函数