1 #include "HalideRuntime.h"
2 #include "printer.h"
3 
4 extern "C" {
5 
6 #define EGLAPI
7 #define EGLAPIENTRY
8 #define EGLAPIENTRYP EGLAPIENTRY *
9 
10 typedef int32_t EGLint;
11 typedef unsigned int EGLBoolean;
12 typedef unsigned int EGLenum;
13 typedef void *EGLContext;
14 typedef void *EGLDisplay;
15 typedef void *EGLNativeDisplayType;
16 typedef void *EGLConfig;
17 typedef void *EGLSurface;
18 typedef void *EGLDeviceEXT;
19 
20 typedef EGLBoolean(EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC)(
21     EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
22 typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(
23     EGLenum platform, void *native_display, const EGLint *attrib_list);
24 
25 #define EGL_NO_CONTEXT ((EGLContext)0)
26 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
27 #define EGL_NO_DISPLAY ((EGLDisplay)0)
28 #define EGL_NO_SURFACE ((EGLSurface)0)
29 
30 #define EGL_SUCCESS 0x3000
31 
32 #define EGL_ALPHA_SIZE 0x3021
33 #define EGL_BLUE_SIZE 0x3022
34 #define EGL_GREEN_SIZE 0x3023
35 #define EGL_RED_SIZE 0x3024
36 #define EGL_SURFACE_TYPE 0x3033
37 #define EGL_NONE 0x3038
38 #define EGL_RENDERABLE_TYPE 0x3040
39 #define EGL_HEIGHT 0x3056
40 #define EGL_WIDTH 0x3057
41 #define EGL_CONTEXT_CLIENT_VERSION 0x3098
42 
43 #define EGL_PLATFORM_DEVICE_EXT 0x313F
44 
45 #define EGL_PBUFFER_BIT 0x0001
46 #define EGL_OPENGL_ES2_BIT 0x0004
47 
48 #define EGL_FALSE 0
49 #define EGL_TRUE 1
50 
51 EGLAPI EGLint EGLAPIENTRY eglGetError(void);
52 EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
53 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
54 EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
55 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
56                                               EGLConfig *configs, EGLint config_size,
57                                               EGLint *num_config);
58 EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
59                                                EGLContext share_context,
60                                                const EGLint *attrib_list);
61 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
62                                                       const EGLint *attrib_list);
63 EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
64                                              EGLSurface read, EGLContext ctx);
65 
66 EGLAPI void *eglGetProcAddress(const char *procname);
67 
68 extern int strcmp(const char *, const char *);
69 
halide_opengl_create_context(void * user_context)70 WEAK int halide_opengl_create_context(void *user_context) {
71     if (eglGetCurrentContext() != EGL_NO_CONTEXT)
72         return 0;
73 
74     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
75     if (display == EGL_NO_DISPLAY || !eglInitialize(display, 0, 0)) {
76         PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
77             reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(
78                 eglGetProcAddress("eglQueryDevicesEXT"));
79         if (eglQueryDevicesEXT == NULL) return 1;
80 
81         PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
82             reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
83                 eglGetProcAddress("eglGetPlatformDisplayEXT"));
84         if (eglGetPlatformDisplayEXT == NULL) return 1;
85 
86         const int kMaxDevices = 32;
87         EGLDeviceEXT egl_devices[kMaxDevices];
88         EGLint num_devices = 0;
89         EGLint egl_error = eglGetError();
90         if (!eglQueryDevicesEXT(kMaxDevices, egl_devices, &num_devices) ||
91             egl_error != EGL_SUCCESS) {
92             return 1;
93         }
94 
95         EGLBoolean initialized = EGL_FALSE;
96         for (EGLint i = 0; i < num_devices; ++i) {
97             display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
98                                                egl_devices[i], NULL);
99             if (eglGetError() == EGL_SUCCESS && display != EGL_NO_DISPLAY) {
100                 int major, minor;
101                 initialized = eglInitialize(display, &major, &minor);
102                 if (eglGetError() == EGL_SUCCESS && initialized == EGL_TRUE) {
103                     break;
104                 }
105             }
106         }
107 
108         if (eglGetError() != EGL_SUCCESS || initialized != EGL_TRUE) {
109             error(user_context) << "Could not initialize EGL display: "
110                                 << eglGetError();
111             return 1;
112         }
113     }
114 
115     EGLint attribs[] = {
116         EGL_SURFACE_TYPE,
117         EGL_PBUFFER_BIT,
118         EGL_RENDERABLE_TYPE,
119         EGL_OPENGL_ES2_BIT,
120         EGL_RED_SIZE,
121         8,
122         EGL_GREEN_SIZE,
123         8,
124         EGL_BLUE_SIZE,
125         8,
126         EGL_ALPHA_SIZE,
127         8,
128         EGL_NONE,
129     };
130     EGLConfig config;
131     int numconfig;
132     eglChooseConfig(display, attribs, &config, 1, &numconfig);
133     if (numconfig != 1) {
134         error(user_context) << "eglChooseConfig(): config not found: "
135                             << eglGetError() << " - " << numconfig;
136         return -1;
137     }
138 
139     EGLint context_attribs[] = {
140         EGL_CONTEXT_CLIENT_VERSION, 2,
141         EGL_NONE};
142     EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT,
143                                           context_attribs);
144     if (context == EGL_NO_CONTEXT) {
145         error(user_context) << "Error: eglCreateContext failed: " << eglGetError();
146         return -1;
147     }
148 
149     EGLint surface_attribs[] = {
150         EGL_WIDTH, 1,
151         EGL_HEIGHT, 1,
152         EGL_NONE};
153     EGLSurface surface = eglCreatePbufferSurface(display, config, surface_attribs);
154     if (surface == EGL_NO_SURFACE) {
155         error(user_context) << "Error: Could not create EGL window surface: " << eglGetError();
156         return -1;
157     }
158 
159     eglMakeCurrent(display, surface, surface, context);
160     return 0;
161 }
162 
halide_opengl_get_proc_address(void * user_context,const char * name)163 WEAK void *halide_opengl_get_proc_address(void *user_context, const char *name) {
164     return (void *)eglGetProcAddress(name);
165 }
166 
167 }  // extern "C"
168