OSDN Git Service

Fix the Linux build.
[android-x86/external-swiftshader.git] / src / OpenGL / libEGL / libEGL.cpp
1 // SwiftShader Software Renderer\r
2 //\r
3 // Copyright(c) 2005-2012 TransGaming Inc.\r
4 //\r
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,\r
6 // transcribed, stored in a retrieval system, translated into any human or computer\r
7 // language by any means, or disclosed to third parties without the explicit written\r
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
9 // or implied, including but not limited to any patent rights, are granted to you.\r
10 //\r
11 \r
12 // libEGL.cpp: Implements the exported EGL functions.\r
13 \r
14 #include "main.h"\r
15 #include "Display.h"\r
16 #include "Surface.h"\r
17 #include "Texture2D.hpp"\r
18 #include "Context.hpp"\r
19 #include "Image.hpp"\r
20 #include "common/debug.h"\r
21 #include "Common/Version.h"\r
22 \r
23 #include <exception>\r
24 #include <string.h>\r
25 \r
26 static bool validateDisplay(egl::Display *display)\r
27 {\r
28     if(display == EGL_NO_DISPLAY)\r
29     {\r
30         return error(EGL_BAD_DISPLAY, false);\r
31     }\r
32 \r
33     if(!display->isInitialized())\r
34     {\r
35         return error(EGL_NOT_INITIALIZED, false);\r
36     }\r
37 \r
38     return true;\r
39 }\r
40 \r
41 static bool validateConfig(egl::Display *display, EGLConfig config)\r
42 {\r
43     if(!validateDisplay(display))\r
44     {\r
45         return false;\r
46     }\r
47 \r
48     if(!display->isValidConfig(config))\r
49     {\r
50         return error(EGL_BAD_CONFIG, false);\r
51     }\r
52 \r
53     return true;\r
54 }\r
55 \r
56 static bool validateContext(egl::Display *display, egl::Context *context)\r
57 {\r
58     if(!validateDisplay(display))\r
59     {\r
60         return false;\r
61     }\r
62 \r
63     if(!display->isValidContext(context))\r
64     {\r
65         return error(EGL_BAD_CONTEXT, false);\r
66     }\r
67 \r
68     return true;\r
69 }\r
70 \r
71 static bool validateSurface(egl::Display *display, egl::Surface *surface)\r
72 {\r
73     if(!validateDisplay(display))\r
74     {\r
75         return false;\r
76     }\r
77 \r
78     if(!display->isValidSurface(surface))\r
79     {\r
80         return error(EGL_BAD_SURFACE, false);\r
81     }\r
82 \r
83     return true;\r
84 }\r
85 \r
86 extern "C"\r
87 {\r
88 EGLint EGLAPIENTRY eglGetError(void)\r
89 {\r
90     TRACE("()");\r
91 \r
92     EGLint error = egl::getCurrentError();\r
93 \r
94     if(error != EGL_SUCCESS)\r
95     {\r
96         egl::setCurrentError(EGL_SUCCESS);\r
97     }\r
98 \r
99     return error;\r
100 }\r
101 \r
102 EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)\r
103 {\r
104     TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);\r
105 \r
106     try\r
107     {\r
108         return egl::Display::getDisplay(display_id);\r
109     }\r
110     catch(std::bad_alloc&)\r
111     {\r
112         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);\r
113     }\r
114 \r
115     return EGL_NO_DISPLAY;\r
116 }\r
117 \r
118 EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)\r
119 {\r
120     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",\r
121           dpy, major, minor);\r
122 \r
123     try\r
124     {\r
125         if(dpy == EGL_NO_DISPLAY)\r
126         {\r
127             return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
128         }\r
129 \r
130         egl::Display *display = static_cast<egl::Display*>(dpy);\r
131 \r
132         if(!display->initialize())\r
133         {\r
134             return error(EGL_NOT_INITIALIZED, EGL_FALSE);\r
135         }\r
136 \r
137         if(major) *major = 1;\r
138         if(minor) *minor = 4;\r
139 \r
140         return success(EGL_TRUE);\r
141     }\r
142     catch(std::bad_alloc&)\r
143     {\r
144         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
145     }\r
146 \r
147     return EGL_FALSE;\r
148 }\r
149 \r
150 EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)\r
151 {\r
152     TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy);\r
153 \r
154     try\r
155     {\r
156         if(dpy == EGL_NO_DISPLAY)\r
157         {\r
158             return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
159         }\r
160 \r
161         egl::Display *display = static_cast<egl::Display*>(dpy);\r
162 \r
163         display->terminate();\r
164 \r
165         return success(EGL_TRUE);\r
166     }\r
167     catch(std::bad_alloc&)\r
168     {\r
169         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
170     }\r
171 \r
172     return EGL_FALSE;\r
173 }\r
174 \r
175 const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)\r
176 {\r
177     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);\r
178 \r
179     try\r
180     {\r
181         egl::Display *display = static_cast<egl::Display*>(dpy);\r
182 \r
183         if(!validateDisplay(display))\r
184         {\r
185             return NULL;\r
186         }\r
187 \r
188         switch(name)\r
189         {\r
190         case EGL_CLIENT_APIS:\r
191             return success("OpenGL_ES");\r
192         case EGL_EXTENSIONS:\r
193             return success("EGL_KHR_gl_texture_2D_image "\r
194                            "EGL_KHR_gl_texture_cubemap_image "\r
195                            "EGL_KHR_gl_renderbuffer_image "\r
196                            "EGL_KHR_image_base");\r
197         case EGL_VENDOR:\r
198             return success("TransGaming Inc.");\r
199         case EGL_VERSION:\r
200             return success("1.4 SwiftShader "VERSION_STRING);\r
201         }\r
202 \r
203         return error(EGL_BAD_PARAMETER, (const char*)NULL);\r
204     }\r
205     catch(std::bad_alloc&)\r
206     {\r
207         return error(EGL_BAD_ALLOC, (const char*)NULL);\r
208     }\r
209 \r
210     return NULL;\r
211 }\r
212 \r
213 EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)\r
214 {\r
215     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "\r
216           "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",\r
217           dpy, configs, config_size, num_config);\r
218 \r
219     try\r
220     {\r
221         egl::Display *display = static_cast<egl::Display*>(dpy);\r
222 \r
223         if(!validateDisplay(display))\r
224         {\r
225             return EGL_FALSE;\r
226         }\r
227 \r
228         if(!num_config)\r
229         {\r
230             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
231         }\r
232 \r
233         const EGLint attribList[] = {EGL_NONE};\r
234 \r
235         if(!display->getConfigs(configs, attribList, config_size, num_config))\r
236         {\r
237             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
238         }\r
239 \r
240         return success(EGL_TRUE);\r
241     }\r
242     catch(std::bad_alloc&)\r
243     {\r
244         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
245     }\r
246 \r
247     return EGL_FALSE;\r
248 }\r
249 \r
250 EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)\r
251 {\r
252     TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "\r
253           "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",\r
254           dpy, attrib_list, configs, config_size, num_config);\r
255 \r
256     try\r
257     {\r
258         egl::Display *display = static_cast<egl::Display*>(dpy);\r
259 \r
260         if(!validateDisplay(display))\r
261         {\r
262             return EGL_FALSE;\r
263         }\r
264 \r
265         if(!num_config)\r
266         {\r
267             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
268         }\r
269 \r
270         const EGLint attribList[] = {EGL_NONE};\r
271 \r
272         if(!attrib_list)\r
273         {\r
274             attrib_list = attribList;\r
275         }\r
276 \r
277         display->getConfigs(configs, attrib_list, config_size, num_config);\r
278 \r
279         return success(EGL_TRUE);\r
280     }\r
281     catch(std::bad_alloc&)\r
282     {\r
283         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
284     }\r
285 \r
286     return EGL_FALSE;\r
287 }\r
288 \r
289 EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)\r
290 {\r
291     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",\r
292           dpy, config, attribute, value);\r
293 \r
294     try\r
295     {\r
296         egl::Display *display = static_cast<egl::Display*>(dpy);\r
297 \r
298         if(!validateConfig(display, config))\r
299         {\r
300             return EGL_FALSE;\r
301         }\r
302 \r
303         if(!display->getConfigAttrib(config, attribute, value))\r
304         {\r
305             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
306         }\r
307 \r
308         return success(EGL_TRUE);\r
309     }\r
310     catch(std::bad_alloc&)\r
311     {\r
312         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
313     }\r
314 \r
315     return EGL_FALSE;\r
316 }\r
317 \r
318 EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)\r
319 {\r
320     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "\r
321           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, window, attrib_list);\r
322 \r
323     try\r
324     {\r
325         egl::Display *display = static_cast<egl::Display*>(dpy);\r
326 \r
327         if(!validateConfig(display, config))\r
328         {\r
329             return EGL_NO_SURFACE;\r
330         }\r
331 \r
332                 if(!display->isValidWindow(window))\r
333                 {\r
334                         return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);\r
335                 }\r
336 \r
337         return display->createWindowSurface(window, config, attrib_list);\r
338     }\r
339     catch(std::bad_alloc&)\r
340     {\r
341         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);\r
342     }\r
343 \r
344     return EGL_NO_SURFACE;\r
345 }\r
346 \r
347 EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)\r
348 {\r
349     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",\r
350           dpy, config, attrib_list);\r
351 \r
352     try\r
353     {\r
354         egl::Display *display = static_cast<egl::Display*>(dpy);\r
355 \r
356         if(!validateConfig(display, config))\r
357         {\r
358             return EGL_NO_SURFACE;\r
359         }\r
360 \r
361         return display->createOffscreenSurface(config, attrib_list);\r
362     }\r
363     catch(std::bad_alloc&)\r
364     {\r
365         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);\r
366     }\r
367 \r
368     return EGL_NO_SURFACE;\r
369 }\r
370 \r
371 EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)\r
372 {\r
373     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "\r
374           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);\r
375 \r
376     try\r
377     {\r
378         egl::Display *display = static_cast<egl::Display*>(dpy);\r
379 \r
380         if(!validateConfig(display, config))\r
381         {\r
382             return EGL_NO_SURFACE;\r
383         }\r
384 \r
385         UNIMPLEMENTED();   // FIXME\r
386 \r
387         return success(EGL_NO_SURFACE);\r
388     }\r
389     catch(std::bad_alloc&)\r
390     {\r
391         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);\r
392     }\r
393 \r
394     return EGL_NO_SURFACE;\r
395 }\r
396 \r
397 EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)\r
398 {\r
399     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);\r
400 \r
401     try\r
402     {\r
403         egl::Display *display = static_cast<egl::Display*>(dpy);\r
404         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
405 \r
406         if(!validateSurface(display, eglSurface))\r
407         {\r
408             return EGL_FALSE;\r
409         }\r
410 \r
411         if(surface == EGL_NO_SURFACE)\r
412         {\r
413             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
414         }\r
415 \r
416         display->destroySurface((egl::Surface*)surface);\r
417 \r
418         return success(EGL_TRUE);\r
419     }\r
420     catch(std::bad_alloc&)\r
421     {\r
422         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
423     }\r
424 \r
425     return EGL_FALSE;\r
426 }\r
427 \r
428 EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)\r
429 {\r
430     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",\r
431           dpy, surface, attribute, value);\r
432 \r
433     try\r
434     {\r
435         egl::Display *display = static_cast<egl::Display*>(dpy);\r
436         egl::Surface *eglSurface = (egl::Surface*)surface;\r
437 \r
438         if(!validateSurface(display, eglSurface))\r
439         {\r
440             return EGL_FALSE;\r
441         }\r
442 \r
443         if(surface == EGL_NO_SURFACE)\r
444         {\r
445             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
446         }\r
447 \r
448         switch(attribute)\r
449         {\r
450           case EGL_VG_ALPHA_FORMAT:\r
451             UNIMPLEMENTED();   // FIXME\r
452             break;\r
453           case EGL_VG_COLORSPACE:\r
454             UNIMPLEMENTED();   // FIXME\r
455             break;\r
456           case EGL_CONFIG_ID:\r
457             *value = eglSurface->getConfigID();\r
458             break;\r
459           case EGL_HEIGHT:\r
460             *value = eglSurface->getHeight();\r
461             break;\r
462           case EGL_HORIZONTAL_RESOLUTION:\r
463             UNIMPLEMENTED();   // FIXME\r
464             break;\r
465           case EGL_LARGEST_PBUFFER:\r
466             UNIMPLEMENTED();   // FIXME\r
467             break;\r
468           case EGL_MIPMAP_TEXTURE:\r
469             UNIMPLEMENTED();   // FIXME\r
470             break;\r
471           case EGL_MIPMAP_LEVEL:\r
472             UNIMPLEMENTED();   // FIXME\r
473             break;\r
474           case EGL_MULTISAMPLE_RESOLVE:\r
475             UNIMPLEMENTED();   // FIXME\r
476             break;\r
477           case EGL_PIXEL_ASPECT_RATIO:\r
478             *value = eglSurface->getPixelAspectRatio();\r
479             break;\r
480           case EGL_RENDER_BUFFER:\r
481             *value = eglSurface->getRenderBuffer();\r
482             break;\r
483           case EGL_SWAP_BEHAVIOR:\r
484             *value = eglSurface->getSwapBehavior();\r
485             break;\r
486           case EGL_TEXTURE_FORMAT:\r
487             *value = eglSurface->getTextureFormat();\r
488             break;\r
489           case EGL_TEXTURE_TARGET:\r
490             *value = eglSurface->getTextureTarget();\r
491             break;\r
492           case EGL_VERTICAL_RESOLUTION:\r
493             UNIMPLEMENTED();   // FIXME\r
494             break;\r
495           case EGL_WIDTH:\r
496             *value = eglSurface->getWidth();\r
497             break;\r
498           default:\r
499             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
500         }\r
501 \r
502         return success(EGL_TRUE);\r
503     }\r
504     catch(std::bad_alloc&)\r
505     {\r
506         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
507     }\r
508 \r
509     return EGL_FALSE;\r
510 }\r
511 \r
512 EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)\r
513 {\r
514     TRACE("(EGLenum api = 0x%X)", api);\r
515 \r
516     try\r
517     {\r
518         switch (api)\r
519         {\r
520           case EGL_OPENGL_API:\r
521           case EGL_OPENVG_API:\r
522             return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation\r
523           case EGL_OPENGL_ES_API:\r
524             break;\r
525           default:\r
526             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
527         }\r
528 \r
529         egl::setCurrentAPI(api);\r
530 \r
531         return success(EGL_TRUE);\r
532     }\r
533     catch(std::bad_alloc&)\r
534     {\r
535         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
536     }\r
537 \r
538     return EGL_FALSE;\r
539 }\r
540 \r
541 EGLenum EGLAPIENTRY eglQueryAPI(void)\r
542 {\r
543     TRACE("()");\r
544 \r
545     try\r
546     {\r
547         EGLenum API = egl::getCurrentAPI();\r
548 \r
549         return success(API);\r
550     }\r
551     catch(std::bad_alloc&)\r
552     {\r
553         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
554     }\r
555 \r
556     return EGL_FALSE;\r
557 }\r
558 \r
559 EGLBoolean EGLAPIENTRY eglWaitClient(void)\r
560 {\r
561     TRACE("()");\r
562 \r
563     try\r
564     {\r
565         UNIMPLEMENTED();   // FIXME\r
566 \r
567         return success(0);\r
568     }\r
569     catch(std::bad_alloc&)\r
570     {\r
571         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
572     }\r
573 \r
574     return EGL_FALSE;\r
575 }\r
576 \r
577 EGLBoolean EGLAPIENTRY eglReleaseThread(void)\r
578 {\r
579     TRACE("()");\r
580 \r
581     try\r
582     {\r
583         eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);\r
584 \r
585         return success(EGL_TRUE);\r
586     }\r
587     catch(std::bad_alloc&)\r
588     {\r
589         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
590     }\r
591 \r
592     return EGL_FALSE;\r
593 }\r
594 \r
595 EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)\r
596 {\r
597     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "\r
598           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",\r
599           dpy, buftype, buffer, config, attrib_list);\r
600 \r
601         UNIMPLEMENTED();\r
602 \r
603     return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);\r
604 }\r
605 \r
606 EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)\r
607 {\r
608     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",\r
609           dpy, surface, attribute, value);\r
610 \r
611     try\r
612     {\r
613         egl::Display *display = static_cast<egl::Display*>(dpy);\r
614         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
615 \r
616         if(!validateSurface(display, eglSurface))\r
617         {\r
618             return EGL_FALSE;\r
619         }\r
620 \r
621         UNIMPLEMENTED();   // FIXME\r
622 \r
623         return success(EGL_TRUE);\r
624     }\r
625     catch(std::bad_alloc&)\r
626     {\r
627         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
628     }\r
629 \r
630     return EGL_FALSE;\r
631 }\r
632 \r
633 EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)\r
634 {\r
635     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);\r
636 \r
637     try\r
638     {\r
639         egl::Display *display = static_cast<egl::Display*>(dpy);\r
640         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
641 \r
642         if(!validateSurface(display, eglSurface))\r
643         {\r
644             return EGL_FALSE;\r
645         }\r
646 \r
647         if(buffer != EGL_BACK_BUFFER)\r
648         {\r
649             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
650         }\r
651 \r
652         if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
653         {\r
654             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
655         }\r
656 \r
657         if(eglSurface->getBoundTexture())\r
658         {\r
659             return error(EGL_BAD_ACCESS, EGL_FALSE);\r
660         }\r
661 \r
662         if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)\r
663         {\r
664             return error(EGL_BAD_MATCH, EGL_FALSE);\r
665         }\r
666 \r
667                 egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());\r
668 \r
669                 if(context)\r
670                 {\r
671                         context->bindTexImage(eglSurface);\r
672                 }\r
673 \r
674         return success(EGL_TRUE);\r
675     }\r
676     catch(std::bad_alloc&)\r
677     {\r
678         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
679     }\r
680 \r
681     return EGL_FALSE;\r
682 }\r
683 \r
684 EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)\r
685 {\r
686     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);\r
687 \r
688     try\r
689     {\r
690         egl::Display *display = static_cast<egl::Display*>(dpy);\r
691         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
692 \r
693         if(!validateSurface(display, eglSurface))\r
694         {\r
695             return EGL_FALSE;\r
696         }\r
697 \r
698         if(buffer != EGL_BACK_BUFFER)\r
699         {\r
700             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
701         }\r
702 \r
703         if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
704         {\r
705             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
706         }\r
707 \r
708         if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)\r
709         {\r
710             return error(EGL_BAD_MATCH, EGL_FALSE);\r
711         }\r
712 \r
713         egl::Texture2D *texture = eglSurface->getBoundTexture();\r
714 \r
715         if(texture)\r
716         {\r
717             texture->releaseTexImage();\r
718         }\r
719 \r
720         return success(EGL_TRUE);\r
721     }\r
722     catch(std::bad_alloc&)\r
723     {\r
724         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
725     }\r
726 \r
727     return EGL_FALSE;\r
728 }\r
729 \r
730 EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)\r
731 {\r
732     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);\r
733 \r
734     try\r
735     {\r
736         egl::Display *display = static_cast<egl::Display*>(dpy);\r
737 \r
738         if(!validateDisplay(display))\r
739         {\r
740             return EGL_FALSE;\r
741         }\r
742 \r
743         egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());\r
744 \r
745         if(draw_surface == NULL)\r
746         {\r
747             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
748         }\r
749 \r
750         draw_surface->setSwapInterval(interval);\r
751 \r
752         return success(EGL_TRUE);\r
753     }\r
754     catch(std::bad_alloc&)\r
755     {\r
756         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
757     }\r
758 \r
759     return EGL_FALSE;\r
760 }\r
761 \r
762 EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)\r
763 {\r
764     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "\r
765           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);\r
766 \r
767     try\r
768     {\r
769         EGLint clientVersion = 1;\r
770         if(attrib_list)\r
771         {\r
772             for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)\r
773             {\r
774                 if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)\r
775                 {\r
776                     clientVersion = attribute[1];\r
777                 }\r
778                 else\r
779                 {\r
780                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);\r
781                 }\r
782             }\r
783         }\r
784                 \r
785         egl::Display *display = static_cast<egl::Display*>(dpy);\r
786 \r
787         if(!validateConfig(display, config))\r
788         {\r
789             return EGL_NO_CONTEXT;\r
790         }\r
791 \r
792         return display->createContext(config, static_cast<egl::Context*>(share_context), clientVersion);\r
793     }\r
794     catch(std::bad_alloc&)\r
795     {\r
796         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);\r
797     }\r
798 \r
799     return EGL_NO_CONTEXT;\r
800 }\r
801 \r
802 EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)\r
803 {\r
804     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);\r
805 \r
806     try\r
807     {\r
808         egl::Display *display = static_cast<egl::Display*>(dpy);\r
809         egl::Context *context = static_cast<egl::Context*>(ctx);\r
810 \r
811         if(!validateContext(display, context))\r
812         {\r
813             return EGL_FALSE;\r
814         }\r
815 \r
816         if(ctx == EGL_NO_CONTEXT)\r
817         {\r
818             return error(EGL_BAD_CONTEXT, EGL_FALSE);\r
819         }\r
820 \r
821         display->destroyContext(context);\r
822 \r
823         return success(EGL_TRUE);\r
824     }\r
825     catch(std::bad_alloc&)\r
826     {\r
827         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
828     }\r
829 \r
830     return EGL_FALSE;\r
831 }\r
832 \r
833 EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)\r
834 {\r
835     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",\r
836           dpy, draw, read, ctx);\r
837 \r
838     try\r
839     {\r
840         egl::Display *display = static_cast<egl::Display*>(dpy);\r
841         egl::Context *context = static_cast<egl::Context*>(ctx);\r
842 \r
843                 if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)\r
844                 {\r
845                         if(!validateDisplay(display))\r
846                         {\r
847                                 return EGL_FALSE;\r
848                         }\r
849                 }\r
850 \r
851                 if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))\r
852                 {\r
853                         return error(EGL_BAD_MATCH, EGL_FALSE);\r
854                 }\r
855 \r
856         if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))\r
857         {\r
858             return EGL_FALSE;\r
859         }\r
860 \r
861         if((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||\r
862            (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))\r
863         {\r
864             return EGL_FALSE;\r
865         }\r
866 \r
867                 if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))\r
868                 {\r
869                         return error(EGL_BAD_MATCH, EGL_FALSE);\r
870                 }\r
871 \r
872         if(draw != read)\r
873         {\r
874             UNIMPLEMENTED();   // FIXME\r
875         }\r
876 \r
877         egl::setCurrentDisplay(dpy);\r
878         egl::setCurrentDrawSurface(draw);\r
879         egl::setCurrentReadSurface(read);\r
880                 egl::setCurrentContext(ctx);\r
881 \r
882                 if(context)\r
883                 {\r
884                         context->makeCurrent(static_cast<egl::Surface*>(draw));\r
885                 }\r
886 \r
887         return success(EGL_TRUE);\r
888     }\r
889     catch(std::bad_alloc&)\r
890     {\r
891         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
892     }\r
893 \r
894     return EGL_FALSE;\r
895 }\r
896 \r
897 EGLContext EGLAPIENTRY eglGetCurrentContext(void)\r
898 {\r
899     TRACE("()");\r
900 \r
901     try\r
902     {\r
903                 EGLContext context = egl::getCurrentContext();\r
904 \r
905                 return success(context);\r
906     }\r
907     catch(std::bad_alloc&)\r
908     {\r
909         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);\r
910     }\r
911 \r
912     return EGL_NO_CONTEXT;\r
913 }\r
914 \r
915 EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)\r
916 {\r
917     TRACE("(EGLint readdraw = %d)", readdraw);\r
918 \r
919     try\r
920     {\r
921         if(readdraw == EGL_READ)\r
922         {\r
923             EGLSurface read = egl::getCurrentReadSurface();\r
924             return success(read);\r
925         }\r
926         else if(readdraw == EGL_DRAW)\r
927         {\r
928             EGLSurface draw = egl::getCurrentDrawSurface();\r
929             return success(draw);\r
930         }\r
931         else\r
932         {\r
933             return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);\r
934         }\r
935     }\r
936     catch(std::bad_alloc&)\r
937     {\r
938         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);\r
939     }\r
940 \r
941     return EGL_NO_SURFACE;\r
942 }\r
943 \r
944 EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)\r
945 {\r
946     TRACE("()");\r
947 \r
948     try\r
949     {\r
950         EGLDisplay dpy = egl::getCurrentDisplay();\r
951 \r
952         return success(dpy);\r
953     }\r
954     catch(std::bad_alloc&)\r
955     {\r
956         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);\r
957     }\r
958 \r
959     return EGL_NO_DISPLAY;\r
960 }\r
961 \r
962 EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)\r
963 {\r
964     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",\r
965           dpy, ctx, attribute, value);\r
966 \r
967     try\r
968     {\r
969         egl::Display *display = static_cast<egl::Display*>(dpy);\r
970         egl::Context *context = static_cast<egl::Context*>(ctx);\r
971 \r
972         if(!validateContext(display, context))\r
973         {\r
974             return EGL_FALSE;\r
975         }\r
976 \r
977         UNIMPLEMENTED();   // FIXME\r
978 \r
979         return success(0);\r
980     }\r
981     catch(std::bad_alloc&)\r
982     {\r
983         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
984     }\r
985 \r
986     return EGL_FALSE;\r
987 }\r
988 \r
989 EGLBoolean EGLAPIENTRY eglWaitGL(void)\r
990 {\r
991     TRACE("()");\r
992 \r
993     try\r
994     {\r
995         UNIMPLEMENTED();   // FIXME\r
996 \r
997         return success(0);\r
998     }\r
999     catch(std::bad_alloc&)\r
1000     {\r
1001         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
1002     }\r
1003 \r
1004     return EGL_FALSE;\r
1005 }\r
1006 \r
1007 EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)\r
1008 {\r
1009     TRACE("(EGLint engine = %d)", engine);\r
1010 \r
1011     try\r
1012     {\r
1013         UNIMPLEMENTED();   // FIXME\r
1014 \r
1015         return success(0);\r
1016     }\r
1017     catch(std::bad_alloc&)\r
1018     {\r
1019         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
1020     }\r
1021 \r
1022     return EGL_FALSE;\r
1023 }\r
1024 \r
1025 EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)\r
1026 {\r
1027     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);\r
1028 \r
1029     try\r
1030     {\r
1031         egl::Display *display = static_cast<egl::Display*>(dpy);\r
1032         egl::Surface *eglSurface = (egl::Surface*)surface;\r
1033 \r
1034         if(!validateSurface(display, eglSurface))\r
1035         {\r
1036             return EGL_FALSE;\r
1037         }\r
1038 \r
1039         if(surface == EGL_NO_SURFACE)\r
1040         {\r
1041             return error(EGL_BAD_SURFACE, EGL_FALSE);\r
1042         }\r
1043 \r
1044         eglSurface->swap();\r
1045 \r
1046         return success(EGL_TRUE);\r
1047     }\r
1048     catch(std::bad_alloc&)\r
1049     {\r
1050         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
1051     }\r
1052 \r
1053     return EGL_FALSE;\r
1054 }\r
1055 \r
1056 EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)\r
1057 {\r
1058     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);\r
1059 \r
1060     try\r
1061     {\r
1062         egl::Display *display = static_cast<egl::Display*>(dpy);\r
1063         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
1064 \r
1065         if(!validateSurface(display, eglSurface))\r
1066         {\r
1067             return EGL_FALSE;\r
1068         }\r
1069 \r
1070         UNIMPLEMENTED();   // FIXME\r
1071 \r
1072         return success(0);\r
1073     }\r
1074     catch(std::bad_alloc&)\r
1075     {\r
1076         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
1077     }\r
1078 \r
1079     return EGL_FALSE;\r
1080 }\r
1081 \r
1082 EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)\r
1083 {\r
1084         TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, buffer = 0x%0.8p, const EGLint attrib_list = 0x%0.8p)", dpy, ctx, target, buffer, attrib_list);\r
1085 \r
1086     try\r
1087     {\r
1088         egl::Display *display = static_cast<egl::Display*>(dpy);\r
1089         egl::Context *context = static_cast<egl::Context*>(ctx);\r
1090 \r
1091         if(!validateDisplay(display))\r
1092         {\r
1093             return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);\r
1094         }\r
1095 \r
1096         if(context != EGL_NO_CONTEXT && !display->isValidContext(context))\r
1097         {\r
1098             return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);\r
1099         }\r
1100 \r
1101         EGLenum imagePreserved = EGL_FALSE;\r
1102         GLuint textureLevel = 0;\r
1103         if(attrib_list)\r
1104         {\r
1105             for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)\r
1106             {\r
1107                 if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)\r
1108                 {\r
1109                     imagePreserved = attribute[1];\r
1110                 }\r
1111                 else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)\r
1112                 {\r
1113                     textureLevel = attribute[1];\r
1114                 }\r
1115                 else\r
1116                 {\r
1117                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);\r
1118                 }\r
1119             }\r
1120         }\r
1121 \r
1122         GLuint name = reinterpret_cast<intptr_t>(buffer);\r
1123 \r
1124         if(name == 0)\r
1125         {\r
1126             return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);\r
1127         }\r
1128 \r
1129                 EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);\r
1130 \r
1131                 if(validationResult != EGL_SUCCESS)\r
1132                 {\r
1133                         return error(validationResult, EGL_NO_IMAGE_KHR);\r
1134                 }\r
1135 \r
1136         egl::Image *image = context->createSharedImage(target, name, textureLevel);\r
1137 \r
1138         if(!image)\r
1139         {\r
1140             return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);\r
1141         }\r
1142 \r
1143         if(image->getMultiSampleDepth() > 1)\r
1144         {\r
1145             return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);\r
1146         }\r
1147 \r
1148         return success((EGLImageKHR)image);\r
1149     }\r
1150     catch(std::bad_alloc&)\r
1151     {\r
1152         return error(EGL_BAD_ALLOC, EGL_NO_IMAGE_KHR);\r
1153     }\r
1154 \r
1155     return EGL_NO_IMAGE_KHR;\r
1156 }\r
1157 \r
1158 EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)\r
1159 {\r
1160         TRACE("(EGLDisplay dpy = 0x%0.8p, EGLImageKHR image = 0x%0.8p)", dpy, image);\r
1161 \r
1162     try\r
1163     {\r
1164         egl::Display *display = static_cast<egl::Display*>(dpy);\r
1165 \r
1166         if(!validateDisplay(display))\r
1167         {\r
1168             return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
1169         }\r
1170 \r
1171         if(!image)\r
1172         {\r
1173             return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
1174         }\r
1175 \r
1176         egl::Image *glImage = static_cast<egl::Image*>(image);\r
1177         glImage->destroyShared();\r
1178 \r
1179         return success(EGL_TRUE);\r
1180     }\r
1181     catch(std::bad_alloc&)\r
1182     {\r
1183         return error(EGL_BAD_ALLOC, EGL_FALSE);\r
1184     }\r
1185 \r
1186     return EGL_FALSE;\r
1187 }\r
1188 \r
1189 __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)\r
1190 {\r
1191     TRACE("(const char *procname = \"%s\")", procname);\r
1192 \r
1193     try\r
1194     {\r
1195         struct Extension\r
1196         {\r
1197             const char *name;\r
1198             __eglMustCastToProperFunctionPointerType address;\r
1199         };\r
1200 \r
1201         static const Extension eglExtensions[] =\r
1202         {\r
1203                         #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}\r
1204 \r
1205                         EXTENSION(eglCreateImageKHR),\r
1206                         EXTENSION(eglDestroyImageKHR),\r
1207 \r
1208                         #undef EXTENSION\r
1209                 };\r
1210 \r
1211         for(int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)\r
1212         {\r
1213             if(strcmp(procname, eglExtensions[ext].name) == 0)\r
1214             {\r
1215                 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;\r
1216             }\r
1217         }\r
1218 \r
1219                 if(es2::getProcAddress != 0)\r
1220                 {\r
1221                         __eglMustCastToProperFunctionPointerType proc = es2::getProcAddress(procname);\r
1222                         if(proc) return proc;\r
1223                 }\r
1224 \r
1225                 if(es1::getProcAddress != 0)\r
1226                 {\r
1227                         __eglMustCastToProperFunctionPointerType proc =  es1::getProcAddress(procname);\r
1228                         if(proc) return proc;\r
1229                 }\r
1230     }\r
1231     catch(std::bad_alloc&)\r
1232     {\r
1233         return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);\r
1234     }\r
1235 \r
1236     return NULL;\r
1237 }\r
1238 }\r