• Android是怎样调用硬件加速的


    Android是怎样调用硬件加速的

    [描述]
    如果处理器只有2D硬件加速而没有3D硬件加速,则可以利用opengl中的libagl,
    实现封装在libagl里的copybit,因为相对3D API来说,这个模块的封装google
    基本是做好的,只要去实现一个copybit HAL即可;
    如果处理器2D/3D硬件加速均有,那么可以丢开 copybit,去实现openGL ES
    2D/3D API 的加速功能。

    [Android是怎样加载软件/硬件加速库的]

    1. 全局变量gEGLImpl: 定义egl&gles的API的指针
        egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
        enum {
            IMPL_HARDWARE = 0,
            IMPL_SOFTWARE,
            IMPL_NUM_IMPLEMENTATIONS
        };
        具体数据结构参看附录。

    2. 初始化全局变量gEGLImpl
      Code:egl_init_drivers_locked()<frameworks/base/opengl/libs/EGL/egl.cpp>
      egl_init_drivers_locked()函数主要的工作就是填充gEGLImp数组变量
      该函数调用Loader.cpp中的Loader::open()加载对应的硬件和软件加速的驱动(动态链接库).
        a. 加载libGLES_android.so填充gEGLImpl[IMPL_SOFTWARE];
        b. 加载libGLES_HWxxxxx.so填充gEGLImpl[IMPL_HARDWARE];
      注:配置文件/system/lib/egl/egl.cfg中列出了系统中的软件/硬件减速库
         格式: dpy  impl  tag
                0    0     android    
                0    1     HWxxxxx

    [2D硬件加速]
      frameworks/base/opengl/libagl/egl.cpp 文件中利用hardware/libhardware/hardware.c
      文件中定义的hw_get_module()函数,该函数判断获得的系统属性是否在variant_keys[]数组中定义
      通过load()函数加载相应的硬件模块;否则加载default硬件模块。
      因此需要研究libagl,根据需要实现相应的copybit硬件模块。

      注:
        libGLES_android.so为编译frameworks/base/opengl/libagl/目录而生成的,其专门有一个
        copybit.cpp文件对copybit模块进一步封装。
        libagl中通过在frameworks/base/opengl/libagl/Android.mk文件中定义:
            LIBAGL_USE_GRALLOC_COPYBITS := 1
        来加载copybit模块;如果未定义LIBAGL_USE_GRALLOC_COPYBITS,则通过软件的方式而不使用
        copybit 模块来达到 2D 硬件加速。

    [2D/3D硬件加速]
      需研究opengles, 并实现
        /system/lib/egl/libGLES_HWxxxxx.so
      或者
        /system/lib/egl/libEGL_HWxxxxx.so
        /system/lib/egl/libGLESv1_CM_HWxxxxx.so
        /system/lib/egl/libGLESv2_HWxxxxx.so
      来提供 openGL ES 2D/3D 硬件加速 API 。

    [应用是怎样使用OpenGLES硬件加速的]
      1.应用调用eglChooseConfig时,libs/EGL/egl.cpp::eglChooseConfig根据参数选择config时,
        调用顺序为:
          gEGLImpl[IMPL_HARDWARE].egl.eglChooseConfig(...)
          gEGLImpl[IMPL_SOFTWARE].egl.eglChooseConfig(...)
        原因: IMPL_HARDWARE=0; IMPL_SOFTWARE=1
        参看:
            enum {
                IMPL_HARDWARE = 0,
                IMPL_SOFTWARE,
                IMPL_NUM_IMPLEMENTATIONS
            };
      2. 创建Surface和Context时, libs/EGL/egl.cpp是根据传入参数config来判断是调用软件还是
        硬件加速API的, 而根据步骤1优先选择的缉硬件的config, 故创建Surface和Context是使用的
        也是硬件加速的API。

    [附录]:
    struct egl_connection_t
    {
        void *              dso;
        gl_hooks_t *        hooks[2];
        EGLint              major;
        EGLint              minor;
        egl_t               egl;
    };

    struct egl_t {
        #include "EGL/egl_entries.in"
    };

    struct gl_hooks_t {
        struct gl_t {
            #include "entries.in"
        } gl;
        struct gl_ext_t {
            void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
        } ext;
    };
  • 相关阅读:
    安卓手机的弱网工具
    渗透测试工具之sqlmap
    渗透测试基础之sql注入
    去哪儿网2017校招在线笔试(前端工程师)编程题及JavaScript代码
    滴滴出行2017秋招工程岗笔试题(0918)编程题
    【面试经历】再惠网络、远景能源、东软集团
    二叉树前序、中序、后序遍历相互求法
    58集团2017校招笔试-前端岗
    途牛前端工程师在线笔试题(含答案和全面解析)
    【经典面试题二】二叉树的递归与非递归遍历(前序、中序、后序)
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124470.html
Copyright © 2020-2023  润新知