简单撸一下EGL
来源:互联网 发布:印象笔记是什么软件 编辑:程序博客网 时间:2024/05/06 02:35
egl复杂构造opengl的工作环境
void egl_demo()
{
EGLDisplaydisplay=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(EGLNativeDisplayTypedisplay)
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(constchar*kind,
egl_connection_t*cnx,uint32_tmask)
{
constchar*constdriver_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,
}
returndso;
}
EGLDisplayegl_display_t::getDisplay(EGLNativeDisplayTypedisplay) {
egl_connection_t*constcnx= &gEGLImpl;
if(cnx->dso&&disp.dpy==EGL_NO_DISPLAY) {//如果没有初始化过则初始化一下
EGLDisplaydpy=cnx->egl.eglGetDisplay(display);
disp.dpy= dpy;
if(dpy==EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso=NULL;
}
}
//返回的索引做一下映射,
returnEGLDisplay(uintptr_t(display) + 1U);
}
2.初始化egl,并获取版本号
EGLBooleaneglInitialize(EGLDisplaydpy,EGLint*major,EGLint*minor) (通过dpy找到egl_display_t)
egl_display_t::initialize(EGLint*major,EGLint*minor)
cnx->egl.eglInitialize(底层的so导出的函数egl)
3.选择最佳的配置
EGLBooleaneglChooseConfig(EGLDisplaydpy,constEGLint*attrib_list,EGLConfig*configs,EGLintconfig_size,EGLint*num_config)
{ //通过dpy找到egl_display_t
constegl_display_ptrdp=validate_display(dpy);
//调用底层获取配置 dpy是底层创建的
cnx->egl.eglChooseConfig(dp->disp.dpy,attrib_list,configs,config_size,num_config);
}
4.本地窗口创建一个gl用的surface
EGLSurfaceeglCreateWindowSurface( EGLDisplaydpy,EGLConfigconfig,NativeWindowTypewindow,constEGLint*attrib_list)
{
//通过dpy找到egl_display_t
egl_display_ptrdp=validate_display_connection(dpy,cnx);
//设置本地窗口的刷新间隔
ANativeWindow*anw=reinterpret_cast<ANativeWindow*>(window);
anw->setSwapInterval(anw, 1);
//本地窗口创建surface
EGLSurfacesurface=cnx->egl.eglCreateWindowSurface(iDpy,config,window,attrib_list);
}
5.创建上下文,保存gl的一些状态
EGLContexteglCreateContext(EGLDisplaydpy,EGLConfigconfig,EGLContextshare_list,constEGLint*attrib_list)
{
//通过dpy找到egl_display_t
constegl_display_ptrdp=validate_display_connection(dpy,cnx);
EGLContextcontext=cnx->egl.eglCreateContext(dp->disp.dpy,config,share_list,attrib_list);
//创建一个内部结构保存状态
egl_context_t*c=newegl_context_t(dpy,context,config,cnx,version);
}
6.设置绘制表面,
EGLBooleaneglMakeCurrent( EGLDisplaydpy,EGLSurfacedraw,EGLSurfaceread,EGLContextctx)
{
//通过dpy找到egl_display_t egl_display_ptrdp=validate_display(dpy);
// 设置到egl_display_ptr中
EGLBooleanresult=dp->makeCurrent(c,cur_c,draw,read,ctx,impl_draw,impl_read,impl_ctx);
}
EGLBooleanegl_display_t::makeCurrent(egl_context_t*c,egl_context_t*cur_c,
EGLSurfacedraw,EGLSurfaceread,EGLContextctx,
EGLSurfaceimpl_draw,EGLSurfaceimpl_read,EGLContextimpl_ctx)
{
//底层egl库
result=c->cnx->egl.eglMakeCurrent(
disp.dpy,impl_draw,impl_read,impl_ctx);
//context中保存一些变量
c->onMakeCurrent(draw,read);
}
7.交换后台缓冲区,绘制
EGLBooleaneglSwapBuffers(EGLDisplaydpy,EGLSurfacedraw)
{
constegl_display_ptrdp=validate_display(dpy);
egl_surface_tconst*consts=get_surface(draw);
returns->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,跟上面过程一样的
EGLBooleaneglDestroySurface(EGLDisplaydpy,EGLSurfacesurface)
{
constegl_display_ptrdp=validate_display(dpy);
SurfaceRef_s(dp.get(),surface);
//egl底层释放
egl_surface_t*consts=get_surface(surface);
EGLBooleanresult=s->cnx->egl.eglDestroySurface(dp->disp.dpy,s->surface);
//释放这一层保存的
_s.terminate();
returnresult;
}
10.结束 ,还是释放display,没有卸载so
EGLBooleaneglTerminate(EGLDisplaydpy)
{
egl_display_ptrdp=get_display(dpy);
EGLBooleanres=dp->terminate();
returnres;
}
egl_display_t保存在一个全局变量中,保存了一些状态
这个的terminate还和上面8,9的不一样
EGLBooleanegl_display_t::terminate() {
//减小引用计数
if(refs> 1) {
refs--;
returnEGL_TRUE;
}
//如果最后一个,
EGLBooleanres=EGL_FALSE;
egl_connection_t*constcnx= &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_tcount=objects.size();
for(size_ti=0 ;i<count;i++) {
egl_object_t*o=objects.itemAt(i);
o->destroy(); //这个调用了下面egl_object_t.destroy 会delete的
}
objects.clear();
refs--;
}
看一下terminate,都用它了
classegl_surface_t:publicegl_object_t
classegl_context_t:publicegl_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() {
}
voidegl_object_t::terminate() {
//数组中移除
display->removeObject(this);
if(decRef() == 1) { //没有delete
}
}
voidegl_object_t::destroy() {
if(decRef() == 1) {//删除,当egl_display_t.terminate 会调用destroy
deletethis;
}
}
就这样吧,简单撸一下过程,回头再分析。
0 0
- 简单撸一下EGL
- egl
- EGL
- 简单理解一下机会成本
- 简单测试一下
- 简单介绍一下SNMP4J
- 简单总结一下指针
- 简单总结一下debug
- 简单学习一下CSS
- 简单学一下javascript
- 简单记录一下
- 简单说一下RecyclerView
- 简单了解一下xml
- 简单看一下ROSPY
- 简单介绍一下OGraph
- 简单封装一下AFNetworking
- 简单介绍一下AjAx
- 简单聊一下const
- 深入分析Parquet列式存储格式
- activiti 流程定义(二)
- 2015年十大热门Android开源新项目
- 在Android Studio中使用androidannotations(安卓注解)的方法(通过Gradle添加)
- 在固定大小div插入N个图片使其一行排列
- 简单撸一下EGL
- C++ Map操作
- 在Asp.net MVC 4.0中使用IHttpHandler
- poj2528 离散化+线段树区间更新
- js扩展(插件算不上 )
- ANativeWindow
- 利用Hog特征和SVM分类器进行行人检测
- 10 个 OS X El Capitan 高级技巧推荐
- React Native开发专题介绍