1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include "evas_common_private.h"
6 #include "evas_macros.h"
7
8 #ifdef HAVE_DLSYM
9 # include <dlfcn.h> /* dlopen,dlclose,etc */
10 #else
11 # undef BUILD_ENGINE_SOFTWARE_XLIB
12 #endif
13
14 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
15 #include "evas_x_egl.h"
16
17 #define EGL_SURFACE_TYPE 0x3033
18 #define EGL_WINDOW_BIT 0x0004
19 #define EGL_RENDERABLE_TYPE 0x3040
20 #define EGL_ALPHA_SIZE 0x3021
21 #define EGL_BLUE_SIZE 0x3022
22 #define EGL_GREEN_SIZE 0x3023
23 #define EGL_RED_SIZE 0x3024
24 #define EGL_DEPTH_SIZE 0x3025
25 #define EGL_STENCIL_SIZE 0x3026
26 #define EGL_SURFACE_TYPE 0x3033
27 #define EGL_NONE 0x3038
28 #define EGL_FALSE 0
29 #define EGL_TRUE 1
30
31 #define EGL_LOCK_SURFACE_BIT_KHR 0x0080
32 #define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
33 #define EGL_MATCH_FORMAT_KHR 0x3043
34 #define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
35 #define EGL_FORMAT_RGB_565_KHR 0x30C1
36 #define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
37 #define EGL_FORMAT_RGBA_8888_KHR 0x30C3
38 #define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
39 #define EGL_LOCK_USAGE_HINT_KHR 0x30C5
40 #define EGL_READ_SURFACE_BIT_KHR 0x0001
41 #define EGL_WRITE_SURFACE_BIT_KHR 0x0002
42 #define EGL_BITMAP_POINTER_KHR 0x30C6
43 #define EGL_BITMAP_PITCH_KHR 0x30C7
44 #define EGL_BITMAP_ORIGIN_KHR 0x30C8
45 #define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
46 #define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
47 #define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
48 #define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
49 #define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
50 #define EGL_LOWER_LEFT_KHR 0x30CE
51 #define EGL_UPPER_LEFT_KHR 0x30CF
52
53 static int egl_found = -1;
54 static void *egl_lib = NULL;
55
56 static struct
57 {
58 void * (*GetProcAddress)(const char *name);
59 void * (*GetDisplay)(void *d);
60 unsigned int (*Initialize)(void *ed, int *vmaj, int *vmin);
61 unsigned int (*Terminate)(void *ed);
62 const char * (*QueryString)(void *ed, int name);
63 unsigned int (*ChooseConfig)(void *ed, int *attr, void **configs, int config_size, int *num_config);
64 unsigned int (*GetConfigAttrib)(void *ed, void *config, int attr, int *val);
65 unsigned int (*QuerySurface)(void *ed, void *surf, int attr, int *val);
66 void * (*CreateWindowSurface)(void *ed, void *config, Window win, int *attr);
67 unsigned int (*DestroySurface)(void *ed, void *surf);
68 unsigned int (*SwapBuffers)(void *ed, void *surf);
69 unsigned int (*SwapInterval)(void *ed, int interval);
70
71 unsigned int (*LockSurface)(void *ed, void *surf, int *attr);
72 unsigned int (*UnlockSurface)(void *ed, void *surf);
73 } egl;
74
75 static int
_egl_find(void)76 _egl_find(void)
77 {
78 if (egl_found == 0) return 0;
79 if (!egl_lib) egl_lib = dlopen("libEGL.so.1", RTLD_NOW | RTLD_LOCAL);
80 if (!egl_lib)
81 {
82 egl_found = 0;
83 return 0;
84 }
85 if (!(egl.GetProcAddress = dlsym(egl_lib, "eglGetProcAddress"))) goto err;
86
87 #define SYM(x, y) if (!(egl.x = egl.GetProcAddress(y))) \
88 goto err
89 // core syms used
90 SYM(GetDisplay, "eglGetDisplay");
91 SYM(Initialize, "eglInitialize");
92 SYM(Terminate, "eglTerminate");
93 SYM(QueryString, "eglQueryString");
94 SYM(ChooseConfig, "eglChooseConfig");
95 SYM(UnlockSurface, "eglGetConfigAttrib");
96 SYM(QuerySurface, "eglQuerySurface");
97 SYM(CreateWindowSurface, "eglCreateWindowSurface");
98 SYM(DestroySurface, "eglDestroySurface");
99 SYM(SwapBuffers, "eglSwapBuffers");
100 SYM(SwapInterval, "eglSwapInterval");
101
102 #undef SYM
103 #define SYM(x, y) egl.x = egl.GetProcAddress(y)
104 // extns
105 SYM(LockSurface, "eglLockSurface");
106 if (!egl.LockSurface) SYM(LockSurface, "eglLockSurfaceKHR");
107 SYM(UnlockSurface, "eglUnlockSurface");
108 if (!egl.UnlockSurface) SYM(UnlockSurface, "eglUnlockSurfaceKHR");
109
110 if (!egl.LockSurface) goto err;
111 if (!egl.UnlockSurface) goto err;
112
113 egl_found = 1;
114 return 1;
115 err:
116 if (egl_lib) dlclose(egl_lib);
117 egl_lib = NULL;
118 return 0;
119 }
120
121 #endif
122
123 void *
_egl_x_disp_get(void * d)124 _egl_x_disp_get(void *d)
125 {
126 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
127 if (!_egl_find()) return NULL;
128 return egl.GetDisplay(d);
129 #else
130 return NULL;
131 (void)d;
132 #endif
133 }
134
135 void
_egl_x_disp_terminate(void * ed)136 _egl_x_disp_terminate(void *ed)
137 {
138 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
139 if (!_egl_find()) return;
140 egl.Terminate(ed);
141 #else
142 (void)ed;
143 #endif
144 }
145
146 int
_egl_x_disp_init(void * ed)147 _egl_x_disp_init(void *ed)
148 {
149 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
150 int vmaj = 0, vmin = 0;
151 if (!_egl_find()) return 0;
152 if (!egl.Initialize(ed, &vmaj, &vmin)) return 0;
153 return 1;
154 #else
155 return 0;
156 (void)ed;
157 #endif
158 }
159
160 void *
_egl_x_disp_choose_config(void * ed)161 _egl_x_disp_choose_config(void *ed)
162 {
163 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
164 int config_attrs[40], n = 0, num_config = 0;
165 void *eglconfig = NULL;
166
167 if (!_egl_find()) return NULL;
168 config_attrs[n++] = EGL_SURFACE_TYPE;
169 config_attrs[n++] = EGL_WINDOW_BIT;
170 config_attrs[n++] = EGL_RED_SIZE;
171 config_attrs[n++] = 8;
172 config_attrs[n++] = EGL_GREEN_SIZE;
173 config_attrs[n++] = 8;
174 config_attrs[n++] = EGL_BLUE_SIZE;
175 config_attrs[n++] = 8;
176 config_attrs[n++] = EGL_ALPHA_SIZE;
177 config_attrs[n++] = 8;
178 config_attrs[n++] = EGL_DEPTH_SIZE;
179 config_attrs[n++] = 0;
180 config_attrs[n++] = EGL_STENCIL_SIZE;
181 config_attrs[n++] = 0;
182 config_attrs[n++] = EGL_SURFACE_TYPE;
183 config_attrs[n++] = EGL_LOCK_SURFACE_BIT_KHR;
184 config_attrs[n++] = EGL_MATCH_FORMAT_KHR;
185 config_attrs[n++] = EGL_FORMAT_RGBA_8888_KHR;
186
187 config_attrs[n++] = EGL_NONE;
188
189 if (!egl.ChooseConfig(ed, config_attrs, &eglconfig, 1, &num_config))
190 return NULL;
191 return eglconfig;
192 #else
193 return NULL;
194 (void)ed;
195 #endif
196 }
197
198 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
199 void *
_egl_x_win_surf_new(void * ed,Window win,void * config)200 _egl_x_win_surf_new(void *ed, Window win, void *config)
201 {
202 if (!_egl_find()) return NULL;
203 return egl.CreateWindowSurface(ed, config, win, NULL);
204 }
205
206 #endif
207
208 void
_egl_x_win_surf_free(void * ed,void * surf)209 _egl_x_win_surf_free(void *ed, void *surf)
210 {
211 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
212 if (!_egl_find()) return;
213 egl.DestroySurface(ed, surf);
214 #else
215 (void)ed;
216 (void)surf;
217 #endif
218 }
219
220 void *
_egl_x_surf_map(void * ed,void * surf,int * stride)221 _egl_x_surf_map(void *ed, void *surf, int *stride)
222 {
223 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
224 int config_attrs[40], n = 0;
225 void *ptr = NULL;
226 int pitch = 0, origin = 0;
227 int r_offset = 0, g_offset = 0, b_offset = 0;
228
229 if (!_egl_find()) return NULL;
230
231 config_attrs[n++] = EGL_MAP_PRESERVE_PIXELS_KHR;
232 config_attrs[n++] = EGL_TRUE;
233 config_attrs[n++] = EGL_LOCK_USAGE_HINT_KHR;
234 config_attrs[n++] = EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR;
235 config_attrs[n++] = EGL_NONE;
236
237 if (!egl.LockSurface(ed, surf, config_attrs)) return NULL;
238 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_POINTER_KHR, (int *)&ptr)) goto err;
239 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PITCH_KHR, &pitch)) goto err;
240 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_ORIGIN_KHR, &origin)) goto err;
241 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_RED_OFFSET_KHR, &r_offset)) goto err;
242 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR, &g_offset)) goto err;
243 if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR, &b_offset)) goto err;
244
245 if (!ptr) goto err;
246 if (pitch <= 0) goto err;
247 // must be top-left to bottom-right ordered
248 if (origin != EGL_UPPER_LEFT_KHR) goto err;
249 // must be xRGB
250 if (!((b_offset == 0) && (g_offset == 8) && (r_offset == 16))) goto err;
251 // return stride
252 *stride = pitch; // pitch is in bytes
253 return ptr;
254 err:
255 egl.UnlockSurface(ed, surf);
256 return NULL;
257 #else
258 return NULL;
259 (void)ed;
260 (void)surf;
261 (void)stride;
262 #endif
263 }
264
265 void
_egl_x_surf_unmap(void * ed,void * surf)266 _egl_x_surf_unmap(void *ed, void *surf)
267 {
268 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
269 egl.UnlockSurface(ed, surf);
270 #else
271 (void)ed;
272 (void)surf;
273 #endif
274 }
275
276 void
_egl_x_surf_swap(void * ed,void * surf,int vsync)277 _egl_x_surf_swap(void *ed, void *surf, int vsync)
278 {
279 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
280 if (vsync) egl.SwapInterval(ed, 1);
281 else egl.SwapInterval(ed, 0);
282 egl.SwapBuffers(ed, surf);
283 #else
284 (void)ed;
285 (void)surf;
286 (void)vsync;
287 #endif
288 }
289
290 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
291 Outbuf *
evas_software_egl_outbuf_setup_x(int w,int h,int rot,Outbuf_Depth depth,Display * disp,Drawable draw,Visual * vis,Colormap cmap,int x_depth,int grayscale,int max_colors,Pixmap mask,int shape_dither,int destination_alpha)292 evas_software_egl_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
293 Display *disp, Drawable draw, Visual *vis,
294 Colormap cmap, int x_depth,
295 int grayscale, int max_colors, Pixmap mask,
296 int shape_dither, int destination_alpha)
297 {
298 (void)w;
299 (void)h;
300 (void)rot;
301 (void)depth;
302 (void)draw;
303 (void)cmap;
304 (void)x_depth;
305 (void)grayscale;
306 (void)max_colors;
307 (void)mask;
308 (void)shape_dither;
309 (void)destination_alpha;
310 (void)disp;
311 (void)vis;
312 return NULL;
313 }
314
315 #endif
316