1 // SwiftShader Software Renderer
\r
3 // Copyright(c) 2005-2012 TransGaming Inc.
\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
12 // libEGL.cpp: Implements the exported EGL functions.
\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
23 #if defined(__ANDROID__)
\r
24 #include <system/window.h>
\r
29 using namespace egl;
\r
31 static bool validateDisplay(egl::Display *display)
\r
33 if(display == EGL_NO_DISPLAY)
\r
35 return error(EGL_BAD_DISPLAY, false);
\r
38 if(!display->isInitialized())
\r
40 return error(EGL_NOT_INITIALIZED, false);
\r
46 static bool validateConfig(egl::Display *display, EGLConfig config)
\r
48 if(!validateDisplay(display))
\r
53 if(!display->isValidConfig(config))
\r
55 return error(EGL_BAD_CONFIG, false);
\r
61 static bool validateContext(egl::Display *display, egl::Context *context)
\r
63 if(!validateDisplay(display))
\r
68 if(!display->isValidContext(context))
\r
70 return error(EGL_BAD_CONTEXT, false);
\r
76 static bool validateSurface(egl::Display *display, egl::Surface *surface)
\r
78 if(!validateDisplay(display))
\r
83 if(!display->isValidSurface(surface))
\r
85 return error(EGL_BAD_SURFACE, false);
\r
93 EGLint GetError(void)
\r
97 EGLint error = egl::getCurrentError();
\r
99 if(error != EGL_SUCCESS)
\r
101 egl::setCurrentError(EGL_SUCCESS);
\r
107 EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
\r
109 TRACE("(EGLNativeDisplayType display_id = %p)", display_id);
\r
111 return egl::Display::getPlatformDisplay(EGL_UNKNOWN, display_id);
\r
114 EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
\r
116 TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",
\r
117 dpy, major, minor);
\r
119 if(dpy == EGL_NO_DISPLAY)
\r
121 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
124 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
126 if(!display->initialize())
\r
128 return error(EGL_NOT_INITIALIZED, EGL_FALSE);
\r
131 if(major) *major = 1;
\r
132 if(minor) *minor = 4;
\r
134 return success(EGL_TRUE);
\r
137 EGLBoolean Terminate(EGLDisplay dpy)
\r
139 TRACE("(EGLDisplay dpy = %p)", dpy);
\r
141 if(dpy == EGL_NO_DISPLAY)
\r
143 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
146 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
148 display->terminate();
\r
150 return success(EGL_TRUE);
\r
153 const char *QueryString(EGLDisplay dpy, EGLint name)
\r
155 TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);
\r
157 if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
\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
165 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
167 if(!validateDisplay(display))
\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_fence_sync "
\r
181 "EGL_KHR_image_base "
\r
182 "EGL_ANDROID_framebuffer_target "
\r
183 "EGL_ANDROID_recordable");
\r
185 return success("TransGaming Inc.");
\r
187 return success("1.4 SwiftShader " VERSION_STRING);
\r
190 return error(EGL_BAD_PARAMETER, (const char*)NULL);
\r
193 EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
\r
195 TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
\r
196 "EGLint config_size = %d, EGLint *num_config = %p)",
\r
197 dpy, configs, config_size, num_config);
\r
199 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
201 if(!validateDisplay(display))
\r
208 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
211 const EGLint attribList[] = {EGL_NONE};
\r
213 if(!display->getConfigs(configs, attribList, config_size, num_config))
\r
215 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
218 return success(EGL_TRUE);
\r
221 EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
\r
223 TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
\r
224 "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
\r
225 dpy, attrib_list, configs, config_size, num_config);
\r
227 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
229 if(!validateDisplay(display))
\r
236 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
239 const EGLint attribList[] = {EGL_NONE};
\r
243 attrib_list = attribList;
\r
246 if(!display->getConfigs(configs, attrib_list, config_size, num_config))
\r
248 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
251 return success(EGL_TRUE);
\r
254 EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
\r
256 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
257 dpy, config, attribute, value);
\r
259 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
261 if(!validateConfig(display, config))
\r
266 if(!display->getConfigAttrib(config, attribute, value))
\r
268 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
271 return success(EGL_TRUE);
\r
274 EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
\r
276 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
\r
277 "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
\r
279 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
281 if(!validateConfig(display, config))
\r
283 return EGL_NO_SURFACE;
\r
286 if(!display->isValidWindow(window))
\r
288 return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
\r
291 return display->createWindowSurface(window, config, attrib_list);
\r
294 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
\r
296 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
\r
297 dpy, config, attrib_list);
\r
299 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
301 if(!validateConfig(display, config))
\r
303 return EGL_NO_SURFACE;
\r
306 return display->createPBufferSurface(config, attrib_list);
\r
309 EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
\r
311 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
\r
312 "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
\r
314 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
316 if(!validateConfig(display, config))
\r
318 return EGL_NO_SURFACE;
\r
321 UNIMPLEMENTED(); // FIXME
\r
323 return success(EGL_NO_SURFACE);
\r
326 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
\r
328 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
\r
330 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
331 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
333 if(!validateSurface(display, eglSurface))
\r
338 if(surface == EGL_NO_SURFACE)
\r
340 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
343 display->destroySurface((egl::Surface*)surface);
\r
345 return success(EGL_TRUE);
\r
348 EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
\r
350 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
351 dpy, surface, attribute, value);
\r
353 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
354 egl::Surface *eglSurface = (egl::Surface*)surface;
\r
356 if(!validateSurface(display, eglSurface))
\r
361 if(surface == EGL_NO_SURFACE)
\r
363 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
368 case EGL_VG_ALPHA_FORMAT:
\r
369 UNIMPLEMENTED(); // FIXME
\r
371 case EGL_VG_COLORSPACE:
\r
372 UNIMPLEMENTED(); // FIXME
\r
374 case EGL_CONFIG_ID:
\r
375 *value = eglSurface->getConfigID();
\r
378 *value = eglSurface->getHeight();
\r
380 case EGL_HORIZONTAL_RESOLUTION:
\r
381 UNIMPLEMENTED(); // FIXME
\r
383 case EGL_LARGEST_PBUFFER:
\r
384 if(eglSurface->isPBufferSurface()) // For a window or pixmap surface, the contents of *value are not modified.
\r
386 *value = eglSurface->getLargestPBuffer();
\r
389 case EGL_MIPMAP_TEXTURE:
\r
390 UNIMPLEMENTED(); // FIXME
\r
392 case EGL_MIPMAP_LEVEL:
\r
393 UNIMPLEMENTED(); // FIXME
\r
395 case EGL_MULTISAMPLE_RESOLVE:
\r
396 UNIMPLEMENTED(); // FIXME
\r
398 case EGL_PIXEL_ASPECT_RATIO:
\r
399 *value = eglSurface->getPixelAspectRatio();
\r
401 case EGL_RENDER_BUFFER:
\r
402 *value = eglSurface->getRenderBuffer();
\r
404 case EGL_SWAP_BEHAVIOR:
\r
405 *value = eglSurface->getSwapBehavior();
\r
407 case EGL_TEXTURE_FORMAT:
\r
408 *value = eglSurface->getTextureFormat();
\r
410 case EGL_TEXTURE_TARGET:
\r
411 *value = eglSurface->getTextureTarget();
\r
413 case EGL_VERTICAL_RESOLUTION:
\r
414 UNIMPLEMENTED(); // FIXME
\r
417 *value = eglSurface->getWidth();
\r
420 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
423 return success(EGL_TRUE);
\r
426 EGLBoolean BindAPI(EGLenum api)
\r
428 TRACE("(EGLenum api = 0x%X)", api);
\r
432 case EGL_OPENGL_API:
\r
433 case EGL_OPENVG_API:
\r
434 return error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
\r
435 case EGL_OPENGL_ES_API:
\r
438 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
441 egl::setCurrentAPI(api);
\r
443 return success(EGL_TRUE);
\r
446 EGLenum QueryAPI(void)
\r
450 EGLenum API = egl::getCurrentAPI();
\r
452 return success(API);
\r
455 EGLBoolean WaitClient(void)
\r
459 UNIMPLEMENTED(); // FIXME
\r
461 return success(EGL_FALSE);
\r
464 EGLBoolean ReleaseThread(void)
\r
468 eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
\r
470 return success(EGL_TRUE);
\r
473 EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
\r
475 TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
\r
476 "EGLConfig config = %p, const EGLint *attrib_list = %p)",
\r
477 dpy, buftype, buffer, config, attrib_list);
\r
481 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
\r
484 EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
\r
486 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
\r
487 dpy, surface, attribute, value);
\r
489 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
490 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
492 if(!validateSurface(display, eglSurface))
\r
499 case EGL_SWAP_BEHAVIOR:
\r
500 if(value == EGL_BUFFER_PRESERVED)
\r
502 if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
\r
504 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
507 else if(value != EGL_BUFFER_DESTROYED)
\r
509 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
511 eglSurface->setSwapBehavior(value);
\r
514 UNIMPLEMENTED(); // FIXME
\r
517 return success(EGL_TRUE);
\r
520 EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
\r
522 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
\r
524 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
525 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
527 if(!validateSurface(display, eglSurface))
\r
532 if(buffer != EGL_BACK_BUFFER)
\r
534 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
537 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
\r
539 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
542 if(eglSurface->getBoundTexture())
\r
544 return error(EGL_BAD_ACCESS, EGL_FALSE);
\r
547 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
\r
549 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
552 egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
\r
556 context->bindTexImage(eglSurface);
\r
559 return success(EGL_TRUE);
\r
562 EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
\r
564 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
\r
566 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
567 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
569 if(!validateSurface(display, eglSurface))
\r
574 if(buffer != EGL_BACK_BUFFER)
\r
576 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
579 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
\r
581 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
584 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
\r
586 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
589 egl::Texture *texture = eglSurface->getBoundTexture();
\r
593 texture->releaseTexImage();
\r
596 return success(EGL_TRUE);
\r
599 EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
\r
601 TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
\r
603 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
605 if(!validateDisplay(display))
\r
610 egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
\r
612 if(draw_surface == NULL)
\r
614 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
617 draw_surface->setSwapInterval(interval);
\r
619 return success(EGL_TRUE);
\r
622 EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
\r
624 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
\r
625 "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
\r
627 EGLint clientVersion = 1;
\r
630 for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
\r
632 if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
\r
634 clientVersion = attribute[1];
\r
638 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
\r
643 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
644 egl::Context *shareContext = static_cast<egl::Context*>(share_context);
\r
646 if(!validateConfig(display, config))
\r
648 return EGL_NO_CONTEXT;
\r
651 if(shareContext && shareContext->getClientVersion() != clientVersion)
\r
653 return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
\r
656 return display->createContext(config, shareContext, clientVersion);
\r
659 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
\r
661 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
\r
663 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
664 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
666 if(!validateContext(display, context))
\r
671 if(ctx == EGL_NO_CONTEXT)
\r
673 return error(EGL_BAD_CONTEXT, EGL_FALSE);
\r
676 display->destroyContext(context);
\r
678 return success(EGL_TRUE);
\r
681 EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
\r
683 TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
\r
684 dpy, draw, read, ctx);
\r
686 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
687 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
688 egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
\r
689 egl::Surface *readSurface = static_cast<egl::Surface*>(read);
\r
691 if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
\r
693 if(!validateDisplay(display))
\r
699 if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
\r
701 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
704 if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
\r
709 if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
\r
710 (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
\r
715 if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
\r
717 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
722 UNIMPLEMENTED(); // FIXME
\r
725 egl::setCurrentDisplay(display);
\r
726 egl::setCurrentDrawSurface(drawSurface);
\r
727 egl::setCurrentReadSurface(readSurface);
\r
728 egl::setCurrentContext(context);
\r
732 context->makeCurrent(drawSurface);
\r
735 return success(EGL_TRUE);
\r
738 EGLContext GetCurrentContext(void)
\r
742 EGLContext context = egl::getCurrentContext();
\r
744 return success(context);
\r
747 EGLSurface GetCurrentSurface(EGLint readdraw)
\r
749 TRACE("(EGLint readdraw = %d)", readdraw);
\r
751 if(readdraw == EGL_READ)
\r
753 EGLSurface read = egl::getCurrentReadSurface();
\r
754 return success(read);
\r
756 else if(readdraw == EGL_DRAW)
\r
758 EGLSurface draw = egl::getCurrentDrawSurface();
\r
759 return success(draw);
\r
763 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
\r
767 EGLDisplay GetCurrentDisplay(void)
\r
771 EGLDisplay dpy = egl::getCurrentDisplay();
\r
773 return success(dpy);
\r
776 EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
\r
778 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
779 dpy, ctx, attribute, value);
\r
781 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
782 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
784 if(!validateContext(display, context))
\r
789 UNIMPLEMENTED(); // FIXME
\r
794 EGLBoolean WaitGL(void)
\r
798 UNIMPLEMENTED(); // FIXME
\r
800 return success(EGL_FALSE);
\r
803 EGLBoolean WaitNative(EGLint engine)
\r
805 TRACE("(EGLint engine = %d)", engine);
\r
807 UNIMPLEMENTED(); // FIXME
\r
809 return success(EGL_FALSE);
\r
812 EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
\r
814 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
\r
816 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
817 egl::Surface *eglSurface = (egl::Surface*)surface;
\r
819 if(!validateSurface(display, eglSurface))
\r
824 if(surface == EGL_NO_SURFACE)
\r
826 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
829 eglSurface->swap();
\r
831 return success(EGL_TRUE);
\r
834 EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
\r
836 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
\r
838 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
839 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
841 if(!validateSurface(display, eglSurface))
\r
846 UNIMPLEMENTED(); // FIXME
\r
848 return success(EGL_FALSE);
\r
851 EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
\r
853 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
855 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
856 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
858 if(!validateDisplay(display))
\r
860 return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
\r
863 if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
\r
865 return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
\r
868 EGLenum imagePreserved = EGL_FALSE;
\r
869 GLuint textureLevel = 0;
\r
872 for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
\r
874 if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
\r
876 imagePreserved = attribute[1];
\r
878 else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
\r
880 textureLevel = attribute[1];
\r
884 return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
\r
889 GLuint name = reinterpret_cast<intptr_t>(buffer);
\r
893 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
\r
896 #if defined(__ANDROID__)
\r
897 if(target == EGL_NATIVE_BUFFER_ANDROID)
\r
899 return new AndroidNativeImage(reinterpret_cast<ANativeWindowBuffer*>(name));
\r
903 EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
\r
905 if(validationResult != EGL_SUCCESS)
\r
907 return error(validationResult, EGL_NO_IMAGE_KHR);
\r
910 egl::Image *image = context->createSharedImage(target, name, textureLevel);
\r
914 return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
\r
917 if(image->getDepth() > 1)
\r
919 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
\r
922 return success((EGLImageKHR)image);
\r
925 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
\r
927 TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
\r
929 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
931 if(!validateDisplay(display))
\r
933 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
938 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
941 egl::Image *glImage = static_cast<egl::Image*>(image);
\r
942 glImage->destroyShared();
\r
944 return success(EGL_TRUE);
\r
947 EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
\r
949 TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
\r
951 return egl::Display::getPlatformDisplay(platform, (EGLNativeDisplayType)native_display);
\r
954 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
\r
956 return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
\r
959 EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
\r
961 return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
\r
967 explicit FenceSync(Context *context) : context(context)
\r
969 status = EGL_UNSIGNALED_KHR;
\r
975 context->release();
\r
979 void wait() const { return context->finish(); }
\r
980 void signal() { status = EGL_SIGNALED_KHR; }
\r
981 bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
\r
988 EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
\r
990 TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
\r
992 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
994 if(!validateDisplay(display))
\r
996 return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
\r
999 if(type != EGL_SYNC_FENCE_KHR)
\r
1001 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
\r
1004 if(attrib_list && attrib_list[0] != EGL_NONE)
\r
1006 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
\r
1009 egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
\r
1011 if(!validateContext(display, context))
\r
1013 return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
\r
1016 return new FenceSync(context);
\r
1019 EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
\r
1021 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
\r
1023 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1024 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1026 if(!validateDisplay(display))
\r
1028 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1036 EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
\r
1038 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
\r
1040 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1041 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1043 if(!validateDisplay(display))
\r
1045 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1051 if(!eglSync->isSignaled())
\r
1054 eglSync->signal();
\r
1057 return EGL_CONDITION_SATISFIED_KHR;
\r
1060 EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
\r
1062 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
\r
1064 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1066 if(!validateDisplay(display))
\r
1068 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1071 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1075 case EGL_SYNC_TYPE_KHR:
\r
1076 *value = EGL_SYNC_FENCE_KHR;
\r
1078 case EGL_SYNC_STATUS_KHR:
\r
1079 *value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
\r
1081 case EGL_SYNC_CONDITION_KHR:
\r
1082 *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
\r
1085 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
1089 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
\r
1091 TRACE("(const char *procname = \"%s\")", procname);
\r
1096 __eglMustCastToProperFunctionPointerType address;
\r
1099 static const Extension eglExtensions[] =
\r
1101 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
\r
1103 EXTENSION(eglCreateImageKHR),
\r
1104 EXTENSION(eglDestroyImageKHR),
\r
1105 EXTENSION(eglGetPlatformDisplayEXT),
\r
1106 EXTENSION(eglCreatePlatformWindowSurfaceEXT),
\r
1107 EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
\r
1108 EXTENSION(eglCreateSyncKHR),
\r
1109 EXTENSION(eglDestroySyncKHR),
\r
1110 EXTENSION(eglClientWaitSyncKHR),
\r
1111 EXTENSION(eglGetSyncAttribKHR),
\r
1116 for(int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
\r
1118 if(strcmp(procname, eglExtensions[ext].name) == 0)
\r
1120 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
\r
1126 __eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
\r
1127 if(proc) return proc;
\r
1132 __eglMustCastToProperFunctionPointerType proc = libGLES_CM->es1GetProcAddress(procname);
\r
1133 if(proc) return proc;
\r