Android 图形驱动初始化(二十三),kotlin协程原理

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("ro.kernel.qemu", prop, "0");

if (atoi(prop) != 1) return;

property_get("ro.kernel.qemu.gles",prop,"0");

if (atoi(prop) == 1) {

ALOGD("Emulator has host GPU support, qemu.gles is set to 1.");

property_set("qemu.gles", "1");

return;

}

// for now, checking the following

// directory is good enough for emulator system images

const char* vendor_lib_path =

#if defined(__LP64__)

"/vendor/lib64/egl";

#else

"/vendor/lib/egl";

#endif

const bool has_vendor_lib = (access(vendor_lib_path, R_OK) == 0);

if (has_vendor_lib) {

ALOGD("Emulator has vendor provided software renderer, qemu.gles is set to 2.");

property_set("qemu.gles", "2");

} else {

ALOGD("Emulator without GPU support detected. "

"Fallback to legacy software renderer, qemu.gles is set to 0.");

property_set("qemu.gles", "0");

}

}

void* Loader::open(egl_connection_t* cnx)

{

void* dso;

driver_t* hnd = 0;

setEmulatorGlesValue();

dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);

if (dso) {

hnd = new driver_t(dso);

} else {

// Always load EGL first

dso = load_driver("EGL", cnx, EGL);

if (dso) {

hnd = new driver_t(dso);

hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM );

hnd->set( load_driver("GLESv2", cnx, GLESv2), GLESv2 );

}

}

LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");

cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");

cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");

cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");

LOG_ALWAYS_FATAL_IF(!cnx->libEgl,

"couldn't load system EGL wrapper libraries");

LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,

"couldn't load system OpenGL ES wrapper libraries");

return (void*)hnd;

}

这个函数中,执行步骤如下:

  1. 为设备是模拟器的情况,设置系统属性 qemu.gles

  2. 加载设备特有的图形驱动库,包括 EGL 库,OpenGL ES 1.0 和 2.0 的库。

  3. 加载图形驱动 Wrapper,它们都位于 /system/lib64 或 /system/lib

egl_connection_t 中的几个指针中,dso 实际为 struct driver_t 指针,该结构定义(位于 frameworks/native/opengl/libs/EGL/Loader.h)如下:

1

2

3

4

5

6

struct driver_t {

driver_t(void* gles);

~driver_t();

status_t set(void* hnd, int32_t api);

void* dso[3];

};

struct driver_t 包含设备生产商提供的设备特有 EGL 和 OpenGL ES 实现库的句柄,如果 EGL 接口和 OpenGL 接口由单独的库实现,它包含一个库的句柄,即这个单独的库,如果 EGL 接口由不同的库实现,它则包含所有这些库的句柄。

egl_connection_t 的 libEgllibGles2 和 libGles1 为动态链接库句柄,其中 libEgl 指向 Android 的 EGL Wrapper 库;libGles1 指向 Android 的 GLESv1_CM Wrapper 库;libGles2 指向 Android 的 GLESv2 Wrapper 库。

然后来看 Loader::load_driver()

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

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值