sync with private
[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    //Temporary Code for Tizen Emulator. With this driver, mapbuf would not
238    //work correctly some kind of the reason.
239    else if (strstr((const char *)vendor, "Huone Inc."))
240      blacklist = 1;
241
242    if (strstr((const char *)renderer, "softpipe"))
243      blacklist = 1;
244    if (blacklist)
245      {
246         ERR("OpenGL Driver blacklisted:");
247         ERR("Vendor: %s", (const char *)vendor);
248         ERR("Renderer: %s", (const char *)renderer);
249         ERR("Version: %s", (const char *)version);
250         eng_window_free(gw);
251         return NULL;
252      }
253 // GLX
254 #else
255    if (!context)
256      {
257 #ifdef NEWGL
258         if (indirect)
259           context = glXCreateNewContext(gw->disp, fbconf,
260                                         GLX_RGBA_TYPE, NULL,
261                                         GL_FALSE);
262         else
263           context = glXCreateNewContext(gw->disp, fbconf,
264                                         GLX_RGBA_TYPE, NULL,
265                                         GL_TRUE);
266 #else
267         if (indirect)
268           context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_FALSE);
269         else
270           context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_TRUE);
271 #endif
272      }
273 #ifdef NEWGL
274    if ((gw->alpha) && (!rgba_context))
275      {
276         if (indirect)
277           rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
278                                              GLX_RGBA_TYPE, context,
279                                              GL_FALSE);
280         else
281           rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
282                                              GLX_RGBA_TYPE, context,
283                                              GL_TRUE);
284      }
285    if (gw->alpha)
286      gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
287    else
288      gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
289    if (!gw->glxwin)
290      {
291         eng_window_free(gw);
292         return NULL;
293      }
294
295    if (gw->alpha) gw->context = rgba_context;
296    else gw->context = context;
297 #else
298    gw->context = context;
299 #endif
300
301    if (!gw->context)
302      {
303         eng_window_free(gw);
304         return NULL;
305      }
306    if (gw->context)
307      {
308         int i, j,  num;
309         GLXFBConfig *fbc;
310
311         if (gw->glxwin)
312           {
313              if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
314                                         gw->context))
315                {
316                   printf("Error: glXMakeContextCurrent(%p, %p, %p, %p)\n", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
317                   eng_window_free(gw);
318                   return NULL;
319                }
320           }
321         else
322           {
323              if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
324                {
325                   printf("Error: glXMakeCurrent(%p, 0x%x, %p) failed\n", (void *)gw->disp, (unsigned int)gw->win, (void *)gw->context);
326                   eng_window_free(gw);
327                   return NULL;
328                }
329           }
330
331         // FIXME: move this up to context creation
332
333         vendor = glGetString(GL_VENDOR);
334         renderer = glGetString(GL_RENDERER);
335         version = glGetString(GL_VERSION);
336         if (getenv("EVAS_GL_INFO"))
337           {
338              fprintf(stderr, "vendor: %s\n", vendor);
339              fprintf(stderr, "renderer: %s\n", renderer);
340              fprintf(stderr, "version: %s\n", version);
341           }
342         //   examples:
343         // vendor: NVIDIA Corporation
344         // renderer: NVIDIA Tegra
345         // version: OpenGL ES 2.0
346         //   or
347         // vendor: Imagination Technologies
348         // renderer: PowerVR SGX 540
349         // version: OpenGL ES 2.0
350         //   or
351         // vendor: NVIDIA Corporation
352         // renderer: GeForce GT 330M/PCI/SSE2
353         // version: 3.3.0 NVIDIA 256.53
354         //   or
355         // vendor: NVIDIA Corporation
356         // renderer: GeForce GT 220/PCI/SSE2
357         // version: 3.2.0 NVIDIA 195.36.24
358         //   or
359         // vendor: NVIDIA Corporation
360         // renderer: GeForce 8600 GTS/PCI/SSE2
361         // version: 3.3.0 NVIDIA 260.19.36
362         //   or
363         // vendor: ATI Technologies Inc.
364         // renderer: ATI Mobility Radeon HD 4650
365         // version: 3.2.9756 Compatibility Profile Context
366         //   or
367         // vendor: Tungsten Graphics, Inc
368         // renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2
369         // version: 2.1 Mesa 7.9-devel
370         //   or
371         // vendor: Advanced Micro Devices, Inc.
372         // renderer: Mesa DRI R600 (RS780 9610) 20090101  TCL DRI2
373         // version: 2.1 Mesa 7.9-devel
374         //   or
375         // vendor: NVIDIA Corporation
376         // renderer: GeForce 9600 GT/PCI/SSE2
377         // version: 3.3.0 NVIDIA 260.19.29
378         //   or
379         // vendor: ATI Technologies Inc.
380         // renderer: ATI Radeon HD 4800 Series
381         // version: 3.3.10237 Compatibility Profile Context
382         //   or
383         // vendor: Advanced Micro Devices, Inc.
384         // renderer: Mesa DRI R600 (RV770 9442) 20090101  TCL DRI2
385         // version: 2.0 Mesa 7.8.2
386         //   or
387         // vendor: Tungsten Graphics, Inc
388         // renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT
389         // version: 2.1 Mesa 7.9-devel
390         //   or (bad - software renderer)
391         // vendor: Mesa Project
392         // renderer: Software Rasterizer
393         // version: 2.1 Mesa 7.9-devel
394         //   or (bad - software renderer)
395         // vendor: VMware, Inc.
396         // renderer: Gallium 0.4 on softpipe
397         // version: 2.1 Mesa 7.9-devel
398
399         if (strstr((const char *)vendor, "Mesa Project"))
400           {
401              if (strstr((const char *)renderer, "Software Rasterizer"))
402                 blacklist = 1;
403           }
404         if (strstr((const char *)renderer, "softpipe"))
405            blacklist = 1;
406         if (blacklist)
407           {
408              ERR("OpenGL Driver blacklisted:");
409              ERR("Vendor: %s", (const char *)vendor);
410              ERR("Renderer: %s", (const char *)renderer);
411              ERR("Version: %s", (const char *)version);
412              eng_window_free(gw);
413              return NULL;
414           }
415         if (strstr((const char *)vendor, "NVIDIA"))
416           {
417              if (!strstr((const char *)renderer, "NVIDIA Tegra"))
418                {
419                   int v1 = 0, v2 = 0, v3 = 0;
420
421                   if (sscanf((const char *)version,
422                              "%*s %*s %i.%i.%i",
423                              &v1, &v2, &v3) != 3)
424                     {
425                        v1 = v2 = v3 = 0;
426                        if (sscanf((const char *)version,
427                                   "%*s %*s %i.%i",
428                                   &v1, &v2) != 2)
429                           v1 = 0;
430                     }
431                   // ALSO as of some nvidia driver version loose binding is
432                   // probably not needed
433                   if (v1 < 195) gw->detected.loose_binding = 1;
434                }
435           }
436         else
437           {
438              // noothing yet. add more cases and options over time
439           }
440
441         fbc = glXGetFBConfigs(gw->disp, screen, &num);
442         if (!fbc)
443           {
444              ERR("glXGetFBConfigs() returned no fb configs");
445              eng_window_free(gw);
446              return NULL;
447           }
448         for (i = 0; i <= 32; i++)
449           {
450              for (j = 0; j < num; j++)
451                {
452                   XVisualInfo *vi;
453                   int vd;
454                   int alph, val, dbuf, stencil, tdepth;
455                   int rgba;
456
457                   vi = glXGetVisualFromFBConfig(gw->disp, fbc[j]);
458                   if (!vi) continue;
459                   vd = vi->depth;
460                   XFree(vi);
461
462                   if (vd != i) continue;
463
464                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_ALPHA_SIZE, &alph);
465                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BUFFER_SIZE, &val);
466
467                   if ((val != i) && ((val - alph) != i)) continue;
468
469                   val = 0;
470                   rgba = 0;
471
472                   if (i == 32)
473                     {
474                        glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
475                        if (val)
476                          {
477                             rgba = 1;
478                             gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
479                          }
480                     }
481                   if (!val)
482                     {
483                        if (rgba) continue;
484                        glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
485                        if (!val) continue;
486                        gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
487                     }
488
489                   dbuf = 0x7fff;
490                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DOUBLEBUFFER, &val);
491                   if (val > dbuf) continue;
492                   dbuf = val;
493
494                   stencil = 0x7fff;
495                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_STENCIL_SIZE, &val);
496                   if (val > stencil) continue;
497                   stencil = val;
498
499                   tdepth = 0x7fff;
500                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DEPTH_SIZE, &val);
501                   if (val > tdepth) continue;
502                   tdepth = val;
503
504                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
505                   if (val < 0) continue;
506                   gw->depth_cfg[i].mipmap = val;
507
508                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_Y_INVERTED_EXT, &val);
509                   gw->depth_cfg[i].yinvert = val;
510
511                   glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
512                   gw->depth_cfg[i].tex_target = val;
513
514                   gw->depth_cfg[i].fbc = fbc[j];
515                }
516           }
517         XFree(fbc);
518         if (!gw->depth_cfg[DefaultDepth(gw->disp, screen)].fbc)
519           {
520              WRN("texture from pixmap not going to work");
521           }
522      }
523 #endif
524
525    gw->gl_context = evas_gl_common_context_new();
526    if (!gw->gl_context)
527      {
528         eng_window_free(gw);
529         return NULL;
530      }
531 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
532    gw->gl_context->egldisp = gw->egl_disp;
533 #endif
534    eng_window_use(gw);
535    evas_gl_common_context_resize(gw->gl_context, w, h, rot);
536    gw->surf = 1;
537    return gw;
538    indirect = 0;
539 }
540
541 void
542 eng_window_free(Evas_GL_X11_Window *gw)
543 {
544    int ref = 0;
545    win_count--;
546    eng_window_use(gw);
547    if (gw == _evas_gl_x11_window) _evas_gl_x11_window = NULL;
548    if (gw->gl_context)
549      {
550         ref = gw->gl_context->references - 1;
551         evas_gl_common_context_free(gw->gl_context);
552      }
553 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
554    if (gw->egl_surface[0] != EGL_NO_SURFACE)
555       eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
556    eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
557    if (ref == 0)
558      {
559         if (context) eglDestroyContext(gw->egl_disp, context);
560         eglTerminate(gw->egl_disp);
561         context = EGL_NO_CONTEXT;
562      }
563    eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
564 #else
565    if (gw->glxwin) glXDestroyWindow(gw->disp, gw->glxwin);
566    if (ref == 0)
567      {
568         if (context) glXDestroyContext(gw->disp, context);
569         if (rgba_context) glXDestroyContext(gw->disp, rgba_context);
570         context = 0;
571         rgba_context = 0;
572         fbconf = 0;
573         rgba_fbconf = 0;
574      }
575 #endif
576    free(gw);
577 }
578
579 void
580 eng_window_use(Evas_GL_X11_Window *gw)
581 {
582    Eina_Bool force_use = EINA_FALSE;
583
584 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
585    if (_evas_gl_x11_window)
586      {
587         if ((eglGetCurrentContext() !=
588              _evas_gl_x11_window->egl_context[0]) ||
589             (eglGetCurrentSurface(EGL_READ) !=
590                 _evas_gl_x11_window->egl_surface[0]) ||
591             (eglGetCurrentSurface(EGL_DRAW) !=
592                 _evas_gl_x11_window->egl_surface[0]))
593            force_use = EINA_TRUE;
594      }
595 #else
596    if (_evas_gl_x11_window)
597      {
598         if (glXGetCurrentContext() != _evas_gl_x11_window->context)
599            force_use = EINA_TRUE;
600      }
601 #endif
602    if ((_evas_gl_x11_window != gw) || (force_use))
603      {
604         if (_evas_gl_x11_window)
605           {
606              evas_gl_common_context_use(_evas_gl_x11_window->gl_context);
607              evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
608           }
609         _evas_gl_x11_window = gw;
610         if (gw)
611           {
612 // EGL / GLES
613 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
614            if (gw->egl_surface[0] != EGL_NO_SURFACE)
615              {
616                 if (eglMakeCurrent(gw->egl_disp,
617                                    gw->egl_surface[0],
618                                    gw->egl_surface[0],
619                                    gw->egl_context[0]) == EGL_FALSE)
620                   {
621                      ERR("eglMakeCurrent() failed!");
622                   }
623              }
624 // GLX
625 #else
626            if (gw->glxwin)
627              {
628                if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
629                                           gw->context))
630                  {
631                    ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
632                  }
633              }
634            else
635              {
636                if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
637                  {
638                    ERR("glXMakeCurrent(%p, 0x%x, %p) failed", gw->disp, (unsigned int)gw->win, (void *)gw->context);
639                  }
640              }
641 #endif
642           }
643      }
644    if (gw) evas_gl_common_context_use(gw->gl_context);
645 }
646
647 void
648 eng_window_unsurf(Evas_GL_X11_Window *gw)
649 {
650    if (!gw->surf) return;
651    if (!getenv("EVAS_GL_WIN_RESURF")) return;
652    if (getenv("EVAS_GL_INFO"))
653       printf("unsurf %p\n", gw);
654 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
655    if (_evas_gl_x11_window)
656       evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
657    if (_evas_gl_x11_window == gw)
658      {
659         eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
660         if (gw->egl_surface[0] != EGL_NO_SURFACE)
661            eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
662         gw->egl_surface[0] = EGL_NO_SURFACE;
663         _evas_gl_x11_window = NULL;
664      }
665 #else
666    if (gw->glxwin)
667       {
668          glXDestroyWindow(gw->disp, gw->glxwin);
669       }
670    else
671      {
672      }
673 #endif
674    gw->surf = 0;
675 }
676
677 void
678 eng_window_resurf(Evas_GL_X11_Window *gw)
679 {
680    if (gw->surf) return;
681    if (getenv("EVAS_GL_INFO"))
682       printf("resurf %p\n", gw);
683 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
684    gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
685                                                      (EGLNativeWindowType)gw->win,
686                                                      NULL);
687    if (gw->egl_surface[0] == EGL_NO_SURFACE)
688      {
689         ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
690             (unsigned int)gw->win, eglGetError());
691         return;
692      }
693    if (eglMakeCurrent(gw->egl_disp,
694                       gw->egl_surface[0],
695                       gw->egl_surface[0],
696                       gw->egl_context[0]) == EGL_FALSE)
697      {
698         ERR("eglMakeCurrent() failed!");
699      }
700 #else
701 #ifdef NEWGL
702    if (gw->alpha)
703      gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
704    else
705      gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
706    if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
707                               gw->context))
708      {
709         ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
710      }
711 #else
712    if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
713      {
714         ERR("glXMakeCurrent(%p, 0x%x, %p) failed", (void *)gw->disp, (unsigned int)gw->win, (void *)gw->context);
715      }
716 #endif
717 #endif
718    gw->surf = 1;
719 }
720
721 Visual *
722 eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
723 {
724    if (!einfo) return NULL;
725    if (!einfo->info.display) return NULL;
726    if (!_evas_gl_x11_vi)
727      {
728         int alpha;
729
730 // EGL / GLES
731 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
732         for (alpha = 0; alpha < 2; alpha++)
733           {
734              int depth = DefaultDepth(einfo->info.display,
735                                       einfo->info.screen);
736              if (alpha)
737                {
738                   XVisualInfo *xvi, vi_in;
739                   int nvi, i;
740                   XRenderPictFormat *fmt;
741
742                   vi_in.screen = einfo->info.screen;
743                   vi_in.depth = 32;
744                   vi_in.class = TrueColor;
745                   xvi = XGetVisualInfo(einfo->info.display,
746                                        VisualScreenMask | VisualDepthMask |
747                                        VisualClassMask,
748                                        &vi_in, &nvi);
749                   if (xvi)
750                     {
751                        for (i = 0; i < nvi; i++)
752                          {
753                             fmt = XRenderFindVisualFormat(einfo->info.display,
754                                                           xvi[i].visual);
755                             if ((fmt->type == PictTypeDirect) &&
756                                 (fmt->direct.alphaMask))
757                               {
758                                  _evas_gl_x11_rgba_vi =
759                                    calloc(1, sizeof(XVisualInfo));
760                                  if (_evas_gl_x11_rgba_vi)
761                                    memcpy(_evas_gl_x11_rgba_vi,
762                                           &(xvi[i]), sizeof(XVisualInfo));
763                                  break;
764                               }
765                          }
766                        XFree (xvi);
767                     }
768                }
769              else
770                {
771                   _evas_gl_x11_vi = calloc(1, sizeof(XVisualInfo));
772                   XMatchVisualInfo(einfo->info.display,
773                                    einfo->info.screen, depth, TrueColor,
774                                    _evas_gl_x11_vi);
775                }
776           }
777 // GLX
778 #else
779         for (alpha = 0; alpha < 2; alpha++)
780           {
781              int config_attrs[40];
782              GLXFBConfig *configs = NULL, config = 0;
783              int i, num;
784
785              i = 0;
786              config_attrs[i++] = GLX_DRAWABLE_TYPE;
787              config_attrs[i++] = GLX_WINDOW_BIT;
788              config_attrs[i++] = GLX_DOUBLEBUFFER;
789              config_attrs[i++] = 1;
790              config_attrs[i++] = GLX_RED_SIZE;
791              config_attrs[i++] = 1;
792              config_attrs[i++] = GLX_GREEN_SIZE;
793              config_attrs[i++] =1;
794              config_attrs[i++] = GLX_BLUE_SIZE;
795              config_attrs[i++] = 1;
796              if (alpha)
797                {
798                   config_attrs[i++] = GLX_RENDER_TYPE;
799                   config_attrs[i++] = GLX_RGBA_BIT;
800                   config_attrs[i++] = GLX_ALPHA_SIZE;
801                   config_attrs[i++] = 1;
802                }
803              else
804                {
805                   config_attrs[i++] = GLX_ALPHA_SIZE;
806                   config_attrs[i++] = 0;
807                }
808              config_attrs[i++] = GLX_DEPTH_SIZE;
809              config_attrs[i++] = 0;
810              config_attrs[i++] = GLX_STENCIL_SIZE;
811              config_attrs[i++] = 0;
812              config_attrs[i++] = GLX_AUX_BUFFERS;
813              config_attrs[i++] = 0;
814              config_attrs[i++] = GLX_STEREO;
815              config_attrs[i++] = 0;
816              config_attrs[i++] = GLX_TRANSPARENT_TYPE;
817              config_attrs[i++] = GLX_NONE;//GLX_NONE;//GLX_TRANSPARENT_INDEX//GLX_TRANSPARENT_RGB;
818              config_attrs[i++] = 0;
819              
820              configs = glXChooseFBConfig(einfo->info.display,
821                                          einfo->info.screen,
822                                          config_attrs, &num);
823              if ((!configs) || (num < 1))
824                {
825                   ERR("glXChooseFBConfig returned no configs");
826                   return NULL;
827                }
828              for (i = 0; i < num; i++)
829                {
830                   XVisualInfo *visinfo;
831                   XRenderPictFormat *format = NULL;
832
833                   visinfo = glXGetVisualFromFBConfig(einfo->info.display,
834                                                      configs[i]);
835                   if (!visinfo) continue;
836                   if (!alpha)
837                     {
838                        config = configs[i];
839                        _evas_gl_x11_vi = malloc(sizeof(XVisualInfo));
840                        memcpy(_evas_gl_x11_vi, visinfo, sizeof(XVisualInfo));
841                        fbconf = config;
842                        XFree(visinfo);
843                        break;
844                     }
845                   else
846                     {
847                        format = XRenderFindVisualFormat
848                          (einfo->info.display, visinfo->visual);
849                        if (!format)
850                          {
851                             XFree(visinfo);
852                             continue;
853                          }
854                        if (format->direct.alphaMask > 0)
855                          {
856                             config = configs[i];
857                             _evas_gl_x11_rgba_vi = malloc(sizeof(XVisualInfo));
858                             memcpy(_evas_gl_x11_rgba_vi, visinfo, sizeof(XVisualInfo));
859                             rgba_fbconf = config;
860                             XFree(visinfo);
861                             break;
862                          }
863                     }
864                   XFree(visinfo);
865                }
866           }
867 #endif
868      }
869    if (!_evas_gl_x11_vi) return NULL;
870    if (einfo->info.destination_alpha)
871      {
872 // EGL / GLES
873 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
874         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
875 #else
876 //# ifdef NEWGL
877         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
878 //# endif
879 #endif
880      }
881    return _evas_gl_x11_vi->visual;
882 }
883
884 Colormap
885 eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo)
886 {
887    if (!einfo) return 0;
888    if (!einfo->info.display) return 0;
889    if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
890    if (!_evas_gl_x11_vi) return 0;
891    if (einfo->info.destination_alpha)
892      {
893         if (!_evas_gl_x11_rgba_cmap)
894           _evas_gl_x11_rgba_cmap =
895           XCreateColormap(einfo->info.display,
896                           RootWindow(einfo->info.display,
897                                      einfo->info.screen),
898                           _evas_gl_x11_rgba_vi->visual,
899                           0);
900         return _evas_gl_x11_rgba_cmap;
901      }
902    if (!_evas_gl_x11_cmap)
903      _evas_gl_x11_cmap =
904      XCreateColormap(einfo->info.display,
905                      RootWindow(einfo->info.display,
906                                 einfo->info.screen),
907                      _evas_gl_x11_vi->visual,
908                      0);
909    return _evas_gl_x11_cmap;
910 }
911
912 int
913 eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo)
914 {
915    if (!einfo) return 0;
916    if (!einfo->info.display) return 0;
917    if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
918    if (!_evas_gl_x11_vi) return 0;
919    if (einfo->info.destination_alpha)
920      {
921         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->depth;
922      }
923    return _evas_gl_x11_vi->depth;
924 }