Codebase list kmscube / c84b17c
common: Check for extensions before resolving symbols eglGetProcAddress is allowed to return any old garbage for symbols it doesn't know about. To avoid any mishaps, check for the appropriate extension presence (split into EGL client extension, EGL display extension, and GL extension, checks) before we look up any symbols through it. The walk through the extension list is taken from libepoxy. Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com> Daniel Stone 7 years ago
1 changed file(s) with 53 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
00 /*
11 * Copyright (c) 2017 Rob Clark <rclark@redhat.com>
2 * Copyright © 2013 Intel Corporation
23 *
34 * Permission is hereby granted, free of charge, to any person obtaining a
45 * copy of this software and associated documentation files (the "Software"),
2223
2324 #include <errno.h>
2425 #include <fcntl.h>
26 #include <stdbool.h>
2527 #include <stdio.h>
2628 #include <stdlib.h>
2729 #include <string.h>
7779 return &gbm;
7880 }
7981
82 static bool has_ext(const char *extension_list, const char *ext)
83 {
84 const char *ptr = extension_list;
85 int len = strlen(ext);
86
87 if (ptr == NULL || *ptr == '\0')
88 return false;
89
90 while (true) {
91 ptr = strstr(ptr, ext);
92 if (!ptr)
93 return false;
94
95 if (ptr[len] == ' ' || ptr[len] == '\0')
96 return true;
97
98 ptr += len;
99 }
100 }
101
80102 int init_egl(struct egl *egl, const struct gbm *gbm)
81103 {
82104 EGLint major, minor, n;
95117 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
96118 EGL_NONE
97119 };
98
99 #define get_proc(name) do { \
100 egl->name = (void *)eglGetProcAddress(#name); \
120 const char *egl_exts_client, *egl_exts_dpy, *gl_exts;
121
122 #define get_proc_client(ext, name) do { \
123 if (has_ext(egl_exts_client, #ext)) \
124 egl->name = (void *)eglGetProcAddress(#name); \
101125 } while (0)
102
103 get_proc(eglGetPlatformDisplayEXT);
104 get_proc(eglCreateImageKHR);
105 get_proc(eglDestroyImageKHR);
106 get_proc(glEGLImageTargetTexture2DOES);
107 get_proc(eglCreateSyncKHR);
108 get_proc(eglDestroySyncKHR);
109 get_proc(eglWaitSyncKHR);
110 get_proc(eglDupNativeFenceFDANDROID);
126 #define get_proc_dpy(ext, name) do { \
127 if (has_ext(egl_exts_dpy, #ext)) \
128 egl->name = (void *)eglGetProcAddress(#name); \
129 } while (0)
130
131 #define get_proc_gl(ext, name) do { \
132 if (has_ext(gl_exts, #ext)) \
133 egl->name = (void *)eglGetProcAddress(#name); \
134 } while (0)
135
136 egl_exts_client = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
137 get_proc_client(EGL_EXT_platform_base, eglGetPlatformDisplayEXT);
111138
112139 if (egl->eglGetPlatformDisplayEXT) {
113140 egl->display = egl->eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR,
121148 return -1;
122149 }
123150
151 egl_exts_dpy = eglQueryString(egl->display, EGL_EXTENSIONS);
152 get_proc_dpy(EGL_KHR_image_base, eglCreateImageKHR);
153 get_proc_dpy(EGL_KHR_image_base, eglDestroyImageKHR);
154 get_proc_dpy(EGL_KHR_fence_sync, eglCreateSyncKHR);
155 get_proc_dpy(EGL_KHR_fence_sync, eglDestroySyncKHR);
156 get_proc_dpy(EGL_KHR_fence_sync, eglWaitSyncKHR);
157 get_proc_dpy(EGL_ANDROID_native_fence_sync, eglDupNativeFenceFDANDROID);
158
124159 printf("Using display %p with EGL version %d.%d\n",
125160 egl->display, major, minor);
126161
128163 printf("EGL information:\n");
129164 printf(" version: \"%s\"\n", eglQueryString(egl->display, EGL_VERSION));
130165 printf(" vendor: \"%s\"\n", eglQueryString(egl->display, EGL_VENDOR));
131 printf(" extensions: \"%s\"\n", eglQueryString(egl->display, EGL_EXTENSIONS));
166 printf(" client extensions: \"%s\"\n", egl_exts_client);
167 printf(" display extensions: \"%s\"\n", egl_exts_dpy);
132168 printf("===================================\n");
133169
134170 if (!eglBindAPI(EGL_OPENGL_ES_API)) {
158194 /* connect the context to the surface */
159195 eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context);
160196
197 gl_exts = (char *) glGetString(GL_EXTENSIONS);
161198 printf("OpenGL ES 2.x information:\n");
162199 printf(" version: \"%s\"\n", glGetString(GL_VERSION));
163200 printf(" shading language version: \"%s\"\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
164201 printf(" vendor: \"%s\"\n", glGetString(GL_VENDOR));
165202 printf(" renderer: \"%s\"\n", glGetString(GL_RENDERER));
166 printf(" extensions: \"%s\"\n", glGetString(GL_EXTENSIONS));
203 printf(" extensions: \"%s\"\n", gl_exts);
167204 printf("===================================\n");
205
206 get_proc_gl(GL_OES_EGL_image, glEGLImageTargetTexture2DOES);
168207
169208 return 0;
170209 }