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_KHR_swap_buffers_with_damage "
\r
183 "EGL_ANDROID_framebuffer_target "
\r
184 "EGL_ANDROID_recordable");
\r
186 return success("TransGaming Inc.");
\r
188 return success("1.4 SwiftShader " VERSION_STRING);
\r
191 return error(EGL_BAD_PARAMETER, (const char*)NULL);
\r
194 EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
\r
196 TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
\r
197 "EGLint config_size = %d, EGLint *num_config = %p)",
\r
198 dpy, configs, config_size, num_config);
\r
200 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
202 if(!validateDisplay(display))
\r
209 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
212 const EGLint attribList[] = {EGL_NONE};
\r
214 if(!display->getConfigs(configs, attribList, config_size, num_config))
\r
216 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
219 return success(EGL_TRUE);
\r
222 EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
\r
224 TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
\r
225 "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
\r
226 dpy, attrib_list, configs, config_size, num_config);
\r
228 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
230 if(!validateDisplay(display))
\r
237 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
240 const EGLint attribList[] = {EGL_NONE};
\r
244 attrib_list = attribList;
\r
247 if(!display->getConfigs(configs, attrib_list, config_size, num_config))
\r
249 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
252 return success(EGL_TRUE);
\r
255 EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
\r
257 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
258 dpy, config, attribute, value);
\r
260 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
262 if(!validateConfig(display, config))
\r
267 if(!display->getConfigAttrib(config, attribute, value))
\r
269 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
272 return success(EGL_TRUE);
\r
275 EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
\r
277 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
\r
278 "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
\r
280 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
282 if(!validateConfig(display, config))
\r
284 return EGL_NO_SURFACE;
\r
287 if(!display->isValidWindow(window))
\r
289 return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
\r
292 return display->createWindowSurface(window, config, attrib_list);
\r
295 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
\r
297 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
\r
298 dpy, config, attrib_list);
\r
300 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
302 if(!validateConfig(display, config))
\r
304 return EGL_NO_SURFACE;
\r
307 return display->createPBufferSurface(config, attrib_list);
\r
310 EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
\r
312 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
\r
313 "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
\r
315 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
317 if(!validateConfig(display, config))
\r
319 return EGL_NO_SURFACE;
\r
322 UNIMPLEMENTED(); // FIXME
\r
324 return success(EGL_NO_SURFACE);
\r
327 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
\r
329 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
\r
331 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
332 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
334 if(!validateSurface(display, eglSurface))
\r
339 if(surface == EGL_NO_SURFACE)
\r
341 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
344 display->destroySurface((egl::Surface*)surface);
\r
346 return success(EGL_TRUE);
\r
349 EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
\r
351 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
352 dpy, surface, attribute, value);
\r
354 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
355 egl::Surface *eglSurface = (egl::Surface*)surface;
\r
357 if(!validateSurface(display, eglSurface))
\r
362 if(surface == EGL_NO_SURFACE)
\r
364 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
369 case EGL_VG_ALPHA_FORMAT:
\r
370 UNIMPLEMENTED(); // FIXME
\r
372 case EGL_VG_COLORSPACE:
\r
373 UNIMPLEMENTED(); // FIXME
\r
375 case EGL_CONFIG_ID:
\r
376 *value = eglSurface->getConfigID();
\r
379 *value = eglSurface->getHeight();
\r
381 case EGL_HORIZONTAL_RESOLUTION:
\r
382 UNIMPLEMENTED(); // FIXME
\r
384 case EGL_LARGEST_PBUFFER:
\r
385 if(eglSurface->isPBufferSurface()) // For a window or pixmap surface, the contents of *value are not modified.
\r
387 *value = eglSurface->getLargestPBuffer();
\r
390 case EGL_MIPMAP_TEXTURE:
\r
391 UNIMPLEMENTED(); // FIXME
\r
393 case EGL_MIPMAP_LEVEL:
\r
394 UNIMPLEMENTED(); // FIXME
\r
396 case EGL_MULTISAMPLE_RESOLVE:
\r
397 UNIMPLEMENTED(); // FIXME
\r
399 case EGL_PIXEL_ASPECT_RATIO:
\r
400 *value = eglSurface->getPixelAspectRatio();
\r
402 case EGL_RENDER_BUFFER:
\r
403 *value = eglSurface->getRenderBuffer();
\r
405 case EGL_SWAP_BEHAVIOR:
\r
406 *value = eglSurface->getSwapBehavior();
\r
408 case EGL_TEXTURE_FORMAT:
\r
409 *value = eglSurface->getTextureFormat();
\r
411 case EGL_TEXTURE_TARGET:
\r
412 *value = eglSurface->getTextureTarget();
\r
414 case EGL_VERTICAL_RESOLUTION:
\r
415 UNIMPLEMENTED(); // FIXME
\r
418 *value = eglSurface->getWidth();
\r
421 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
424 return success(EGL_TRUE);
\r
427 EGLBoolean BindAPI(EGLenum api)
\r
429 TRACE("(EGLenum api = 0x%X)", api);
\r
433 case EGL_OPENGL_API:
\r
434 case EGL_OPENVG_API:
\r
435 return error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
\r
436 case EGL_OPENGL_ES_API:
\r
439 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
442 egl::setCurrentAPI(api);
\r
444 return success(EGL_TRUE);
\r
447 EGLenum QueryAPI(void)
\r
451 EGLenum API = egl::getCurrentAPI();
\r
453 return success(API);
\r
456 EGLBoolean WaitClient(void)
\r
460 UNIMPLEMENTED(); // FIXME
\r
462 return success(EGL_FALSE);
\r
465 EGLBoolean ReleaseThread(void)
\r
469 eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
\r
471 return success(EGL_TRUE);
\r
474 EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
\r
476 TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
\r
477 "EGLConfig config = %p, const EGLint *attrib_list = %p)",
\r
478 dpy, buftype, buffer, config, attrib_list);
\r
482 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
\r
485 EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
\r
487 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
\r
488 dpy, surface, attribute, value);
\r
490 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
491 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
493 if(!validateSurface(display, eglSurface))
\r
500 case EGL_SWAP_BEHAVIOR:
\r
501 if(value == EGL_BUFFER_PRESERVED)
\r
503 if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
\r
505 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
508 else if(value != EGL_BUFFER_DESTROYED)
\r
510 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
512 eglSurface->setSwapBehavior(value);
\r
515 UNIMPLEMENTED(); // FIXME
\r
518 return success(EGL_TRUE);
\r
521 EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
\r
523 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
\r
525 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
526 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
528 if(!validateSurface(display, eglSurface))
\r
533 if(buffer != EGL_BACK_BUFFER)
\r
535 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
538 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
\r
540 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
543 if(eglSurface->getBoundTexture())
\r
545 return error(EGL_BAD_ACCESS, EGL_FALSE);
\r
548 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
\r
550 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
553 egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
\r
557 context->bindTexImage(eglSurface);
\r
560 return success(EGL_TRUE);
\r
563 EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
\r
565 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
\r
567 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
568 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
570 if(!validateSurface(display, eglSurface))
\r
575 if(buffer != EGL_BACK_BUFFER)
\r
577 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
580 if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
\r
582 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
585 if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
\r
587 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
590 egl::Texture *texture = eglSurface->getBoundTexture();
\r
594 texture->releaseTexImage();
\r
597 return success(EGL_TRUE);
\r
600 EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
\r
602 TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
\r
604 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
606 if(!validateDisplay(display))
\r
611 egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
\r
613 if(draw_surface == NULL)
\r
615 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
618 draw_surface->setSwapInterval(interval);
\r
620 return success(EGL_TRUE);
\r
623 EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
\r
625 TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
\r
626 "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
\r
628 EGLint clientVersion = 1;
\r
631 for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
\r
633 if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
\r
635 clientVersion = attribute[1];
\r
639 return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
\r
644 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
645 egl::Context *shareContext = static_cast<egl::Context*>(share_context);
\r
647 if(!validateConfig(display, config))
\r
649 return EGL_NO_CONTEXT;
\r
652 if(shareContext && shareContext->getClientVersion() != clientVersion)
\r
654 return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
\r
657 return display->createContext(config, shareContext, clientVersion);
\r
660 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
\r
662 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
\r
664 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
665 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
667 if(!validateContext(display, context))
\r
672 if(ctx == EGL_NO_CONTEXT)
\r
674 return error(EGL_BAD_CONTEXT, EGL_FALSE);
\r
677 display->destroyContext(context);
\r
679 return success(EGL_TRUE);
\r
682 EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
\r
684 TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
\r
685 dpy, draw, read, ctx);
\r
687 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
688 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
689 egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
\r
690 egl::Surface *readSurface = static_cast<egl::Surface*>(read);
\r
692 if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
\r
694 if(!validateDisplay(display))
\r
700 if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
\r
702 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
705 if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
\r
710 if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
\r
711 (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
\r
716 if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
\r
718 return error(EGL_BAD_MATCH, EGL_FALSE);
\r
723 UNIMPLEMENTED(); // FIXME
\r
726 egl::setCurrentDisplay(display);
\r
727 egl::setCurrentDrawSurface(drawSurface);
\r
728 egl::setCurrentReadSurface(readSurface);
\r
729 egl::setCurrentContext(context);
\r
733 context->makeCurrent(drawSurface);
\r
736 return success(EGL_TRUE);
\r
739 EGLContext GetCurrentContext(void)
\r
743 EGLContext context = egl::getCurrentContext();
\r
745 return success(context);
\r
748 EGLSurface GetCurrentSurface(EGLint readdraw)
\r
750 TRACE("(EGLint readdraw = %d)", readdraw);
\r
752 if(readdraw == EGL_READ)
\r
754 EGLSurface read = egl::getCurrentReadSurface();
\r
755 return success(read);
\r
757 else if(readdraw == EGL_DRAW)
\r
759 EGLSurface draw = egl::getCurrentDrawSurface();
\r
760 return success(draw);
\r
764 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
\r
768 EGLDisplay GetCurrentDisplay(void)
\r
772 EGLDisplay dpy = egl::getCurrentDisplay();
\r
774 return success(dpy);
\r
777 EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
\r
779 TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
\r
780 dpy, ctx, attribute, value);
\r
782 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
783 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
785 if(!validateContext(display, context))
\r
790 UNIMPLEMENTED(); // FIXME
\r
795 EGLBoolean WaitGL(void)
\r
799 UNIMPLEMENTED(); // FIXME
\r
801 return success(EGL_FALSE);
\r
804 EGLBoolean WaitNative(EGLint engine)
\r
806 TRACE("(EGLint engine = %d)", engine);
\r
808 UNIMPLEMENTED(); // FIXME
\r
810 return success(EGL_FALSE);
\r
813 EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
\r
815 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
\r
817 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
818 egl::Surface *eglSurface = (egl::Surface*)surface;
\r
820 if(!validateSurface(display, eglSurface))
\r
825 if(surface == EGL_NO_SURFACE)
\r
827 return error(EGL_BAD_SURFACE, EGL_FALSE);
\r
830 eglSurface->swap();
\r
832 return success(EGL_TRUE);
\r
835 EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
\r
837 TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
\r
839 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
840 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
\r
842 if(!validateSurface(display, eglSurface))
\r
847 UNIMPLEMENTED(); // FIXME
\r
849 return success(EGL_FALSE);
\r
852 EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
\r
854 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
856 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
857 egl::Context *context = static_cast<egl::Context*>(ctx);
\r
859 if(!validateDisplay(display))
\r
861 return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
\r
864 if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
\r
866 return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
\r
869 EGLenum imagePreserved = EGL_FALSE;
\r
870 GLuint textureLevel = 0;
\r
873 for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
\r
875 if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
\r
877 imagePreserved = attribute[1];
\r
879 else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
\r
881 textureLevel = attribute[1];
\r
885 return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
\r
890 GLuint name = reinterpret_cast<intptr_t>(buffer);
\r
894 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
\r
897 #if defined(__ANDROID__)
\r
898 if(target == EGL_NATIVE_BUFFER_ANDROID)
\r
900 return new AndroidNativeImage(reinterpret_cast<ANativeWindowBuffer*>(name));
\r
904 EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
\r
906 if(validationResult != EGL_SUCCESS)
\r
908 return error(validationResult, EGL_NO_IMAGE_KHR);
\r
911 egl::Image *image = context->createSharedImage(target, name, textureLevel);
\r
915 return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
\r
918 if(image->getDepth() > 1)
\r
920 return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
\r
923 return success((EGLImageKHR)image);
\r
926 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
\r
928 TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
\r
930 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
932 if(!validateDisplay(display))
\r
934 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
939 return error(EGL_BAD_PARAMETER, EGL_FALSE);
\r
942 egl::Image *glImage = static_cast<egl::Image*>(image);
\r
943 glImage->destroyShared();
\r
945 return success(EGL_TRUE);
\r
948 EGLBoolean SwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects)
\r
950 return eglSwapBuffers(dpy, surface); // FIXME: Pass damage rects to compositor for optimization
\r
953 EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
\r
955 TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
\r
957 return egl::Display::getPlatformDisplay(platform, (EGLNativeDisplayType)native_display);
\r
960 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
\r
962 return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
\r
965 EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
\r
967 return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
\r
973 explicit FenceSync(Context *context) : context(context)
\r
975 status = EGL_UNSIGNALED_KHR;
\r
981 context->release();
\r
985 void wait() const { return context->finish(); }
\r
986 void signal() { status = EGL_SIGNALED_KHR; }
\r
987 bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
\r
994 EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
\r
996 TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
\r
998 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1000 if(!validateDisplay(display))
\r
1002 return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
\r
1005 if(type != EGL_SYNC_FENCE_KHR)
\r
1007 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
\r
1010 if(attrib_list && attrib_list[0] != EGL_NONE)
\r
1012 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
\r
1015 egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
\r
1017 if(!validateContext(display, context))
\r
1019 return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
\r
1022 return new FenceSync(context);
\r
1025 EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
\r
1027 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
\r
1029 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1030 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1032 if(!validateDisplay(display))
\r
1034 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1042 EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
\r
1044 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
\r
1046 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1047 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1049 if(!validateDisplay(display))
\r
1051 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1057 if(!eglSync->isSignaled())
\r
1060 eglSync->signal();
\r
1063 return EGL_CONDITION_SATISFIED_KHR;
\r
1066 EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
\r
1068 TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
\r
1070 egl::Display *display = static_cast<egl::Display*>(dpy);
\r
1072 if(!validateDisplay(display))
\r
1074 return error(EGL_BAD_DISPLAY, EGL_FALSE);
\r
1077 FenceSync *eglSync = static_cast<FenceSync*>(sync);
\r
1081 case EGL_SYNC_TYPE_KHR:
\r
1082 *value = EGL_SYNC_FENCE_KHR;
\r
1084 case EGL_SYNC_STATUS_KHR:
\r
1085 *value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
\r
1087 case EGL_SYNC_CONDITION_KHR:
\r
1088 *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
\r
1091 return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
\r
1095 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
\r
1097 TRACE("(const char *procname = \"%s\")", procname);
\r
1102 __eglMustCastToProperFunctionPointerType address;
\r
1105 static const Extension eglExtensions[] =
\r
1107 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
\r
1109 EXTENSION(eglCreateImageKHR),
\r
1110 EXTENSION(eglDestroyImageKHR),
\r
1111 EXTENSION(eglGetPlatformDisplayEXT),
\r
1112 EXTENSION(eglCreatePlatformWindowSurfaceEXT),
\r
1113 EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
\r
1114 EXTENSION(eglCreateSyncKHR),
\r
1115 EXTENSION(eglDestroySyncKHR),
\r
1116 EXTENSION(eglClientWaitSyncKHR),
\r
1117 EXTENSION(eglGetSyncAttribKHR),
\r
1118 EXTENSION(eglSwapBuffersWithDamageKHR),
\r
1123 for(int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
\r
1125 if(strcmp(procname, eglExtensions[ext].name) == 0)
\r
1127 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
\r
1133 __eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
\r
1134 if(proc) return proc;
\r
1139 __eglMustCastToProperFunctionPointerType proc = libGLES_CM->es1GetProcAddress(procname);
\r
1140 if(proc) return proc;
\r