搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
盐析白兔
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
数学建模----MATLAB----for&&while循环(进阶)
2
NXP(I.MX6uLL)DDR3实验——DDR3重要时间参数、时钟配置与原理图简析_i.max6ull 正点原子原理图
3
自学软件测试天赋异禀——不是盖的_学习软件测学习天赋
4
我用笨办法啃下了一个开源项目的源码!_如何啃透代码
5
C++:函数指针进阶(三):Lambda函数详解(二):Lambda接收方式_c++ lambda 函数指针
6
华为OD机试题-最长合法表达式(java解法)_提取字符串中的最长合法简单数学表达式
7
AI-机器学习-自学笔记(七)支持向量机(SVG)算法_svg算法
8
动态规划课堂7-----两个数组的dp问题(等价代换)_动态规划dp数组
9
基于Java+Vue+uniapp微信小程序商品展示系统设计和实现_微信小程序通过weui实现商品列表展示页面。
10
让AI替你回复微信——大语言模型的创意调用_微信端调用大语言模型接口
当前位置:
article
> 正文
简单撸一下EGL_撸片轻量版
作者:盐析白兔 | 2024-04-09 22:32:15
赞
踩
撸片轻量版
egl复杂构造opengl的工作环境
void egl_demo()
{
EGLDisplay
display
=
eglGetDisplay
(
EGL_DEFAULT_DISPLAY
);
eglInitialize
(
display
, 0, 0);
EGLConfig
config;
eglChooseConfig
(
display
,
attribs
, &
config
, 1, &
numConfigs
);
EGLSurface
surface
=
eglCreateWindowSurface
(
display
,
config
,
ANativeWindow
,
NULL
);
EGLContext
context
=
eglCreateContext
(
display
,
config
,
NULL
,
NULL
);
eglMakeCurrent
(
display
,
surface
,
surface
,
context
)
while(true){
//opengl绘制
glxx();
eglSwapBuffers
(
display
,
surface
);
}
eglDestroyContext
(
display
,
context
);
eglDestroySurface
(
display
,
surface
);
eglTerminate
(
display
);
}
1. 动态加载opengles实现so
eglGetDisplay(
EGLNativeDisplayType
display
)
egl_init_drivers
egl_init_drivers_locked(未加载gl等模块,则加载,否则直接跳出)
Loader.open(
egl_connection_t
)
load_driver(根据规则加载选定的so文件,把一段函数指针进行初始化)
egl_display_t
::
getFromNativeDisplay
(
display
)调用上面初始化的函数指针初始化display
,
cnx
->
egl
.
eglGetDisplay
)
egl_display_t.
getDisplay
egl_init_drivers_locked()
{
// dynamically load our EGL implementation
egl_connection_t
*
cnx
= &
gEGLImpl
;
if
(
cnx
->
dso
== 0) {
//opengl的一堆函数指针,未初始化
cnx
->
hooks
[
egl_connection_t
::
GLESv1_INDEX
] =
&
gHooks
[
egl_connection_t
::
GLESv1_INDEX
];
cnx
->
hooks
[
egl_connection_t
::
GLESv2_INDEX
] =
&
gHooks
[
egl_connection_t
::
GLESv2_INDEX
];
//
cnx
->
dso
=
loader
.
open
(
cnx
);
}
}
void
*
Loader
::
load_driver
(
const
char
*
kind
,
egl_connection_t
*
cnx
,
uint32_t
mask
)
{
const
char
*
const
driver_absolute_path 找到so的路径;
void
*
dso
=
dlopen
(
driver_absolute_path
,
RTLD_NOW
|
RTLD_LOCAL
);
if
(
mask
&
EGL
) {
getProcAddress
= (
getProcAddressType
)
dlsym
(
dso
,
"eglGetProcAddress"
);
cnx
->
egl
; 填充egl数组中的指针
}
if
(
mask
&
GLESv1_CM
) {//填充v1指针
cnx
->
hooks
[
egl_connection_t
::
GLESv1_INDEX
]->
gl
,
}
if
(
mask
&
GLESv2
) {
//填充v2指针
cnx
->
hooks
[
egl_connection_t
::
GLESv2_INDEX
]->
gl
,
}
return
dso
;
}
EGLDisplay
egl_display_t
::
getDisplay
(
EGLNativeDisplayType
display
) {
egl_connection_t
*
const
cnx
= &
gEGLImpl
;
if
(
cnx
->
dso
&&
disp
.
dpy
==
EGL_NO_DISPLAY
) {//如果没有初始化过则初始化一下
EGLDisplay
dpy
=
cnx
->
egl
.
eglGetDisplay
(
display
);
disp
.
dpy
=
dpy
;
if
(
dpy
==
EGL_NO_DISPLAY
) {
loader
.
close
(
cnx
->
dso
);
cnx
->
dso
=
NULL
;
}
}
//返回的索引做一下映射,
return
EGLDisplay
(
uintptr_t
(
display
) + 1U);
}
2.初始化egl,并获取版本号
EGLBoolean
eglInitialize
(
EGLDisplay
dpy
,
EGLint
*
major
,
EGLint
*
minor
) (通过dpy找到
egl_display_t
)
egl_display_t
::
initialize
(
EGLint
*
major
,
EGLint
*
minor)
cnx
->
egl
.
eglInitialize(底层的so导出的函数egl)
3.选择最佳的配置
EGLBoolean
eglChooseConfig
(
EGLDisplay
dpy
,
const
EGLint
*
attrib_list
,
EGLConfig
*
configs
,
EGLint
config_size
,
EGLint
*
num_config
)
{ //
通过dpy找到
egl_display_t
const
egl_display_ptr
dp
=
validate_display
(
dpy
);
//调用底层获取配置 dpy是底层创建的
cnx
->
egl
.
eglChooseConfig
(
dp
->
disp
.
dpy
,
attrib_list
,
configs
,
config_size
,
num_config
);
}
4.本地窗口创建一个gl用的surface
EGLSurface
eglCreateWindowSurface
(
EGLDisplay
dpy
,
EGLConfig
config
,
NativeWindowType
window
,
const
EGLint
*
attrib_list
)
{
//
通过dpy找到
egl_display_t
egl_display_ptr
dp
=
validate_display_connection
(
dpy
,
cnx
);
//设置本地窗口的刷新间隔
ANativeWindow
*
anw
=
reinterpret_cast
<
ANativeWindow
*>(
window
);
anw
->
setSwapInterval
(
anw
, 1);
//本地窗口创建surface
EGLSurface
surface
=
cnx
->
egl
.
eglCreateWindowSurface
(
iDpy
,
config
,
window
,
attrib_list
);
}
5.创建上下文,保存gl的一些状态
EGLContext
eglCreateContext
(
EGLDisplay
dpy
,
EGLConfig
config
,
E
GLContext
share_list
,
const
EGLint
*
attrib_list
)
{
//
通过dpy找到
egl_display_t
const
egl_display_ptr
dp
=
validate_display_connection
(
dpy
,
cnx
);
EGLContext
context
=
cnx
->
egl
.
eglCreateContext
(
dp
->
disp
.
dpy
,
config
,
share_list
,
attrib_list
);
//创建一个内部结构保存状态
egl_context_t
*
c
=
new
egl_context_t
(
dpy
,
context
,
config
,
cnx
,
version
);
}
6.设置绘制表面,
EGLBoolean
eglMakeCurrent
(
EGLDisplay
dpy
,
EGLSurface
draw
,
EGLSurface
read
,
EGLContext
ctx
)
{
//
通过dpy找到
egl_display_t
egl_display_ptr
dp
=
validate_display
(
dpy
);
// 设置到
egl_display_ptr中
EGLBoolean
result
=
dp
->
makeCurrent
(
c
,
cur_c
,
draw
,
read
,
ctx
,
impl_draw
,
impl_read
,
impl_ctx
);
}
EGLBoolean
egl_display_t
::
makeCurrent
(
egl_context_t
*
c
,
egl_context_t
*
cur_c
,
EGLSurface
draw
,
EGLSurface
read
,
EGLContext
ctx
,
EGLSurface
impl_draw
,
EGLSurface
impl_read
,
EGLContext
impl_ctx
)
{
//底层egl库
result
=
c
->
cnx
->
egl
.
eglMakeCurrent
(
disp
.
dpy
,
impl_draw
,
impl_read
,
impl_ctx
);
//context中保存一些变量
c
->
onMakeCurrent
(
draw
,
read
);
}
7.交换后台缓冲区,绘制
EGLBoolean
eglSwapBuffers
(
EGLDisplay
dpy
,
EGLSurface
draw
)
{
const
egl_display_ptr
dp
=
validate_display
(
dpy
);
egl_surface_t
const
*
const
s
=
get_surface
(
draw
);
return
s
->
cnx
->
egl
.
eglSwapBuffers
(
dp
->
disp
.
dpy
,
s
->
surface
);
}
8.释放context
EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
const egl_display_ptr dp = validate_display(dpy);
ContextRef _c(dp.get(), ctx);
egl_context_t * const c = get_context(ctx);
//egl底层释放
EGLBoolean result =
c->cnx->egl
.eglDestroyContext(dp->disp.dpy, c->context);
//释放这一层保存的
_c->teminate
}
9.释放surface,跟上面过程一样的
EGLBoolean
eglDestroySurface
(
EGLDisplay
dpy
,
EGLSurface
surface
)
{
const
egl_display_ptr
dp
=
validate_display
(
dpy
);
SurfaceRef
_s
(
dp
.
get
(),
surface
);
//egl底层释放
egl_surface_t
*
const
s
=
get_surface
(
surface
);
EGLBoolean
result
=
s
->
cnx
->
egl
.
eglDestroySurface
(
dp
->
disp
.
dpy
,
s
->
surface
);
//释放这一层保存的
_s
.
terminate
();
return
result
;
}
10.结束 ,还是释放display,没有卸载so
EGLBoolean
eglTerminate
(
EGLDisplay
dpy
)
{
egl_display_ptr
dp
=
get_display
(
dpy
);
EGLBoolean
res
=
dp
->
terminate
();
return
res
;
}
egl_display_t保存在一个全局变量中,保存了一些状态
这个的terminate还和上面8,9的不一样
EGLBoolean
egl_display_t
::
terminate
() {
//减小引用计数
if
(
refs
> 1) {
refs
--;
return
EGL_TRUE
;
}
//如果最后一个,
EGLBoolean
res
=
EGL_FALSE
;
egl_connection_t
*
const
cnx
= &
gEGLImpl
;
if
(
cnx
->
dso
&&
disp
.
state
==
egl_display_t
::
INITIALIZED
) {
cnx
->
egl
.
eglTerminate
(
disp
.
dpy
) //更改状态
disp
.
state
=
egl_display_t
::
TERMINATED
;
res
=
EGL_TRUE
;
}
//清空内部保存的content,surface等变量,
size_t
count
=
objects
.
size
();
for
(
size_t
i
=0 ;
i
<
count
;
i
++) {
egl_object_t
*
o
=
objects
.
itemAt
(
i
);
o
->
destroy
(); //这个调用了下面
egl_object_t.destroy 会delete的
}
objects
.
clear
();
refs
--;
}
看一下
terminate,都用它了
class
egl_surface_t
:
public
egl_object_t
class
egl_context_t
:
public
egl_object_t
egl_object_t
::
egl_object_t
(
egl_display_t
*
disp
) :
display
(
disp
),
count
(1) {
//display
就是全局的
egl_display_t,addobject就是添加到了数组中
display
->
addObject
(
this
);
}
egl_object_t
::~
egl_object_t
() {
}
void
egl_object_t
::
terminate
() {
//数组中移除
display
->
removeObject
(
this
);
if
(
decRef
() == 1) { //没有delete
}
}
void
egl_object_t
::
destroy
() {
if
(
decRef
() == 1) {//删除,当
egl_display_t.
terminate 会调用destroy
delete
this
;
}
}
就这样吧,简单撸一下过程,回头再分析。
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/盐析白兔/article/detail/395230
推荐阅读
article
如何解决Git
代码
冲突
?_
vscode
解决
git
冲突
...
本文主要用的是
vscode
工具1.为什么会出现
代码
冲突
问题呢?可以理解为就是同一时间几个人更改同一个文件,
git
不知道...
赞
踩
article
三
、
c++
代码中
的
安全
风险-
open
...
要模拟实现一个场景,涉及文件打开时
的
安全
问题,比如通过符号链接重定向
、
强制打开特殊文件类型(如设备文件)
、
创建竞争条件
、
...
赞
踩
article
shell实现脚本
监控
服务器
及
web
应用_
print
$3*
100
/2...
实际工作中我们需要知道部署在
服务器
上的应用有没有问题,但是人为的操作太麻烦有咩有简单的方式呢shell来
监控
我们
服务器
运...
赞
踩
article
fpga
_
hdmi
...
大二在读,因比赛接触了
fpga
,希望可以踏实系统的学习,视频csdn记录学习过程,和大家分享,也希望得到更多的指导。fp...
赞
踩
article
git
拉取
远程
分支
代码_
git
连接
远程
分支
拉代码...
2、将本地仓库与
远程
仓库建立链接:
git
remote add origin http: //xxx/.
git
(
远程
仓库...
赞
踩
article
微
服务
管理
(完整)...
etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据...
赞
踩
article
Java
官网下载
JDK21
版本详细教程(下载、安装、
环境变量
配置)_
java
21xiazaii
...
本文将为您提供关于
Java
官网下载
JDK21
版本的详细教程。作为
Java
开发者,我们知道JDK是开发
Java
应用程序所必...
赞
踩
article
iOS
:如何
安全
且
优雅
地操控
数组
元素
...
在
iOS
开发的世界里,
数组
(Array)的操作频率高得令人咋舌。
数组
贯穿于我们每一个功能的实现和每一行代码的编写之中...
赞
踩
article
操作系统-
磁盘
调度
算法
(
SCAN
、C
SCAN
)...
该系统名称为:
磁盘
调度
算法
2,使用的是C++。本次课设题目是
磁盘
调度
算法
,使我更加理解了
磁盘
调度
算法
的全过程。要实现该算...
赞
踩
article
仪表盘
,
新增
快捷筛选器
组件
...
手写签名 卡片模式 嵌套模式 隐藏显示1.1 【打印模板】
新增
支持手写签名
组件
说明:之前打印模板中只支持在流程...
赞
踩
article
Apache
Hive
详解...
hive详细介绍_apache hiveapache hive 目录 一、引入
Hive
简介 为...
赞
踩
article
luckysheet
的使用——13.
开启
表格非
编辑
模式
(
指定
单元格
可
编辑
,
除此以外
其他
单元格
全部不可...
对
指定
单元格
进行设置为可
编辑
,在
开启
非
编辑
模式
后,只有
指定
的
单元格
才可以进行
编辑
,其余
单元格
全部无法
编辑
。_luckys...
赞
踩
article
【计算机
毕业设计
】
在线商城
系统
_
java
在线商城
系统
...
Java SpringBoot
在线商城
系统
,基于SpringBoot框架进行开发,前端页面效果通过使用Vue进行编码实现...
赞
踩
article
imx6
vpu
程序分析_libimx
vpu
api...
imx6
vpu
程序分析背景最近公司需要将产品与外界的设备进行流媒体通信,经过一系列的方案研究确立,最终把功能完成,目前...
赞
踩
article
大
数据
毕业设计
hadoop
+
spark
旅游
推荐
系统
旅游
可视化
系统
地方
旅游
网站
旅游
爬虫
旅游
管理...
大
数据
毕业设计
hadoop
+
spark
旅游
推荐
系统
旅游
可视化
系统
地方
旅游
网站
旅游
爬虫
旅游
管理
系统
计算机
毕业设计
...
赞
踩
article
软件测试
人员应该怎样做好
需求
分析
_
it
行业中
软件测试
工程师
需要些
需求
分析
吗...
软件测试
人员如何做好
需求
分析
发布时间: 2013-5-17 15:34 作者: 未知 来源: 51Testing
软件测试
...
赞
踩
article
数据结构
题库:单
链表
(一)_若
链表
中
元素
有序,
下列
叙述
哪
一个
正确
...
1.栈和队列的共同特点是(只允许在端点处插入和删除
元素
)4.栈通常采用的两种存储结构是(线性存储结构和
链表
存储结构)5....
赞
踩
article
hadoop
HA启动时 两个
namenode
节点都
是
standby
,
解决办法
_
hadoop
高可用...
首先你要确定不用ha的时候你的
hadoop
集群
是
正常的,不然找错误的方向就偏离了如果都正常,配置ha 需要zookeep...
赞
踩
article
#和
##
操作符
使用
分析
_
操作符
#...
1 #运算符#运算符用于在预处理期将宏参数转换为字符串。#的转换作用是在预处理完成的,因此只在宏定义中有效。编译器不知道...
赞
踩
article
测试
需求
分析流程...
测试
需求
分析流程:根据产品
需求
提取系统的
测试
点编写
需求
跟踪矩阵根据
测试
点利用适当的
测试
用例设计方法设计
测试
用例。_
测试
需...
赞
踩
相关标签
git代码冲突
git工具
c++
安全
fpga开发
视频传输
git
github
微服务
架构
云原生
java
开发语言
ios
swift
算法
前端
数据库
hive
大数据
hadoop
vue.js
elementui
javascript