// static AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes) { AttributeMap map; if (attributes) { for (const EGLAttrib *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) { map.insert(curAttrib[0], curAttrib[1]); } } return map; }
// static AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes) { AttributeMap map; if (attributes) { for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) { map.insert(static_cast<EGLAttrib>(curAttrib[0]), static_cast<EGLAttrib>(curAttrib[1])); } } return map; }
// EGL_EXT_platform_base EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list) { EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", platform, native_display, attrib_list); const ClientExtensions &clientExtensions = Display::getClientExtensions(); switch (platform) { case EGL_PLATFORM_ANGLE_ANGLE: if (!clientExtensions.platformANGLE) { SetGlobalError(Error(EGL_BAD_PARAMETER)); return EGL_NO_DISPLAY; } break; case EGL_PLATFORM_DEVICE_EXT: if (!clientExtensions.platformDevice) { SetGlobalError(Error(EGL_BAD_PARAMETER, "Platform Device extension is not active")); return EGL_NO_DISPLAY; } break; default: SetGlobalError(Error(EGL_BAD_CONFIG)); return EGL_NO_DISPLAY; } if (platform == EGL_PLATFORM_ANGLE_ANGLE) { EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; bool majorVersionSpecified = false; bool minorVersionSpecified = false; bool enableAutoTrimSpecified = false; bool deviceTypeSpecified = false; bool presentPathSpecified = false; bool foundRenderToBackbuffer = false; bool requestedAllowRenderToBackBuffer = false; if (attrib_list) { for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) { switch (curAttrib[0]) { case EGL_PLATFORM_ANGLE_TYPE_ANGLE: switch (curAttrib[1]) { case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: break; case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: if (!clientExtensions.platformANGLED3D) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } break; case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: if (!clientExtensions.platformANGLEOpenGL) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } platformType = curAttrib[1]; break; case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: if (curAttrib[1] != EGL_DONT_CARE) { majorVersionSpecified = true; } break; case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: if (curAttrib[1] != EGL_DONT_CARE) { minorVersionSpecified = true; } break; case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: switch (curAttrib[1]) { case EGL_TRUE: case EGL_FALSE: break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } enableAutoTrimSpecified = true; break; case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: if (!clientExtensions.experimentalPresentPath) { SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_experimental_present_path extension not active")); return EGL_NO_DISPLAY; } switch (curAttrib[1]) { case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: break; default: SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE")); return EGL_NO_DISPLAY; } presentPathSpecified = true; break; case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: switch (curAttrib[1]) { case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: deviceTypeSpecified = true; break; case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: // This is a hidden option, accepted by the OpenGL back-end. break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "Invalid value for " "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " "attrib")); return EGL_NO_DISPLAY; } deviceType = curAttrib[1]; break; case EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER: ERR("EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is deprecated, please use" "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE."); switch (curAttrib[1]) { case EGL_FALSE: case EGL_TRUE: break; default: SetGlobalError(egl::Error(EGL_SUCCESS)); return EGL_NO_DISPLAY; } foundRenderToBackbuffer = true; requestedAllowRenderToBackBuffer = (curAttrib[1] == EGL_TRUE); break; default: break; } } } if (!majorVersionSpecified && minorVersionSpecified) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); return EGL_NO_DISPLAY; } if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); return EGL_NO_DISPLAY; } if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); return EGL_NO_DISPLAY; } if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { SetGlobalError( Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.")); return EGL_NO_DISPLAY; } AttributeMap attribMap = AttributeMap(attrib_list); if (requestedAllowRenderToBackBuffer) { // Redirect EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER to // EGL_PLATFORM_ANGLE_EXPERIMENTAL_DIRECT_RENDERING for backcompat attribMap.insert(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE); } SetGlobalError(Error(EGL_SUCCESS)); return Display::GetDisplayFromAttribs(native_display, attribMap); } else if (platform == EGL_PLATFORM_DEVICE_EXT) { Device *eglDevice = reinterpret_cast<Device *>(native_display); if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "native_display should be a valid EGL device if platform equals " "EGL_PLATFORM_DEVICE_EXT")); return EGL_NO_DISPLAY; } SetGlobalError(Error(EGL_SUCCESS)); return Display::GetDisplayFromDevice(native_display); } else { UNREACHABLE(); return EGL_NO_DISPLAY; } }