1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // libEGL.cpp: Implements the exported EGL functions.
19 #include "EGLSurface.h"
20 #include "Texture.hpp"
21 #include "Context.hpp"
22 #include "common/Image.hpp"
23 #include "common/debug.h"
24 #include "Common/Version.h"
26 #if defined(__ANDROID__)
27 #include <system/window.h>
28 #elif defined(__linux__)
29 #include "Main/libX11.hpp"
36 static bool validateDisplay(egl::Display *display)
38 if(display == EGL_NO_DISPLAY)
40 return error(EGL_BAD_DISPLAY, false);
43 if(!display->isInitialized())
45 return error(EGL_NOT_INITIALIZED, false);
51 static bool validateConfig(egl::Display *display, EGLConfig config)
53 if(!validateDisplay(display))
58 if(!display->isValidConfig(config))
60 return error(EGL_BAD_CONFIG, false);
66 static bool validateContext(egl::Display *display, egl::Context *context)
68 if(!validateDisplay(display))
73 if(!display->isValidContext(context))
75 return error(EGL_BAD_CONTEXT, false);
81 static bool validateSurface(egl::Display *display, egl::Surface *surface)
83 if(!validateDisplay(display))
88 if(!display->isValidSurface(surface))
90 return error(EGL_BAD_SURFACE, false);
102 EGLint error = egl::getCurrentError();
104 if(error != EGL_SUCCESS)
106 egl::setCurrentError(EGL_SUCCESS);
112 EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
114 TRACE("(EGLNativeDisplayType display_id = %p)", display_id);
116 if(display_id != EGL_DEFAULT_DISPLAY)
118 // FIXME: Check if display_id is the default display
121 #if defined(__linux__) && !defined(__ANDROID__)
124 return success(HEADLESS_DISPLAY);
128 return success(PRIMARY_DISPLAY); // We only support the default display
131 EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
133 TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",
136 if(dpy == EGL_NO_DISPLAY)
138 return error(EGL_BAD_DISPLAY, EGL_FALSE);
141 egl::Display *display = egl::Display::get(dpy);
143 if(!display->initialize())
145 return error(EGL_NOT_INITIALIZED, EGL_FALSE);
148 if(major) *major = 1;
149 if(minor) *minor = 4;
151 return success(EGL_TRUE);
154 EGLBoolean Terminate(EGLDisplay dpy)
156 TRACE("(EGLDisplay dpy = %p)", dpy);
158 if(dpy == EGL_NO_DISPLAY)
160 return error(EGL_BAD_DISPLAY, EGL_FALSE);
163 egl::Display *display = egl::Display::get(dpy);
165 display->terminate();
167 return success(EGL_TRUE);
170 const char *QueryString(EGLDisplay dpy, EGLint name)
172 TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);
174 #if defined(__linux__) && !defined(__ANDROID__)
175 if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
177 return success("EGL_KHR_platform_gbm "
178 "EGL_KHR_platform_x11 "
179 "EGL_EXT_client_extensions "
180 "EGL_EXT_platform_base");
184 egl::Display *display = egl::Display::get(dpy);
186 if(!validateDisplay(display))
193 case EGL_CLIENT_APIS:
194 return success("OpenGL_ES");
196 return success("EGL_KHR_create_context "
197 "EGL_KHR_gl_texture_2D_image "
198 "EGL_KHR_gl_texture_cubemap_image "
199 "EGL_KHR_gl_renderbuffer_image "
200 "EGL_KHR_fence_sync "
201 "EGL_KHR_image_base "
202 "EGL_ANDROID_framebuffer_target "
203 "EGL_ANDROID_recordable");
205 return success("Google Inc.");
207 return success("1.4 SwiftShader " VERSION_STRING);
210 return error(EGL_BAD_PARAMETER, (const char*)nullptr);
213 EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
215 TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
216 "EGLint config_size = %d, EGLint *num_config = %p)",
217 dpy, configs, config_size, num_config);
219 egl::Display *display = egl::Display::get(dpy);
221 if(!validateDisplay(display))
228 return error(EGL_BAD_PARAMETER, EGL_FALSE);
231 const EGLint attribList[] = {EGL_NONE};
233 if(!display->getConfigs(configs, attribList, config_size, num_config))
235 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
238 return success(EGL_TRUE);
241 EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
243 TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
244 "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
245 dpy, attrib_list, configs, config_size, num_config);
247 egl::Display *display = egl::Display::get(dpy);
249 if(!validateDisplay(display))
256 return error(EGL_BAD_PARAMETER, EGL_FALSE);
259 const EGLint attribList[] = {EGL_NONE};
263 attrib_list = attribList;
266 if(!display->getConfigs(configs, attrib_list, config_size, num_config))
268 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
271 return success(EGL_TRUE);
274 EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
276 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
277 dpy, config, attribute, value);
279 egl::Display *display = egl::Display::get(dpy);
281 if(!validateConfig(display, config))
286 if(!display->getConfigAttrib(config, attribute, value))
288 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
291 return success(EGL_TRUE);
294 EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
296 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
297 "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
299 egl::Display *display = egl::Display::get(dpy);
301 if(!validateConfig(display, config))
303 return EGL_NO_SURFACE;
306 if(!display->isValidWindow(window))
308 return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
311 return display->createWindowSurface(window, config, attrib_list);
314 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
316 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
317 dpy, config, attrib_list);
319 egl::Display *display = egl::Display::get(dpy);
321 if(!validateConfig(display, config))
323 return EGL_NO_SURFACE;
326 return display->createPBufferSurface(config, attrib_list);
329 EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
331 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
332 "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
334 egl::Display *display = egl::Display::get(dpy);
336 if(!validateConfig(display, config))
338 return EGL_NO_SURFACE;
341 UNIMPLEMENTED(); // FIXME
343 return success(EGL_NO_SURFACE);
346 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
348 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
350 egl::Display *display = egl::Display::get(dpy);
351 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
353 if(!validateSurface(display, eglSurface))
358 if(surface == EGL_NO_SURFACE)
360 return error(EGL_BAD_SURFACE, EGL_FALSE);
363 display->destroySurface((egl::Surface*)surface);
365 return success(EGL_TRUE);
368 EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
370 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
371 dpy, surface, attribute, value);
373 egl::Display *display = egl::Display::get(dpy);
374 egl::Surface *eglSurface = (egl::Surface*)surface;
376 if(!validateSurface(display, eglSurface))
381 if(surface == EGL_NO_SURFACE)
383 return error(EGL_BAD_SURFACE, EGL_FALSE);
388 case EGL_VG_ALPHA_FORMAT:
389 UNIMPLEMENTED(); // FIXME
391 case EGL_VG_COLORSPACE:
392 UNIMPLEMENTED(); // FIXME
395 *value = eglSurface->getConfigID();
398 *value = eglSurface->getHeight();
400 case EGL_HORIZONTAL_RESOLUTION:
401 UNIMPLEMENTED(); // FIXME
403 case EGL_LARGEST_PBUFFER:
404 if(eglSurface->isPBufferSurface()) // For a window or pixmap surface, the contents of *value are not modified.
406 *value = eglSurface->getLargestPBuffer();
409 case EGL_MIPMAP_TEXTURE:
410 UNIMPLEMENTED(); // FIXME
412 case EGL_MIPMAP_LEVEL:
413 UNIMPLEMENTED(); // FIXME
415 case EGL_MULTISAMPLE_RESOLVE:
416 UNIMPLEMENTED(); // FIXME
418 case EGL_PIXEL_ASPECT_RATIO:
419 *value = eglSurface->getPixelAspectRatio();
421 case EGL_RENDER_BUFFER:
422 *value = eglSurface->getRenderBuffer();
424 case EGL_SWAP_BEHAVIOR:
425 *value = eglSurface->getSwapBehavior();
427 case EGL_TEXTURE_FORMAT:
428 *value = eglSurface->getTextureFormat();
430 case EGL_TEXTURE_TARGET:
431 *value = eglSurface->getTextureTarget();
433 case EGL_VERTICAL_RESOLUTION:
434 UNIMPLEMENTED(); // FIXME
437 *value = eglSurface->getWidth();
440 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
443 return success(EGL_TRUE);
446 EGLBoolean BindAPI(EGLenum api)
448 TRACE("(EGLenum api = 0x%X)", api);
454 return error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
455 case EGL_OPENGL_ES_API:
458 return error(EGL_BAD_PARAMETER, EGL_FALSE);
461 egl::setCurrentAPI(api);
463 return success(EGL_TRUE);
466 EGLenum QueryAPI(void)
470 EGLenum API = egl::getCurrentAPI();
475 EGLBoolean WaitClient(void)
479 UNIMPLEMENTED(); // FIXME
481 return success(EGL_FALSE);
484 EGLBoolean ReleaseThread(void)
490 return success(EGL_TRUE);
493 EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
495 TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
496 "EGLConfig config = %p, const EGLint *attrib_list = %p)",
497 dpy, buftype, buffer, config, attrib_list);
501 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
504 EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
506 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
507 dpy, surface, attribute, value);
509 egl::Display *display = egl::Display::get(dpy);
510 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
512 if(!validateSurface(display, eglSurface))
519 case EGL_SWAP_BEHAVIOR:
520 if(value == EGL_BUFFER_PRESERVED)
522 if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
524 return error(EGL_BAD_MATCH, EGL_FALSE);
527 else if(value != EGL_BUFFER_DESTROYED)
529 return error(EGL_BAD_PARAMETER, EGL_FALSE);
531 eglSurface->setSwapBehavior(value);
534 UNIMPLEMENTED(); // FIXME
537 return success(EGL_TRUE);
540 EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
542 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
544 egl::Display *display = egl::Display::get(dpy);
545 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
547 if(!validateSurface(display, eglSurface))
552 if(buffer != EGL_BACK_BUFFER)
554 return error(EGL_BAD_PARAMETER, EGL_FALSE);
557 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
559 return error(EGL_BAD_SURFACE, EGL_FALSE);
562 if(eglSurface->getBoundTexture())
564 return error(EGL_BAD_ACCESS, EGL_FALSE);
567 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
569 return error(EGL_BAD_MATCH, EGL_FALSE);
572 egl::Context *context = egl::getCurrentContext();
576 context->bindTexImage(eglSurface);
579 return success(EGL_TRUE);
582 EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
584 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
586 egl::Display *display = egl::Display::get(dpy);
587 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
589 if(!validateSurface(display, eglSurface))
594 if(buffer != EGL_BACK_BUFFER)
596 return error(EGL_BAD_PARAMETER, EGL_FALSE);
599 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
601 return error(EGL_BAD_SURFACE, EGL_FALSE);
604 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
606 return error(EGL_BAD_MATCH, EGL_FALSE);
609 egl::Texture *texture = eglSurface->getBoundTexture();
613 texture->releaseTexImage();
616 return success(EGL_TRUE);
619 EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
621 TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
623 egl::Display *display = egl::Display::get(dpy);
624 egl::Context *context = egl::getCurrentContext();
626 if(!validateContext(display, context))
631 egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
635 return error(EGL_BAD_SURFACE, EGL_FALSE);
638 draw_surface->setSwapInterval(interval);
640 return success(EGL_TRUE);
643 EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
645 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
646 "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
648 EGLint majorVersion = 1;
649 EGLint minorVersion = 0;
653 for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
657 case EGL_CONTEXT_MAJOR_VERSION_KHR: // This token is an alias for EGL_CONTEXT_CLIENT_VERSION
658 majorVersion = attribute[1];
660 case EGL_CONTEXT_MINOR_VERSION_KHR:
661 minorVersion = attribute[1];
663 case EGL_CONTEXT_FLAGS_KHR:
666 case EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR:
667 // According to the EGL_KHR_create_context spec:
668 // "Khronos is still defining the expected and required features of debug contexts, so
669 // implementations are currently free to implement "debug contexts" with little or no debug
670 // functionality. However, OpenGL and OpenGL ES implementations supporting the GL_KHR_debug
671 // extension should enable it when this bit is set."
673 case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR:
674 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR:
675 // These bits are for OpenGL contexts only, not OpenGL ES contexts
676 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
678 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
681 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
684 case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
685 case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
686 // These bits are for OpenGL contexts only, not OpenGL ES contexts
687 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
689 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
692 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
695 case EGL_NO_RESET_NOTIFICATION_KHR:
696 case EGL_LOSE_CONTEXT_ON_RESET_KHR:
697 // These bits are for OpenGL contexts only, not OpenGL ES contexts
698 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
700 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
704 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
712 if(minorVersion != 0 && minorVersion != 1)
714 // 1.X: Only OpenGL ES 1.0 and 1.1 contexts are supported
715 return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
720 if(minorVersion != 0)
722 // 2.X and 3.X: Only OpenGL ES 2.0 and 3.0 contexts are currently supported
723 return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
727 return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
730 egl::Display *display = egl::Display::get(dpy);
731 egl::Context *shareContext = static_cast<egl::Context*>(share_context);
733 if(!validateConfig(display, config))
735 return EGL_NO_CONTEXT;
738 if(shareContext && shareContext->getClientVersion() != majorVersion)
740 return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
743 return display->createContext(config, shareContext, majorVersion);
746 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
748 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
750 egl::Display *display = egl::Display::get(dpy);
751 egl::Context *context = static_cast<egl::Context*>(ctx);
753 if(!validateContext(display, context))
758 if(ctx == EGL_NO_CONTEXT)
760 return error(EGL_BAD_CONTEXT, EGL_FALSE);
763 display->destroyContext(context);
765 return success(EGL_TRUE);
768 EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
770 TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
771 dpy, draw, read, ctx);
773 egl::Display *display = egl::Display::get(dpy);
774 egl::Context *context = static_cast<egl::Context*>(ctx);
775 egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
776 egl::Surface *readSurface = static_cast<egl::Surface*>(read);
778 if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
780 if(!validateDisplay(display))
786 if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
788 return error(EGL_BAD_MATCH, EGL_FALSE);
791 if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
796 if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
797 (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
802 if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
804 return error(EGL_BAD_MATCH, EGL_FALSE);
809 UNIMPLEMENTED(); // FIXME
812 egl::setCurrentDisplay(dpy);
813 egl::setCurrentDrawSurface(drawSurface);
814 egl::setCurrentReadSurface(readSurface);
815 egl::setCurrentContext(context);
819 context->makeCurrent(drawSurface);
822 return success(EGL_TRUE);
825 EGLContext GetCurrentContext(void)
829 EGLContext context = egl::getCurrentContext();
831 return success(context);
834 EGLSurface GetCurrentSurface(EGLint readdraw)
836 TRACE("(EGLint readdraw = %d)", readdraw);
838 if(readdraw == EGL_READ)
840 EGLSurface read = egl::getCurrentReadSurface();
841 return success(read);
843 else if(readdraw == EGL_DRAW)
845 EGLSurface draw = egl::getCurrentDrawSurface();
846 return success(draw);
850 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
854 EGLDisplay GetCurrentDisplay(void)
858 return success(egl::getCurrentDisplay());
861 EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
863 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
864 dpy, ctx, attribute, value);
866 egl::Display *display = egl::Display::get(dpy);
867 egl::Context *context = static_cast<egl::Context*>(ctx);
869 if(!validateContext(display, context))
876 case EGL_CONFIG_ID:
\r
877 *value = context->getConfigID();
\r
879 case EGL_CONTEXT_CLIENT_TYPE:
\r
880 *value = egl::getCurrentAPI();
\r
882 case EGL_CONTEXT_CLIENT_VERSION:
883 *value = context->getClientVersion();
885 case EGL_RENDER_BUFFER:
886 *value = EGL_BACK_BUFFER;
\r
889 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
892 return success(EGL_TRUE);
895 EGLBoolean WaitGL(void)
899 UNIMPLEMENTED(); // FIXME
901 return success(EGL_FALSE);
904 EGLBoolean WaitNative(EGLint engine)
906 TRACE("(EGLint engine = %d)", engine);
908 UNIMPLEMENTED(); // FIXME
910 return success(EGL_FALSE);
913 EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
915 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
917 egl::Display *display = egl::Display::get(dpy);
918 egl::Surface *eglSurface = (egl::Surface*)surface;
920 if(!validateSurface(display, eglSurface))
925 if(surface == EGL_NO_SURFACE)
927 return error(EGL_BAD_SURFACE, EGL_FALSE);
932 return success(EGL_TRUE);
935 EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
937 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
939 egl::Display *display = egl::Display::get(dpy);
940 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
942 if(!validateSurface(display, eglSurface))
947 UNIMPLEMENTED(); // FIXME
949 return success(EGL_FALSE);
952 EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
954 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);
956 egl::Display *display = egl::Display::get(dpy);
957 egl::Context *context = static_cast<egl::Context*>(ctx);
959 if(!validateDisplay(display))
961 return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
964 if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
966 return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
969 EGLenum imagePreserved = EGL_FALSE;
970 GLuint textureLevel = 0;
973 for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
975 if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
977 imagePreserved = attribute[1];
979 else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
981 textureLevel = attribute[1];
985 return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
990 #if defined(__ANDROID__)
991 if(target == EGL_NATIVE_BUFFER_ANDROID)
993 ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);
995 if(!nativeBuffer || GLPixelFormatFromAndroid(nativeBuffer->format) == GL_NONE)
997 ALOGW("%s badness unsupported HAL format=%x", __FUNCTION__, nativeBuffer ? nativeBuffer->format : 0);
998 return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
1001 Image *image = new AndroidNativeImage(nativeBuffer);
1002 EGLImageKHR eglImage = display->createSharedImage(image);
1004 return success(eglImage);
1008 GLuint name = static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1012 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1015 EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
1017 if(validationResult != EGL_SUCCESS)
1019 return error(validationResult, EGL_NO_IMAGE_KHR);
1022 Image *image = context->createSharedImage(target, name, textureLevel);
1026 return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
1029 if(image->getDepth() > 1)
1031 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1034 EGLImageKHR eglImage = display->createSharedImage(image);
1036 return success(eglImage);
1039 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1041 TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
1043 egl::Display *display = egl::Display::get(dpy);
1045 if(!validateDisplay(display))
1047 return error(EGL_BAD_DISPLAY, EGL_FALSE);
1050 if(!display->destroySharedImage(image))
1052 return error(EGL_BAD_PARAMETER, EGL_FALSE);
1055 return success(EGL_TRUE);
1058 EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
1060 TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
1062 #if defined(__linux__) && !defined(__ANDROID__)
1065 case EGL_PLATFORM_X11_EXT: break;
1066 case EGL_PLATFORM_GBM_KHR: break;
1068 return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
1071 if(platform == EGL_PLATFORM_X11_EXT)
1075 return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);
1078 if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
1080 return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY); // Unimplemented
1083 else if(platform == EGL_PLATFORM_GBM_KHR)
1085 if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
1087 return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY); // Unimplemented
1090 return success(HEADLESS_DISPLAY);
1093 return success(PRIMARY_DISPLAY); // We only support the default display
1095 return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
1099 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
1101 return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
1104 EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
1106 return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
1109 EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1111 TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
1113 egl::Display *display = egl::Display::get(dpy);
1115 if(!validateDisplay(display))
1117 return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
1120 if(type != EGL_SYNC_FENCE_KHR)
1122 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1125 if(attrib_list && attrib_list[0] != EGL_NONE)
1127 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1130 egl::Context *context = egl::getCurrentContext();
1132 if(!validateContext(display, context))
1134 return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1137 EGLSyncKHR sync = display->createSync(context);
1139 return success(sync);
1142 EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1144 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
1146 egl::Display *display = egl::Display::get(dpy);
1147 FenceSync *eglSync = static_cast<FenceSync*>(sync);
1149 if(!validateDisplay(display))
1151 return error(EGL_BAD_DISPLAY, EGL_FALSE);
1154 if(!display->isValidSync(eglSync))
1156 return error(EGL_BAD_PARAMETER, EGL_FALSE);
1159 display->destroySync(eglSync);
1161 return success(EGL_TRUE);
1164 EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1166 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
1168 egl::Display *display = egl::Display::get(dpy);
1169 FenceSync *eglSync = static_cast<FenceSync*>(sync);
1171 if(!validateDisplay(display))
1173 return error(EGL_BAD_DISPLAY, EGL_FALSE);
1176 if(!display->isValidSync(eglSync))
1178 return error(EGL_BAD_PARAMETER, EGL_FALSE);
1184 if(!eglSync->isSignaled())
1189 return success(EGL_CONDITION_SATISFIED_KHR);
1192 EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1194 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
1196 egl::Display *display = egl::Display::get(dpy);
1197 FenceSync *eglSync = static_cast<FenceSync*>(sync);
1199 if(!validateDisplay(display))
1201 return error(EGL_BAD_DISPLAY, EGL_FALSE);
1204 if(!display->isValidSync(eglSync))
1206 return error(EGL_BAD_PARAMETER, EGL_FALSE);
1211 case EGL_SYNC_TYPE_KHR:
1212 *value = EGL_SYNC_FENCE_KHR;
1213 return success(EGL_TRUE);
1214 case EGL_SYNC_STATUS_KHR:
1215 eglSync->wait(); // TODO: Don't block. Just poll based on sw::Query.
1216 *value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
1217 return success(EGL_TRUE);
1218 case EGL_SYNC_CONDITION_KHR:
1219 *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
1220 return success(EGL_TRUE);
1222 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
1226 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
1228 TRACE("(const char *procname = \"%s\")", procname);
1233 __eglMustCastToProperFunctionPointerType address;
1236 static const Extension eglExtensions[] =
1238 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
1240 EXTENSION(eglCreateImageKHR),
1241 EXTENSION(eglDestroyImageKHR),
1242 EXTENSION(eglGetPlatformDisplayEXT),
1243 EXTENSION(eglCreatePlatformWindowSurfaceEXT),
1244 EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
1245 EXTENSION(eglCreateSyncKHR),
1246 EXTENSION(eglDestroySyncKHR),
1247 EXTENSION(eglClientWaitSyncKHR),
1248 EXTENSION(eglGetSyncAttribKHR),
1253 for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
1255 if(strcmp(procname, eglExtensions[ext].name) == 0)
1257 return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);
1263 __eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
1264 if(proc) return success(proc);
1269 __eglMustCastToProperFunctionPointerType proc = libGLES_CM->es1GetProcAddress(procname);
1270 if(proc) return success(proc);
1273 return success((__eglMustCastToProperFunctionPointerType)NULL);