简单撸一下EGL

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 ;
    }
}


就这样吧,简单撸一下过程,回头再分析。
遗传算法优化BP神经网络(GABP)是一种结合了遗传算法(GA)和BP神经网络的优化预测方法。BP神经网络是一种多层前馈神经网络,常用于模式识别和预测问题,但其容易陷入局部最优。而遗传算法是一种模拟自然选择和遗传机制的全局优化方法,能够有效避免局部最优 。GABP算法通过遗传算法优化BP神经网络的权重和阈值,从而提高网络的学习效率和预测精度 。 种群:遗传算法中个体的集合,每个个体代表一种可能的解决方案。 编码:将解决方案转化为适合遗传操作的形式,如二进制编码。 适应度函数:用于评估个体解的质量,通常与目标函数相反,目标函数值越小,适应度越高。 选择:根据适应度保留优秀个体,常见方法有轮盘赌选择、锦标赛选择等。 交叉:两个父代个体交换部分基因生成子代。 变异:随机改变个体的部分基因,增加种群多样。 终止条件:当迭代次数或适应度阈值达到预设值时停止算法 。 初始化种群:随机生成一组神经网络参数(权重和阈值)作为初始种群 。 计算适应度:使用神经网络模型进行训练和预测,根据预测误差计算适应度 。 选择操作:根据适应度选择优秀个体 。 交叉操作:对选择的个体进行交叉,生成新的子代个体 。 变异操作:对子代进行随机变异 。 替换操作:用新生成的子代替换掉一部分旧种群 。 重复步骤2-6,直到满足终止条件 。 适应度函数通常以预测误差为基础,误差越小,适应度越高。常用的误差指标包括均方根误差(RMSE)或平均绝对误差(MAE)等 。 GABP代码中包含了适应度函数的定义、种群的生成、选择、交叉、变异以及训练过程。代码注释详尽,便于理解每个步骤的作用 。 GABP算法适用于多种领域,如时间序列预测、经济预测、工程问题的优化等。它特别适合解决多峰优化问题,能够有效提高预测的准确和稳定
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值