// // Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // entry_points_egl.cpp : Implements the EGL entry points. #include "libGLESv2/entry_points_egl.h" #include "libGLESv2/entry_points_egl_ext.h" #include "libGLESv2/entry_points_gles_2_0.h" #include "libGLESv2/entry_points_gles_2_0_ext.h" #include "libGLESv2/entry_points_gles_3_0.h" #include "libGLESv2/global_state.h" #include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Texture.h" #include "libANGLE/Surface.h" #include "libANGLE/validationEGL.h" #include "common/debug.h" #include "common/version.h" #include namespace egl { // EGL 1.0 EGLint EGLAPIENTRY GetError(void) { EVENT("()"); EGLint error = GetGlobalError(); SetGlobalError(Error(EGL_SUCCESS)); return error; } EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id) { EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); return Display::GetDisplayFromAttribs(reinterpret_cast(display_id), AttributeMap()); } EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, major, minor); Display *display = static_cast(dpy); if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY)); return EGL_FALSE; } Error error = display->initialize(); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (major) *major = 1; if (minor) *minor = 4; SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy) { EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); Display *display = static_cast(dpy); if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY)); return EGL_FALSE; } gl::Context *context = GetGlobalContext(); if (display->isValidContext(context)) { SetGlobalContext(NULL); SetGlobalDisplay(NULL); } display->terminate(); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); Display *display = static_cast(dpy); if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)) { Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return NULL; } } const char *result; switch (name) { case EGL_CLIENT_APIS: result = "OpenGL_ES"; break; case EGL_EXTENSIONS: if (display == EGL_NO_DISPLAY) { result = Display::getClientExtensionString().c_str(); } else { result = display->getExtensionString().c_str(); } break; case EGL_VENDOR: result = display->getVendorString().c_str(); break; case EGL_VERSION: result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")"; break; default: SetGlobalError(Error(EGL_BAD_PARAMETER)); return NULL; } SetGlobalError(Error(EGL_SUCCESS)); return result; } EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, configs, config_size, num_config); Display *display = static_cast(dpy); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (!num_config) { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; } std::vector filteredConfigs = display->getConfigs(AttributeMap()); if (configs) { filteredConfigs.resize(std::min(filteredConfigs.size(), config_size)); for (size_t i = 0; i < filteredConfigs.size(); i++) { configs[i] = const_cast(filteredConfigs[i]); } } *num_config = static_cast(filteredConfigs.size()); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, attrib_list, configs, config_size, num_config); Display *display = static_cast(dpy); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (!num_config) { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; } std::vector filteredConfigs = display->getConfigs(AttributeMap(attrib_list)); if (configs) { filteredConfigs.resize(std::min(filteredConfigs.size(), config_size)); for (size_t i = 0; i < filteredConfigs.size(); i++) { configs[i] = const_cast(filteredConfigs[i]); } } *num_config = static_cast(filteredConfigs.size()); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, config, attribute, value); Display *display = static_cast(dpy); Config *configuration = static_cast(config); Error error = ValidateConfig(display, configuration); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (!display->getConfigAttrib(configuration, attribute, value)) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); Display *display = static_cast(dpy); Config *configuration = static_cast(config); AttributeMap attributes(attrib_list); Error error = ValidateCreateWindowSurface(display, configuration, win, attributes); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; error = display->createWindowSurface(configuration, win, attributes, &surface); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } return static_cast(surface); } EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, config, attrib_list); Display *display = static_cast(dpy); Config *configuration = static_cast(config); AttributeMap attributes(attrib_list); Error error = ValidateCreatePbufferSurface(display, configuration, attributes); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; error = display->createPbufferSurface(configuration, attributes, &surface); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } return static_cast(surface); } EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); Display *display = static_cast(dpy); Config *configuration = static_cast(config); Error error = ValidateConfig(display, configuration); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } UNIMPLEMENTED(); // FIXME SetGlobalError(Error(EGL_SUCCESS)); return EGL_NO_SURFACE; } EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } display->destroySurface((Surface*)surface); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, surface, attribute, value); Display *display = static_cast(dpy); Surface *eglSurface = (Surface*)surface; Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } switch (attribute) { case EGL_VG_ALPHA_FORMAT: UNIMPLEMENTED(); // FIXME break; case EGL_VG_COLORSPACE: UNIMPLEMENTED(); // FIXME break; case EGL_CONFIG_ID: *value = eglSurface->getConfig()->configID; break; case EGL_HEIGHT: *value = eglSurface->getHeight(); break; case EGL_HORIZONTAL_RESOLUTION: UNIMPLEMENTED(); // FIXME break; case EGL_LARGEST_PBUFFER: UNIMPLEMENTED(); // FIXME break; case EGL_MIPMAP_TEXTURE: UNIMPLEMENTED(); // FIXME break; case EGL_MIPMAP_LEVEL: UNIMPLEMENTED(); // FIXME break; case EGL_MULTISAMPLE_RESOLVE: UNIMPLEMENTED(); // FIXME break; case EGL_PIXEL_ASPECT_RATIO: *value = eglSurface->getPixelAspectRatio(); break; case EGL_RENDER_BUFFER: *value = eglSurface->getRenderBuffer(); break; case EGL_SWAP_BEHAVIOR: *value = eglSurface->getSwapBehavior(); break; case EGL_TEXTURE_FORMAT: *value = eglSurface->getTextureFormat(); break; case EGL_TEXTURE_TARGET: *value = eglSurface->getTextureTarget(); break; case EGL_VERTICAL_RESOLUTION: UNIMPLEMENTED(); // FIXME break; case EGL_WIDTH: *value = eglSurface->getWidth(); break; case EGL_POST_SUB_BUFFER_SUPPORTED_NV: if (!display->getExtensions().postSubBuffer) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; } *value = eglSurface->isPostSubBufferSupported(); break; case EGL_FIXED_SIZE_ANGLE: if (!display->getExtensions().windowFixedSize) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; } *value = eglSurface->isFixedSize(); break; case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: if (!display->getExtensions().flexibleSurfaceCompatibility) { SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " "EGL_ANGLE_flexible_surface_compatibility support.")); return EGL_FALSE; } *value = eglSurface->flexibleSurfaceCompatibilityRequested(); break; case EGL_SURFACE_ORIENTATION_ANGLE: if (!display->getExtensions().surfaceOrientation) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without " "EGL_ANGLE_surface_orientation support.")); return EGL_FALSE; } *value = eglSurface->getOrientation(); break; case EGL_DIRECT_COMPOSITION_ANGLE: if (!display->getExtensions().directComposition) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without " "EGL_ANGLE_direct_composition support.")); return EGL_FALSE; } *value = eglSurface->directComposition(); break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); Display *display = static_cast(dpy); Config *configuration = static_cast(config); gl::Context* sharedGLContext = static_cast(share_context); AttributeMap attributes(attrib_list); Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes); if (error.isError()) { SetGlobalError(error); return EGL_NO_CONTEXT; } gl::Context *context = nullptr; error = display->createContext(configuration, sharedGLContext, attributes, &context); if (error.isError()) { SetGlobalError(error); return EGL_NO_CONTEXT; } SetGlobalError(Error(EGL_SUCCESS)); return static_cast(context); } EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); Display *display = static_cast(dpy); gl::Context *context = static_cast(ctx); Error error = ValidateContext(display, context); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (ctx == EGL_NO_CONTEXT) { SetGlobalError(Error(EGL_BAD_CONTEXT)); return EGL_FALSE; } if (context == GetGlobalContext()) { SetGlobalDisplay(NULL); SetGlobalContext(NULL); } display->destroyContext(context); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, draw, read, ctx); Display *display = static_cast(dpy); gl::Context *context = static_cast(ctx); // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH // error is generated. if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an // EGL_BAD_MATCH error is generated. if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) { SetGlobalError(Error( EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE")); return EGL_FALSE; } if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle")); return EGL_FALSE; } // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) { SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized")); return EGL_FALSE; } if (ctx != EGL_NO_CONTEXT) { Error error = ValidateContext(display, context); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } } if (display->isInitialized()) { if (display->testDeviceLost()) { display->notifyDeviceLost(); return EGL_FALSE; } if (display->isDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; } } Surface *drawSurface = static_cast(draw); if (draw != EGL_NO_SURFACE) { Error error = ValidateSurface(display, drawSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } } Surface *readSurface = static_cast(read); if (read != EGL_NO_SURFACE) { Error error = ValidateSurface(display, readSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } } if (readSurface) { Error readCompatError = ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface, context->getConfig(), readSurface->getType()); if (readCompatError.isError()) { SetGlobalError(readCompatError); return EGL_FALSE; } } if (draw != read) { UNIMPLEMENTED(); // FIXME if (drawSurface) { Error drawCompatError = ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface, context->getConfig(), drawSurface->getType()); if (drawCompatError.isError()) { SetGlobalError(drawCompatError); return EGL_FALSE; } } } Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context); if (makeCurrentError.isError()) { SetGlobalError(makeCurrentError); return EGL_FALSE; } gl::Context *previousContext = GetGlobalContext(); SetGlobalDisplay(display); SetGlobalDrawSurface(drawSurface); SetGlobalReadSurface(readSurface); SetGlobalContext(context); // Release the surface from the previously-current context, to allow // destroyed surfaces to delete themselves. if (previousContext != nullptr && context != previousContext) { previousContext->releaseSurface(); } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) { EVENT("(EGLint readdraw = %d)", readdraw); if (readdraw == EGL_READ) { SetGlobalError(Error(EGL_SUCCESS)); return GetGlobalReadSurface(); } else if (readdraw == EGL_DRAW) { SetGlobalError(Error(EGL_SUCCESS)); return GetGlobalDrawSurface(); } else { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_NO_SURFACE; } } EGLDisplay EGLAPIENTRY GetCurrentDisplay(void) { EVENT("()"); EGLDisplay dpy = GetGlobalDisplay(); SetGlobalError(Error(EGL_SUCCESS)); return dpy; } EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, ctx, attribute, value); Display *display = static_cast(dpy); gl::Context *context = static_cast(ctx); Error error = ValidateContext(display, context); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } switch (attribute) { case EGL_CONFIG_ID: *value = context->getConfig()->configID; break; case EGL_CONTEXT_CLIENT_TYPE: *value = context->getClientType(); break; case EGL_CONTEXT_CLIENT_VERSION: *value = context->getClientVersion(); break; case EGL_RENDER_BUFFER: *value = context->getRenderBuffer(); break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitGL(void) { EVENT("()"); Display *display = GetGlobalDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement // OpenGL ES we can do the call directly. error = display->waitClient(); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitNative(EGLint engine) { EVENT("(EGLint engine = %d)", engine); Display *display = GetGlobalDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (engine != EGL_CORE_NATIVE_ENGINE) { SetGlobalError( Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value")); } error = display->waitNative(engine, GetGlobalDrawSurface(), GetGlobalReadSurface()); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); Display *display = static_cast(dpy); Surface *eglSurface = (Surface*)surface; Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (display->isDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } error = eglSurface->swap(); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (display->isDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; } UNIMPLEMENTED(); // FIXME SetGlobalError(Error(EGL_SUCCESS)); return 0; } // EGL 1.1 EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } if (eglSurface->getBoundTexture()) { SetGlobalError(Error(EGL_BAD_ACCESS)); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } gl::Context *context = GetGlobalContext(); if (context) { gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D); ASSERT(textureObject != NULL); if (textureObject->getImmutableFormat()) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } error = eglSurface->bindTexImage(textureObject, buffer); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", dpy, surface, attribute, value); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } UNIMPLEMENTED(); // FIXME SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } gl::Texture *texture = eglSurface->getBoundTexture(); if (texture) { error = eglSurface->releaseTexImage(buffer); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); Display *display = static_cast(dpy); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } Surface *draw_surface = static_cast(GetGlobalDrawSurface()); if (draw_surface == NULL) { SetGlobalError(Error(EGL_BAD_SURFACE)); return EGL_FALSE; } const egl::Config *surfaceConfig = draw_surface->getConfig(); EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval); draw_surface->setSwapInterval(clampedInterval); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } // EGL 1.2 EGLBoolean EGLAPIENTRY BindAPI(EGLenum api) { EVENT("(EGLenum api = 0x%X)", api); switch (api) { case EGL_OPENGL_API: case EGL_OPENVG_API: SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; // Not supported by this implementation case EGL_OPENGL_ES_API: break; default: SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_FALSE; } SetGlobalAPI(api); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLenum EGLAPIENTRY QueryAPI(void) { EVENT("()"); EGLenum API = GetGlobalAPI(); SetGlobalError(Error(EGL_SUCCESS)); return API; } EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, buftype, buffer, config, attrib_list); Display *display = static_cast(dpy); Config *configuration = static_cast(config); AttributeMap attributes(attrib_list); Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface); if (error.isError()) { SetGlobalError(error); return EGL_NO_SURFACE; } return static_cast(surface); } EGLBoolean EGLAPIENTRY ReleaseThread(void) { EVENT("()"); MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitClient(void) { EVENT("()"); Display *display = GetGlobalDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } error = display->waitClient(); if (error.isError()) { SetGlobalError(error); return EGL_FALSE; } SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } // EGL 1.4 EGLContext EGLAPIENTRY GetCurrentContext(void) { EVENT("()"); gl::Context *context = GetGlobalContext(); SetGlobalError(Error(EGL_SUCCESS)); return static_cast(context); } // EGL 1.5 EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list); UNIMPLEMENTED(); return EGL_NO_SYNC; } EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync); UNIMPLEMENTED(); return EGL_FALSE; } EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout); UNIMPLEMENTED(); return 0; } EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value); UNIMPLEMENTED(); return EGL_FALSE; } EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", dpy, ctx, target, buffer, attrib_list); UNIMPLEMENTED(); return EGL_NO_IMAGE; } EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); UNIMPLEMENTED(); return EGL_FALSE; } EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) { EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", platform, native_display, attrib_list); UNIMPLEMENTED(); return EGL_NO_DISPLAY; } EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", dpy, config, native_window, attrib_list); UNIMPLEMENTED(); return EGL_NO_SURFACE; } EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", dpy, config, native_pixmap, attrib_list); UNIMPLEMENTED(); return EGL_NO_SURFACE; } EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags); UNIMPLEMENTED(); return EGL_FALSE; } __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname) { EVENT("(const char *procname = \"%s\")", procname); typedef std::map ProcAddressMap; auto generateProcAddressMap = []() { ProcAddressMap map; #define INSERT_PROC_ADDRESS(ns, proc) \ map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc) // GLES2 core INSERT_PROC_ADDRESS(gl, ActiveTexture); INSERT_PROC_ADDRESS(gl, AttachShader); INSERT_PROC_ADDRESS(gl, BindAttribLocation); INSERT_PROC_ADDRESS(gl, BindBuffer); INSERT_PROC_ADDRESS(gl, BindFramebuffer); INSERT_PROC_ADDRESS(gl, BindRenderbuffer); INSERT_PROC_ADDRESS(gl, BindTexture); INSERT_PROC_ADDRESS(gl, BlendColor); INSERT_PROC_ADDRESS(gl, BlendEquation); INSERT_PROC_ADDRESS(gl, BlendEquationSeparate); INSERT_PROC_ADDRESS(gl, BlendFunc); INSERT_PROC_ADDRESS(gl, BlendFuncSeparate); INSERT_PROC_ADDRESS(gl, BufferData); INSERT_PROC_ADDRESS(gl, BufferSubData); INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus); INSERT_PROC_ADDRESS(gl, Clear); INSERT_PROC_ADDRESS(gl, ClearColor); INSERT_PROC_ADDRESS(gl, ClearDepthf); INSERT_PROC_ADDRESS(gl, ClearStencil); INSERT_PROC_ADDRESS(gl, ColorMask); INSERT_PROC_ADDRESS(gl, CompileShader); INSERT_PROC_ADDRESS(gl, CompressedTexImage2D); INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D); INSERT_PROC_ADDRESS(gl, CopyTexImage2D); INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D); INSERT_PROC_ADDRESS(gl, CreateProgram); INSERT_PROC_ADDRESS(gl, CreateShader); INSERT_PROC_ADDRESS(gl, CullFace); INSERT_PROC_ADDRESS(gl, DeleteBuffers); INSERT_PROC_ADDRESS(gl, DeleteFramebuffers); INSERT_PROC_ADDRESS(gl, DeleteProgram); INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers); INSERT_PROC_ADDRESS(gl, DeleteShader); INSERT_PROC_ADDRESS(gl, DeleteTextures); INSERT_PROC_ADDRESS(gl, DepthFunc); INSERT_PROC_ADDRESS(gl, DepthMask); INSERT_PROC_ADDRESS(gl, DepthRangef); INSERT_PROC_ADDRESS(gl, DetachShader); INSERT_PROC_ADDRESS(gl, Disable); INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray); INSERT_PROC_ADDRESS(gl, DrawArrays); INSERT_PROC_ADDRESS(gl, DrawElements); INSERT_PROC_ADDRESS(gl, Enable); INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray); INSERT_PROC_ADDRESS(gl, Finish); INSERT_PROC_ADDRESS(gl, Flush); INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer); INSERT_PROC_ADDRESS(gl, FramebufferTexture2D); INSERT_PROC_ADDRESS(gl, FrontFace); INSERT_PROC_ADDRESS(gl, GenBuffers); INSERT_PROC_ADDRESS(gl, GenerateMipmap); INSERT_PROC_ADDRESS(gl, GenFramebuffers); INSERT_PROC_ADDRESS(gl, GenRenderbuffers); INSERT_PROC_ADDRESS(gl, GenTextures); INSERT_PROC_ADDRESS(gl, GetActiveAttrib); INSERT_PROC_ADDRESS(gl, GetActiveUniform); INSERT_PROC_ADDRESS(gl, GetAttachedShaders); INSERT_PROC_ADDRESS(gl, GetAttribLocation); INSERT_PROC_ADDRESS(gl, GetBooleanv); INSERT_PROC_ADDRESS(gl, GetBufferParameteriv); INSERT_PROC_ADDRESS(gl, GetError); INSERT_PROC_ADDRESS(gl, GetFloatv); INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv); INSERT_PROC_ADDRESS(gl, GetIntegerv); INSERT_PROC_ADDRESS(gl, GetProgramiv); INSERT_PROC_ADDRESS(gl, GetProgramInfoLog); INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv); INSERT_PROC_ADDRESS(gl, GetShaderiv); INSERT_PROC_ADDRESS(gl, GetShaderInfoLog); INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat); INSERT_PROC_ADDRESS(gl, GetShaderSource); INSERT_PROC_ADDRESS(gl, GetString); INSERT_PROC_ADDRESS(gl, GetTexParameterfv); INSERT_PROC_ADDRESS(gl, GetTexParameteriv); INSERT_PROC_ADDRESS(gl, GetUniformfv); INSERT_PROC_ADDRESS(gl, GetUniformiv); INSERT_PROC_ADDRESS(gl, GetUniformLocation); INSERT_PROC_ADDRESS(gl, GetVertexAttribfv); INSERT_PROC_ADDRESS(gl, GetVertexAttribiv); INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv); INSERT_PROC_ADDRESS(gl, Hint); INSERT_PROC_ADDRESS(gl, IsBuffer); INSERT_PROC_ADDRESS(gl, IsEnabled); INSERT_PROC_ADDRESS(gl, IsFramebuffer); INSERT_PROC_ADDRESS(gl, IsProgram); INSERT_PROC_ADDRESS(gl, IsRenderbuffer); INSERT_PROC_ADDRESS(gl, IsShader); INSERT_PROC_ADDRESS(gl, IsTexture); INSERT_PROC_ADDRESS(gl, LineWidth); INSERT_PROC_ADDRESS(gl, LinkProgram); INSERT_PROC_ADDRESS(gl, PixelStorei); INSERT_PROC_ADDRESS(gl, PolygonOffset); INSERT_PROC_ADDRESS(gl, ReadPixels); INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler); INSERT_PROC_ADDRESS(gl, RenderbufferStorage); INSERT_PROC_ADDRESS(gl, SampleCoverage); INSERT_PROC_ADDRESS(gl, Scissor); INSERT_PROC_ADDRESS(gl, ShaderBinary); INSERT_PROC_ADDRESS(gl, ShaderSource); INSERT_PROC_ADDRESS(gl, StencilFunc); INSERT_PROC_ADDRESS(gl, StencilFuncSeparate); INSERT_PROC_ADDRESS(gl, StencilMask); INSERT_PROC_ADDRESS(gl, StencilMaskSeparate); INSERT_PROC_ADDRESS(gl, StencilOp); INSERT_PROC_ADDRESS(gl, StencilOpSeparate); INSERT_PROC_ADDRESS(gl, TexImage2D); INSERT_PROC_ADDRESS(gl, TexParameterf); INSERT_PROC_ADDRESS(gl, TexParameterfv); INSERT_PROC_ADDRESS(gl, TexParameteri); INSERT_PROC_ADDRESS(gl, TexParameteriv); INSERT_PROC_ADDRESS(gl, TexSubImage2D); INSERT_PROC_ADDRESS(gl, Uniform1f); INSERT_PROC_ADDRESS(gl, Uniform1fv); INSERT_PROC_ADDRESS(gl, Uniform1i); INSERT_PROC_ADDRESS(gl, Uniform1iv); INSERT_PROC_ADDRESS(gl, Uniform2f); INSERT_PROC_ADDRESS(gl, Uniform2fv); INSERT_PROC_ADDRESS(gl, Uniform2i); INSERT_PROC_ADDRESS(gl, Uniform2iv); INSERT_PROC_ADDRESS(gl, Uniform3f); INSERT_PROC_ADDRESS(gl, Uniform3fv); INSERT_PROC_ADDRESS(gl, Uniform3i); INSERT_PROC_ADDRESS(gl, Uniform3iv); INSERT_PROC_ADDRESS(gl, Uniform4f); INSERT_PROC_ADDRESS(gl, Uniform4fv); INSERT_PROC_ADDRESS(gl, Uniform4i); INSERT_PROC_ADDRESS(gl, Uniform4iv); INSERT_PROC_ADDRESS(gl, UniformMatrix2fv); INSERT_PROC_ADDRESS(gl, UniformMatrix3fv); INSERT_PROC_ADDRESS(gl, UniformMatrix4fv); INSERT_PROC_ADDRESS(gl, UseProgram); INSERT_PROC_ADDRESS(gl, ValidateProgram); INSERT_PROC_ADDRESS(gl, VertexAttrib1f); INSERT_PROC_ADDRESS(gl, VertexAttrib1fv); INSERT_PROC_ADDRESS(gl, VertexAttrib2f); INSERT_PROC_ADDRESS(gl, VertexAttrib2fv); INSERT_PROC_ADDRESS(gl, VertexAttrib3f); INSERT_PROC_ADDRESS(gl, VertexAttrib3fv); INSERT_PROC_ADDRESS(gl, VertexAttrib4f); INSERT_PROC_ADDRESS(gl, VertexAttrib4fv); INSERT_PROC_ADDRESS(gl, VertexAttribPointer); INSERT_PROC_ADDRESS(gl, Viewport); // GL_ANGLE_framebuffer_blit INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE); // GL_ANGLE_framebuffer_multisample INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE); // GL_EXT_discard_framebuffer INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT); // GL_NV_fence INSERT_PROC_ADDRESS(gl, DeleteFencesNV); INSERT_PROC_ADDRESS(gl, GenFencesNV); INSERT_PROC_ADDRESS(gl, IsFenceNV); INSERT_PROC_ADDRESS(gl, TestFenceNV); INSERT_PROC_ADDRESS(gl, GetFenceivNV); INSERT_PROC_ADDRESS(gl, FinishFenceNV); INSERT_PROC_ADDRESS(gl, SetFenceNV); // GL_ANGLE_translated_shader_source INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE); // GL_EXT_texture_storage INSERT_PROC_ADDRESS(gl, TexStorage2DEXT); // GL_EXT_robustness INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT); INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT); INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT); INSERT_PROC_ADDRESS(gl, GetnUniformivEXT); // GL_EXT_occlusion_query_boolean INSERT_PROC_ADDRESS(gl, GenQueriesEXT); INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT); INSERT_PROC_ADDRESS(gl, IsQueryEXT); INSERT_PROC_ADDRESS(gl, BeginQueryEXT); INSERT_PROC_ADDRESS(gl, EndQueryEXT); INSERT_PROC_ADDRESS(gl, GetQueryivEXT); INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT); // GL_EXT_draw_buffers INSERT_PROC_ADDRESS(gl, DrawBuffersEXT); // GL_ANGLE_instanced_arrays INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE); INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE); INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE); // GL_OES_get_program_binary INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES); INSERT_PROC_ADDRESS(gl, ProgramBinaryOES); // GL_OES_mapbuffer INSERT_PROC_ADDRESS(gl, MapBufferOES); INSERT_PROC_ADDRESS(gl, UnmapBufferOES); INSERT_PROC_ADDRESS(gl, GetBufferPointervOES); // GL_EXT_map_buffer_range INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT); INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT); // GL_EXT_debug_marker INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT); INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT); INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT); // GL_OES_EGL_image INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES); INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES); // GL_OES_vertex_array_object INSERT_PROC_ADDRESS(gl, BindVertexArrayOES); INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES); INSERT_PROC_ADDRESS(gl, GenVertexArraysOES); INSERT_PROC_ADDRESS(gl, IsVertexArrayOES); // GL_KHR_debug INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR); INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR); INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR); INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR); INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR); INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR); INSERT_PROC_ADDRESS(gl, ObjectLabelKHR); INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR); INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR); INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR); INSERT_PROC_ADDRESS(gl, GetPointervKHR); // GLES3 core INSERT_PROC_ADDRESS(gl, ReadBuffer); INSERT_PROC_ADDRESS(gl, DrawRangeElements); INSERT_PROC_ADDRESS(gl, TexImage3D); INSERT_PROC_ADDRESS(gl, TexSubImage3D); INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D); INSERT_PROC_ADDRESS(gl, CompressedTexImage3D); INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D); INSERT_PROC_ADDRESS(gl, GenQueries); INSERT_PROC_ADDRESS(gl, DeleteQueries); INSERT_PROC_ADDRESS(gl, IsQuery); INSERT_PROC_ADDRESS(gl, BeginQuery); INSERT_PROC_ADDRESS(gl, EndQuery); INSERT_PROC_ADDRESS(gl, GetQueryiv); INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv); INSERT_PROC_ADDRESS(gl, UnmapBuffer); INSERT_PROC_ADDRESS(gl, GetBufferPointerv); INSERT_PROC_ADDRESS(gl, DrawBuffers); INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv); INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv); INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv); INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv); INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv); INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv); INSERT_PROC_ADDRESS(gl, BlitFramebuffer); INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample); INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer); INSERT_PROC_ADDRESS(gl, MapBufferRange); INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange); INSERT_PROC_ADDRESS(gl, BindVertexArray); INSERT_PROC_ADDRESS(gl, DeleteVertexArrays); INSERT_PROC_ADDRESS(gl, GenVertexArrays); INSERT_PROC_ADDRESS(gl, IsVertexArray); INSERT_PROC_ADDRESS(gl, GetIntegeri_v); INSERT_PROC_ADDRESS(gl, BeginTransformFeedback); INSERT_PROC_ADDRESS(gl, EndTransformFeedback); INSERT_PROC_ADDRESS(gl, BindBufferRange); INSERT_PROC_ADDRESS(gl, BindBufferBase); INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings); INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying); INSERT_PROC_ADDRESS(gl, VertexAttribIPointer); INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv); INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv); INSERT_PROC_ADDRESS(gl, VertexAttribI4i); INSERT_PROC_ADDRESS(gl, VertexAttribI4ui); INSERT_PROC_ADDRESS(gl, VertexAttribI4iv); INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv); INSERT_PROC_ADDRESS(gl, GetUniformuiv); INSERT_PROC_ADDRESS(gl, GetFragDataLocation); INSERT_PROC_ADDRESS(gl, Uniform1ui); INSERT_PROC_ADDRESS(gl, Uniform2ui); INSERT_PROC_ADDRESS(gl, Uniform3ui); INSERT_PROC_ADDRESS(gl, Uniform4ui); INSERT_PROC_ADDRESS(gl, Uniform1uiv); INSERT_PROC_ADDRESS(gl, Uniform2uiv); INSERT_PROC_ADDRESS(gl, Uniform3uiv); INSERT_PROC_ADDRESS(gl, Uniform4uiv); INSERT_PROC_ADDRESS(gl, ClearBufferiv); INSERT_PROC_ADDRESS(gl, ClearBufferuiv); INSERT_PROC_ADDRESS(gl, ClearBufferfv); INSERT_PROC_ADDRESS(gl, ClearBufferfi); INSERT_PROC_ADDRESS(gl, GetStringi); INSERT_PROC_ADDRESS(gl, CopyBufferSubData); INSERT_PROC_ADDRESS(gl, GetUniformIndices); INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv); INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex); INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv); INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName); INSERT_PROC_ADDRESS(gl, UniformBlockBinding); INSERT_PROC_ADDRESS(gl, DrawArraysInstanced); INSERT_PROC_ADDRESS(gl, DrawElementsInstanced); map["glFenceSync"] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(gl::FenceSync_); INSERT_PROC_ADDRESS(gl, IsSync); INSERT_PROC_ADDRESS(gl, DeleteSync); INSERT_PROC_ADDRESS(gl, ClientWaitSync); INSERT_PROC_ADDRESS(gl, WaitSync); INSERT_PROC_ADDRESS(gl, GetInteger64v); INSERT_PROC_ADDRESS(gl, GetSynciv); INSERT_PROC_ADDRESS(gl, GetInteger64i_v); INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v); INSERT_PROC_ADDRESS(gl, GenSamplers); INSERT_PROC_ADDRESS(gl, DeleteSamplers); INSERT_PROC_ADDRESS(gl, IsSampler); INSERT_PROC_ADDRESS(gl, BindSampler); INSERT_PROC_ADDRESS(gl, SamplerParameteri); INSERT_PROC_ADDRESS(gl, SamplerParameteriv); INSERT_PROC_ADDRESS(gl, SamplerParameterf); INSERT_PROC_ADDRESS(gl, SamplerParameterfv); INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv); INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv); INSERT_PROC_ADDRESS(gl, VertexAttribDivisor); INSERT_PROC_ADDRESS(gl, BindTransformFeedback); INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks); INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks); INSERT_PROC_ADDRESS(gl, IsTransformFeedback); INSERT_PROC_ADDRESS(gl, PauseTransformFeedback); INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback); INSERT_PROC_ADDRESS(gl, GetProgramBinary); INSERT_PROC_ADDRESS(gl, ProgramBinary); INSERT_PROC_ADDRESS(gl, ProgramParameteri); INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer); INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer); INSERT_PROC_ADDRESS(gl, TexStorage2D); INSERT_PROC_ADDRESS(gl, TexStorage3D); INSERT_PROC_ADDRESS(gl, GetInternalformativ); // EGL 1.0 INSERT_PROC_ADDRESS(egl, ChooseConfig); INSERT_PROC_ADDRESS(egl, CopyBuffers); INSERT_PROC_ADDRESS(egl, CreateContext); INSERT_PROC_ADDRESS(egl, CreatePbufferSurface); INSERT_PROC_ADDRESS(egl, CreatePixmapSurface); INSERT_PROC_ADDRESS(egl, CreateWindowSurface); INSERT_PROC_ADDRESS(egl, DestroyContext); INSERT_PROC_ADDRESS(egl, DestroySurface); INSERT_PROC_ADDRESS(egl, GetConfigAttrib); INSERT_PROC_ADDRESS(egl, GetConfigs); INSERT_PROC_ADDRESS(egl, GetCurrentDisplay); INSERT_PROC_ADDRESS(egl, GetCurrentSurface); INSERT_PROC_ADDRESS(egl, GetDisplay); INSERT_PROC_ADDRESS(egl, GetError); INSERT_PROC_ADDRESS(egl, GetProcAddress); INSERT_PROC_ADDRESS(egl, Initialize); INSERT_PROC_ADDRESS(egl, MakeCurrent); INSERT_PROC_ADDRESS(egl, QueryContext); INSERT_PROC_ADDRESS(egl, QueryString); INSERT_PROC_ADDRESS(egl, QuerySurface); INSERT_PROC_ADDRESS(egl, SwapBuffers); INSERT_PROC_ADDRESS(egl, Terminate); INSERT_PROC_ADDRESS(egl, WaitGL); INSERT_PROC_ADDRESS(egl, WaitNative); // EGL 1.1 INSERT_PROC_ADDRESS(egl, BindTexImage); INSERT_PROC_ADDRESS(egl, ReleaseTexImage); INSERT_PROC_ADDRESS(egl, SurfaceAttrib); INSERT_PROC_ADDRESS(egl, SwapInterval); // EGL 1.2 INSERT_PROC_ADDRESS(egl, BindAPI); INSERT_PROC_ADDRESS(egl, QueryAPI); INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer); INSERT_PROC_ADDRESS(egl, ReleaseThread); INSERT_PROC_ADDRESS(egl, WaitClient); // EGL 1.4 INSERT_PROC_ADDRESS(egl, GetCurrentContext); // EGL 1.5 INSERT_PROC_ADDRESS(egl, CreateSync); INSERT_PROC_ADDRESS(egl, DestroySync); INSERT_PROC_ADDRESS(egl, ClientWaitSync); INSERT_PROC_ADDRESS(egl, GetSyncAttrib); INSERT_PROC_ADDRESS(egl, CreateImage); INSERT_PROC_ADDRESS(egl, DestroyImage); INSERT_PROC_ADDRESS(egl, GetPlatformDisplay); INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface); INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface); INSERT_PROC_ADDRESS(egl, WaitSync); // EGL_ANGLE_query_surface_pointer INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE); // EGL_NV_post_sub_buffer INSERT_PROC_ADDRESS(egl, PostSubBufferNV); // EGL_EXT_platform_base INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT); // EGL_EXT_device_query INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT); INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT); INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT); // EGL_KHR_image_base/EGL_KHR_image INSERT_PROC_ADDRESS(egl, CreateImageKHR); INSERT_PROC_ADDRESS(egl, DestroyImageKHR); // EGL_EXT_device_creation INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE); INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE); #undef INSERT_PROC_ADDRESS return map; }; static const ProcAddressMap procAddressMap = generateProcAddressMap(); auto iter = procAddressMap.find(procname); if (iter != procAddressMap.end()) { return iter->second; } else { return nullptr; } } }