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)
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
;
}
}
就这样吧,简单撸一下过程,回头再分析。