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

news2024/11/22 16:20:04

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

文章目录

  • 前言
  • 一、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 600

struct 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 object
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

	// Load the source code into it
	glShaderSource(fragmentShader, 1, (const char**)&fragmentShaderSource, NULL);
	
	// Compile the source code
	glCompileShader(fragmentShader);

	// Check that the shader compiled
	GLint isShaderCompiled;
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isShaderCompiled);
	if (!isShaderCompiled)
	{
   
		// If an error happened, first retrieve the length of the log message

		glGetShaderInfoLog(fragmentShader, sizeof msg, &len, msg)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1453124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink理论—Flink架构设计

Flink架构设计 Flink 是一个分布式系统&#xff0c;需要有效分配和管理计算资源才能执行流应用程序。它集成了所有常见的集群资源管理器&#xff0c;例如Hadoop YARN&#xff0c;但也可以设置作为独立集群甚至库运行,例如Spark 的 Standalone Mode 本节概述了 Flink 架构&…

单片机学习笔记---直流电机驱动(PWM)

直流电机介绍 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&#xff08;转子&#xff09;和换向器…

leetcode(双指针)15.三数之和(C++详细解释)DAY10

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的…

shell脚本之高级变量

目录 一、高级变量赋值 1、高级变量赋值总结表 2、相关操作 二、变量间接引用 1、eval命令 一、高级变量赋值 1、高级变量赋值总结表 变量配置方式str 无配置str 为空字符串str 已配置为非空字符串var${str-expr}varexprvarvar$strvar${str:-expr}varexprvarexprvar$str…

RK3399平台开发系列讲解(调试篇)死锁检测工具lockdep

🚀返回专栏总目录 文章目录 一、常见死锁场景二、lockdep使用方法三、lockdep技术原理3.1、锁类状态3.2、检查规则沉淀、分享、成长,让自己和他人都能有所收获!😄 📢介绍死锁检测工具lockdep。 资料 一、常见死锁场景 场景1:进程重复申请同一个锁,称为AA死锁。例如…

多模态(三)--- BLIP原理与源码解读

1 BLIP简介 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 传统的Vision-Language Pre-training &#xff08;VLP&#xff09;任务大多是基于理解的任务或基于生成的任务&#xff0c;同时预训练数据多是从web获…

CMU和ETH联合研发了一个名为 「敏捷但安全」的新框架,为四足机器人在复杂环境中实现高速运动提供了解决方案

在高速机器人运动领域&#xff0c;实现同时兼顾速度和安全一直是一大挑战。但现在&#xff0c;卡内基梅隆大学&#xff08;CMU&#xff09;和苏黎世联邦理工学院&#xff08;ETH&#xff09;的研究团队带来了突破性进展。他们开发的新型四足机器人算法&#xff0c;不仅能在复杂…

程序的控制结构详解

程序的控制结构 结构化程序设计方法的基础 在计算机刚出现的早期&#xff0c;它的价格昂贵、内存很小、速度慢。程序员为了在很小的内存中解决大量的科学计算问题&#xff0c;并为了节省昂贵的CPU机时费&#xff0c;不得不使用巧妙的手段和技术&#xff0c;手工编写各种高效的…

吴恩达机器学习全课程笔记第一篇

目录 前言 P1 - P8 监督学习 ​无监督学习 P9-P14 线性回归模型 成本&#xff08;代价&#xff09;函数 P15-P20 梯度下降 P21-P24 多类特征 向量化 多元线性回归的梯度下降 P25-P30 特征缩放 检查梯度下降是否收敛 学习率的选择 特征工程 多项式回归 前言…

【力扣hot100】刷题笔记Day5

前言 回学校了&#xff0c;荒废了半天之后打算奋发图强猛猛刷题&#xff0c;找实习&#xff01;赚钱&#xff01;&#xff01; 560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 前缀法 哈希表 这个题解解释比官方清晰&#xff0c;截个图方便看&#xff0c;另一…

【Java】文件操作与IO

文件操作与IO Java中操作文件针对文件系统的操作File类概述字段构造方法方法及示例 文件内容的读写 —— 数据流Java提供的 “流” API文件流读写文件内容InputStream 示例读文件示例1&#xff1a;将文件完全读完的两种方式示例二&#xff1a;读取汉字 写文件谈谈 OutputStream…

Practical User Research for Enterprise UX

2.1 Why It’s Hard to Get Support for Research in Enterprises 2.1.1 Time and Budget Instead of answering the question “What dowe gain if we do this research?”, ask instead “What do we stand to lose if we don’t do the research?” 2.1.2 Legacy Thinkin…

HMI界面:感官与体验俱佳的智能家居界面分享

Hello&#xff0c;我是大千UI工场&#xff0c;本期分享HMI人机交互界面在智能家居领域的案例&#xff0c;关注大千&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;可以联络。 设计感官和体验俱佳智能家居的UI界面时&#xff0c;可以考虑以下几个方面&#xff1a;…

算法中关于数学的题目练习

算法中关于数学的题目练习 1、买不到的数目题目信息思路题解 2、蚂蚁感冒题目信息思路题解 3、饮料换购题目信息思路题解 1、买不到的数目 题目信息 思路 数学结论&#xff08;证明略&#xff09;&#xff1a; p、q为正整数且互质&#xff0c;不能由p、q凑出来的最大的数为(p…

DNS服务正反解析

1.正向解析 1.配置基本 1.1防火墙配置 二者都要关闭 setenforce 0 systemctl stop firewalld #关闭防火墙 yum install bind -y #下载bind软件 客户端可以不用下 1.2服务端配置静态ip&#xff0c; ip a 查看网卡 nmcli c modify ens33 ipv4.method manual ipv4.addresses …

使用PaddleNLP UIE模型提取上市公司PDF公告关键信息

项目地址&#xff1a;使用PaddleNLP UIE模型抽取PDF版上市公司公告 - 飞桨AI Studio星河社区 (baidu.com) 背景介绍 本项目将演示如何通过PDFPlumber库和PaddleNLP UIE模型&#xff0c;抽取公告中的相关信息。本次任务的PDF内容是破产清算的相关公告&#xff0c;目标是获取受理…

第三百五十回

文章目录 1. 概要介绍2. 获取方法2.1 获取语言2.2 获取地址 3.示例代码3. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题"相关的内容&#xff0c;本章回中将介绍如何获取系统语言.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概要介绍 我们在本…

机试复习-4

1.string类 string类型和数值的转换 ※数值→字符串 to_string函数 //具体做法 int i1234; string gto_string(i);//这样就转成字符串1234了 //下面就是字符串转为数字&#xff0c;类似下面还有stof,stoi,stod string d "1289347647"; int j stoi(d); cout <…

Halcon 相机标定

文章目录 算子单相机标定单相机标定畸变的矫正 算子 gen_caltab 生成标定文件 gen_caltab(::XNum,YNum,MarkDist,DiameterRatio,CalTabDescrFile,CalTabPSFile :) 算子来制作一个标定板XNum 每行黑色标志圆点的数量。YNum 每列黑色标志圆点的数…

RAG近期发展综述

RAG简介 RAG全称为检索增强生成技术&#xff0c;其主要可以分为三部分&#xff0c;索引&#xff08;构建&#xff09;、检索以及生成&#xff0c;各个部分又可以进一步细分。 索引 索引阶段主要是构建知识库的过程&#xff0c;这里的知识库是泛指&#xff0c;包括了向量数据…