From 5d2857b3c470cb9b24c1d59568a2dcbcf78bb780 Mon Sep 17 00:00:00 2001 From: Dale Stammen Date: Wed, 19 Nov 2014 15:55:18 -0800 Subject: [PATCH] updated angle to commit 4a980d2612 --- cocos/platform/win8.1-universal/OpenGLES.cpp | 114 ++++++++++++++---- cocos/platform/win8.1-universal/OpenGLES.h | 1 - .../App.Shared/OpenGLES.cpp | 114 ++++++++++++++---- .../App.Shared/OpenGLES.h | 1 - 4 files changed, 178 insertions(+), 52 deletions(-) diff --git a/cocos/platform/win8.1-universal/OpenGLES.cpp b/cocos/platform/win8.1-universal/OpenGLES.cpp index 943b0856fc..3f696abba7 100644 --- a/cocos/platform/win8.1-universal/OpenGLES.cpp +++ b/cocos/platform/win8.1-universal/OpenGLES.cpp @@ -48,51 +48,107 @@ void OpenGLES::Initialize() EGL_NONE }; - const EGLint displayAttributes[] = - { - // This can be used to configure D3D11. For example, EGL_PLATFORM_ANGLE_TYPE_D3D11_FL9_3_ANGLE could be used. - // This would ask the graphics card to use D3D11 Feature Level 9_3 instead of Feature Level 11_0+. - // On Windows Phone, this would allow the Phone Emulator to act more like the GPUs that are available on real Phone devices. -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_FL9_3_ANGLE, - EGL_NONE, -#else - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_NONE, -#endif - }; - const EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - // eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in 'displayAttributes' to configure D3D11. + const EGLint defaultDisplayAttributes[] = + { + // These are the default display attributes, used to request ANGLE's D3D11 renderer. + // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + + // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. + // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + const EGLint fl9_3DisplayAttributes[] = + { + // These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature Level 9_3. + // These attributes are used if the call to eglInitialize fails with the default display attributes. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + const EGLint warpDisplayAttributes[] = + { + // These attributes can be used to request D3D11 WARP. + // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + EGLConfig config = NULL; + + // eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in display attributes, used to configure D3D11. PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast(eglGetProcAddress("eglGetPlatformDisplayEXT")); if (!eglGetPlatformDisplayEXT) { throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT"); } - mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); + // + // To initialize the display, we make three sets of calls to eglGetPlatformDisplayEXT and eglInitialize, with varying + // parameters passed to eglGetPlatformDisplayEXT: + // 1) The first calls uses "defaultDisplayAttributes" as a parameter. This corresponds to D3D11 Feature Level 10_0+. + // 2) If eglInitialize fails for step 1 (e.g. because 10_0+ isn't supported by the default GPU), then we try again + // using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level 9_3. + // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again + // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. + // + // Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize. + // Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+. + // We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like + // real Windows Phone devices. + // If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef. + // + +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) + // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); if (mEglDisplay == EGL_NO_DISPLAY) { - throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display"); + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); } if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) +#endif { - throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); + // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); + if (mEglDisplay == EGL_NO_DISPLAY) + { + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); + } + + if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) + { + // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); + if (mEglDisplay == EGL_NO_DISPLAY) + { + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); + } + + if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) + { + // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. + throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); + } + } } EGLint numConfigs = 0; - if (eglGetConfigs(mEglDisplay, NULL, 0, &numConfigs) == EGL_FALSE) - { - throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count"); - } - - if (eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &numConfigs) == EGL_FALSE) + if ((eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0)) { throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig"); } @@ -134,6 +190,14 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf EGLSurface surface = EGL_NO_SURFACE; + const EGLint surfaceAttributes[] = + { + // EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is part of the same optimization as EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER (see above). + // If you have compilation issues with it then please update your Visual Studio templates. + EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE + }; + // Create a PropertySet and initialize with the EGLNativeWindowType. PropertySet^ surfaceCreationProperties = ref new PropertySet(); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel); @@ -144,7 +208,7 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); } - surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast(surfaceCreationProperties), NULL); + surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast(surfaceCreationProperties), surfaceAttributes); if (surface == EGL_NO_SURFACE) { throw Exception::CreateException(E_FAIL, L"Failed to create EGL surface"); diff --git a/cocos/platform/win8.1-universal/OpenGLES.h b/cocos/platform/win8.1-universal/OpenGLES.h index ce9f2a9cdf..1a57b68739 100644 --- a/cocos/platform/win8.1-universal/OpenGLES.h +++ b/cocos/platform/win8.1-universal/OpenGLES.h @@ -28,7 +28,6 @@ #include #include - class OpenGLES { public: diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.cpp b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.cpp index 943b0856fc..3f696abba7 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.cpp +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.cpp @@ -48,51 +48,107 @@ void OpenGLES::Initialize() EGL_NONE }; - const EGLint displayAttributes[] = - { - // This can be used to configure D3D11. For example, EGL_PLATFORM_ANGLE_TYPE_D3D11_FL9_3_ANGLE could be used. - // This would ask the graphics card to use D3D11 Feature Level 9_3 instead of Feature Level 11_0+. - // On Windows Phone, this would allow the Phone Emulator to act more like the GPUs that are available on real Phone devices. -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_FL9_3_ANGLE, - EGL_NONE, -#else - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_NONE, -#endif - }; - const EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - // eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in 'displayAttributes' to configure D3D11. + const EGLint defaultDisplayAttributes[] = + { + // These are the default display attributes, used to request ANGLE's D3D11 renderer. + // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + + // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. + // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + const EGLint fl9_3DisplayAttributes[] = + { + // These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature Level 9_3. + // These attributes are used if the call to eglInitialize fails with the default display attributes. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + const EGLint warpDisplayAttributes[] = + { + // These attributes can be used to request D3D11 WARP. + // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE, + }; + + EGLConfig config = NULL; + + // eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in display attributes, used to configure D3D11. PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast(eglGetProcAddress("eglGetPlatformDisplayEXT")); if (!eglGetPlatformDisplayEXT) { throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT"); } - mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); + // + // To initialize the display, we make three sets of calls to eglGetPlatformDisplayEXT and eglInitialize, with varying + // parameters passed to eglGetPlatformDisplayEXT: + // 1) The first calls uses "defaultDisplayAttributes" as a parameter. This corresponds to D3D11 Feature Level 10_0+. + // 2) If eglInitialize fails for step 1 (e.g. because 10_0+ isn't supported by the default GPU), then we try again + // using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level 9_3. + // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again + // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. + // + // Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize. + // Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+. + // We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like + // real Windows Phone devices. + // If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef. + // + +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) + // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); if (mEglDisplay == EGL_NO_DISPLAY) { - throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display"); + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); } if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) +#endif { - throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); + // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); + if (mEglDisplay == EGL_NO_DISPLAY) + { + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); + } + + if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) + { + // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). + mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); + if (mEglDisplay == EGL_NO_DISPLAY) + { + throw Exception::CreateException(E_FAIL, L"Failed to get EGL display"); + } + + if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) + { + // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. + throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); + } + } } EGLint numConfigs = 0; - if (eglGetConfigs(mEglDisplay, NULL, 0, &numConfigs) == EGL_FALSE) - { - throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count"); - } - - if (eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &numConfigs) == EGL_FALSE) + if ((eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0)) { throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig"); } @@ -134,6 +190,14 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf EGLSurface surface = EGL_NO_SURFACE; + const EGLint surfaceAttributes[] = + { + // EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is part of the same optimization as EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER (see above). + // If you have compilation issues with it then please update your Visual Studio templates. + EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE, + EGL_NONE + }; + // Create a PropertySet and initialize with the EGLNativeWindowType. PropertySet^ surfaceCreationProperties = ref new PropertySet(); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel); @@ -144,7 +208,7 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); } - surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast(surfaceCreationProperties), NULL); + surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast(surfaceCreationProperties), surfaceAttributes); if (surface == EGL_NO_SURFACE) { throw Exception::CreateException(E_FAIL, L"Failed to create EGL surface"); diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.h b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.h index ce9f2a9cdf..1a57b68739 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.h +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLES.h @@ -28,7 +28,6 @@ #include #include - class OpenGLES { public: