Android 图形驱动初始化(二十三)

它仅是 void 指针的 typedef。

总结一下获取 Display 的整个过程

  • 通过 frameworks/native/opengl/libs/EGL 初始化图形驱动;

  • 通过厂商提供的设备特有的 EGL 库接口初始化 Display。

Android 图形驱动初始化

===============

接下来更详细地看一下图形驱动初始化。这通过 egl_init_drivers() 完成,该函数定义 (位于frameworks/native/opengl/libs/EGL/egl.cpp) 如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

egl_connection_t gEGLImpl;

gl_hooks_t gHooks[2];

. . . . . .

static EGLBoolean egl_init_drivers_locked() {

if (sEarlyInitState) {

// initialized by static ctor. should be set here.

return EGL_FALSE;

}

// get our driver loader

Loader& loader(Loader::getInstance());

// dynamically load our EGL implementation

egl_connection_t* cnx = &gEGLImpl;

if (cnx->dso == 0) {

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

}

return cnx->dso ? EGL_TRUE : EGL_FALSE;

}

static pthread_mutex_t sInitDriverMutex = PTHREAD_MUTEX_INITIALIZER;

EGLBoolean egl_init_drivers() {

EGLBoolean res;

pthread_mutex_lock(&sInitDriverMutex);

res = egl_init_drivers_locked();

pthread_mutex_unlock(&sInitDriverMutex);

return res;

}

图形驱动初始化通过 Loader::open(egl_connection_t* cnx) 完成,初始化的结果将存储于全局结构 egl_connection_t gEGLImpl 和 gl_hooks_t gHooks[2] 中。

来看一下 gl_hooks_t 的定义(位于 frameworks/native/opengl/libs/hooks.h):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

// maximum number of GL extensions that can be used simultaneously in

// a given process. this limitation exists because we need to have

// a static function for each extension and currently these static functions

// are generated at compile time.

#define MAX_NUMBER_OF_GL_EXTENSIONS 256

. . . . . .

#undef GL_ENTRY

#undef EGL_ENTRY

#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);

#define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);

struct egl_t {

#include "EGL/egl_entries.in"

};

struct gl_hooks_t {

struct gl_t {

#include "entries.in"

} gl;

struct gl_ext_t {

__eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];

} ext;

};

#undef GL_ENTRY

#undef EGL_ENTRY

其中 __eglMustCastToProperFunctionPointerType 定义 (位于frameworks/native/opengl/include/EGL/egl.h) 如下:

1

2

3

4

/* This is a generic function pointer type, whose name indicates it must

* be cast to the proper type *and calling convention* before use.

*/

typedef void (*__eglMustCastToProperFunctionPointerType)(void);

__eglMustCastToProperFunctionPointerType 是函数指针类型。struct gl_hooks_t 的 struct gl_ext_t ext 即为函数指针表,它们用来描述 EGL 扩展接口。

struct gl_hooks_t 内的 struct gl_t 结构体,其结构体成员在另外一个文件,即 entries.in 中定义,该文件位于 frameworks/native/opengl/libs/entries.in

1

2

3

4

5

6

GL_ENTRY(void, glActiveShaderProgram, GLuint pipeline, GLuint program)

GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)

GL_ENTRY(void, glActiveTexture, GLenum texture)

GL_ENTRY(void, glAlphaFunc, GLenum func, GLfloat ref)

GL_ENTRY(void, glAlphaFuncQCOM, GLenum func, GLclampf ref)

. . . . . .

配合 frameworks/native/opengl/libs/hooks.h 中 GL_ENTRY 宏的定义:

1

#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);

可以看到 struct gl_hooks_t 的 struct gl_t gl 的所有成员都是函数指针,即它是一个函数表,一个 OpenGL 接口函数的函数表。

上面看到的 struct egl_t 与 struct gl_hooks_t 的 struct gl_t gl 定义类似,只是它的结构体成员来自于另外一个文件 frameworks/native/opengl/libs/EGL/egl_entries.in

1

2

3

4

5

6

EGL_ENTRY(EGLDisplay, eglGetDisplay, NativeDisplayType)

EGL_ENTRY(EGLBoolean, eglInitialize, EGLDisplay, EGLint*, EGLint*)

EGL_ENTRY(EGLBoolean, eglTerminate, EGLDisplay)

EGL_ENTRY(EGLBoolean, eglGetConfigs, EGLDisplay, EGLConfig*, EGLint, EGLint*)

EGL_ENTRY(EGLBoolean, eglChooseConfig, EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)

. . . . . .

EGL_ENTRY 宏的定义与 GL_ENTRY 宏的完全相同。struct egl_t 同样为一个函数表,只是它是 EGL 接口的函数表。

再来看 egl_connection_t 的定义,位于 frameworks/native/opengl/libs/EGL/egldefs.h

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

struct egl_connection_t {

enum {

GLESv1_INDEX = 0,

GLESv2_INDEX = 1

};

inline egl_connection_t() : dso(0) { }

void * dso;

gl_hooks_t * hooks[2];

EGLint major;

EGLint minor;

egl_t egl;

void* libEgl;

void* libGles1;

void* libGles2;

};

这个结构包含了主、次版本号; 4 个指针;两个函数表的指针以及一个函数表。

Loader::open(egl_connection_t* cnx) 初始化图形驱动,主要是初始化这些函数表和指针。Loader::open(egl_connection_t* cnx) 的定义如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

static void* load_wrapper(const char* path) {

void* so = dlopen(path, RTLD_NOW | RTLD_LOCAL);

ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror());

return so;

}

#ifndef EGL_WRAPPER_DIR

#if defined(__LP64__)

#define EGL_WRAPPER_DIR "/system/lib64"

#else

#define EGL_WRAPPER_DIR "/system/lib"

#endif

#endif

static void setEmulatorGlesValue(void) {

char prop[PROPERTY_VALUE_MAX];

property_get

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值