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