Android中opengles,egl库的结构

目录

egl,opengl es的软硬件实现

需要的库

库的分工

加载模块

软件实现模块

硬件实现模块


egl,opengl es的软硬件实现

需要的库

//算是android中的egl库,用来加载具体的实现(软件实现或者硬件实现)

system\lib\libEGL.so

//opengl具体实现的wrapper,无论软件硬件实现时,均需加载这2个调用转发库



 system\lib\libGLESv1_CM.so  // opengl es 1.0调用的wrapper壳,对应的源文件是:                                                              

///frameworks/native/opengl/libs/GLES_CM/gl.cpp

system\lib\libGLESv2.so      // opengl es 2.0调用的wrapper壳,可shader编程, 对应的源文件是:

//opengl软件实现,即agl,包括egl和gl的实现,不分opengl es 1.0和2.0

system\lib\egl\libGLES_android.so



//opengl的硬件实现,例如高通的实现

system\vendor\lib\egl\libEGL_adreno.so

//opengl硬件实现

system\vendor\lib\egl\libGLESv1_CM_adreno.so

system\vendor\lib\egl\libGLESv2_adreno.so

以上无论软件还是硬件具体实现的接口是 EGL/egl.h,GLES/gl.h。

库的分工

Eglgl的标准在/frameworks/native/opengl/include/下,通常如下加入标准:

include <EGL/egl.h>

include <GLES/gl.h>

加载模块

这俩标准的实现一个是软件实现,一个硬件实现,无论软硬,都需要一个加载模块。在/frameworks/native/opengl/libs/Android.mk文件里的libEGL模块便是。

23LOCAL_SRC_FILES:= 	       \
24	EGL/egl_tls.cpp        \
25	EGL/egl_cache.cpp      \
26	EGL/egl_display.cpp    \
27	EGL/egl_object.cpp     \
28	EGL/egl.cpp 	       \
29	EGL/eglApi.cpp 	       \   ,
30	EGL/trace.cpp              \
31	EGL/getProcAddress.cpp.arm \
32	EGL/Loader.cpp 	       \

37LOCAL_MODULE:= libEGL

当开始使用libEGL 模块中的egl接口(eglApi.cpp中的某些函数,他们是eglGetDisplay,eglGetProcAddress,eglBindAPI等,他们包含了egl_init_drivers()函数用来初始化模块的加载,它是实现在egl.cpp中,而且eglApi.cpp是egl接口实现,它是软件实现的第一层调用)时,就会触发软硬件实现模块的加载,加载软件实现还硬件实现,在4.3版本中的判断是:

153    FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
154    if (cfg == NULL) {//说明软件模块
155        // default config
156        ALOGD("egl.cfg not found, using default config");
157        mDriverTag.setTo("android");//说明软件模块
158    } else {//硬件模块
159        while (fgets(line, 256, cfg)) {
160            int dpy, impl;
161            if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
162                //ALOGD(">>> %u %u %s", dpy, impl, tag);
163                // We only load the h/w accelerated implementation
164                if (tag != String8("android")) {
165                    mDriverTag = tag;
166                }
167            }
168        }
169        fclose(cfg);
170    }

其中EGL/eglApi.cpp 实现了egl接口,这里的是egl接口的第一层调用,最终调用的是软硬件实现里面的egl实现,为什么?Loader.cpp加载libGLES_android.so或者加载其他opengl厂商实现的so包的时候,有如下一段代码:

void *Loader::load_driver(const char* kind, const char *tag,
282        egl_connection_t* cnx, uint32_t mask)
……
	egl_t* egl = &cnx->egl;//加载实现包里的egl接口实现到此处。
342        __eglMustCastToProperFunctionPointerType* curr =
343            (__eglMustCastToProperFunctionPointerType*)egl;
344        char const * const * api = egl_names;
345        while (*api) {
346            char const * name = *api;
347            __eglMustCastToProperFunctionPointerType f =
348                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
349            if (f == NULL) {
350                // couldn't find the entry-point, use eglGetProcAddress()
351                f = getProcAddress(name);
352                if (f == NULL) {
353                    f = (__eglMustCastToProperFunctionPointerType)0;
354                }
355            }
356            *curr++ = f;
357            api++;
358        }

//看一下egl_connection_t结构:
34struct egl_connection_t {
35    enum {
36        GLESv1_INDEX = 0,
37        GLESv2_INDEX = 1
38    };
39
40    inline egl_connection_t() : dso(0) { }
41    void *              dso;
42    gl_hooks_t *        hooks[2];//gl1,gl2接口函数实现加载到此处
43    EGLint              major;
44    EGLint              minor;
45    egl_t               egl;//软硬件实现的egl接口函数加载到此处
46
47    void*               libGles1;
48    void*               libGles2;
49};

//在看一下其中的egl_t,gl_hooks_t结构:
71struct egl_t {
72    #include "EGL/egl_entries.in",//一系列egl接口中的函数指针变量,待实现库来填充
73};
74
75struct gl_hooks_t {
76    struct gl_t {
77        #include "entries.in"//,一系列gl接口中函数指针变量,待实现库来填充
78    } gl;
79    struct gl_ext_t {
80        __eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
81    } ext;
82};

