852a603f21b2e695152b33db3a9aff947396588f
[profile/ivi/evas.git] / src / modules / engines / gl_x11 / evas_x_main.c
1 #include "evas_engine.h"
2
3 static Evas_GL_X11_Window *_evas_gl_x11_window = NULL;
4
5 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
6 static EGLContext context = EGL_NO_CONTEXT;
7 #else
8 // FIXME: this will only work for 1 display connection (glx land can have > 1)
9 static GLXContext context = 0;
10 static GLXContext rgba_context = 0;
11 static GLXFBConfig fbconf = 0;
12 static GLXFBConfig rgba_fbconf = 0;
13 #endif
14
15 // fixme: something is up/wrong here - dont know what tho...
16 //#define NEWGL 1
17
18 static XVisualInfo *_evas_gl_x11_vi = NULL;
19 static XVisualInfo *_evas_gl_x11_rgba_vi = NULL;
20 static Colormap     _evas_gl_x11_cmap = 0;
21 static Colormap     _evas_gl_x11_rgba_cmap = 0;
22
23 static int win_count = 0;
24
25 Evas_GL_X11_Window *
26 eng_window_new(Display *disp,
27                Window   win,
28                int      screen,
29                Visual  *vis,
30                Colormap cmap,
31                int      depth,
32                int      w,
33                int      h,
34                int      indirect,
35                int      alpha,
36                int      rot)
37 {
38    Evas_GL_X11_Window *gw;
39 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
40    int context_attrs[3];
41    int config_attrs[40];
42    int major_version, minor_version;
43    int num_config, n = 0;
44 #endif
45    XVisualInfo *vi_use;
46    const GLubyte *vendor, *renderer, *version;
47    int blacklist = 0;
48
49    if (!_evas_gl_x11_vi) return NULL;
50
51    gw = calloc(1, sizeof(Evas_GL_X11_Window));
52    if (!gw) return NULL;
53
54    win_count++;
55    gw->disp = disp;
56    gw->win = win;
57    gw->screen = screen;
58    gw->visual = vis;
59    gw->colormap = cmap;
60    gw->depth = depth;
61    gw->alpha = alpha;
62    gw->w = w;
63    gw->h = h;
64    gw->rot = rot;
65
66    vi_use = _evas_gl_x11_vi;
67    if (gw->alpha)
68      {
69 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
70         if (_evas_gl_x11_rgba_vi)
71           {
72              vi_use = _evas_gl_x11_rgba_vi;
73           }
74 #else
75 //#ifdef NEWGL
76         if (_evas_gl_x11_rgba_vi)
77           {
78              vi_use = _evas_gl_x11_rgba_vi;
79           }
80 //#endif
81 #endif
82      }
83    gw->visualinfo = vi_use;
84
85 // EGL / GLES
86 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
87    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
88    context_attrs[1] = 2;
89    context_attrs[2] = EGL_NONE;
90
91 # if defined(GLES_VARIETY_S3C6410)
92    if (gw->visualinfo->depth == 16) // 16bpp
93      {
94         config_attrs[n++] = EGL_SURFACE_TYPE;
95         config_attrs[n++] = EGL_WINDOW_BIT;
96         config_attrs[n++] = EGL_RENDERABLE_TYPE;
97         config_attrs[n++] = EGL_OPENGL_ES2_BIT;
98         config_attrs[n++] = EGL_RED_SIZE;
99         config_attrs[n++] = 5;
100         config_attrs[n++] = EGL_GREEN_SIZE;
101         config_attrs[n++] = 6;
102         config_attrs[n++] = EGL_BLUE_SIZE;
103         config_attrs[n++] = 5;
104         config_attrs[n++] = EGL_DEPTH_SIZE;
105         config_attrs[n++] = 0;
106         config_attrs[n++] = EGL_STENCIL_SIZE;
107         config_attrs[n++] = 0;
108         config_attrs[n++] = EGL_NONE;
109      }
110    else // 24/32bit. no one does 8bpp anymore. and 15bpp... dead
111      {
112         config_attrs[n++] = EGL_SURFACE_TYPE;
113         config_attrs[n++] = EGL_WINDOW_BIT;
114         config_attrs[n++] = EGL_RENDERABLE_TYPE;
115         config_attrs[n++] = EGL_OPENGL_ES2_BIT;
116         config_attrs[n++] = EGL_RED_SIZE;
117         config_attrs[n++] = 8;
118         config_attrs[n++] = EGL_GREEN_SIZE;
119         config_attrs[n++] = 8;
120         config_attrs[n++] = EGL_BLUE_SIZE;
121         config_attrs[n++] = 8;
122         config_attrs[n++] = EGL_DEPTH_SIZE;
123         config_attrs[n++] = 0;
124         config_attrs[n++] = EGL_STENCIL_SIZE;
125         config_attrs[n++] = 0;
126         config_attrs[n++] = EGL_NONE;
127      }
128 # elif defined(GLES_VARIETY_SGX)
129    config_attrs[n++] = EGL_SURFACE_TYPE;
130    config_attrs[n++] = EGL_WINDOW_BIT;
131    config_attrs[n++] = EGL_RENDERABLE_TYPE;
132    config_attrs[n++] = EGL_OPENGL_ES2_BIT;
133 #if 0
134 // FIXME: n900 - omap3 sgx libs break here
135    config_attrs[n++] = EGL_RED_SIZE;
136    config_attrs[n++] = 1;
137    config_attrs[n++] = EGL_GREEN_SIZE;
138    config_attrs[n++] = 1;
139    config_attrs[n++] = EGL_BLUE_SIZE;
140    config_attrs[n++] = 1;
141 // FIXME: end n900 breakage
142 #endif
143    if (gw->alpha)
144      {
145         config_attrs[n++] = EGL_ALPHA_SIZE;
146         config_attrs[n++] = 1;
147      }
148    else
149      {
150         config_attrs[n++] = EGL_ALPHA_SIZE;
151         config_attrs[n++] = 0;
152      }
153    config_attrs[n++] = EGL_DEPTH_SIZE;
154    config_attrs[n++] = 0;
155    config_attrs[n++] = EGL_STENCIL_SIZE;
156    config_attrs[n++] = 0;
157    config_attrs[n++] = EGL_NONE;
158 # endif
159
160    gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
161    if (!gw->egl_disp)
162      {
163         ERR("eglGetDisplay() fail. code=%#x", eglGetError());
164         eng_window_free(gw);
165         return NULL;
166      }
167    if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
168      {
169         ERR("eglInitialize() fail. code=%#x", eglGetError());
170         eng_window_free(gw);
171         return NULL;
172      }
173    eglBindAPI(EGL_OPENGL_ES_API);
174    if (eglGetError() != EGL_SUCCESS)
175      {
176         ERR("eglBindAPI() fail. code=%#x", eglGetError());
177         eng_window_free(gw);
178         return NULL;
179      }
180
181    num_config = 0;
182    if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config,
183                         1, &num_config) || (num_config != 1))
184      {
185         ERR("eglChooseConfig() fail. code=%#x", eglGetError());
186         eng_window_free(gw);
187         return NULL;
188      }
189    gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
190                                                (EGLNativeWindowType)gw->win,
191                                                NULL);
192    if (gw->egl_surface[0] == EGL_NO_SURFACE)
193      {
194         ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
195             (unsigned int)gw->win, eglGetError());
196         eng_window_free(gw);
197         return NULL;
198      }
199    if (context == EGL_NO_CONTEXT)
200      context = eglCreateContext(gw->egl_disp, gw->egl_config, NULL,
201                                 context_attrs);
202    gw->egl_context[0] = context;
203    if (gw->egl_context[0] == EGL_NO_CONTEXT)
204      {
205         ERR("eglCreateContext() fail. code=%#x", eglGetError());
206         eng_window_free(gw);
207         return NULL;
208      }
209    if (eglMakeCurrent(gw->egl_disp,
210                       gw->egl_surface[0],
211                       gw->egl_surface[0],
212                       gw->egl_context[0]) == EGL_FALSE)
213      {
214         ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
215         eng_window_free(gw);
216         return NULL;
217      }
218
219    vendor = glGetString(GL_VENDOR);
220    renderer = glGetString(GL_RENDERER);
221    version = glGetString(GL_VERSION);
222    if (!vendor)   vendor   = (unsigned char *)"-UNKNOWN-";
223    if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
224    if (!version)  version  = (unsigned char *)"-UNKNOWN-";
225    if (getenv("EVAS_GL_INFO"))
226      {
227         fprintf(stderr, "vendor: %s\n", vendor);
228         fprintf(stderr, "renderer: %s\n", renderer);
229         fprintf(stderr, "version: %s\n", version);
230      }
231
232    if (strstr((const char *)vendor, "Mesa Project"))
233      {
234         if (strstr((const char *)renderer, "Software Rasterizer"))
235           blacklist = 1;
236      }
237    if (strstr((const char *)renderer, "softpipe"))
238      blacklist = 1;
239    if (blacklist)
240      {
241         ERR("OpenGL Driver blacklisted:");
242         ERR("Vendor: %s", (const char *)vendor);
243         ERR("Renderer: %s", (const char *)renderer);
244         ERR("Version: %s", (const char *)version);
245         eng_window_free(gw);
246         return NULL;
247      }
248 // GLX
249 #else
250    if (!context)
251      {
252 #ifdef NEWGL
253         if (indirect)
254           context = glXCreateNewContext(gw->disp, fbconf,
255                                         GLX_RGBA_TYPE, NULL,
256                                         GL_FALSE);
257         else
258           context = glXCreateNewContext(gw->disp, fbconf,
259                                         GLX_RGBA_TYPE, NULL,
260                                         GL_TRUE);
261 #else
262         if (indirect)
263           context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_FALSE);
264         else
265           context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_TRUE);
266 #endif
267      }
268 #ifdef NEWGL
269    if ((gw->alpha) && (!rgba_context))
270      {
271         if (indirect)
272           rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
273                                              GLX_RGBA_TYPE, context,
274                                              GL_FALSE);
275         else
276           rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
277                                              GLX_RGBA_TYPE, context,
278                                              GL_TRUE);
279      }
280    if (gw->alpha)
281      gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
282    else
283      gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
284    if (!gw->glxwin)
285      {
286         eng_window_free(gw);
287         return NULL;
288      }
289
290    if (gw->alpha) gw->context = rgba_context;
291    else gw->context = context;
292 #else
293    gw->context = context;
294 #endif
295
296    if (!gw->context)
297      {
298         eng_window_free(gw);
299         return NULL;
300      }
301    if (gw->context)
302      {
303         int i, j,  num;
304         GLXFBConfig *fbc;
305
306         if (gw->glxwin)
307           {
308              if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
309                                         gw->context))
310                {
311                   printf("Error: glXMakeContextCurrent(%p, %p, %p, %p)\n", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
312                   eng_window_free(gw);
313                   return NULL;
314                }
315           }
316         else
317           {
318              if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
319                {
320                   printf("Error: glXMakeCurrent(%p, 0x%x, %p) failed\n", (void *)gw->disp, (unsigned int)gw->win, (void *)gw->context);
321                   eng_window_free(gw);
322                   return NULL;
323                }
324           }
325
326         // FIXME: move this up to context creation
327
328         vendor = glGetString(GL_VENDOR);
329         renderer = glGetString(GL_RENDERER);
330         version = glGetString(GL_VERSION);
331         if (getenv("EVAS_GL_INFO"))
332           {
333              fprintf(stderr, "vendor: %s\n", vendor);
334              fprintf(stderr, "renderer: %s\n", renderer);
335              fprintf(stderr, "version: %s\n", version);
336           }
337         //   examples:
338         // vendor: NVIDIA Corporation
339         // renderer: NVIDIA Tegra
340         // version: OpenGL ES 2.0
341         //   or
342         // vendor: Imagination Technologies
343         // renderer: PowerVR SGX 540
344         // version: OpenGL ES 2.0
345         //   or
346         // vendor: NVIDIA Corporation
347         // renderer: GeForce GT 330M/PCI/SSE2
348         // version: 3.3.0 NVIDIA 256.53
349         //   or
350         // vendor: NVIDIA Corporation
351         // renderer: GeForce GT 220/PCI/SSE2
352         // version: 3.2.0 NVIDIA 195.36.24
353         //   or
354         // vendor: NVIDIA Corporation
355         // renderer: GeForce 8600 GTS/PCI/SSE2
356         // version: 3.3.0 NVIDIA 260.19.36
357         //   or
358         // vendor: ATI Technologies Inc.
359         // renderer: ATI Mobility Radeon HD 4650
360         // version: 3.2.9756 Compatibility Profile Context
361         //   or
362         // vendor: Tungsten Graphics, Inc
363         // renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2
364         // version: 2.1 Mesa 7.9-devel
365         //   or
366         // vendor: Advanced Micro Devices, Inc.
367         // renderer: Mesa DRI R600 (RS780 9610) 20090101  TCL DRI2
368         // version: 2.1 Mesa 7.9-devel
369         //   or
370         // vendor: NVIDIA Corporation
371         // renderer: GeForce 9600 GT/PCI/SSE2
372         // version: 3.3.0 NVIDIA 260.19.29
373         //   or
374         // vendor: ATI Technologies Inc.
375         // renderer: ATI Radeon HD 4800 Series
376         // version: 3.3.10237 Compatibility Profile Context
377         //   or
378         // vendor: Advanced Micro Devices, Inc.
379         // renderer: Mesa DRI R600 (RV770 9442) 20090101  TCL DRI2
380         // version: 2.0 Mesa 7.8.2
381         //   or
382         // vendor: Tungsten Graphics, Inc
383         // renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT
384         // version: 2.1 Mesa 7.9-devel
385         //   or (bad - software renderer)
386         // vendor: Mesa Project
387         // renderer: Software Rasterizer
388         // version: 2.1 Mesa 7.9-devel
389         //   or (bad - software renderer)
390         // vendor: VMware, Inc.
391         // renderer: Gallium 0.4 on softpipe
392         // version: 2.1 Mesa 7.9-devel
393
394         if (strstr((const char *)vendor, "Mesa Project"))
395           {
396              if (strstr((const char *)renderer, "Software Rasterizer"))
397                 blacklist = 1;
398           }
399         if (strstr((const char *)renderer, "softpipe"))
400            blacklist = 1;
401         if (blacklist)
402           {
403              ERR("OpenGL Driver blacklisted:");
404              ERR("Vendor: %s", (const char *)vendor);
405              ERR("Renderer: %s", (const char *)renderer);
406              ERR("Version: %s", (const char *)version);
407              eng_window_free(gw);
408              return NULL;
409           }
410         if (strstr((const char *)vendor, "NVIDIA"))
411           {
412              if (!strstr((const char *)renderer, "NVIDIA Tegra"))
413                {
414                   int v1 = 0, v2 = 0, v3 = 0;
415
416                   if (sscanf((const char *)version,
417                              "%*s %*s %i.%i.%i",
418                              &v1, &v2, &v3) != 3)
419                     {
420                        v1 = v2 = v3 = 0;
421                        if (sscanf((const char *)version,
422                                   "%*s %*s %i.%i",
423                                   &v1, &v2) != 2)
424                           v1 = 0;
425                     }
426                   // ALSO as of some nvidia driver version loose binding is
427                   // probably not needed
428                   if (v1 < 195) gw->detected.loose_binding = 1;
429                }
430           }
431         else
432           {
433              // noothing yet. add more cases and options over time
434           }
435
436         fbc = glXGetFBConfigs(gw->disp, screen, &num);
437         if (!fbc)
438           {
439              ERR("glXGetFBConfigs() returned no fb configs");
440              eng_window_free(gw);
441              return NULL;
442           }
443         for (i = 0; i <= 32; i++)
444           {
445              for (j = 0; j < num; j++)
446                {
447                   XVisualInfo *vi;
448                   int vd;
449                   int alph, val, dbuf, stencil, tdepth;
450                   int rgba;
451
452                   vi = glXGetVisualFromFBConfig(gw->disp, fbc[j]);
453                   if (!vi) continue;
454                   vd = vi->depth;
455                   XFree(vi);
456
457                   if (vd != i) continue;
458
459                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_ALPHA_SIZE, &alph);
460                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BUFFER_SIZE, &val);
461
462                   if ((val != i) && ((val - alph) != i)) continue;
463
464                   val = 0;
465                   rgba = 0;
466
467                   if (i == 32)
468                     {
469                        glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
470                        if (val)
471                          {
472                             rgba = 1;
473                             gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
474                          }
475                     }
476                   if (!val)
477                     {
478                        if (rgba) continue;
479                        glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
480                        if (!val) continue;
481                        gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
482                     }
483
484                   dbuf = 0x7fff;
485                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DOUBLEBUFFER, &val);
486                   if (val > dbuf) continue;
487                   dbuf = val;
488
489                   stencil = 0x7fff;
490                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_STENCIL_SIZE, &val);
491                   if (val > stencil) continue;
492                   stencil = val;
493
494                   tdepth = 0x7fff;
495                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DEPTH_SIZE, &val);
496                   if (val > tdepth) continue;
497                   tdepth = val;
498
499                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
500                   if (val < 0) continue;
501                   gw->depth_cfg[i].mipmap = val;
502
503                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_Y_INVERTED_EXT, &val);
504                   gw->depth_cfg[i].yinvert = val;
505
506                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
507                   gw->depth_cfg[i].tex_target = val;
508
509                   gw->depth_cfg[i].fbc = fbc[j];
510                }
511           }
512         XFree(fbc);
513         if (!gw->depth_cfg[DefaultDepth(gw->disp, screen)].fbc)
514           {
515              WRN("texture from pixmap not going to work");
516           }
517      }
518 #endif
519
520    gw->gl_context = evas_gl_common_context_new();
521    if (!gw->gl_context)
522      {
523         eng_window_free(gw);
524         return NULL;
525      }
526 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
527    gw->gl_context->egldisp = gw->egl_disp;
528 #endif
529    eng_window_use(gw);
530    evas_gl_common_context_resize(gw->gl_context, w, h, rot);
531    gw->surf = 1;
532    return gw;
533    indirect = 0;
534 }
535
536 void
537 eng_window_free(Evas_GL_X11_Window *gw)
538 {
539    int ref = 0;
540    win_count--;
541    eng_window_use(gw);
542    if (gw == _evas_gl_x11_window) _evas_gl_x11_window = NULL;
543    if (gw->gl_context)
544      {
545         ref = gw->gl_context->references - 1;
546         evas_gl_common_context_free(gw->gl_context);
547      }
548 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
549    if (gw->egl_surface[0] != EGL_NO_SURFACE)
550       eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
551    eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
552    if (ref == 0)
553      {
554         if (context) eglDestroyContext(gw->egl_disp, context);
555         eglTerminate(gw->egl_disp);
556         context = EGL_NO_CONTEXT;
557      }
558    eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
559 #else
560    if (gw->glxwin) glXDestroyWindow(gw->disp, gw->glxwin);
561    if (ref == 0)
562      {
563         if (context) glXDestroyContext(gw->disp, context);
564         if (rgba_context) glXDestroyContext(gw->disp, rgba_context);
565         context = 0;
566         rgba_context = 0;
567         fbconf = 0;
568         rgba_fbconf = 0;
569      }
570 #endif
571    free(gw);
572 }
573
574 void
575 eng_window_use(Evas_GL_X11_Window *gw)
576 {
577    Eina_Bool force_use = EINA_FALSE;
578
579 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
580    if (_evas_gl_x11_window)
581      {
582         if ((eglGetCurrentContext() !=
583              _evas_gl_x11_window->egl_context[0]) ||
584             (eglGetCurrentSurface(EGL_READ) !=
585                 _evas_gl_x11_window->egl_surface[0]) ||
586             (eglGetCurrentSurface(EGL_DRAW) !=
587                 _evas_gl_x11_window->egl_surface[0]))
588            force_use = EINA_TRUE;
589      }
590 #else
591    if (_evas_gl_x11_window)
592      {
593         if (glXGetCurrentContext() != _evas_gl_x11_window->context)
594            force_use = EINA_TRUE;
595      }
596 #endif
597    if ((_evas_gl_x11_window != gw) || (force_use))
598      {
599         if (_evas_gl_x11_window)
600           {
601              evas_gl_common_context_use(_evas_gl_x11_window->gl_context);
602              evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
603           }
604         _evas_gl_x11_window = gw;
605         if (gw)
606           {
607 // EGL / GLES
608 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
609            if (gw->egl_surface[0] != EGL_NO_SURFACE)
610              {
611                 if (eglMakeCurrent(gw->egl_disp,
612                                    gw->egl_surface[0],
613                                    gw->egl_surface[0],
614                                    gw->egl_context[0]) == EGL_FALSE)
615                   {
616                      ERR("eglMakeCurrent() failed!");
617                   }
618              }
619 // GLX
620 #else
621            if (gw->glxwin)
622              {
623                if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
624                                           gw->context))
625                  {
626                    ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
627                  }
628              }
629            else
630              {
631                if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
632                  {
633                    ERR("glXMakeCurrent(%p, 0x%x, %p) failed", gw->disp, (unsigned int)gw->win, (void *)gw->context);
634                  }
635              }
636 #endif
637           }
638      }
639    if (gw) evas_gl_common_context_use(gw->gl_context);
640 }
641
642 void
643 eng_window_unsurf(Evas_GL_X11_Window *gw)
644 {
645    if (!gw->surf) return;
646    if (!getenv("EVAS_GL_WIN_RESURF")) return;
647    if (getenv("EVAS_GL_INFO"))
648       printf("unsurf %p\n", gw);
649 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
650    if (_evas_gl_x11_window)
651       evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
652    if (_evas_gl_x11_window == gw)
653      {
654         eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
655         if (gw->egl_surface[0] != EGL_NO_SURFACE)
656            eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
657         gw->egl_surface[0] = EGL_NO_SURFACE;
658         _evas_gl_x11_window = NULL;
659      }
660 #else
661    if (gw->glxwin)
662       {
663          glXDestroyWindow(gw->disp, gw->glxwin);
664       }
665    else
666      {
667      }
668 #endif
669    gw->surf = 0;
670 }
671
672 void
673 eng_window_resurf(Evas_GL_X11_Window *gw)
674 {
675    if (gw->surf) return;
676    if (getenv("EVAS_GL_INFO"))
677       printf("resurf %p\n", gw);
678 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
679    gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
680                                                      (EGLNativeWindowType)gw->win,
681                                                      NULL);
682    if (gw->egl_surface[0] == EGL_NO_SURFACE)
683      {
684         ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
685             (unsigned int)gw->win, eglGetError());
686         return;
687      }
688    if (eglMakeCurrent(gw->egl_disp,
689                       gw->egl_surface[0],
690                       gw->egl_surface[0],
691                       gw->egl_context[0]) == EGL_FALSE)
692      {
693         ERR("eglMakeCurrent() failed!");
694      }
695 #else
696 #ifdef NEWGL
697    if (gw->alpha)
698      gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
699    else
700      gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
701    if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
702                               gw->context))
703      {
704         ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
705      }
706 #else
707    if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
708      {
709         ERR("glXMakeCurrent(%p, 0x%x, %p) failed", (void *)gw->disp, (unsigned int)gw->win, (void *)gw->context);
710      }
711 #endif
712 #endif
713    gw->surf = 1;
714 }
715
716 Visual *
717 eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
718 {
719    if (!einfo) return NULL;
720    if (!einfo->info.display) return NULL;
721    if (!_evas_gl_x11_vi)
722      {
723         int alpha;
724
725 // EGL / GLES
726 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
727         for (alpha = 0; alpha < 2; alpha++)
728           {
729              int depth = DefaultDepth(einfo->info.display,
730                                       einfo->info.screen);
731              if (alpha)
732                {
733                   XVisualInfo *xvi, vi_in;
734                   int nvi, i;
735                   XRenderPictFormat *fmt;
736
737                   vi_in.screen = einfo->info.screen;
738                   vi_in.depth = 32;
739                   vi_in.class = TrueColor;
740                   xvi = XGetVisualInfo(einfo->info.display,
741                                        VisualScreenMask | VisualDepthMask |
742                                        VisualClassMask,
743                                        &vi_in, &nvi);
744                   if (xvi)
745                     {
746                        for (i = 0; i < nvi; i++)
747                          {
748                             fmt = XRenderFindVisualFormat(einfo->info.display,
749                                                           xvi[i].visual);
750                             if ((fmt->type == PictTypeDirect) &&
751                                 (fmt->direct.alphaMask))
752                               {
753                                  _evas_gl_x11_rgba_vi =
754                                    calloc(1, sizeof(XVisualInfo));
755                                  if (_evas_gl_x11_rgba_vi)
756                                    memcpy(_evas_gl_x11_rgba_vi,
757                                           &(xvi[i]), sizeof(XVisualInfo));
758                                  break;
759                               }
760                          }
761                        XFree (xvi);
762                     }
763                }
764              else
765                {
766                   _evas_gl_x11_vi = calloc(1, sizeof(XVisualInfo));
767                   XMatchVisualInfo(einfo->info.display,
768                                    einfo->info.screen, depth, TrueColor,
769                                    _evas_gl_x11_vi);
770                }
771           }
772 // GLX
773 #else
774         for (alpha = 0; alpha < 2; alpha++)
775           {
776              int config_attrs[40];
777              GLXFBConfig *configs = NULL, config = 0;
778              int i, num;
779
780              i = 0;
781              config_attrs[i++] = GLX_DRAWABLE_TYPE;
782              config_attrs[i++] = GLX_WINDOW_BIT;
783              config_attrs[i++] = GLX_DOUBLEBUFFER;
784              config_attrs[i++] = 1;
785              config_attrs[i++] = GLX_RED_SIZE;
786              config_attrs[i++] = 1;
787              config_attrs[i++] = GLX_GREEN_SIZE;
788              config_attrs[i++] =1;
789              config_attrs[i++] = GLX_BLUE_SIZE;
790              config_attrs[i++] = 1;
791              if (alpha)
792                {
793                   config_attrs[i++] = GLX_RENDER_TYPE;
794                   config_attrs[i++] = GLX_RGBA_BIT;
795                   config_attrs[i++] = GLX_ALPHA_SIZE;
796                   config_attrs[i++] = 1;
797                }
798              else
799                {
800                   config_attrs[i++] = GLX_ALPHA_SIZE;
801                   config_attrs[i++] = 0;
802                }
803              config_attrs[i++] = GLX_DEPTH_SIZE;
804              config_attrs[i++] = 0;
805              config_attrs[i++] = GLX_STENCIL_SIZE;
806              config_attrs[i++] = 0;
807              config_attrs[i++] = GLX_AUX_BUFFERS;
808              config_attrs[i++] = 0;
809              config_attrs[i++] = GLX_STEREO;
810              config_attrs[i++] = 0;
811              config_attrs[i++] = GLX_TRANSPARENT_TYPE;
812              config_attrs[i++] = GLX_NONE;//GLX_NONE;//GLX_TRANSPARENT_INDEX//GLX_TRANSPARENT_RGB;
813              config_attrs[i++] = 0;
814              
815              configs = glXChooseFBConfig(einfo->info.display,
816                                          einfo->info.screen,
817                                          config_attrs, &num);
818              if ((!configs) || (num < 1))
819                {
820                   ERR("glXChooseFBConfig returned no configs");
821                   return NULL;
822                }
823              for (i = 0; i < num; i++)
824                {
825                   XVisualInfo *visinfo;
826                   XRenderPictFormat *format = NULL;
827
828                   visinfo = glXGetVisualFromFBConfig(einfo->info.display,
829                                                      configs[i]);
830                   if (!visinfo) continue;
831                   if (!alpha)
832                     {
833                        config = configs[i];
834                        _evas_gl_x11_vi = malloc(sizeof(XVisualInfo));
835                        memcpy(_evas_gl_x11_vi, visinfo, sizeof(XVisualInfo));
836                        fbconf = config;
837                        XFree(visinfo);
838                        break;
839                     }
840                   else
841                     {
842                        format = XRenderFindVisualFormat
843                          (einfo->info.display, visinfo->visual);
844                        if (!format)
845                          {
846                             XFree(visinfo);
847                             continue;
848                          }
849                        if (format->direct.alphaMask > 0)
850                          {
851                             config = configs[i];
852                             _evas_gl_x11_rgba_vi = malloc(sizeof(XVisualInfo));
853                             memcpy(_evas_gl_x11_rgba_vi, visinfo, sizeof(XVisualInfo));
854                             rgba_fbconf = config;
855                             XFree(visinfo);
856                             break;
857                          }
858                     }
859                   XFree(visinfo);
860                }
861           }
862 #endif
863      }
864    if (!_evas_gl_x11_vi) return NULL;
865    if (einfo->info.destination_alpha)
866      {
867 // EGL / GLES
868 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
869         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
870 #else
871 //# ifdef NEWGL
872         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
873 //# endif
874 #endif
875      }
876    return _evas_gl_x11_vi->visual;
877 }
878
879 Colormap
880 eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo)
881 {
882    if (!einfo) return 0;
883    if (!einfo->info.display) return 0;
884    if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
885    if (!_evas_gl_x11_vi) return 0;
886    if (einfo->info.destination_alpha)
887      {
888         if (!_evas_gl_x11_rgba_cmap)
889           _evas_gl_x11_rgba_cmap =
890           XCreateColormap(einfo->info.display,
891                           RootWindow(einfo->info.display,
892                                      einfo->info.screen),
893                           _evas_gl_x11_rgba_vi->visual,
894                           0);
895         return _evas_gl_x11_rgba_cmap;
896      }
897    if (!_evas_gl_x11_cmap)
898      _evas_gl_x11_cmap =
899      XCreateColormap(einfo->info.display,
900                      RootWindow(einfo->info.display,
901                                 einfo->info.screen),
902                      _evas_gl_x11_vi->visual,
903                      0);
904    return _evas_gl_x11_cmap;
905 }
906
907 int
908 eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo)
909 {
910    if (!einfo) return 0;
911    if (!einfo->info.display) return 0;
912    if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
913    if (!_evas_gl_x11_vi) return 0;
914    if (einfo->info.destination_alpha)
915      {
916         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->depth;
917      }
918    return _evas_gl_x11_vi->depth;
919 }