OSDN Git Service

Fix Android EGL config attribute retrieval.
[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 "Texture.hpp"\r
18 #include "Context.hpp"\r
19 #include "common/Image.hpp"\r
20 #include "common/debug.h"\r
21 #include "Common/Version.h"\r
22 \r
23 #if defined(__ANDROID__)\r
24 #include <system/window.h>\r
25 #endif\r
26 \r
27 #include <string.h>\r
28 \r
29 using namespace egl;\r
30 \r
31 static bool validateDisplay(egl::Display *display)\r
32 {\r
33         if(display == EGL_NO_DISPLAY)\r
34         {\r
35                 return error(EGL_BAD_DISPLAY, false);\r
36         }\r
37 \r
38         if(!display->isInitialized())\r
39         {\r
40                 return error(EGL_NOT_INITIALIZED, false);\r
41         }\r
42 \r
43         return true;\r
44 }\r
45 \r
46 static bool validateConfig(egl::Display *display, EGLConfig config)\r
47 {\r
48         if(!validateDisplay(display))\r
49         {\r
50                 return false;\r
51         }\r
52 \r
53         if(!display->isValidConfig(config))\r
54         {\r
55                 return error(EGL_BAD_CONFIG, false);\r
56         }\r
57 \r
58         return true;\r
59 }\r
60 \r
61 static bool validateContext(egl::Display *display, egl::Context *context)\r
62 {\r
63         if(!validateDisplay(display))\r
64         {\r
65                 return false;\r
66         }\r
67 \r
68         if(!display->isValidContext(context))\r
69         {\r
70                 return error(EGL_BAD_CONTEXT, false);\r
71         }\r
72 \r
73         return true;\r
74 }\r
75 \r
76 static bool validateSurface(egl::Display *display, egl::Surface *surface)\r
77 {\r
78         if(!validateDisplay(display))\r
79         {\r
80                 return false;\r
81         }\r
82 \r
83         if(!display->isValidSurface(surface))\r
84         {\r
85                 return error(EGL_BAD_SURFACE, false);\r
86         }\r
87 \r
88         return true;\r
89 }\r
90 \r
91 namespace egl\r
92 {\r
93 EGLint GetError(void)\r
94 {\r
95         TRACE("()");\r
96 \r
97         EGLint error = egl::getCurrentError();\r
98 \r
99         if(error != EGL_SUCCESS)\r
100         {\r
101                 egl::setCurrentError(EGL_SUCCESS);\r
102         }\r
103 \r
104         return error;\r
105 }\r
106 \r
107 EGLDisplay GetDisplay(EGLNativeDisplayType display_id)\r
108 {\r
109         TRACE("(EGLNativeDisplayType display_id = %p)", display_id);\r
110 \r
111         return egl::Display::getPlatformDisplay(EGL_UNKNOWN, display_id);\r
112 }\r
113 \r
114 EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)\r
115 {\r
116         TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",\r
117                   dpy, major, minor);\r
118 \r
119         if(dpy == EGL_NO_DISPLAY)\r
120         {\r
121                 return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
122         }\r
123 \r
124         egl::Display *display = static_cast<egl::Display*>(dpy);\r
125 \r
126         if(!display->initialize())\r
127         {\r
128                 return error(EGL_NOT_INITIALIZED, EGL_FALSE);\r
129         }\r
130 \r
131         if(major) *major = 1;\r
132         if(minor) *minor = 4;\r
133 \r
134         return success(EGL_TRUE);\r
135 }\r
136 \r
137 EGLBoolean Terminate(EGLDisplay dpy)\r
138 {\r
139         TRACE("(EGLDisplay dpy = %p)", dpy);\r
140 \r
141         if(dpy == EGL_NO_DISPLAY)\r
142         {\r
143                 return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
144         }\r
145 \r
146         egl::Display *display = static_cast<egl::Display*>(dpy);\r
147 \r
148         display->terminate();\r
149 \r
150         return success(EGL_TRUE);\r
151 }\r
152 \r
153 const char *QueryString(EGLDisplay dpy, EGLint name)\r
154 {\r
155         TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);\r
156 \r
157         if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)\r
158         {\r
159                 return success("EGL_KHR_platform_gbm "\r
160                                "EGL_KHR_platform_x11 "\r
161                                "EGL_EXT_client_extensions "\r
162                                "EGL_EXT_platform_base");\r
163         }\r
164 \r
165         egl::Display *display = static_cast<egl::Display*>(dpy);\r
166 \r
167         if(!validateDisplay(display))\r
168         {\r
169                 return NULL;\r
170         }\r
171 \r
172         switch(name)\r
173         {\r
174         case EGL_CLIENT_APIS:\r
175                 return success("OpenGL_ES");\r
176         case EGL_EXTENSIONS:\r
177                 return success("EGL_KHR_gl_texture_2D_image "\r
178                                "EGL_KHR_gl_texture_cubemap_image "\r
179                                "EGL_KHR_gl_renderbuffer_image "\r
180                                "EGL_KHR_image_base "\r
181                                "EGL_ANDROID_framebuffer_target "\r
182                                "EGL_ANDROID_recordable");\r
183         case EGL_VENDOR:\r
184                 return success("TransGaming Inc.");\r
185         case EGL_VERSION:\r
186                 return success("1.4 SwiftShader " VERSION_STRING);\r
187         }\r
188 \r
189         return error(EGL_BAD_PARAMETER, (const char*)NULL);\r
190 }\r
191 \r
192 EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)\r
193 {\r
194         TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "\r
195                   "EGLint config_size = %d, EGLint *num_config = %p)",\r
196                   dpy, configs, config_size, num_config);\r
197 \r
198         egl::Display *display = static_cast<egl::Display*>(dpy);\r
199 \r
200         if(!validateDisplay(display))\r
201         {\r
202                 return EGL_FALSE;\r
203         }\r
204 \r
205         if(!num_config)\r
206         {\r
207                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
208         }\r
209 \r
210         const EGLint attribList[] = {EGL_NONE};\r
211 \r
212         if(!display->getConfigs(configs, attribList, config_size, num_config))\r
213         {\r
214                 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
215         }\r
216 \r
217         return success(EGL_TRUE);\r
218 }\r
219 \r
220 EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)\r
221 {\r
222         TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "\r
223                   "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",\r
224                   dpy, attrib_list, configs, config_size, num_config);\r
225 \r
226         egl::Display *display = static_cast<egl::Display*>(dpy);\r
227 \r
228         if(!validateDisplay(display))\r
229         {\r
230                 return EGL_FALSE;\r
231         }\r
232 \r
233         if(!num_config)\r
234         {\r
235                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
236         }\r
237 \r
238         const EGLint attribList[] = {EGL_NONE};\r
239 \r
240         if(!attrib_list)\r
241         {\r
242                 attrib_list = attribList;\r
243         }\r
244 \r
245         if(!display->getConfigs(configs, attrib_list, config_size, num_config))\r
246         {\r
247                 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
248         }\r
249 \r
250         return success(EGL_TRUE);\r
251 }\r
252 \r
253 EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)\r
254 {\r
255         TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",\r
256                   dpy, config, attribute, value);\r
257 \r
258         egl::Display *display = static_cast<egl::Display*>(dpy);\r
259 \r
260         if(!validateConfig(display, config))\r
261         {\r
262                 return EGL_FALSE;\r
263         }\r
264 \r
265         if(!display->getConfigAttrib(config, attribute, value))\r
266         {\r
267                 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
268         }\r
269 \r
270         return success(EGL_TRUE);\r
271 }\r
272 \r
273 EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)\r
274 {\r
275         TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "\r
276                   "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);\r
277 \r
278         egl::Display *display = static_cast<egl::Display*>(dpy);\r
279 \r
280         if(!validateConfig(display, config))\r
281         {\r
282                 return EGL_NO_SURFACE;\r
283         }\r
284 \r
285         if(!display->isValidWindow(window))\r
286         {\r
287                 return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);\r
288         }\r
289 \r
290         return display->createWindowSurface(window, config, attrib_list);\r
291 }\r
292 \r
293 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)\r
294 {\r
295         TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",\r
296                   dpy, config, attrib_list);\r
297 \r
298         egl::Display *display = static_cast<egl::Display*>(dpy);\r
299 \r
300         if(!validateConfig(display, config))\r
301         {\r
302                 return EGL_NO_SURFACE;\r
303         }\r
304 \r
305         return display->createOffscreenSurface(config, attrib_list);\r
306 }\r
307 \r
308 EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)\r
309 {\r
310         TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "\r
311                   "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);\r
312 \r
313         egl::Display *display = static_cast<egl::Display*>(dpy);\r
314 \r
315         if(!validateConfig(display, config))\r
316         {\r
317                 return EGL_NO_SURFACE;\r
318         }\r
319 \r
320         UNIMPLEMENTED();   // FIXME\r
321 \r
322         return success(EGL_NO_SURFACE);\r
323 }\r
324 \r
325 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)\r
326 {\r
327         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);\r
328 \r
329         egl::Display *display = static_cast<egl::Display*>(dpy);\r
330         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
331 \r
332         if(!validateSurface(display, eglSurface))\r
333         {\r
334                 return EGL_FALSE;\r
335         }\r
336 \r
337         if(surface == EGL_NO_SURFACE)\r
338         {\r
339                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
340         }\r
341 \r
342         display->destroySurface((egl::Surface*)surface);\r
343 \r
344         return success(EGL_TRUE);\r
345 }\r
346 \r
347 EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)\r
348 {\r
349         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",\r
350                   dpy, surface, attribute, value);\r
351 \r
352         egl::Display *display = static_cast<egl::Display*>(dpy);\r
353         egl::Surface *eglSurface = (egl::Surface*)surface;\r
354 \r
355         if(!validateSurface(display, eglSurface))\r
356         {\r
357                 return EGL_FALSE;\r
358         }\r
359 \r
360         if(surface == EGL_NO_SURFACE)\r
361         {\r
362                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
363         }\r
364 \r
365         switch(attribute)\r
366         {\r
367         case EGL_VG_ALPHA_FORMAT:\r
368                 UNIMPLEMENTED();   // FIXME\r
369                 break;\r
370         case EGL_VG_COLORSPACE:\r
371                 UNIMPLEMENTED();   // FIXME\r
372                 break;\r
373         case EGL_CONFIG_ID:\r
374                 *value = eglSurface->getConfigID();\r
375                 break;\r
376         case EGL_HEIGHT:\r
377                 *value = eglSurface->getHeight();\r
378                 break;\r
379         case EGL_HORIZONTAL_RESOLUTION:\r
380                 UNIMPLEMENTED();   // FIXME\r
381                 break;\r
382         case EGL_LARGEST_PBUFFER:\r
383                 UNIMPLEMENTED();   // FIXME\r
384                 break;\r
385         case EGL_MIPMAP_TEXTURE:\r
386                 UNIMPLEMENTED();   // FIXME\r
387                 break;\r
388         case EGL_MIPMAP_LEVEL:\r
389                 UNIMPLEMENTED();   // FIXME\r
390                 break;\r
391         case EGL_MULTISAMPLE_RESOLVE:\r
392                 UNIMPLEMENTED();   // FIXME\r
393                 break;\r
394         case EGL_PIXEL_ASPECT_RATIO:\r
395                 *value = eglSurface->getPixelAspectRatio();\r
396                 break;\r
397         case EGL_RENDER_BUFFER:\r
398                 *value = eglSurface->getRenderBuffer();\r
399                 break;\r
400         case EGL_SWAP_BEHAVIOR:\r
401                 *value = eglSurface->getSwapBehavior();\r
402                 break;\r
403         case EGL_TEXTURE_FORMAT:\r
404                 *value = eglSurface->getTextureFormat();\r
405                 break;\r
406         case EGL_TEXTURE_TARGET:\r
407                 *value = eglSurface->getTextureTarget();\r
408                 break;\r
409         case EGL_VERTICAL_RESOLUTION:\r
410                 UNIMPLEMENTED();   // FIXME\r
411                 break;\r
412         case EGL_WIDTH:\r
413                 *value = eglSurface->getWidth();\r
414                 break;\r
415         default:\r
416                 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);\r
417         }\r
418 \r
419         return success(EGL_TRUE);\r
420 }\r
421 \r
422 EGLBoolean BindAPI(EGLenum api)\r
423 {\r
424         TRACE("(EGLenum api = 0x%X)", api);\r
425 \r
426         switch(api)\r
427         {\r
428                 case EGL_OPENGL_API:\r
429                 case EGL_OPENVG_API:\r
430                 return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation\r
431                 case EGL_OPENGL_ES_API:\r
432                 break;\r
433                 default:\r
434                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
435         }\r
436 \r
437         egl::setCurrentAPI(api);\r
438 \r
439         return success(EGL_TRUE);\r
440 }\r
441 \r
442 EGLenum QueryAPI(void)\r
443 {\r
444         TRACE("()");\r
445 \r
446         EGLenum API = egl::getCurrentAPI();\r
447 \r
448         return success(API);\r
449 }\r
450 \r
451 EGLBoolean WaitClient(void)\r
452 {\r
453         TRACE("()");\r
454 \r
455         UNIMPLEMENTED();   // FIXME\r
456 \r
457         return success(EGL_FALSE);\r
458 }\r
459 \r
460 EGLBoolean ReleaseThread(void)\r
461 {\r
462         TRACE("()");\r
463 \r
464         eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);\r
465 \r
466         return success(EGL_TRUE);\r
467 }\r
468 \r
469 EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)\r
470 {\r
471         TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "\r
472                   "EGLConfig config = %p, const EGLint *attrib_list = %p)",\r
473                   dpy, buftype, buffer, config, attrib_list);\r
474 \r
475         UNIMPLEMENTED();\r
476 \r
477         return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);\r
478 }\r
479 \r
480 EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)\r
481 {\r
482         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",\r
483                   dpy, surface, attribute, value);\r
484 \r
485         egl::Display *display = static_cast<egl::Display*>(dpy);\r
486         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
487 \r
488         if(!validateSurface(display, eglSurface))\r
489         {\r
490                 return EGL_FALSE;\r
491         }\r
492 \r
493         switch(attribute)\r
494         {\r
495         case EGL_SWAP_BEHAVIOR:\r
496                 if(value == EGL_BUFFER_PRESERVED)\r
497                 {\r
498                         if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))\r
499                         {\r
500                                 return error(EGL_BAD_MATCH, EGL_FALSE);\r
501                         }\r
502                 }\r
503                 else if(value != EGL_BUFFER_DESTROYED)\r
504                 {\r
505                         return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
506                 }\r
507                 eglSurface->setSwapBehavior(value);\r
508                 break;\r
509         default:\r
510                 UNIMPLEMENTED();   // FIXME\r
511         }\r
512 \r
513         return success(EGL_TRUE);\r
514 }\r
515 \r
516 EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)\r
517 {\r
518         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);\r
519 \r
520         egl::Display *display = static_cast<egl::Display*>(dpy);\r
521         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
522 \r
523         if(!validateSurface(display, eglSurface))\r
524         {\r
525                 return EGL_FALSE;\r
526         }\r
527 \r
528         if(buffer != EGL_BACK_BUFFER)\r
529         {\r
530                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
531         }\r
532 \r
533         if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
534         {\r
535                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
536         }\r
537 \r
538         if(eglSurface->getBoundTexture())\r
539         {\r
540                 return error(EGL_BAD_ACCESS, EGL_FALSE);\r
541         }\r
542 \r
543         if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)\r
544         {\r
545                 return error(EGL_BAD_MATCH, EGL_FALSE);\r
546         }\r
547 \r
548         egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());\r
549 \r
550         if(context)\r
551         {\r
552                 context->bindTexImage(eglSurface);\r
553         }\r
554 \r
555         return success(EGL_TRUE);\r
556 }\r
557 \r
558 EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)\r
559 {\r
560         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);\r
561 \r
562         egl::Display *display = static_cast<egl::Display*>(dpy);\r
563         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
564 \r
565         if(!validateSurface(display, eglSurface))\r
566         {\r
567                 return EGL_FALSE;\r
568         }\r
569 \r
570         if(buffer != EGL_BACK_BUFFER)\r
571         {\r
572                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
573         }\r
574 \r
575         if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())\r
576         {\r
577                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
578         }\r
579 \r
580         if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)\r
581         {\r
582                 return error(EGL_BAD_MATCH, EGL_FALSE);\r
583         }\r
584 \r
585         egl::Texture *texture = eglSurface->getBoundTexture();\r
586 \r
587         if(texture)\r
588         {\r
589                 texture->releaseTexImage();\r
590         }\r
591 \r
592         return success(EGL_TRUE);\r
593 }\r
594 \r
595 EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)\r
596 {\r
597         TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);\r
598 \r
599         egl::Display *display = static_cast<egl::Display*>(dpy);\r
600 \r
601         if(!validateDisplay(display))\r
602         {\r
603                 return EGL_FALSE;\r
604         }\r
605 \r
606         egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());\r
607 \r
608         if(draw_surface == NULL)\r
609         {\r
610                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
611         }\r
612 \r
613         draw_surface->setSwapInterval(interval);\r
614 \r
615         return success(EGL_TRUE);\r
616 }\r
617 \r
618 EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)\r
619 {\r
620         TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "\r
621                   "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);\r
622 \r
623         EGLint clientVersion = 1;\r
624         if(attrib_list)\r
625         {\r
626                 for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)\r
627                 {\r
628                         if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)\r
629                         {\r
630                                 clientVersion = attribute[1];\r
631                         }\r
632                         else\r
633                         {\r
634                                 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);\r
635                         }\r
636                 }\r
637         }\r
638 \r
639         egl::Display *display = static_cast<egl::Display*>(dpy);\r
640         egl::Context *shareContext = static_cast<egl::Context*>(share_context);\r
641 \r
642         if(!validateConfig(display, config))\r
643         {\r
644                 return EGL_NO_CONTEXT;\r
645         }\r
646 \r
647         if(shareContext && shareContext->getClientVersion() != clientVersion)\r
648         {\r
649                 return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);\r
650         }\r
651 \r
652         return display->createContext(config, shareContext, clientVersion);\r
653 }\r
654 \r
655 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)\r
656 {\r
657         TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);\r
658 \r
659         egl::Display *display = static_cast<egl::Display*>(dpy);\r
660         egl::Context *context = static_cast<egl::Context*>(ctx);\r
661 \r
662         if(!validateContext(display, context))\r
663         {\r
664                 return EGL_FALSE;\r
665         }\r
666 \r
667         if(ctx == EGL_NO_CONTEXT)\r
668         {\r
669                 return error(EGL_BAD_CONTEXT, EGL_FALSE);\r
670         }\r
671 \r
672         display->destroyContext(context);\r
673 \r
674         return success(EGL_TRUE);\r
675 }\r
676 \r
677 EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)\r
678 {\r
679         TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",\r
680                   dpy, draw, read, ctx);\r
681 \r
682         egl::Display *display = static_cast<egl::Display*>(dpy);\r
683         egl::Context *context = static_cast<egl::Context*>(ctx);\r
684         egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);\r
685         egl::Surface *readSurface = static_cast<egl::Surface*>(read);\r
686 \r
687         if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)\r
688         {\r
689                 if(!validateDisplay(display))\r
690                 {\r
691                         return EGL_FALSE;\r
692                 }\r
693         }\r
694 \r
695         if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))\r
696         {\r
697                 return error(EGL_BAD_MATCH, EGL_FALSE);\r
698         }\r
699 \r
700         if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))\r
701         {\r
702                 return EGL_FALSE;\r
703         }\r
704 \r
705         if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||\r
706            (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))\r
707         {\r
708                 return EGL_FALSE;\r
709         }\r
710 \r
711         if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))\r
712         {\r
713                 return error(EGL_BAD_MATCH, EGL_FALSE);\r
714         }\r
715 \r
716         if(draw != read)\r
717         {\r
718                 UNIMPLEMENTED();   // FIXME\r
719         }\r
720 \r
721         egl::setCurrentDisplay(display);\r
722         egl::setCurrentDrawSurface(drawSurface);\r
723         egl::setCurrentReadSurface(readSurface);\r
724         egl::setCurrentContext(context);\r
725 \r
726         if(context)\r
727         {\r
728                 context->makeCurrent(drawSurface);\r
729         }\r
730 \r
731         return success(EGL_TRUE);\r
732 }\r
733 \r
734 EGLContext GetCurrentContext(void)\r
735 {\r
736         TRACE("()");\r
737 \r
738         EGLContext context = egl::getCurrentContext();\r
739 \r
740         return success(context);\r
741 }\r
742 \r
743 EGLSurface GetCurrentSurface(EGLint readdraw)\r
744 {\r
745         TRACE("(EGLint readdraw = %d)", readdraw);\r
746 \r
747         if(readdraw == EGL_READ)\r
748         {\r
749                 EGLSurface read = egl::getCurrentReadSurface();\r
750                 return success(read);\r
751         }\r
752         else if(readdraw == EGL_DRAW)\r
753         {\r
754                 EGLSurface draw = egl::getCurrentDrawSurface();\r
755                 return success(draw);\r
756         }\r
757         else\r
758         {\r
759                 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);\r
760         }\r
761 }\r
762 \r
763 EGLDisplay GetCurrentDisplay(void)\r
764 {\r
765         TRACE("()");\r
766 \r
767         EGLDisplay dpy = egl::getCurrentDisplay();\r
768 \r
769         return success(dpy);\r
770 }\r
771 \r
772 EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)\r
773 {\r
774         TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",\r
775                   dpy, ctx, attribute, value);\r
776 \r
777         egl::Display *display = static_cast<egl::Display*>(dpy);\r
778         egl::Context *context = static_cast<egl::Context*>(ctx);\r
779 \r
780         if(!validateContext(display, context))\r
781         {\r
782                 return EGL_FALSE;\r
783         }\r
784 \r
785         UNIMPLEMENTED();   // FIXME\r
786 \r
787         return success(0);\r
788 }\r
789 \r
790 EGLBoolean WaitGL(void)\r
791 {\r
792         TRACE("()");\r
793 \r
794         UNIMPLEMENTED();   // FIXME\r
795 \r
796         return success(EGL_FALSE);\r
797 }\r
798 \r
799 EGLBoolean WaitNative(EGLint engine)\r
800 {\r
801         TRACE("(EGLint engine = %d)", engine);\r
802 \r
803         UNIMPLEMENTED();   // FIXME\r
804 \r
805         return success(EGL_FALSE);\r
806 }\r
807 \r
808 EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)\r
809 {\r
810         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);\r
811 \r
812         egl::Display *display = static_cast<egl::Display*>(dpy);\r
813         egl::Surface *eglSurface = (egl::Surface*)surface;\r
814 \r
815         if(!validateSurface(display, eglSurface))\r
816         {\r
817                 return EGL_FALSE;\r
818         }\r
819 \r
820         if(surface == EGL_NO_SURFACE)\r
821         {\r
822                 return error(EGL_BAD_SURFACE, EGL_FALSE);\r
823         }\r
824 \r
825         eglSurface->swap();\r
826 \r
827         return success(EGL_TRUE);\r
828 }\r
829 \r
830 EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)\r
831 {\r
832         TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);\r
833 \r
834         egl::Display *display = static_cast<egl::Display*>(dpy);\r
835         egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);\r
836 \r
837         if(!validateSurface(display, eglSurface))\r
838         {\r
839                 return EGL_FALSE;\r
840         }\r
841 \r
842         UNIMPLEMENTED();   // FIXME\r
843 \r
844         return success(EGL_FALSE);\r
845 }\r
846 \r
847 EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)\r
848 {\r
849         TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);\r
850 \r
851         egl::Display *display = static_cast<egl::Display*>(dpy);\r
852         egl::Context *context = static_cast<egl::Context*>(ctx);\r
853 \r
854         if(!validateDisplay(display))\r
855         {\r
856                 return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);\r
857         }\r
858 \r
859         if(context != EGL_NO_CONTEXT && !display->isValidContext(context))\r
860         {\r
861                 return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);\r
862         }\r
863 \r
864         EGLenum imagePreserved = EGL_FALSE;\r
865         GLuint textureLevel = 0;\r
866         if(attrib_list)\r
867         {\r
868                 for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)\r
869                 {\r
870                         if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)\r
871                         {\r
872                                 imagePreserved = attribute[1];\r
873                         }\r
874                         else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)\r
875                         {\r
876                                 textureLevel = attribute[1];\r
877                         }\r
878                         else\r
879                         {\r
880                                 return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);\r
881                         }\r
882                 }\r
883         }\r
884 \r
885         GLuint name = reinterpret_cast<intptr_t>(buffer);\r
886 \r
887         if(name == 0)\r
888         {\r
889                 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);\r
890         }\r
891 \r
892         #if defined(__ANDROID__)\r
893                 if(target == EGL_NATIVE_BUFFER_ANDROID)\r
894                 {\r
895                         return new AndroidNativeImage(reinterpret_cast<ANativeWindowBuffer*>(name));\r
896                 }\r
897         #endif\r
898 \r
899         EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);\r
900 \r
901         if(validationResult != EGL_SUCCESS)\r
902         {\r
903                 return error(validationResult, EGL_NO_IMAGE_KHR);\r
904         }\r
905 \r
906         egl::Image *image = context->createSharedImage(target, name, textureLevel);\r
907 \r
908         if(!image)\r
909         {\r
910                 return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);\r
911         }\r
912 \r
913         if(image->getDepth() > 1)\r
914         {\r
915                 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);\r
916         }\r
917 \r
918         return success((EGLImageKHR)image);\r
919 }\r
920 \r
921 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)\r
922 {\r
923         TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);\r
924 \r
925         egl::Display *display = static_cast<egl::Display*>(dpy);\r
926 \r
927         if(!validateDisplay(display))\r
928         {\r
929                 return error(EGL_BAD_DISPLAY, EGL_FALSE);\r
930         }\r
931 \r
932         if(!image)\r
933         {\r
934                 return error(EGL_BAD_PARAMETER, EGL_FALSE);\r
935         }\r
936 \r
937         egl::Image *glImage = static_cast<egl::Image*>(image);\r
938         glImage->destroyShared();\r
939 \r
940         return success(EGL_TRUE);\r
941 }\r
942 \r
943 EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)\r
944 {\r
945         TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);\r
946 \r
947         return egl::Display::getPlatformDisplay(platform, (EGLNativeDisplayType)native_display);\r
948 }\r
949 \r
950 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)\r
951 {\r
952         return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);\r
953 }\r
954 \r
955 EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)\r
956 {\r
957         return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);\r
958 }\r
959 \r
960 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)\r
961 {\r
962         TRACE("(const char *procname = \"%s\")", procname);\r
963 \r
964         struct Extension\r
965         {\r
966                 const char *name;\r
967                 __eglMustCastToProperFunctionPointerType address;\r
968         };\r
969 \r
970         static const Extension eglExtensions[] =\r
971         {\r
972                 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}\r
973 \r
974                 EXTENSION(eglCreateImageKHR),\r
975                 EXTENSION(eglDestroyImageKHR),\r
976                 EXTENSION(eglGetPlatformDisplayEXT),\r
977                 EXTENSION(eglCreatePlatformWindowSurfaceEXT),\r
978                 EXTENSION(eglCreatePlatformPixmapSurfaceEXT),\r
979 \r
980                 #undef EXTENSION\r
981         };\r
982 \r
983         for(int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)\r
984         {\r
985                 if(strcmp(procname, eglExtensions[ext].name) == 0)\r
986                 {\r
987                         return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;\r
988                 }\r
989         }\r
990 \r
991         if(libGLESv2)\r
992         {\r
993                 __eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);\r
994                 if(proc) return proc;\r
995         }\r
996 \r
997         if(libGLES_CM)\r
998         {\r
999                 __eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);\r
1000                 if(proc) return proc;\r
1001         }\r
1002 \r
1003         return NULL;\r
1004 }\r
1005 }\r