总结,无论是SF模块,还是Bootanimation模块,他们在使用egl的时候,首先找到eglApi.cpp的第一层调用,然后再:例如:

344EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
345        EGLint attribute, EGLint *value)
346{
347    clearError();
348
349    egl_connection_t* cnx = NULL;
350    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
351    if (!dp) return EGL_FALSE;
352
353    return cnx->egl.eglGetConfigAttrib(//!
354            dp->disp.dpy, config, attribute, value);
355}	

         至于gl的调用逻辑,在调用egl_init_drivers()函数用来初始化模块的加载的时候,也把软硬家的gl实现加载到了一个地方。

361    if (mask & GLESv1_CM) {
362        init_api(dso, gl_names,
363            (__eglMustCastToProperFunctionPointerType*)
364                &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
365            getProcAddress);
366    }
367
368    if (mask & GLESv2) {
369      init_api(dso, gl_names,
370            (__eglMustCastToProperFunctionPointerType*)
371                &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
372            getProcAddress);
373    }

         就是egl_connection_t的hooks成员中。

         那么egl_connection_t又在哪里存储呢?libEGL 模块的egl_context_t里。当我们eglcreateContext后,我们会把创建的eglcontext中的egl_connection_t的hooks存储在线程相关的tls中,当调用的gl函数的时候,就从当前线程的tls里取出hooks来,然后再调用相关gl函数。它的存储过程是在eglMakeCurrent函数中:

581EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
582                            EGLSurface read, EGLContext ctx)
583{
……
613    // these are our objects structs passed in
614    egl_context_t       * c = NULL;
……
621    if (ctx != EGL_NO_CONTEXT) {
622        c = get_context(ctx);
623        impl_ctx = c->context;
624    } else {
……
650    EGLBoolean result = dp->makeCurrent(c, cur_c,
651            draw, read, ctx,
652            impl_draw, impl_read, impl_ctx);
653
654    if (result == EGL_TRUE) {
655        if (c) {
656            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);//!
……
}

libGLESv1_CM.solibGLESv2.so他们其实是对gl接口的第一层实现,他们转发调用了当前线程里的hooks里相关的实现。

         看一下gl2接口的调用逻辑,:

// /frameworks/native/opengl/libs/GLES2/gl2.cpp 
109    #define API_ENTRY(_api) _api
110
111    #define CALL_GL_API(_api, ...)                                       \
112        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \  //!
113        _c->_api(__VA_ARGS__);
114
115    #define CALL_GL_API_RETURN(_api, ...)                                \
116        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
117        return _c->_api(__VA_ARGS__)
……
122extern "C" {
123#include "gl3_api.in"
124#include "gl2ext_api.in"
125#include "gl3ext_api.in"
126}

// /frameworks/native/opengl/libs/GLES2/gl3_api.in :
1void API_ENTRY(glActiveTexture)(GLenum texture) {
2    CALL_GL_API(glActiveTexture, texture);
3}
4void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
5    CALL_GL_API(glAttachShader, program, shader);
6}
7void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar* name) {
8    CALL_GL_API(glBindAttribLocation, program, index, name);
9}
…….


//	最后看一下关于hooks的本地线程存储:
368void setGlThreadSpecific(gl_hooks_t const *value) {
369    pthread_setspecific(gGLWrapperKey, value);
370}
371
372gl_hooks_t const* getGlThreadSpecific() {
373    gl_hooks_t const* hooks =  static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
374    if (hooks) return hooks;
375    return &gHooksNoContext;
376}

         总结,无论是SF模块,还是Bootanimation模块,他们在使用gl接口的时候,先去找libGLESv1_CM.solibGLESv2.so的第一层实现,然后再转发软件或硬件实现。

软件实现模块

这俩标准的agl软件实现在/frameworks/native/opengl/libagl/下,观其部分mk文件:

9LOCAL_SRC_FILES:= \
10	egl.cpp                     \  //egl的实现,其余是gl的实现
11	state.cpp		            \
12	texture.cpp		            \
13    Tokenizer.cpp               \
14    TokenManager.cpp            \
15    TextureObjectManager.cpp    \
16    BufferObjectManager.cpp     \
17	array.cpp.arm		        \
18	fp.cpp.arm		            \
19	light.cpp.arm		        \
20	matrix.cpp.arm		        \
21	mipmap.cpp.arm		        \
22	primitives.cpp.arm	        \
23	vertex.cpp.arm
……
29LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils liblog libpixelflinger libETC1 libui
30LOCAL_LDLIBS := -lpthread -ldl
31
32ifeq ($(TARGET_ARCH),arm)
33	LOCAL_SRC_FILES += fixed_asm.S iterators.S
34	LOCAL_CFLAGS += -fstrict-aliasing
35endif

……

44# we need to access the private Bionic header <bionic_tls.h>
45LOCAL_C_INCLUDES += bionic/libc/private

……

48LOCAL_MODULE:= libGLES_android
49
50include $(BUILD_SHARED_LIBRARY)

硬件实现模块

硬件的实现包括在/frameworks/native/opengl/libs/Android.mk文件里:

Egl实现:例如高通的\libEGL_adreno.so

Gl实现:system\vendor\lib\egl\libGLESv1_CM_adreno.so,system\vendor\lib\egl\libGLESv2_adreno.so

图示:

转载请注明。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值