Evas (wayland_egl): More bug fixes & cleanups ! :)
[profile/ivi/evas.git] / src / modules / engines / wayland_egl / evas_wl_main.c
1 #include "evas_engine.h"
2
3 static Evas_GL_Wl_Window *_evas_gl_wl_window = NULL;
4
5 static EGLContext share_context = EGL_NO_CONTEXT;
6
7 // fixme: something is up/wrong here - dont know what tho...
8 //#define NEWGL 1
9
10 static int win_count = 0;
11
12 Evas_GL_Wl_Window *
13 eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
14                int depth, int w, int h, int indirect, int alpha, int rot)
15 {
16    Evas_GL_Wl_Window *gw;
17    int context_attrs[3];
18    int config_attrs[40];
19    int major_version, minor_version;
20    int num_config, n = 0;
21    const GLubyte *vendor, *renderer, *version;
22
23    gw = calloc(1, sizeof(Evas_GL_Wl_Window));
24    if (!gw) return NULL;
25
26    win_count++;
27    gw->disp = disp;
28    gw->surface = surface;
29    gw->screen = screen;
30    gw->depth = depth;
31    gw->alpha = alpha;
32    gw->w = w;
33    gw->h = h;
34    gw->rot = rot;
35
36 // EGL / GLES
37    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
38    context_attrs[1] = 2;
39    context_attrs[2] = EGL_NONE;
40
41 #if defined(GLES_VARIETY_S3C6410)
42    if (gw->depth == 16) // 16bpp
43      {
44         config_attrs[n++] = EGL_SURFACE_TYPE;
45         config_attrs[n++] = EGL_WINDOW_BIT;
46         config_attrs[n++] = EGL_RENDERABLE_TYPE;
47         config_attrs[n++] = EGL_OPENGL_ES2_BIT;
48         config_attrs[n++] = EGL_RED_SIZE;
49         config_attrs[n++] = 5;
50         config_attrs[n++] = EGL_GREEN_SIZE;
51         config_attrs[n++] = 6;
52         config_attrs[n++] = EGL_BLUE_SIZE;
53         config_attrs[n++] = 5;
54         config_attrs[n++] = EGL_DEPTH_SIZE;
55         config_attrs[n++] = 0;
56         config_attrs[n++] = EGL_STENCIL_SIZE;
57         config_attrs[n++] = 0;
58         config_attrs[n++] = EGL_NONE;
59      }
60    else // 24/32bit. no one does 8bpp anymore. and 15bpp... dead
61      {
62         config_attrs[n++] = EGL_SURFACE_TYPE;
63         config_attrs[n++] = EGL_WINDOW_BIT;
64         config_attrs[n++] = EGL_RENDERABLE_TYPE;
65         config_attrs[n++] = EGL_OPENGL_ES2_BIT;
66         config_attrs[n++] = EGL_RED_SIZE;
67         config_attrs[n++] = 8;
68         config_attrs[n++] = EGL_GREEN_SIZE;
69         config_attrs[n++] = 8;
70         config_attrs[n++] = EGL_BLUE_SIZE;
71         config_attrs[n++] = 8;
72         config_attrs[n++] = EGL_DEPTH_SIZE;
73         config_attrs[n++] = 0;
74         config_attrs[n++] = EGL_STENCIL_SIZE;
75         config_attrs[n++] = 0;
76         config_attrs[n++] = EGL_NONE;
77      }
78 #elif defined(GLES_VARIETY_SGX)
79    config_attrs[n++] = EGL_SURFACE_TYPE;
80    config_attrs[n++] = EGL_WINDOW_BIT;
81    config_attrs[n++] = EGL_RENDERABLE_TYPE;
82    config_attrs[n++] = EGL_OPENGL_ES2_BIT;
83 # if 0
84 // FIXME: n900 - omap3 sgx libs break here
85    config_attrs[n++] = EGL_RED_SIZE;
86    config_attrs[n++] = 1;
87    config_attrs[n++] = EGL_GREEN_SIZE;
88    config_attrs[n++] = 1;
89    config_attrs[n++] = EGL_BLUE_SIZE;
90    config_attrs[n++] = 1;
91 // FIXME: end n900 breakage
92 # endif
93    if (gw->alpha)
94      {
95         config_attrs[n++] = EGL_ALPHA_SIZE;
96         config_attrs[n++] = 1;
97      }
98    else
99      {
100         config_attrs[n++] = EGL_ALPHA_SIZE;
101         config_attrs[n++] = 0;
102      }
103    config_attrs[n++] = EGL_DEPTH_SIZE;
104    config_attrs[n++] = 0;
105    config_attrs[n++] = EGL_STENCIL_SIZE;
106    config_attrs[n++] = 0;
107    config_attrs[n++] = EGL_NONE;
108 #endif
109    
110    gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
111    if (!gw->egl_disp)
112      {
113         ERR("eglGetDisplay() fail. code=%#x", eglGetError());
114         eng_window_free(gw);
115         return NULL;
116      }
117    if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
118      {
119         ERR("eglInitialize() fail. code=%#x", eglGetError());
120         eng_window_free(gw);
121         return NULL;
122      }
123    eglBindAPI(EGL_OPENGL_ES_API);
124    if (eglGetError() != EGL_SUCCESS)
125      {
126         ERR("eglBindAPI() fail. code=%#x", eglGetError());
127         eng_window_free(gw);
128         return NULL;
129      }
130
131    num_config = 0;
132    if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config,
133                         1, &num_config) || (num_config != 1))
134      {
135         ERR("eglChooseConfig() fail. code=%#x", eglGetError());
136         eng_window_free(gw);
137         return NULL;
138      }
139
140    if ((gw->rot == 0) || (gw->rot == 180))
141      gw->win = wl_egl_window_create(gw->surface, gw->w, gw->h);
142    else if ((gw->rot == 90) || (gw->rot == 270))
143      gw->win = wl_egl_window_create(gw->surface, gw->h, gw->w);
144
145    gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
146                                                (EGLNativeWindowType)gw->win,
147                                                NULL);
148    if (gw->egl_surface[0] == EGL_NO_SURFACE)
149      {
150         ERR("eglCreateWindowSurface() fail for %p. code=%#x",
151             gw->win, eglGetError());
152         eng_window_free(gw);
153         return NULL;
154      }
155
156    gw->egl_context[0] = 
157      eglCreateContext(gw->egl_disp, gw->egl_config, share_context, 
158                       context_attrs);
159
160    if (gw->egl_context[0] == EGL_NO_CONTEXT)
161      {
162         ERR("eglCreateContext() fail. code=%#x", eglGetError());
163         eng_window_free(gw);
164         return NULL;
165      }
166
167    if (share_context == EGL_NO_CONTEXT)
168      share_context = gw->egl_context[0];
169
170    if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
171                       gw->egl_context[0]) == EGL_FALSE)
172      {
173         ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
174         eng_window_free(gw);
175         return NULL;
176      }
177
178    vendor = glGetString(GL_VENDOR);
179    renderer = glGetString(GL_RENDERER);
180    version = glGetString(GL_VERSION);
181    if (!vendor) vendor   = (unsigned char *)"-UNKNOWN-";
182    if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
183    if (!version) version  = (unsigned char *)"-UNKNOWN-";
184    if (getenv("EVAS_GL_INFO"))
185      {
186         fprintf(stderr, "vendor: %s\n", vendor);
187         fprintf(stderr, "renderer: %s\n", renderer);
188         fprintf(stderr, "version: %s\n", version);
189      }
190
191    gw->gl_context = evas_gl_common_context_new();
192    if (!gw->gl_context)
193      {
194         eng_window_free(gw);
195         return NULL;
196      }
197    gw->gl_context->egldisp = gw->egl_disp;
198    eng_window_use(gw);
199    evas_gl_common_context_resize(gw->gl_context, w, h, rot);
200    gw->surf = 1;
201    return gw;
202    indirect = 0;
203 }
204
205 void
206 eng_window_free(Evas_GL_Wl_Window *gw)
207 {
208    int ref = 0;
209
210    win_count--;
211    eng_window_use(gw);
212    if (gw == _evas_gl_wl_window) _evas_gl_wl_window = NULL;
213 //   if (gw->win) wl_egl_window_destroy(gw->win);
214    if (gw->gl_context)
215      {
216         ref = gw->gl_context->references - 1;
217         evas_gl_common_context_free(gw->gl_context);
218      }
219    if (gw->egl_surface[0] != EGL_NO_SURFACE)
220       eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
221    eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
222
223    if (gw->egl_context[0] != EGL_NO_CONTEXT && gw->egl_context[0] != share_context) 
224      eglDestroyContext(gw->egl_disp, gw->egl_context[0]);
225
226    if (ref == 0)
227      {
228         /* NB: This is causing an unknown hang when we run elm apps as 
229          * wayland clients inside the weston compositor */
230         /* eglTerminate(gw->egl_disp); */
231         eglReleaseThread();
232      }
233    free(gw);
234 }
235
236 void
237 eng_window_use(Evas_GL_Wl_Window *gw)
238 {
239    Eina_Bool force_use = EINA_FALSE;
240
241    if (_evas_gl_wl_window)
242      {
243         if ((eglGetCurrentContext() !=
244              _evas_gl_wl_window->egl_context[0]) ||
245             (eglGetCurrentSurface(EGL_READ) !=
246                 _evas_gl_wl_window->egl_surface[0]) ||
247             (eglGetCurrentSurface(EGL_DRAW) !=
248                 _evas_gl_wl_window->egl_surface[0]))
249            force_use = EINA_TRUE;
250      }
251    if ((_evas_gl_wl_window != gw) || (force_use))
252      {
253         if (_evas_gl_wl_window)
254           {
255              evas_gl_common_context_use(_evas_gl_wl_window->gl_context);
256              evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
257           }
258         _evas_gl_wl_window = gw;
259         if (gw)
260           {
261              // EGL / GLES
262              if (gw->egl_surface[0] != EGL_NO_SURFACE)
263                {
264                   if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
265                                      gw->egl_surface[0],
266                                      gw->egl_context[0]) == EGL_FALSE)
267                     {
268                        ERR("eglMakeCurrent() failed!");
269                     }
270                }
271           }
272      }
273    if (gw) evas_gl_common_context_use(gw->gl_context);
274 }
275
276 void
277 eng_window_unsurf(Evas_GL_Wl_Window *gw)
278 {
279    if (!gw->surf) return;
280    if (!getenv("EVAS_GL_WIN_RESURF")) return;
281    if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw);
282
283    if (_evas_gl_wl_window)
284       evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
285    if (_evas_gl_wl_window == gw)
286      {
287         eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
288         if (gw->egl_surface[0] != EGL_NO_SURFACE)
289            eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
290         gw->egl_surface[0] = EGL_NO_SURFACE;
291         _evas_gl_wl_window = NULL;
292      }
293    gw->surf = 0;
294 }
295
296 void
297 eng_window_resurf(Evas_GL_Wl_Window *gw)
298 {
299    if (gw->surf) return;
300    if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", gw);
301
302    gw->egl_surface[0] = 
303      eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
304                             (EGLNativeWindowType)gw->win, NULL);
305
306    if (gw->egl_surface[0] == EGL_NO_SURFACE)
307      {
308         ERR("eglCreateWindowSurface() fail for %p. code=%#x",
309             gw->win, eglGetError());
310         return;
311      }
312    if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
313                       gw->egl_context[0]) == EGL_FALSE)
314      {
315         ERR("eglMakeCurrent() failed!");
316      }
317    gw->surf = 1;
318 }
319
320 int
321 eng_best_depth_get(Evas_Engine_Info_Wayland_Egl *einfo)
322 {
323    if (!einfo) return 0;
324    if (!einfo->info.display) return 0;
325    return (einfo->info.depth ? einfo->info.depth : 32);
326 }