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