summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/egl_tests
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/angle/src/tests/egl_tests
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/tests/egl_tests')
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp287
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLContextSharingTest.cpp87
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLDeviceTest.cpp587
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp378
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLQueryContextTest.cpp153
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLRobustnessTest.cpp234
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp30
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLStreamTest.cpp547
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLSurfaceTest.cpp517
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLThreadTest.cpp83
-rwxr-xr-xgfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp216
-rwxr-xr-xgfx/angle/src/tests/egl_tests/media/yuvtest.inl1548
12 files changed, 4667 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp b/gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp
new file mode 100755
index 000000000..63c58afba
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp
@@ -0,0 +1,287 @@
+//
+// Copyright (c) 2015 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.
+//
+
+// EGLContextCompatibilityTest.cpp:
+// This test will try to use all combinations of context configs and
+// surface configs. If the configs are compatible, it checks that simple
+// rendering works, otherwise it checks an error is generated one MakeCurrent.
+#include <gtest/gtest.h>
+
+#include <vector>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+#include "test_utils/angle_test_configs.h"
+
+using namespace angle;
+
+namespace
+{
+
+const EGLint contextAttribs[] =
+{
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+};
+
+}
+
+class EGLContextCompatibilityTest : public ANGLETest
+{
+ public:
+ EGLContextCompatibilityTest()
+ : mDisplay(0)
+ {
+ }
+
+ void SetUp() override
+ {
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);
+
+ EGLint dispattrs[] =
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
+ EGL_NONE
+ };
+ mDisplay = eglGetPlatformDisplayEXT(
+ EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
+ ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
+
+ ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);
+
+ int nConfigs = 0;
+ ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);
+ ASSERT_TRUE(nConfigs != 0);
+
+ int nReturnedConfigs = 0;
+ mConfigs.resize(nConfigs);
+ ASSERT_TRUE(eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs) == EGL_TRUE);
+ ASSERT_TRUE(nConfigs == nReturnedConfigs);
+ }
+
+ void TearDown() override
+ {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(mDisplay);
+ };
+
+ protected:
+ bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit)
+ {
+ EGLint colorBufferType1, colorBufferType2;
+ EGLint red1, red2, green1, green2, blue1, blue2, alpha1, alpha2;
+ EGLint depth1, depth2, stencil1, stencil2;
+ EGLint surfaceType1, surfaceType2;
+
+ eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_BUFFER_TYPE, &colorBufferType1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_BUFFER_TYPE, &colorBufferType2);
+
+ eglGetConfigAttrib(mDisplay, c1, EGL_RED_SIZE, &red1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_RED_SIZE, &red2);
+ eglGetConfigAttrib(mDisplay, c1, EGL_GREEN_SIZE, &green1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_GREEN_SIZE, &green2);
+ eglGetConfigAttrib(mDisplay, c1, EGL_BLUE_SIZE, &blue1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_BLUE_SIZE, &blue2);
+ eglGetConfigAttrib(mDisplay, c1, EGL_ALPHA_SIZE, &alpha1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_ALPHA_SIZE, &alpha2);
+
+ eglGetConfigAttrib(mDisplay, c1, EGL_DEPTH_SIZE, &depth1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_DEPTH_SIZE, &depth2);
+ eglGetConfigAttrib(mDisplay, c1, EGL_STENCIL_SIZE, &stencil1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_STENCIL_SIZE, &stencil2);
+
+ eglGetConfigAttrib(mDisplay, c1, EGL_SURFACE_TYPE, &surfaceType1);
+ eglGetConfigAttrib(mDisplay, c2, EGL_SURFACE_TYPE, &surfaceType2);
+
+ return colorBufferType1 == colorBufferType2 &&
+ red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2 &&
+ depth1 == depth2 && stencil1 == stencil2 &&
+ (surfaceType1 & surfaceBit) != 0 &&
+ (surfaceType2 & surfaceBit) != 0;
+ }
+
+ void testWindowCompatibility(EGLConfig windowConfig, EGLConfig contextConfig, bool compatible) const
+ {
+ OSWindow *osWindow = CreateOSWindow();
+ ASSERT_TRUE(osWindow != nullptr);
+ osWindow->initialize("EGLContextCompatibilityTest", 500, 500);
+ osWindow->setVisible(true);
+
+ EGLContext context = eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, contextAttribs);
+ ASSERT_TRUE(context != EGL_NO_CONTEXT);
+
+ EGLSurface window = eglCreateWindowSurface(mDisplay, windowConfig, osWindow->getNativeWindow(), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ if (compatible)
+ {
+ testClearSurface(window, context);
+ }
+ else
+ {
+ testMakeCurrentFails(window, context);
+ }
+
+ eglDestroySurface(mDisplay, window);
+ ASSERT_EGL_SUCCESS();
+
+ eglDestroyContext(mDisplay, context);
+ ASSERT_EGL_SUCCESS();
+
+ SafeDelete(osWindow);
+ }
+
+ void testPbufferCompatibility(EGLConfig pbufferConfig, EGLConfig contextConfig, bool compatible) const
+ {
+ EGLContext context = eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, contextAttribs);
+ ASSERT_TRUE(context != EGL_NO_CONTEXT);
+
+ const EGLint pBufferAttribs[] =
+ {
+ EGL_WIDTH, 500,
+ EGL_HEIGHT, 500,
+ EGL_NONE,
+ };
+ EGLSurface pbuffer = eglCreatePbufferSurface(mDisplay, pbufferConfig, pBufferAttribs);
+ ASSERT_TRUE(pbuffer != EGL_NO_SURFACE);
+
+ if (compatible)
+ {
+ testClearSurface(pbuffer, context);
+ }
+ else
+ {
+ testMakeCurrentFails(pbuffer, context);
+ }
+
+ eglDestroySurface(mDisplay, pbuffer);
+ ASSERT_EGL_SUCCESS();
+
+ eglDestroyContext(mDisplay, context);
+ ASSERT_EGL_SUCCESS();
+ }
+
+ std::vector<EGLConfig> mConfigs;
+ EGLDisplay mDisplay;
+
+ private:
+ void testClearSurface(EGLSurface surface, EGLContext context) const
+ {
+ eglMakeCurrent(mDisplay, surface, surface, context);
+ ASSERT_EGL_SUCCESS();
+
+ glViewport(0, 0, 500, 500);
+ glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
+
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ASSERT_EGL_SUCCESS();
+ }
+
+ void testMakeCurrentFails(EGLSurface surface, EGLContext context) const
+ {
+ eglMakeCurrent(mDisplay, surface, surface, context);
+ EXPECT_EGL_ERROR(EGL_BAD_MATCH);
+ }
+};
+
+// The test is split in several subtest so that simple cases
+// are tested separately. Also each surface types are not tested
+// together.
+
+// Basic test checking contexts and windows created with the
+// same config can render.
+TEST_P(EGLContextCompatibilityTest, WindowSameConfig)
+{
+ for (size_t i = 0; i < mConfigs.size(); i++)
+ {
+ EGLConfig config = mConfigs[i];
+
+ EGLint surfaceType;
+ eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
+ ASSERT_EGL_SUCCESS();
+
+ if ((surfaceType & EGL_WINDOW_BIT) != 0)
+ {
+ testWindowCompatibility(config, config, true);
+ }
+ }
+}
+
+// Basic test checking contexts and pbuffers created with the
+// same config can render.
+TEST_P(EGLContextCompatibilityTest, PbufferSameConfig)
+{
+ for (size_t i = 0; i < mConfigs.size(); i++)
+ {
+ EGLConfig config = mConfigs[i];
+
+ EGLint surfaceType;
+ eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
+ ASSERT_EGL_SUCCESS();
+
+ if ((surfaceType & EGL_PBUFFER_BIT) != 0)
+ {
+ testPbufferCompatibility(config, config, true);
+ }
+ }
+}
+
+// Check that a context rendering to a window with a different
+// config works or errors according to the EGL compatibility rules
+TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
+{
+ for (size_t i = 0; i < mConfigs.size(); i++)
+ {
+ EGLConfig config1 = mConfigs[i];
+ EGLint surfaceType;
+ eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
+ ASSERT_EGL_SUCCESS();
+
+ if ((surfaceType & EGL_WINDOW_BIT) == 0)
+ {
+ continue;
+ }
+
+ for (size_t j = 0; j < mConfigs.size(); j++)
+ {
+ EGLConfig config2 = mConfigs[j];
+ testWindowCompatibility(config1, config2,
+ areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
+ }
+ }
+}
+
+// Check that a context rendering to a pbuffer with a different
+// config works or errors according to the EGL compatibility rules
+TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig)
+{
+ for (size_t i = 0; i < mConfigs.size(); i++)
+ {
+ EGLConfig config1 = mConfigs[i];
+ EGLint surfaceType;
+ eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
+ ASSERT_EGL_SUCCESS();
+
+ if ((surfaceType & EGL_PBUFFER_BIT) == 0)
+ {
+ continue;
+ }
+
+ for (size_t j = 0; j < mConfigs.size(); j++)
+ {
+ EGLConfig config2 = mConfigs[j];
+ testPbufferCompatibility(config1, config2, areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
+ }
+ }
+}
+
+ANGLE_INSTANTIATE_TEST(EGLContextCompatibilityTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
diff --git a/gfx/angle/src/tests/egl_tests/EGLContextSharingTest.cpp b/gfx/angle/src/tests/egl_tests/EGLContextSharingTest.cpp
new file mode 100755
index 000000000..fc66b7909
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLContextSharingTest.cpp
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2016 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.
+//
+// EGLContextSharingTest.cpp:
+// Tests relating to shared Contexts.
+
+#include <gtest/gtest.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "test_utils/ANGLETest.h"
+#include "test_utils/angle_test_configs.h"
+
+using namespace angle;
+
+namespace
+{
+
+EGLBoolean SafeDestroyContext(EGLDisplay display, EGLContext &context)
+{
+ EGLBoolean result = EGL_TRUE;
+ if (context != EGL_NO_CONTEXT)
+ {
+ result = eglDestroyContext(display, context);
+ context = EGL_NO_CONTEXT;
+ }
+ return result;
+}
+
+class EGLContextSharingTest : public ANGLETest
+{
+ public:
+ EGLContextSharingTest() : mContexts{EGL_NO_CONTEXT, EGL_NO_CONTEXT}, mTexture(0) {}
+
+ void TearDown() override
+ {
+ glDeleteTextures(1, &mTexture);
+
+ EGLDisplay display = getEGLWindow()->getDisplay();
+
+ if (display != EGL_NO_DISPLAY)
+ {
+ for (auto &context : mContexts)
+ {
+ SafeDestroyContext(display, context);
+ }
+ }
+
+ ANGLETest::TearDown();
+ }
+
+ EGLContext mContexts[2];
+ GLuint mTexture;
+};
+
+// Tests that creating resources works after freeing the share context.
+TEST_P(EGLContextSharingTest, BindTextureAfterShareContextFree)
+{
+ EGLDisplay display = getEGLWindow()->getDisplay();
+ EGLConfig config = getEGLWindow()->getConfig();
+ EGLSurface surface = getEGLWindow()->getSurface();
+
+ const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,
+ getEGLWindow()->getClientMajorVersion(), EGL_NONE};
+
+ mContexts[0] = eglCreateContext(display, config, nullptr, contextAttribs);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_TRUE(mContexts[0] != EGL_NO_CONTEXT);
+ mContexts[1] = eglCreateContext(display, config, mContexts[1], contextAttribs);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_TRUE(mContexts[1] != EGL_NO_CONTEXT);
+
+ ASSERT_EGL_TRUE(SafeDestroyContext(display, mContexts[0]));
+ ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
+ ASSERT_EGL_SUCCESS();
+
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ ASSERT_GL_NO_ERROR();
+}
+
+} // anonymous namespace
+
+ANGLE_INSTANTIATE_TEST(EGLContextSharingTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
diff --git a/gfx/angle/src/tests/egl_tests/EGLDeviceTest.cpp b/gfx/angle/src/tests/egl_tests/EGLDeviceTest.cpp
new file mode 100755
index 000000000..721754181
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLDeviceTest.cpp
@@ -0,0 +1,587 @@
+//
+// Copyright 2015 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.
+//
+
+#ifndef ANGLE_ENABLE_D3D9
+#define ANGLE_ENABLE_D3D9
+#endif
+
+#ifndef ANGLE_ENABLE_D3D11
+#define ANGLE_ENABLE_D3D11
+#endif
+
+#include <d3d11.h>
+
+#include "com_utils.h"
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+class EGLDeviceCreationTest : public testing::Test
+{
+ protected:
+ EGLDeviceCreationTest()
+ : mD3D11Available(false),
+ mD3D11Module(nullptr),
+ mD3D11CreateDevice(nullptr),
+ mDevice(nullptr),
+ mDeviceContext(nullptr),
+ mDeviceCreationD3D11ExtAvailable(false),
+ mOSWindow(nullptr),
+ mDisplay(EGL_NO_DISPLAY),
+ mSurface(EGL_NO_SURFACE),
+ mContext(EGL_NO_CONTEXT),
+ mConfig(0)
+ {
+ }
+
+ void SetUp() override
+ {
+ mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
+ if (mD3D11Module == nullptr)
+ {
+ std::cout << "Unable to LoadLibrary D3D11" << std::endl;
+ return;
+ }
+
+ mD3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
+ GetProcAddress(mD3D11Module, "D3D11CreateDevice"));
+ if (mD3D11CreateDevice == nullptr)
+ {
+ std::cout << "Could not retrieve D3D11CreateDevice from d3d11.dll" << std::endl;
+ return;
+ }
+
+ mD3D11Available = true;
+
+ const char *extensionString =
+ static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
+ if (strstr(extensionString, "EGL_ANGLE_device_creation"))
+ {
+ if (strstr(extensionString, "EGL_ANGLE_device_creation_d3d11"))
+ {
+ mDeviceCreationD3D11ExtAvailable = true;
+ }
+ }
+ }
+
+ void TearDown() override
+ {
+ SafeRelease(mDevice);
+ SafeRelease(mDeviceContext);
+
+ SafeDelete(mOSWindow);
+
+ if (mSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mDisplay, mSurface);
+ mSurface = EGL_NO_SURFACE;
+ }
+
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(mDisplay, mContext);
+ mContext = EGL_NO_CONTEXT;
+ }
+
+ if (mDisplay != EGL_NO_DISPLAY)
+ {
+ eglTerminate(mDisplay);
+ mDisplay = EGL_NO_DISPLAY;
+ }
+ }
+
+ void CreateD3D11Device()
+ {
+ ASSERT_TRUE(mD3D11Available);
+ ASSERT_EQ(nullptr, mDevice); // The device shouldn't be created twice
+
+ HRESULT hr =
+ mD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, nullptr, 0,
+ D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, &mDeviceContext);
+
+ ASSERT_TRUE(SUCCEEDED(hr));
+ ASSERT_GE(mFeatureLevel, D3D_FEATURE_LEVEL_9_3);
+ }
+
+ void CreateD3D11FL9_3Device()
+ {
+ ASSERT_TRUE(mD3D11Available);
+ ASSERT_EQ(nullptr, mDevice);
+
+ D3D_FEATURE_LEVEL fl93 = D3D_FEATURE_LEVEL_9_3;
+
+ HRESULT hr =
+ mD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, &fl93, 1, D3D11_SDK_VERSION,
+ &mDevice, &mFeatureLevel, &mDeviceContext);
+
+ ASSERT_TRUE(SUCCEEDED(hr));
+ }
+
+ void CreateWindowSurface()
+ {
+ EGLint majorVersion, minorVersion;
+ ASSERT_EGL_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion));
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ ASSERT_EGL_SUCCESS();
+
+ // Choose a config
+ const EGLint configAttributes[] = {EGL_NONE};
+ EGLint configCount = 0;
+ ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount));
+
+ // Create an OS Window
+ mOSWindow = CreateOSWindow();
+ mOSWindow->initialize("EGLSurfaceTest", 64, 64);
+
+ // Create window surface
+ mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ // Create EGL context
+ EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+ mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
+ ASSERT_EGL_SUCCESS();
+
+ // Make the surface current
+ eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+ ASSERT_EGL_SUCCESS();
+ }
+
+ // This triggers a D3D device lost on current Windows systems
+ // This behavior could potentially change in the future
+ void trigger9_3DeviceLost()
+ {
+ ID3D11Buffer *gsBuffer = nullptr;
+ D3D11_BUFFER_DESC bufferDesc = {0};
+ bufferDesc.ByteWidth = 64;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+
+ HRESULT result = mDevice->CreateBuffer(&bufferDesc, nullptr, &gsBuffer);
+ ASSERT_TRUE(SUCCEEDED(result));
+
+ mDeviceContext->GSSetConstantBuffers(0, 1, &gsBuffer);
+ SafeRelease(gsBuffer);
+ gsBuffer = nullptr;
+
+ result = mDevice->GetDeviceRemovedReason();
+ ASSERT_TRUE(FAILED(result));
+ }
+
+ bool mD3D11Available;
+ HMODULE mD3D11Module;
+ PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice;
+
+ ID3D11Device *mDevice;
+ ID3D11DeviceContext *mDeviceContext;
+ D3D_FEATURE_LEVEL mFeatureLevel;
+
+ bool mDeviceCreationD3D11ExtAvailable;
+
+ OSWindow *mOSWindow;
+
+ EGLDisplay mDisplay;
+ EGLSurface mSurface;
+ EGLContext mContext;
+ EGLConfig mConfig;
+};
+
+// Test that creating a EGLDeviceEXT from D3D11 device works, and it can be queried to retrieve
+// D3D11 device
+TEST_F(EGLDeviceCreationTest, BasicD3D11Device)
+{
+ if (!mDeviceCreationD3D11ExtAvailable || !mD3D11Available)
+ {
+ std::cout << "EGLDevice creation and/or D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ EGLDeviceEXT eglDevice =
+ eglCreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_NE(EGL_NO_DEVICE_EXT, eglDevice);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib deviceAttrib;
+ eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, &deviceAttrib);
+ ASSERT_EGL_SUCCESS();
+
+ ID3D11Device *queriedDevice = reinterpret_cast<ID3D11Device *>(deviceAttrib);
+ ASSERT_EQ(mFeatureLevel, queriedDevice->GetFeatureLevel());
+
+ eglReleaseDeviceANGLE(eglDevice);
+}
+
+// Test that creating a EGLDeviceEXT from D3D11 device works, and it can be queried to retrieve
+// D3D11 device
+TEST_F(EGLDeviceCreationTest, BasicD3D11DeviceViaFuncPointer)
+{
+ if (!mDeviceCreationD3D11ExtAvailable || !mD3D11Available)
+ {
+ std::cout << "EGLDevice creation and/or D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ PFNEGLCREATEDEVICEANGLEPROC createDeviceANGLE =
+ (PFNEGLCREATEDEVICEANGLEPROC)eglGetProcAddress("eglCreateDeviceANGLE");
+ PFNEGLRELEASEDEVICEANGLEPROC releaseDeviceANGLE =
+ (PFNEGLRELEASEDEVICEANGLEPROC)eglGetProcAddress("eglReleaseDeviceANGLE");
+
+ EGLDeviceEXT eglDevice =
+ createDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_NE(EGL_NO_DEVICE_EXT, eglDevice);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib deviceAttrib;
+ eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, &deviceAttrib);
+ ASSERT_EGL_SUCCESS();
+
+ ID3D11Device *queriedDevice = reinterpret_cast<ID3D11Device *>(deviceAttrib);
+ ASSERT_EQ(mFeatureLevel, queriedDevice->GetFeatureLevel());
+
+ releaseDeviceANGLE(eglDevice);
+}
+
+// Test that creating a EGLDeviceEXT from D3D11 device works, and can be used for rendering
+TEST_F(EGLDeviceCreationTest, RenderingUsingD3D11Device)
+{
+ if (!mD3D11Available)
+ {
+ std::cout << "D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ EGLDeviceEXT eglDevice =
+ eglCreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ // Create an EGLDisplay using the EGLDevice
+ mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
+ ASSERT_NE(EGL_NO_DISPLAY, mDisplay);
+
+ // Create a surface using the display
+ CreateWindowSurface();
+
+ // Perform some very basic rendering
+ glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_EQ(32, 32, 255, 0, 255, 255);
+
+ // Note that we must call TearDown() before we release the EGL device, since the display
+ // depends on the device
+ TearDown();
+
+ eglReleaseDeviceANGLE(eglDevice);
+}
+
+// Test that ANGLE doesn't try to recreate a D3D11 device if the inputted one is lost
+TEST_F(EGLDeviceCreationTest, D3D11DeviceRecovery)
+{
+ if (!mD3D11Available)
+ {
+ std::cout << "D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ // Force Feature Level 9_3 so we can easily trigger a device lost later
+ CreateD3D11FL9_3Device();
+
+ EGLDeviceEXT eglDevice =
+ eglCreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ // Create an EGLDisplay using the EGLDevice
+ mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
+ ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
+
+ // Create a surface using the display
+ CreateWindowSurface();
+
+ // Perform some very basic rendering
+ glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_EQ(32, 32, 255, 0, 255, 255);
+ ASSERT_GL_NO_ERROR();
+
+ // ANGLE's SwapChain11::initPassThroughResources doesn't handle device lost before
+ // eglSwapBuffers, so we must call eglSwapBuffers before we lose the device.
+ ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));
+
+ // Trigger a lost device
+ trigger9_3DeviceLost();
+
+ // Destroy the old EGL Window Surface
+ if (mSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mDisplay, mSurface);
+ mSurface = EGL_NO_SURFACE;
+ }
+
+ // Try to create a new window surface. In certain configurations this will recreate the D3D11
+ // device. We want to test that it doesn't recreate the D3D11 device when EGLDeviceEXT is
+ // used. The window surface creation should fail if a new D3D11 device isn't created.
+ mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
+ ASSERT_EQ(EGL_NO_SURFACE, mSurface);
+ ASSERT_EGL_ERROR(EGL_BAD_ALLOC);
+
+ // Get the D3D11 device out of the EGLDisplay again. It should be the same one as above.
+ EGLAttrib device = 0;
+ EGLAttrib newEglDevice = 0;
+ ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &newEglDevice));
+ ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(newEglDevice),
+ EGL_D3D11_DEVICE_ANGLE, &device));
+ ID3D11Device *newDevice = reinterpret_cast<ID3D11Device *>(device);
+
+ ASSERT_EQ(reinterpret_cast<EGLDeviceEXT>(newEglDevice), eglDevice);
+ ASSERT_EQ(newDevice, mDevice);
+
+ // Note that we must call TearDown() before we release the EGL device, since the display
+ // depends on the device
+ TearDown();
+
+ eglReleaseDeviceANGLE(eglDevice);
+}
+
+// Test that calling eglGetPlatformDisplayEXT with the same device returns the same display
+TEST_F(EGLDeviceCreationTest, getPlatformDisplayTwice)
+{
+ if (!mD3D11Available)
+ {
+ std::cout << "D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ EGLDeviceEXT eglDevice =
+ eglCreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ // Create an EGLDisplay using the EGLDevice
+ EGLDisplay display1 = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
+ ASSERT_NE(EGL_NO_DISPLAY, display1);
+
+ EGLDisplay display2 = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
+ ASSERT_NE(EGL_NO_DISPLAY, display2);
+
+ ASSERT_EQ(display1, display2);
+
+ eglTerminate(display1);
+ eglReleaseDeviceANGLE(eglDevice);
+}
+
+// Test that creating a EGLDeviceEXT from an invalid D3D11 device fails
+TEST_F(EGLDeviceCreationTest, InvalidD3D11Device)
+{
+ if (!mDeviceCreationD3D11ExtAvailable || !mD3D11Available)
+ {
+ std::cout << "EGLDevice creation and/or D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ // Use mDeviceContext instead of mDevice
+ EGLDeviceEXT eglDevice = eglCreateDeviceANGLE(
+ EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDeviceContext), nullptr);
+ EXPECT_EQ(EGL_NO_DEVICE_EXT, eglDevice);
+ EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
+}
+
+// Test that EGLDeviceEXT holds a ref to the D3D11 device
+TEST_F(EGLDeviceCreationTest, D3D11DeviceReferenceCounting)
+{
+ if (!mDeviceCreationD3D11ExtAvailable || !mD3D11Available)
+ {
+ std::cout << "EGLDevice creation and/or D3D11 not available, skipping test" << std::endl;
+ return;
+ }
+
+ CreateD3D11Device();
+
+ EGLDeviceEXT eglDevice =
+ eglCreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, reinterpret_cast<void *>(mDevice), nullptr);
+ ASSERT_NE(EGL_NO_DEVICE_EXT, eglDevice);
+ ASSERT_EGL_SUCCESS();
+
+ // Now release our D3D11 device/context
+ SafeRelease(mDevice);
+ SafeRelease(mDeviceContext);
+
+ EGLAttrib deviceAttrib;
+ eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, &deviceAttrib);
+ ASSERT_EGL_SUCCESS();
+
+ ID3D11Device *queriedDevice = reinterpret_cast<ID3D11Device *>(deviceAttrib);
+ ASSERT_EQ(mFeatureLevel, queriedDevice->GetFeatureLevel());
+
+ eglReleaseDeviceANGLE(eglDevice);
+}
+
+// Test that creating a EGLDeviceEXT from a D3D9 device fails
+TEST_F(EGLDeviceCreationTest, AnyD3D9Device)
+{
+ if (!mDeviceCreationD3D11ExtAvailable)
+ {
+ std::cout << "EGLDevice creation not available, skipping test" << std::endl;
+ return;
+ }
+
+ std::string fakeD3DDevice = "This is a string, not a D3D device";
+
+ EGLDeviceEXT eglDevice = eglCreateDeviceANGLE(
+ EGL_D3D9_DEVICE_ANGLE, reinterpret_cast<void *>(&fakeD3DDevice), nullptr);
+ EXPECT_EQ(EGL_NO_DEVICE_EXT, eglDevice);
+ EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
+}
+
+class EGLDeviceQueryTest : public ANGLETest
+{
+ protected:
+ EGLDeviceQueryTest()
+ {
+ mQueryDisplayAttribEXT = nullptr;
+ mQueryDeviceAttribEXT = nullptr;
+ mQueryDeviceStringEXT = nullptr;
+ }
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ const char *extensionString =
+ static_cast<const char *>(eglQueryString(getEGLWindow()->getDisplay(), EGL_EXTENSIONS));
+ if (strstr(extensionString, "EGL_EXT_device_query"))
+ {
+ mQueryDisplayAttribEXT =
+ (PFNEGLQUERYDISPLAYATTRIBEXTPROC)eglGetProcAddress("eglQueryDisplayAttribEXT");
+ mQueryDeviceAttribEXT =
+ (PFNEGLQUERYDEVICEATTRIBEXTPROC)eglGetProcAddress("eglQueryDeviceAttribEXT");
+ mQueryDeviceStringEXT =
+ (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");
+ }
+
+ if (!mQueryDeviceStringEXT)
+ {
+ FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDeviceStringEXT was not "
+ "found";
+ }
+
+ if (!mQueryDisplayAttribEXT)
+ {
+ FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDisplayAttribEXT was "
+ "not found";
+ }
+
+ if (!mQueryDeviceAttribEXT)
+ {
+ FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDeviceAttribEXT was not "
+ "found";
+ }
+
+ EGLAttrib angleDevice = 0;
+ EXPECT_EGL_TRUE(
+ mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ extensionString = static_cast<const char *>(
+ mQueryDeviceStringEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_EXTENSIONS));
+ if (strstr(extensionString, "EGL_ANGLE_device_d3d") == NULL)
+ {
+ FAIL() << "ANGLE extension EGL_ANGLE_device_d3d was not found";
+ }
+ }
+
+ void TearDown() override { ANGLETest::TearDown(); }
+
+ PFNEGLQUERYDISPLAYATTRIBEXTPROC mQueryDisplayAttribEXT;
+ PFNEGLQUERYDEVICEATTRIBEXTPROC mQueryDeviceAttribEXT;
+ PFNEGLQUERYDEVICESTRINGEXTPROC mQueryDeviceStringEXT;
+};
+
+// This test attempts to obtain a D3D11 device and a D3D9 device using the eglQueryDeviceAttribEXT
+// function.
+// If the test is configured to use D3D11 then it should succeed to obtain a D3D11 device.
+// If the test is confitured to use D3D9, then it should succeed to obtain a D3D9 device.
+TEST_P(EGLDeviceQueryTest, QueryDevice)
+{
+ EGLAttrib device = 0;
+ EGLAttrib angleDevice = 0;
+ if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ EXPECT_EGL_TRUE(
+ mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EXPECT_EGL_TRUE(mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_D3D11_DEVICE_ANGLE, &device));
+ ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
+ IDXGIDevice *dxgiDevice = DynamicCastComObject<IDXGIDevice>(d3d11Device);
+ EXPECT_TRUE(dxgiDevice != nullptr);
+ SafeRelease(dxgiDevice);
+ }
+
+ if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+ {
+ EXPECT_EGL_TRUE(
+ mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EXPECT_EGL_TRUE(mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_D3D9_DEVICE_ANGLE, &device));
+ IDirect3DDevice9 *d3d9Device = reinterpret_cast<IDirect3DDevice9 *>(device);
+ IDirect3D9 *d3d9 = nullptr;
+ EXPECT_EQ(S_OK, d3d9Device->GetDirect3D(&d3d9));
+ EXPECT_TRUE(d3d9 != nullptr);
+ SafeRelease(d3d9);
+ }
+}
+
+// This test attempts to obtain a D3D11 device from a D3D9 configured system and a D3D9 device from
+// a D3D11 configured system using the eglQueryDeviceAttribEXT function.
+// If the test is configured to use D3D11 then it should fail to obtain a D3D11 device.
+// If the test is confitured to use D3D9, then it should fail to obtain a D3D9 device.
+TEST_P(EGLDeviceQueryTest, QueryDeviceBadAttribute)
+{
+ EGLAttrib device = 0;
+ EGLAttrib angleDevice = 0;
+ if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ EXPECT_EGL_TRUE(
+ mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EXPECT_EGL_FALSE(mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_D3D9_DEVICE_ANGLE, &device));
+ }
+
+ if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+ {
+ EXPECT_EGL_TRUE(
+ mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EXPECT_EGL_FALSE(mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_D3D11_DEVICE_ANGLE, &device));
+ }
+}
+
+// Ensure that:
+// - calling getPlatformDisplayEXT using ANGLE_Platform with some parameters
+// - extracting the EGLDeviceEXT from the EGLDisplay
+// - calling getPlatformDisplayEXT with this EGLDeviceEXT
+// results in the same EGLDisplay being returned from getPlatformDisplayEXT both times
+TEST_P(EGLDeviceQueryTest, getPlatformDisplayDeviceReuse)
+{
+ EGLAttrib eglDevice = 0;
+ EXPECT_EGL_TRUE(
+ eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &eglDevice));
+
+ EGLDisplay display2 = eglGetPlatformDisplayEXT(
+ EGL_PLATFORM_DEVICE_EXT, reinterpret_cast<EGLDeviceEXT>(eglDevice), nullptr);
+ EXPECT_EQ(getEGLWindow()->getDisplay(), display2);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these
+// tests should be run against.
+ANGLE_INSTANTIATE_TEST(EGLDeviceQueryTest, ES2_D3D9(), ES2_D3D11());
diff --git a/gfx/angle/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp b/gfx/angle/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp
new file mode 100755
index 000000000..c73c7c4ff
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp
@@ -0,0 +1,378 @@
+//
+// Copyright 2015 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.
+//
+
+#include "test_utils/ANGLETest.h"
+
+#include <cstdint>
+#include "com_utils.h"
+#include "OSWindow.h"
+#include <d3d11.h>
+
+using namespace angle;
+
+class EGLPresentPathD3D11 : public testing::TestWithParam<PlatformParameters>
+{
+ protected:
+ EGLPresentPathD3D11()
+ : mDisplay(EGL_NO_DISPLAY),
+ mContext(EGL_NO_CONTEXT),
+ mSurface(EGL_NO_SURFACE),
+ mOffscreenSurfaceD3D11Texture(nullptr),
+ mConfig(0),
+ mOSWindow(nullptr),
+ mWindowWidth(0)
+ {
+ }
+
+ void SetUp() override
+ {
+ mOSWindow = CreateOSWindow();
+ mWindowWidth = 64;
+ mOSWindow->initialize("EGLPresentPathD3D11", mWindowWidth, mWindowWidth);
+ }
+
+ void initializeEGL(bool usePresentPathFast)
+ {
+ int clientVersion = GetParam().majorVersion;
+
+ const char *extensionString =
+ static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
+ ASSERT_NE(nullptr, strstr(extensionString, "EGL_ANGLE_experimental_present_path"));
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
+ reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
+ eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ ASSERT_NE(nullptr, eglGetPlatformDisplayEXT);
+
+ // Set up EGL Display
+ EGLint displayAttribs[] = {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, GetParam().eglParameters.majorVersion,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, GetParam().eglParameters.majorVersion,
+ EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
+ usePresentPathFast ? EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE
+ : EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE,
+ EGL_NONE};
+ mDisplay =
+ eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttribs);
+ ASSERT_TRUE(EGL_NO_DISPLAY != mDisplay);
+ ASSERT_EGL_TRUE(eglInitialize(mDisplay, NULL, NULL));
+
+ // Choose the EGL config
+ EGLint numConfigs;
+ EGLint configAttribs[] = {EGL_RED_SIZE,
+ 8,
+ EGL_GREEN_SIZE,
+ 8,
+ EGL_BLUE_SIZE,
+ 8,
+ EGL_ALPHA_SIZE,
+ 8,
+ EGL_RENDERABLE_TYPE,
+ clientVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE,
+ EGL_PBUFFER_BIT,
+ EGL_NONE};
+ ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &mConfig, 1, &numConfigs));
+ ASSERT_EQ(1, numConfigs);
+
+ // Set up the EGL context
+ EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL_NONE};
+ mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttribs);
+ ASSERT_TRUE(EGL_NO_CONTEXT != mContext);
+ }
+
+ void createWindowSurface()
+ {
+ mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
+ }
+
+ void createPbufferFromClientBufferSurface()
+ {
+ EGLAttrib device = 0;
+ EGLAttrib angleDevice = 0;
+
+ PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
+ PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
+
+ const char *extensionString =
+ static_cast<const char *>(eglQueryString(mDisplay, EGL_EXTENSIONS));
+ EXPECT_TRUE(strstr(extensionString, "EGL_EXT_device_query"));
+
+ queryDisplayAttribEXT =
+ (PFNEGLQUERYDISPLAYATTRIBEXTPROC)eglGetProcAddress("eglQueryDisplayAttribEXT");
+ queryDeviceAttribEXT =
+ (PFNEGLQUERYDEVICEATTRIBEXTPROC)eglGetProcAddress("eglQueryDeviceAttribEXT");
+ ASSERT_NE(nullptr, queryDisplayAttribEXT);
+ ASSERT_NE(nullptr, queryDeviceAttribEXT);
+
+ ASSERT_EGL_TRUE(queryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &angleDevice));
+ ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_D3D11_DEVICE_ANGLE, &device));
+ ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
+
+ D3D11_TEXTURE2D_DESC textureDesc = {0};
+ textureDesc.Width = mWindowWidth;
+ textureDesc.Height = mWindowWidth;
+ textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ textureDesc.MipLevels = 1;
+ textureDesc.ArraySize = 1;
+ textureDesc.SampleDesc.Count = 1;
+ textureDesc.SampleDesc.Quality = 0;
+ textureDesc.Usage = D3D11_USAGE_DEFAULT;
+ textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+ textureDesc.CPUAccessFlags = 0;
+ textureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
+
+ ASSERT_TRUE(SUCCEEDED(
+ d3d11Device->CreateTexture2D(&textureDesc, nullptr, &mOffscreenSurfaceD3D11Texture)));
+
+ IDXGIResource *dxgiResource =
+ DynamicCastComObject<IDXGIResource>(mOffscreenSurfaceD3D11Texture);
+ ASSERT_NE(nullptr, dxgiResource);
+
+ HANDLE sharedHandle = 0;
+ ASSERT_TRUE(SUCCEEDED(dxgiResource->GetSharedHandle(&sharedHandle)));
+ SafeRelease(dxgiResource);
+
+ EGLint pBufferAttributes[] = {EGL_WIDTH, mWindowWidth, EGL_HEIGHT,
+ mWindowWidth, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_NONE};
+
+ mSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
+ sharedHandle, mConfig, pBufferAttributes);
+ ASSERT_TRUE(EGL_NO_SURFACE != mSurface);
+ }
+
+ void makeCurrent() { ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)); }
+
+ void TearDown() override
+ {
+ SafeRelease(mOffscreenSurfaceD3D11Texture);
+
+ if (mDisplay != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (mSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mDisplay, mSurface);
+ mSurface = EGL_NO_SURFACE;
+ }
+
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(mDisplay, mContext);
+ mContext = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(mDisplay);
+ mDisplay = EGL_NO_DISPLAY;
+ }
+
+ mOSWindow->destroy();
+ SafeDelete(mOSWindow);
+ }
+
+ void drawQuadUsingGL()
+ {
+ GLuint m2DProgram;
+ GLint mTexture2DUniformLocation;
+
+ const std::string vertexShaderSource =
+ SHADER_SOURCE(precision highp float; attribute vec4 position; varying vec2 texcoord;
+
+ void main()
+ {
+ gl_Position = vec4(position.xy, 0.0, 1.0);
+ texcoord = (position.xy * 0.5) + 0.5;
+ });
+
+ const std::string fragmentShaderSource2D =
+ SHADER_SOURCE(precision highp float; uniform sampler2D tex; varying vec2 texcoord;
+
+ void main()
+ {
+ gl_FragColor = texture2D(tex, texcoord);
+ });
+
+ m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
+ mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
+
+ uint8_t textureInitData[16] = {
+ 255, 0, 0, 255, // Red
+ 0, 255, 0, 255, // Green
+ 0, 0, 255, 255, // Blue
+ 255, 255, 0, 255 // Red + Green
+ };
+
+ // Create a simple RGBA texture
+ GLuint tex = 0;
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ textureInitData);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ // Draw a quad using the texture
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUseProgram(m2DProgram);
+ glUniform1i(mTexture2DUniformLocation, 0);
+
+ GLint positionLocation = glGetAttribLocation(m2DProgram, "position");
+ glUseProgram(m2DProgram);
+ const GLfloat vertices[] =
+ {
+ -1.0f, 1.0f, 0.5f,
+ -1.0f, -1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+ -1.0f, 1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+ 1.0f, 1.0f, 0.5f,
+ };
+
+ glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
+ glEnableVertexAttribArray(positionLocation);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ ASSERT_GL_NO_ERROR();
+
+ glDeleteProgram(m2DProgram);
+ }
+
+ void checkPixelsUsingGL()
+ {
+ // Note that the texture is in BGRA format
+ EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); // Red
+ EXPECT_PIXEL_EQ(mWindowWidth - 1, 0, 0, 255, 0, 255); // Green
+ EXPECT_PIXEL_EQ(0, mWindowWidth - 1, 0, 0, 255, 255); // Blue
+ EXPECT_PIXEL_EQ(mWindowWidth - 1, mWindowWidth - 1, 255, 255, 0, 255); // Red + green
+ }
+
+ void checkPixelsUsingD3D(bool usingPresentPathFast)
+ {
+ ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture);
+
+ D3D11_TEXTURE2D_DESC textureDesc = {0};
+ ID3D11Device *device;
+ ID3D11DeviceContext *context;
+ mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc);
+ mOffscreenSurfaceD3D11Texture->GetDevice(&device);
+ device->GetImmediateContext(&context);
+ ASSERT_NE(nullptr, device);
+ ASSERT_NE(nullptr, context);
+
+ textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ textureDesc.Usage = D3D11_USAGE_STAGING;
+ textureDesc.BindFlags = 0;
+ textureDesc.MiscFlags = 0;
+ ID3D11Texture2D *cpuTexture = nullptr;
+ ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture)));
+
+ context->CopyResource(cpuTexture, mOffscreenSurfaceD3D11Texture);
+
+ D3D11_MAPPED_SUBRESOURCE mappedSubresource;
+ context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource);
+ ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch);
+ ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch);
+
+ angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData);
+
+ // Note that the texture is in BGRA format, although the GLColor struct is RGBA
+ GLColor expectedTopLeftPixel = GLColor(0, 0, 255, 255); // Red
+ GLColor expectedTopRightPixel = GLColor(0, 255, 0, 255); // Green
+ GLColor expectedBottomLeftPixel = GLColor(255, 0, 0, 255); // Blue
+ GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255); // Red + Green
+
+ if (usingPresentPathFast)
+ {
+ // Invert the expected values
+ GLColor tempTopLeft = expectedTopLeftPixel;
+ GLColor tempTopRight = expectedTopRightPixel;
+ expectedTopLeftPixel = expectedBottomLeftPixel;
+ expectedTopRightPixel = expectedBottomRightPixel;
+ expectedBottomLeftPixel = tempTopLeft;
+ expectedBottomRightPixel = tempTopRight;
+ }
+
+ EXPECT_EQ(expectedTopLeftPixel, byteData[0]);
+ EXPECT_EQ(expectedTopRightPixel, byteData[(mWindowWidth - 1)]);
+ EXPECT_EQ(expectedBottomLeftPixel, byteData[(mWindowWidth - 1) * mWindowWidth]);
+ EXPECT_EQ(expectedBottomRightPixel,
+ byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]);
+
+ context->Unmap(cpuTexture, 0);
+ SafeRelease(cpuTexture);
+ SafeRelease(device);
+ SafeRelease(context);
+ }
+
+ EGLDisplay mDisplay;
+ EGLContext mContext;
+ EGLSurface mSurface;
+ ID3D11Texture2D *mOffscreenSurfaceD3D11Texture;
+ EGLConfig mConfig;
+ OSWindow *mOSWindow;
+ GLint mWindowWidth;
+};
+
+// Test that rendering basic content onto a window surface when present path fast
+// is enabled works as expected
+TEST_P(EGLPresentPathD3D11, WindowPresentPathFast)
+{
+ initializeEGL(true);
+ createWindowSurface();
+ makeCurrent();
+
+ drawQuadUsingGL();
+
+ checkPixelsUsingGL();
+}
+
+// Test that rendering basic content onto a client buffer surface when present path fast
+// works as expected, and is also oriented the correct way around
+TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathFast)
+{
+ initializeEGL(true);
+ createPbufferFromClientBufferSurface();
+ makeCurrent();
+
+ drawQuadUsingGL();
+
+ checkPixelsUsingGL();
+ checkPixelsUsingD3D(true);
+}
+
+// Test that rendering basic content onto a window surface when present path fast
+// is disabled works as expected
+TEST_P(EGLPresentPathD3D11, WindowPresentPathCopy)
+{
+ initializeEGL(false);
+ createWindowSurface();
+ makeCurrent();
+
+ drawQuadUsingGL();
+
+ checkPixelsUsingGL();
+}
+
+// Test that rendering basic content onto a client buffer surface when present path
+// fast is disabled works as expected, and is also oriented the correct way around
+TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathCopy)
+{
+ initializeEGL(false);
+ createPbufferFromClientBufferSurface();
+ makeCurrent();
+
+ drawQuadUsingGL();
+
+ checkPixelsUsingGL();
+ checkPixelsUsingD3D(false);
+}
+
+ANGLE_INSTANTIATE_TEST(EGLPresentPathD3D11, ES2_D3D11(), ES2_D3D11_FL9_3()); \ No newline at end of file
diff --git a/gfx/angle/src/tests/egl_tests/EGLQueryContextTest.cpp b/gfx/angle/src/tests/egl_tests/EGLQueryContextTest.cpp
new file mode 100755
index 000000000..ff4a43f23
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLQueryContextTest.cpp
@@ -0,0 +1,153 @@
+//
+// Copyright (c) 2015 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.
+//
+
+#include <gtest/gtest.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "test_utils/angle_test_configs.h"
+
+using namespace angle;
+
+class EGLQueryContextTest : public testing::TestWithParam<PlatformParameters>
+{
+ public:
+ void SetUp() override
+ {
+ int clientVersion = GetParam().majorVersion;
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ EXPECT_TRUE(eglGetPlatformDisplayEXT != NULL);
+
+ EGLint dispattrs[] =
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
+ EGL_NONE
+ };
+ mDisplay = eglGetPlatformDisplayEXT(
+ EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
+ EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
+ EXPECT_TRUE(eglInitialize(mDisplay, NULL, NULL) != EGL_FALSE);
+
+ EGLint ncfg;
+ EGLint cfgattrs[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_RENDERABLE_TYPE, clientVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_NONE
+ };
+ EXPECT_TRUE(eglChooseConfig(mDisplay, cfgattrs, &mConfig, 1, &ncfg) != EGL_FALSE);
+ EXPECT_TRUE(ncfg == 1);
+
+ EGLint ctxattrs[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, clientVersion,
+ EGL_NONE
+ };
+ mContext = eglCreateContext(mDisplay, mConfig, NULL, ctxattrs);
+ EXPECT_TRUE(mContext != EGL_NO_CONTEXT);
+
+ EGLint surfattrs[] =
+ {
+ EGL_WIDTH, 16,
+ EGL_HEIGHT, 16,
+ EGL_NONE
+ };
+ mSurface = eglCreatePbufferSurface(mDisplay, mConfig, surfattrs);
+ EXPECT_TRUE(mSurface != EGL_NO_SURFACE);
+ }
+
+ void TearDown() override
+ {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(mDisplay, mContext);
+ eglDestroySurface(mDisplay, mSurface);
+ eglTerminate(mDisplay);
+ }
+
+ EGLDisplay mDisplay;
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mSurface;
+};
+
+TEST_P(EGLQueryContextTest, GetConfigID)
+{
+ EGLint configId, contextConfigId;
+ EXPECT_TRUE(eglGetConfigAttrib(mDisplay, mConfig, EGL_CONFIG_ID, &configId) != EGL_FALSE);
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_CONFIG_ID, &contextConfigId) != EGL_FALSE);
+ EXPECT_TRUE(configId == contextConfigId);
+}
+
+TEST_P(EGLQueryContextTest, GetClientType)
+{
+ EGLint clientType;
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_CONTEXT_CLIENT_TYPE, &clientType) != EGL_FALSE);
+ EXPECT_TRUE(clientType == EGL_OPENGL_ES_API);
+}
+
+TEST_P(EGLQueryContextTest, GetClientVersion)
+{
+ EGLint clientVersion;
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_CONTEXT_CLIENT_VERSION, &clientVersion) != EGL_FALSE);
+ EXPECT_TRUE(clientVersion == GetParam().majorVersion);
+}
+
+TEST_P(EGLQueryContextTest, GetRenderBufferNoSurface)
+{
+ EGLint renderBuffer;
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_RENDER_BUFFER, &renderBuffer) != EGL_FALSE);
+ EXPECT_TRUE(renderBuffer == EGL_NONE);
+}
+
+TEST_P(EGLQueryContextTest, GetRenderBufferBoundSurface)
+{
+ EGLint renderBuffer, contextRenderBuffer;
+ EXPECT_TRUE(eglQuerySurface(mDisplay, mSurface, EGL_RENDER_BUFFER, &renderBuffer) != EGL_FALSE);
+ EXPECT_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContext) != EGL_FALSE);
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_RENDER_BUFFER, &contextRenderBuffer) != EGL_FALSE);
+ EXPECT_TRUE(renderBuffer == contextRenderBuffer);
+}
+
+TEST_P(EGLQueryContextTest, BadDisplay)
+{
+ EGLint val;
+ EXPECT_TRUE(eglQueryContext(EGL_NO_DISPLAY, mContext, EGL_CONTEXT_CLIENT_TYPE, &val) == EGL_FALSE);
+ EXPECT_TRUE(eglGetError() == EGL_BAD_DISPLAY);
+}
+
+TEST_P(EGLQueryContextTest, NotInitialized)
+{
+ EGLint val;
+ TearDown();
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_CONTEXT_CLIENT_TYPE, &val) == EGL_FALSE);
+ EXPECT_TRUE(eglGetError() == EGL_NOT_INITIALIZED);
+
+ mDisplay = EGL_NO_DISPLAY;
+ mSurface = EGL_NO_SURFACE;
+ mContext = EGL_NO_CONTEXT;
+}
+
+TEST_P(EGLQueryContextTest, BadContext)
+{
+ EGLint val;
+ EXPECT_TRUE(eglQueryContext(mDisplay, EGL_NO_CONTEXT, EGL_CONTEXT_CLIENT_TYPE, &val) == EGL_FALSE);
+ EXPECT_TRUE(eglGetError() == EGL_BAD_CONTEXT);
+}
+
+TEST_P(EGLQueryContextTest, BadAttribute)
+{
+ EGLint val;
+ EXPECT_TRUE(eglQueryContext(mDisplay, mContext, EGL_HEIGHT, &val) == EGL_FALSE);
+ EXPECT_TRUE(eglGetError() == EGL_BAD_ATTRIBUTE);
+}
+
+ANGLE_INSTANTIATE_TEST(EGLQueryContextTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL(),
+ ES3_D3D11(), ES3_OPENGL());
diff --git a/gfx/angle/src/tests/egl_tests/EGLRobustnessTest.cpp b/gfx/angle/src/tests/egl_tests/EGLRobustnessTest.cpp
new file mode 100755
index 000000000..0482a7fe5
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLRobustnessTest.cpp
@@ -0,0 +1,234 @@
+//
+// Copyright (c) 2016 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.
+//
+
+// EGLRobustnessTest.cpp: tests for EGL_EXT_create_context_robustness
+
+#include <gtest/gtest.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+class EGLRobustnessTest : public ::testing::TestWithParam<angle::PlatformParameters>
+{
+ public:
+ void SetUp() override
+ {
+ mOSWindow = CreateOSWindow();
+ mOSWindow->initialize("EGLRobustnessTest", 500, 500);
+ mOSWindow->setVisible(true);
+
+ auto eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
+ eglGetProcAddress("eglGetPlatformDisplayEXT"));
+
+ const auto &platform = GetParam().eglParameters;
+
+ std::vector<EGLint> displayAttributes;
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ displayAttributes.push_back(platform.renderer);
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
+ displayAttributes.push_back(platform.majorVersion);
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
+ displayAttributes.push_back(platform.minorVersion);
+
+ if (platform.deviceType != EGL_DONT_CARE)
+ {
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
+ displayAttributes.push_back(platform.deviceType);
+ }
+
+ displayAttributes.push_back(EGL_NONE);
+
+ mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
+ reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
+ &displayAttributes[0]);
+ ASSERT_NE(EGL_NO_DISPLAY, mDisplay);
+
+ ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);
+
+ const char *extensions = eglQueryString(mDisplay, EGL_EXTENSIONS);
+ if (strstr(extensions, "EGL_EXT_create_context_robustness") == nullptr)
+ {
+ std::cout << "Test skipped due to missing EGL_EXT_create_context_robustness"
+ << std::endl;
+ return;
+ }
+
+ int nConfigs = 0;
+ ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);
+ ASSERT_LE(1, nConfigs);
+
+ int nReturnedConfigs = 0;
+ ASSERT_TRUE(eglGetConfigs(mDisplay, &mConfig, 1, &nReturnedConfigs) == EGL_TRUE);
+ ASSERT_EQ(1, nReturnedConfigs);
+
+ mWindow = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ mInitialized = true;
+ }
+
+ void TearDown() override
+ {
+ eglDestroySurface(mDisplay, mWindow);
+ eglDestroyContext(mDisplay, mContext);
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(mDisplay);
+ EXPECT_EGL_SUCCESS();
+
+ SafeDelete(mOSWindow);
+ }
+
+ void createContext(EGLint resetStrategy)
+ {
+ const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
+ resetStrategy, EGL_NONE};
+ mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, contextAttribs);
+ ASSERT_NE(EGL_NO_CONTEXT, mContext);
+
+ eglMakeCurrent(mDisplay, mWindow, mWindow, mContext);
+ ASSERT_EGL_SUCCESS();
+
+ const char *extensionString = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ ASSERT_NE(nullptr, strstr(extensionString, "GL_ANGLE_instanced_arrays"));
+
+ mDrawElementsInstancedANGLE =
+ (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)eglGetProcAddress("glDrawElementsInstancedANGLE");
+ ASSERT_NE(nullptr, mDrawElementsInstancedANGLE);
+ }
+
+ void forceContextReset()
+ {
+ // Cause a GPU reset by drawing 100,000,000 fullscreen quads
+ GLuint program = CompileProgram(
+ "attribute vec4 pos;\n"
+ "void main() {gl_Position = pos;}\n",
+ "precision mediump float;\n"
+ "void main() {gl_FragColor = vec4(1.0);}\n");
+ ASSERT_NE(0u, program);
+ glUseProgram(program);
+
+ GLfloat vertices[] = {
+ -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+ };
+
+ const int kNumQuads = 10000;
+ std::vector<GLushort> indices(6 * kNumQuads);
+
+ for (size_t i = 0; i < kNumQuads; i++)
+ {
+ indices[i * 6 + 0] = 0;
+ indices[i * 6 + 1] = 1;
+ indices[i * 6 + 2] = 2;
+ indices[i * 6 + 3] = 1;
+ indices[i * 6 + 4] = 2;
+ indices[i * 6 + 5] = 3;
+ }
+
+ glBindAttribLocation(program, 0, "pos");
+ glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, vertices);
+ glEnableVertexAttribArray(0);
+
+ glViewport(0, 0, mOSWindow->getWidth(), mOSWindow->getHeight());
+ glClearColor(1.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ mDrawElementsInstancedANGLE(GL_TRIANGLES, kNumQuads * 6, GL_UNSIGNED_SHORT, indices.data(),
+ 10000);
+
+ glFinish();
+ }
+
+ protected:
+ EGLDisplay mDisplay = EGL_NO_DISPLAY;
+ EGLSurface mWindow = EGL_NO_SURFACE;
+ bool mInitialized = false;
+ PFNGLDRAWELEMENTSINSTANCEDANGLEPROC mDrawElementsInstancedANGLE = nullptr;
+
+ private:
+ EGLContext mContext = EGL_NO_CONTEXT;
+ EGLConfig mConfig = 0;
+ OSWindow *mOSWindow = nullptr;
+};
+
+// Check glGetGraphicsResetStatusEXT returns GL_NO_ERROR if we did nothing
+TEST_P(EGLRobustnessTest, NoErrorByDefault)
+{
+ if (!mInitialized)
+ {
+ return;
+ }
+ ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);
+}
+
+// Checks that the application gets no loss with NO_RESET_NOTIFICATION
+TEST_P(EGLRobustnessTest, DISABLED_NoResetNotification)
+{
+ if (!mInitialized)
+ {
+ return;
+ }
+
+ createContext(EGL_NO_RESET_NOTIFICATION_EXT);
+
+ if (!IsWindows())
+ {
+ std::cout << "Test disabled on non Windows platforms because drivers can't recover. "
+ << "See " << __FILE__ << ":" << __LINE__ << std::endl;
+ return;
+ }
+ std::cout << "Causing a GPU reset, brace for impact." << std::endl;
+
+ forceContextReset();
+ ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);
+}
+
+// Checks that resetting the ANGLE display allows to get rid of the context loss.
+// Also checks that the application gets notified of the loss of the display.
+// We coalesce both tests to reduce the number of TDRs done on Windows: by default
+// having more than 5 TDRs in a minute will cause Windows to disable the GPU until
+// the computer is rebooted.
+TEST_P(EGLRobustnessTest, DISABLED_ResettingDisplayWorks)
+{
+ if (!mInitialized)
+ {
+ return;
+ }
+
+ createContext(EGL_LOSE_CONTEXT_ON_RESET_EXT);
+
+ if (!IsWindows())
+ {
+ std::cout << "Test disabled on non Windows platforms because drivers can't recover. "
+ << "See " << __FILE__ << ":" << __LINE__ << std::endl;
+ return;
+ }
+ std::cout << "Causing a GPU reset, brace for impact." << std::endl;
+
+ forceContextReset();
+ ASSERT_TRUE(glGetGraphicsResetStatusEXT() != GL_NO_ERROR);
+
+ TearDown();
+ SetUp();
+ ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);
+}
+
+// Tests causing GPU resets are disabled, use the following args to run them:
+// --gtest_also_run_disabled_tests --gtest_filter=EGLRobustnessTest\*
+
+// Note that on Windows the OpenGL driver fails hard (popup that closes the application)
+// if there was a TDR caused by D3D so we don't run D3D tests at the same time as the OpenGL tests.
+#define D3D_HAS_PRIORITY 1
+#if D3D_HAS_PRIORITY && (defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11))
+ANGLE_INSTANTIATE_TEST(EGLRobustnessTest, ES2_D3D9(), ES2_D3D11());
+#else
+ANGLE_INSTANTIATE_TEST(EGLRobustnessTest, ES2_OPENGL());
+#endif
diff --git a/gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp b/gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
new file mode 100755
index 000000000..b92f9bc16
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright 2015 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.
+//
+
+// EGLSanityCheckTest.cpp:
+// tests used to check setup in which tests are run.
+
+#include <gtest/gtest.h>
+
+#include "test_utils/ANGLETest.h"
+
+// Checks the tests are running against ANGLE
+TEST(EGLSanityCheckTest, IsRunningOnANGLE)
+{
+ const char *extensionString =
+ static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
+ ASSERT_NE(strstr(extensionString, "EGL_ANGLE_platform_angle"), nullptr);
+}
+
+// Checks that getting function pointer works
+TEST(EGLSanityCheckTest, HasGetPlatformDisplayEXT)
+{
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
+ reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
+ eglGetProcAddress("eglGetPlatformDisplayEXT"));
+
+ ASSERT_NE(eglGetPlatformDisplayEXT, nullptr);
+}
diff --git a/gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp b/gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
new file mode 100755
index 000000000..b667cf778
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
@@ -0,0 +1,547 @@
+//
+// Copyright 2016 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.
+//
+// EGLStreamTest:
+// Tests pertaining to egl::Stream.
+//
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "media/yuvtest.inl"
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+namespace
+{
+
+class EGLStreamTest : public ANGLETest
+{
+ protected:
+ EGLStreamTest()
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ }
+};
+
+// Tests validation of the stream API
+TEST_P(EGLStreamTest, StreamValidationTest)
+{
+ EGLWindow *window = getEGLWindow();
+ EGLDisplay display = window->getDisplay();
+ const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_KHR_stream") == nullptr)
+ {
+ std::cout << "Stream extension not supported" << std::endl;
+ return;
+ }
+
+ const EGLint streamAttributesBad[] = {
+ EGL_STREAM_STATE_KHR,
+ 0,
+ EGL_NONE,
+ EGL_PRODUCER_FRAME_KHR,
+ 0,
+ EGL_NONE,
+ EGL_CONSUMER_FRAME_KHR,
+ 0,
+ EGL_NONE,
+ EGL_CONSUMER_LATENCY_USEC_KHR,
+ -1,
+ EGL_NONE,
+ EGL_RED_SIZE,
+ EGL_DONT_CARE,
+ EGL_NONE,
+ };
+
+ // Validate create stream attributes
+ EGLStreamKHR stream = eglCreateStreamKHR(display, &streamAttributesBad[0]);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ stream = eglCreateStreamKHR(display, &streamAttributesBad[3]);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ stream = eglCreateStreamKHR(display, &streamAttributesBad[6]);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ stream = eglCreateStreamKHR(display, &streamAttributesBad[9]);
+ ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ stream = eglCreateStreamKHR(display, &streamAttributesBad[12]);
+ ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ const EGLint streamAttributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_NONE,
+ };
+
+ stream = eglCreateStreamKHR(EGL_NO_DISPLAY, streamAttributes);
+ ASSERT_EGL_ERROR(EGL_BAD_DISPLAY);
+ ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
+
+ // Create an actual stream
+ stream = eglCreateStreamKHR(display, streamAttributes);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_NE(EGL_NO_STREAM_KHR, stream);
+
+ // Assert it is in the created state
+ EGLint state;
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_CREATED_KHR, state);
+
+ // Test getting and setting the latency
+ EGLint latency = 10;
+ eglStreamAttribKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, latency);
+ ASSERT_EGL_SUCCESS();
+ eglQueryStreamKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, &latency);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(10, latency);
+ eglStreamAttribKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, -1);
+ ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
+ ASSERT_EQ(10, latency);
+
+ // Test the 64-bit queries
+ EGLuint64KHR value;
+ eglQueryStreamu64KHR(display, stream, EGL_CONSUMER_FRAME_KHR, &value);
+ ASSERT_EGL_SUCCESS();
+ eglQueryStreamu64KHR(display, stream, EGL_PRODUCER_FRAME_KHR, &value);
+ ASSERT_EGL_SUCCESS();
+
+ // Destroy the stream
+ eglDestroyStreamKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+}
+
+// Tests validation of stream consumer gltexture API
+TEST_P(EGLStreamTest, StreamConsumerGLTextureValidationTest)
+{
+ EGLWindow *window = getEGLWindow();
+ EGLDisplay display = window->getDisplay();
+ const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_KHR_stream_consumer_gltexture") == nullptr)
+ {
+ std::cout << "Stream consumer gltexture extension not supported" << std::endl;
+ return;
+ }
+
+ const EGLint streamAttributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
+ };
+
+ EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
+ ASSERT_EGL_SUCCESS();
+
+ EGLBoolean result = eglStreamConsumerGLTextureExternalKHR(display, stream);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+
+ GLuint tex;
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
+ result = eglStreamConsumerGLTextureExternalKHR(display, stream);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLint state;
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_CONNECTING_KHR, state);
+
+ eglDestroyStreamKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+}
+
+// Tests validation of stream consumer gltexture yuv API
+TEST_P(EGLStreamTest, StreamConsumerGLTextureYUVValidationTest)
+{
+ EGLWindow *window = getEGLWindow();
+ EGLDisplay display = window->getDisplay();
+ const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_NV_stream_consumer_gltexture_yuv") == nullptr)
+ {
+ std::cout << "Stream consumer gltexture yuv extension not supported" << std::endl;
+ return;
+ }
+
+ const EGLint streamAttributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
+ };
+
+ EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib consumerAttributesBad[] = {
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT, // 0
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 0,
+ EGL_NONE,
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT, // 5
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 1,
+ EGL_NONE,
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT, // 10
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 1,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 9999,
+ EGL_NONE,
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT, // 17
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 1,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 1,
+ EGL_NONE,
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT, // 26
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 2,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 0,
+ EGL_NONE,
+ };
+
+ EGLAttrib consumerAttributes[] = {
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT,
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 2,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 1,
+ EGL_NONE,
+ };
+
+ EGLBoolean result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[0]);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_MATCH);
+
+ result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[5]);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_MATCH);
+
+ result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[10]);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+
+ result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[17]);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_MATCH);
+
+ result = eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+
+ GLuint tex[2];
+ glGenTextures(2, tex);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
+
+ result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[26]);
+ ASSERT_EGL_FALSE(result);
+ ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
+
+ result = eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLint state;
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_CONNECTING_KHR, state);
+
+ eglDestroyStreamKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+}
+
+// Tests that deleting a texture invalidates the associated stream
+TEST_P(EGLStreamTest, StreamConsumerGLTextureYUVDeletionTest)
+{
+ EGLWindow *window = getEGLWindow();
+ EGLDisplay display = window->getDisplay();
+ const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture_nv12") == nullptr)
+ {
+ std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
+ return;
+ }
+
+ const EGLint streamAttributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
+ };
+
+ EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib consumerAttributes[] = {
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT,
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 2,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 1,
+ EGL_NONE,
+ };
+
+ GLuint tex[2];
+ glGenTextures(2, tex);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
+
+ EGLBoolean result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib producerAttributes[] = {
+ EGL_NONE,
+ };
+
+ result = eglCreateStreamProducerD3DTextureNV12ANGLE(display, stream, producerAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLint state;
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_EMPTY_KHR, state);
+
+ // Delete the first texture, which should be enough to invalidate the stream
+ glDeleteTextures(1, tex);
+
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_DISCONNECTED_KHR, state);
+
+ eglDestroyStreamKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+}
+
+// End2end test for rendering an NV12 texture. Renders a YUV quad, reads back the RGB values, and
+// ensures they are correct
+TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End)
+{
+ EGLWindow *window = getEGLWindow();
+ EGLDisplay display = window->getDisplay();
+ if (!eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture_nv12"))
+ {
+ std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
+ return;
+ }
+
+ bool useESSL3Shaders =
+ getClientMajorVersion() >= 3 && extensionEnabled("GL_OES_EGL_image_external_essl3");
+
+ // yuv to rgb conversion shader using Microsoft's given conversion formulas
+ std::string yuvVS, yuvPS;
+ if (useESSL3Shaders)
+ {
+ yuvVS =
+ "#version 300 es\n"
+ "in highp vec4 position;\n"
+ "out vec2 texcoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ " texcoord.y = 1.0 - texcoord.y;\n"
+ "}\n";
+ yuvPS =
+ "#version 300 es\n"
+ "#extension GL_OES_EGL_image_external_essl3 : require\n"
+ "#extension GL_NV_EGL_stream_consumer_external : require\n"
+ "precision highp float;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 color;\n"
+ "uniform samplerExternalOES y;\n"
+ "uniform samplerExternalOES uv\n;"
+ "void main(void)\n"
+ "{\n"
+ " float c = texture(y, texcoord).r - (16.0 / 256.0);\n"
+ " float d = texture(uv, texcoord).r - 0.5;\n"
+ " float e = texture(uv, texcoord).g - 0.5;\n"
+ " float r = 1.164383 * c + 1.596027 * e;\n"
+ " float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
+ " float b = 1.164383 * c + 2.017232 * d;\n"
+ " color = vec4(r, g, b, 1.0);\n"
+ "}\n";
+ }
+ else
+ {
+ yuvVS =
+ "attribute highp vec4 position;\n"
+ "varying vec2 texcoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ " texcoord.y = 1.0 - texcoord.y;\n"
+ "}\n";
+
+ yuvPS =
+ "#extension GL_NV_EGL_stream_consumer_external : require\n"
+ "precision highp float;\n"
+ "varying vec2 texcoord;\n"
+ "uniform samplerExternalOES y;\n"
+ "uniform samplerExternalOES uv\n;"
+ "void main(void)\n"
+ "{\n"
+ " float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n"
+ " float d = texture2D(uv, texcoord).r - 0.5;\n"
+ " float e = texture2D(uv, texcoord).g - 0.5;\n"
+ " float r = 1.164383 * c + 1.596027 * e;\n"
+ " float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
+ " float b = 1.164383 * c + 2.017232 * d;\n"
+ " gl_FragColor = vec4(r, g, b, 1.0);\n"
+ "}\n";
+ }
+
+ GLuint program = CompileProgram(yuvVS, yuvPS);
+ ASSERT_NE(0u, program);
+ GLuint yUniform = glGetUniformLocation(program, "y");
+ GLuint uvUniform = glGetUniformLocation(program, "uv");
+
+ // Fetch the D3D11 device
+ EGLDeviceEXT eglDevice;
+ eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, (EGLAttrib *)&eglDevice);
+ ID3D11Device *device;
+ eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, (EGLAttrib *)&device);
+
+ // Create the NV12 D3D11 texture
+ HRESULT res;
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = yuvtest_width;
+ desc.Height = yuvtest_height;
+ desc.Format = DXGI_FORMAT_NV12;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ D3D11_SUBRESOURCE_DATA subres;
+ subres.pSysMem = yuvtest_data;
+ subres.SysMemPitch = yuvtest_width;
+ subres.SysMemSlicePitch = yuvtest_width * yuvtest_height * 3 / 2;
+
+ ID3D11Texture2D *texture = nullptr;
+ res = device->CreateTexture2D(&desc, &subres, &texture);
+
+ // Create the stream
+ const EGLint streamAttributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
+ };
+
+ EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib consumerAttributes[] = {
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT,
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 2,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 1,
+ EGL_NONE,
+ };
+
+ GLuint tex[2];
+ glGenTextures(2, tex);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ASSERT_GL_NO_ERROR();
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ASSERT_GL_NO_ERROR();
+
+ EGLBoolean result =
+ eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLAttrib producerAttributes[] = {
+ EGL_NONE,
+ };
+
+ result = eglCreateStreamProducerD3DTextureNV12ANGLE(display, stream, producerAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ // Insert the frame
+ EGLAttrib frameAttributes[] = {
+ EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE,
+ };
+ result = eglStreamPostD3DTextureNV12ANGLE(display, stream, (void *)texture, frameAttributes);
+ ASSERT_EGL_TRUE(result);
+ ASSERT_EGL_SUCCESS();
+
+ EGLint state;
+ eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR, state);
+
+ eglStreamConsumerAcquireKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+
+ glUseProgram(program);
+ glUniform1i(yUniform, 0);
+ glUniform1i(uvUniform, 1);
+ drawQuad(program, "position", 0.0f);
+ ASSERT_GL_NO_ERROR();
+
+ eglStreamConsumerReleaseKHR(display, stream);
+ ASSERT_EGL_SUCCESS();
+
+ eglSwapBuffers(display, window->getSurface());
+ SafeRelease(texture);
+}
+
+ANGLE_INSTANTIATE_TEST(EGLStreamTest,
+ ES2_D3D9(),
+ ES2_D3D11(),
+ ES3_D3D11(),
+ ES2_OPENGL(),
+ ES3_OPENGL());
+} // anonymous namespace
diff --git a/gfx/angle/src/tests/egl_tests/EGLSurfaceTest.cpp b/gfx/angle/src/tests/egl_tests/EGLSurfaceTest.cpp
new file mode 100755
index 000000000..513b01d44
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLSurfaceTest.cpp
@@ -0,0 +1,517 @@
+//
+// Copyright 2015 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.
+//
+// EGLSurfaceTest:
+// Tests pertaining to egl::Surface.
+//
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+
+namespace
+{
+
+class EGLSurfaceTest : public testing::Test
+{
+ protected:
+ EGLSurfaceTest()
+ : mDisplay(EGL_NO_DISPLAY),
+ mWindowSurface(EGL_NO_SURFACE),
+ mPbufferSurface(EGL_NO_SURFACE),
+ mContext(EGL_NO_CONTEXT),
+ mSecondContext(EGL_NO_CONTEXT),
+ mOSWindow(nullptr)
+ {
+ }
+
+ void SetUp() override
+ {
+ mOSWindow = CreateOSWindow();
+ mOSWindow->initialize("EGLSurfaceTest", 64, 64);
+ }
+
+ // Release any resources created in the test body
+ void TearDown() override
+ {
+ if (mDisplay != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (mWindowSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mDisplay, mWindowSurface);
+ mWindowSurface = EGL_NO_SURFACE;
+ }
+
+ if (mPbufferSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mDisplay, mPbufferSurface);
+ mPbufferSurface = EGL_NO_SURFACE;
+ }
+
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(mDisplay, mContext);
+ mContext = EGL_NO_CONTEXT;
+ }
+
+ if (mSecondContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(mDisplay, mSecondContext);
+ mSecondContext = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(mDisplay);
+ mDisplay = EGL_NO_DISPLAY;
+ }
+
+ mOSWindow->destroy();
+ SafeDelete(mOSWindow);
+
+ ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT);
+ }
+
+ void initializeDisplay(EGLenum platformType)
+ {
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);
+
+ std::vector<EGLint> displayAttributes;
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ displayAttributes.push_back(platformType);
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
+ displayAttributes.push_back(EGL_DONT_CARE);
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
+ displayAttributes.push_back(EGL_DONT_CARE);
+
+ if (platformType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE || platformType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
+ displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
+ }
+ displayAttributes.push_back(EGL_NONE);
+
+ mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
+ reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
+ displayAttributes.data());
+ ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
+
+ EGLint majorVersion, minorVersion;
+ ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+ }
+
+ void initializeSurface(EGLConfig config)
+ {
+ mConfig = config;
+
+ std::vector<EGLint> surfaceAttributes;
+ surfaceAttributes.push_back(EGL_NONE);
+ surfaceAttributes.push_back(EGL_NONE);
+
+ // Create first window surface
+ mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), &surfaceAttributes[0]);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ mPbufferSurface = eglCreatePbufferSurface(mDisplay, mConfig, &surfaceAttributes[0]);
+
+ EGLint contextAttibutes[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ mSecondContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+ }
+
+ void initializeSurfaceWithDefaultConfig()
+ {
+ const EGLint configAttributes[] =
+ {
+ EGL_RED_SIZE, EGL_DONT_CARE,
+ EGL_GREEN_SIZE, EGL_DONT_CARE,
+ EGL_BLUE_SIZE, EGL_DONT_CARE,
+ EGL_ALPHA_SIZE, EGL_DONT_CARE,
+ EGL_DEPTH_SIZE, EGL_DONT_CARE,
+ EGL_STENCIL_SIZE, EGL_DONT_CARE,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ EGLint configCount;
+ EGLConfig config;
+ ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) || (configCount != 1) == EGL_TRUE);
+
+ initializeSurface(config);
+ }
+
+ GLuint createProgram()
+ {
+ const std::string testVertexShaderSource = SHADER_SOURCE
+ (
+ attribute highp vec4 position;
+
+ void main(void)
+ {
+ gl_Position = position;
+ }
+ );
+
+ const std::string testFragmentShaderSource = SHADER_SOURCE
+ (
+ void main(void)
+ {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+ );
+
+ return CompileProgram(testVertexShaderSource, testFragmentShaderSource);
+ }
+
+ void drawWithProgram(GLuint program)
+ {
+ glClearColor(0, 0, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ GLint positionLocation = glGetAttribLocation(program, "position");
+
+ glUseProgram(program);
+
+ const GLfloat vertices[] =
+ {
+ -1.0f, 1.0f, 0.5f,
+ -1.0f, -1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+
+ -1.0f, 1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+ 1.0f, 1.0f, 0.5f,
+ };
+
+ glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
+ glEnableVertexAttribArray(positionLocation);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ glDisableVertexAttribArray(positionLocation);
+ glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
+
+ EXPECT_PIXEL_EQ(mOSWindow->getWidth() / 2, mOSWindow->getHeight() / 2, 255, 0, 0, 255);
+ }
+
+ void runMessageLoopTest(EGLSurface secondSurface, EGLContext secondContext)
+ {
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ // Make a second context current
+ eglMakeCurrent(mDisplay, secondSurface, secondSurface, secondContext);
+ eglDestroySurface(mDisplay, mWindowSurface);
+
+ // Create second window surface
+ std::vector<EGLint> surfaceAttributes;
+ surfaceAttributes.push_back(EGL_NONE);
+ surfaceAttributes.push_back(EGL_NONE);
+
+ mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), &surfaceAttributes[0]);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ mOSWindow->signalTestEvent();
+ mOSWindow->messageLoop();
+ ASSERT_TRUE(mOSWindow->didTestEventFire());
+
+ // Simple operation to test the FBO is set appropriately
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ EGLDisplay mDisplay;
+ EGLSurface mWindowSurface;
+ EGLSurface mPbufferSurface;
+ EGLContext mContext;
+ EGLContext mSecondContext;
+ EGLConfig mConfig;
+ OSWindow *mOSWindow;
+};
+
+// Test a surface bug where we could have two Window surfaces active
+// at one time, blocking message loops. See http://crbug.com/475085
+TEST_F(EGLSurfaceTest, MessageLoopBug)
+{
+ const char *extensionsString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_ANGLE_platform_angle_d3d") == nullptr)
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ initializeSurfaceWithDefaultConfig();
+
+ runMessageLoopTest(EGL_NO_SURFACE, EGL_NO_CONTEXT);
+}
+
+// Tests the message loop bug, but with setting a second context
+// instead of null.
+TEST_F(EGLSurfaceTest, MessageLoopBugContext)
+{
+ const char *extensionsString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_ANGLE_platform_angle_d3d") == nullptr)
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ initializeSurfaceWithDefaultConfig();
+
+ runMessageLoopTest(mPbufferSurface, mSecondContext);
+}
+
+// Test a bug where calling makeCurrent twice would release the surface
+TEST_F(EGLSurfaceTest, MakeCurrentTwice)
+{
+#if defined(ANGLE_PLATFORM_APPLE) && !defined(ANGLE_STANDALONE_BUILD)
+ // TODO(cwallez) Make context creation return at least an OpenGL ES 2 context on
+ // the Mac trybots.
+ std::cout << "Test skipped temporarily skipped on the Mac trybots" << std::endl;
+ return;
+#endif
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ initializeSurfaceWithDefaultConfig();
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
+
+ // Simple operation to test the FBO is set appropriately
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+// Test that the D3D window surface is correctly resized after calling swapBuffers
+TEST_F(EGLSurfaceTest, ResizeD3DWindow)
+{
+ const char *extensionsString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (strstr(extensionsString, "EGL_ANGLE_platform_angle_d3d") == nullptr)
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ initializeSurfaceWithDefaultConfig();
+
+ eglSwapBuffers(mDisplay, mWindowSurface);
+ ASSERT_EGL_SUCCESS();
+
+ EGLint height;
+ eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(64, height); // initial size
+
+ // set window's height to 0
+ mOSWindow->resize(64, 0);
+
+ eglSwapBuffers(mDisplay, mWindowSurface);
+ ASSERT_EGL_SUCCESS();
+
+ eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(0, height);
+
+ // restore window's height
+ mOSWindow->resize(64, 64);
+
+ eglSwapBuffers(mDisplay, mWindowSurface);
+ ASSERT_EGL_SUCCESS();
+
+ eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
+ ASSERT_EGL_SUCCESS();
+ ASSERT_EQ(64, height);
+}
+
+// Test creating a surface that supports a EGLConfig with 16bit
+// support GL_RGB565
+TEST_F(EGLSurfaceTest, CreateWithEGLConfig5650Support)
+{
+ if (!ANGLETest::eglDisplayExtensionEnabled(EGL_NO_DISPLAY, "EGL_ANGLE_platform_angle_d3d"))
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ const EGLint configAttributes[] =
+ {
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ EGLConfig config;
+ if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
+ {
+ std::cout << "EGLConfig for a GL_RGB565 surface is not supported, skipping test" << std::endl;
+ return;
+ }
+
+ initializeSurface(config);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_EGL_SUCCESS();
+
+ GLuint program = createProgram();
+ ASSERT_NE(0u, program);
+ drawWithProgram(program);
+ EXPECT_GL_NO_ERROR();
+ glDeleteProgram(program);
+}
+
+// Test creating a surface that supports a EGLConfig with 16bit
+// support GL_RGBA4
+TEST_F(EGLSurfaceTest, CreateWithEGLConfig4444Support)
+{
+ if (!ANGLETest::eglDisplayExtensionEnabled(EGL_NO_DISPLAY, "EGL_ANGLE_platform_angle_d3d"))
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ const EGLint configAttributes[] =
+ {
+ EGL_RED_SIZE, 4,
+ EGL_GREEN_SIZE, 4,
+ EGL_BLUE_SIZE, 4,
+ EGL_ALPHA_SIZE, 4,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ EGLConfig config;
+ if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
+ {
+ std::cout << "EGLConfig for a GL_RGBA4 surface is not supported, skipping test" << std::endl;
+ return;
+ }
+
+ initializeSurface(config);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_EGL_SUCCESS();
+
+ GLuint program = createProgram();
+ ASSERT_NE(0u, program);
+ drawWithProgram(program);
+ EXPECT_GL_NO_ERROR();
+ glDeleteProgram(program);
+}
+
+// Test creating a surface that supports a EGLConfig with 16bit
+// support GL_RGB5_A1
+TEST_F(EGLSurfaceTest, CreateWithEGLConfig5551Support)
+{
+ if (!ANGLETest::eglDisplayExtensionEnabled(EGL_NO_DISPLAY, "EGL_ANGLE_platform_angle_d3d"))
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ const EGLint configAttributes[] =
+ {
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 5,
+ EGL_BLUE_SIZE, 5,
+ EGL_ALPHA_SIZE, 1,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ EGLConfig config;
+ if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
+ {
+ std::cout << "EGLConfig for a GL_RGB5_A1 surface is not supported, skipping test" << std::endl;
+ return;
+ }
+
+ initializeSurface(config);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_EGL_SUCCESS();
+
+ GLuint program = createProgram();
+ ASSERT_NE(0u, program);
+ drawWithProgram(program);
+ EXPECT_GL_NO_ERROR();
+ glDeleteProgram(program);
+}
+
+// Test creating a surface that supports a EGLConfig without alpha support
+TEST_F(EGLSurfaceTest, CreateWithEGLConfig8880Support)
+{
+ if (!ANGLETest::eglDisplayExtensionEnabled(EGL_NO_DISPLAY, "EGL_ANGLE_platform_angle_d3d"))
+ {
+ std::cout << "D3D Platform not supported in ANGLE" << std::endl;
+ return;
+ }
+
+ const EGLint configAttributes[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ EGLConfig config;
+ if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
+ {
+ std::cout << "EGLConfig for a GL_RGB8_OES surface is not supported, skipping test"
+ << std::endl;
+ return;
+ }
+
+ initializeSurface(config);
+
+ eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
+ ASSERT_EGL_SUCCESS();
+
+ GLuint program = createProgram();
+ ASSERT_NE(0u, program);
+ drawWithProgram(program);
+ EXPECT_GL_NO_ERROR();
+ glDeleteProgram(program);
+}
+}
diff --git a/gfx/angle/src/tests/egl_tests/EGLThreadTest.cpp b/gfx/angle/src/tests/egl_tests/EGLThreadTest.cpp
new file mode 100755
index 000000000..305ccc25f
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLThreadTest.cpp
@@ -0,0 +1,83 @@
+#include "gtest/gtest.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+typedef EGLAPI EGLDisplay EGLAPIENTRY EGLGetDisplay(EGLNativeDisplayType display_id);
+typedef EGLAPI EGLBoolean EGLAPIENTRY EGLInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+typedef EGLAPI EGLContext EGLAPIENTRY EGLGetCurrentContext(void);
+typedef EGLAPI EGLSurface EGLAPIENTRY EGLGetCurrentSurface(EGLint readdraw);
+typedef EGLAPI EGLBoolean EGLAPIENTRY EGLTerminate(EGLDisplay dpy);
+
+class EGLThreadTest : public testing::Test
+{
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ EGLGetDisplay *mGetDisplay;
+ EGLInitialize *mInitialize;
+ EGLGetCurrentContext *mGetCurrentContext;
+ EGLGetCurrentSurface *mGetCurrentSurface;
+
+ EGLDisplay mDisplay;
+
+ HMODULE mEGL;
+ HMODULE mGLESv2;
+
+ static DWORD WINAPI ThreadingTestEntryPoint(LPVOID thisPointer);
+
+ private:
+ void ThreadingTest();
+};
+
+DWORD WINAPI EGLThreadTest::ThreadingTestEntryPoint(LPVOID lpParameter)
+{
+ EGLThreadTest *test = (EGLThreadTest *)lpParameter;
+ test->ThreadingTest();
+ return 0;
+}
+
+void EGLThreadTest::ThreadingTest()
+{
+ mEGL = LoadLibrary(TEXT("libEGL.dll"));
+ mGLESv2 = LoadLibrary(TEXT("libGLESv2.dll"));
+
+ EXPECT_TRUE(mEGL != NULL);
+ EXPECT_TRUE(mGLESv2 != NULL);
+
+ mGetDisplay = (EGLGetDisplay *)GetProcAddress(mEGL, "eglGetDisplay");
+ mInitialize = (EGLInitialize *)GetProcAddress(mEGL, "eglInitialize");
+ mGetCurrentContext = (EGLGetCurrentContext *)GetProcAddress(mEGL, "eglGetCurrentContext");
+ mGetCurrentSurface = (EGLGetCurrentSurface *)GetProcAddress(mEGL, "eglGetCurrentSurface");
+
+ EXPECT_TRUE(mGetDisplay != NULL);
+ EXPECT_TRUE(mInitialize != NULL);
+ EXPECT_TRUE(mGetCurrentContext != NULL);
+ EXPECT_TRUE(mGetCurrentSurface != NULL);
+
+ mDisplay = mGetDisplay(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
+
+ EXPECT_TRUE(mDisplay!= EGL_NO_DISPLAY);
+
+ mInitialize(mDisplay, NULL, NULL);
+ mGetCurrentContext();
+}
+
+TEST_F(EGLThreadTest, thread_init_crash)
+{
+ DWORD threadId;
+ HANDLE threadHandle = CreateThread(NULL, 0, EGLThreadTest::ThreadingTestEntryPoint, this, 0, &threadId);
+ EXPECT_TRUE(threadHandle != NULL);
+
+ // wait for signal from thread
+ DWORD waitResult = WaitForSingleObject(threadHandle, 1000);
+ EXPECT_EQ(waitResult, WAIT_OBJECT_0);
+
+ // crash, because the TLS value is NULL on main thread
+ mGetCurrentSurface(EGL_DRAW);
+ mGetCurrentContext();
+
+ auto terminate = (EGLTerminate *)GetProcAddress(mEGL, "eglTerminate");
+ terminate(mDisplay);
+}
diff --git a/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp b/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp
new file mode 100755
index 000000000..4d5179964
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp
@@ -0,0 +1,216 @@
+//
+// Copyright (c) 2015 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.
+//
+
+// EGLX11VisualTest.cpp: tests for EGL_ANGLE_x11_visual extension
+
+#include <gtest/gtest.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <X11/Xlib.h>
+
+#include "OSWindow.h"
+#include "test_utils/ANGLETest.h"
+#include "x11/X11Window.h"
+
+using namespace angle;
+
+namespace
+{
+
+const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+}
+
+class EGLX11VisualHintTest : public ::testing::TestWithParam<angle::PlatformParameters>
+{
+ public:
+ void SetUp() override
+ {
+ mEglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
+ eglGetProcAddress("eglGetPlatformDisplayEXT"));
+
+ mDisplay = XOpenDisplay(NULL);
+ }
+
+ std::vector<EGLint> getDisplayAttributes(int visualId) const
+ {
+ std::vector<EGLint> attribs;
+
+ attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ attribs.push_back(GetParam().getRenderer());
+ attribs.push_back(EGL_X11_VISUAL_ID_ANGLE);
+ attribs.push_back(visualId);
+ attribs.push_back(EGL_NONE);
+
+ return attribs;
+ }
+
+ unsigned int chooseDifferentVisual(unsigned int visualId)
+ {
+ int numVisuals;
+ XVisualInfo visualTemplate;
+ visualTemplate.screen = DefaultScreen(mDisplay);
+
+ XVisualInfo *visuals =
+ XGetVisualInfo(mDisplay, VisualScreenMask, &visualTemplate, &numVisuals);
+ EXPECT_TRUE(numVisuals >= 2);
+
+ for (int i = 0; i < numVisuals; ++i)
+ {
+ if (visuals[i].visualid != visualId)
+ {
+ int result = visuals[i].visualid;
+ XFree(visuals);
+ return result;
+ }
+ }
+
+ UNREACHABLE();
+ return -1;
+ }
+
+ protected:
+ PFNEGLGETPLATFORMDISPLAYEXTPROC mEglGetPlatformDisplayEXT;
+ Display *mDisplay;
+};
+
+// Test that display creation fails if the visual ID passed in invalid.
+TEST_P(EGLX11VisualHintTest, InvalidVisualID)
+{
+ // The test platform will log an error in this negative test.
+ IgnoreANGLEPlatformMessages();
+
+ static const int gInvalidVisualId = -1;
+ auto attributes = getDisplayAttributes(gInvalidVisualId);
+
+ EGLDisplay display =
+ mEglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
+ ASSERT_TRUE(display != EGL_NO_DISPLAY);
+
+ ASSERT_TRUE(EGL_FALSE == eglInitialize(display, nullptr, nullptr));
+ ASSERT_EGL_ERROR(EGL_NOT_INITIALIZED);
+}
+
+// Test that context creation with a visual ID succeeds, that the context exposes
+// only one config, and that a clear on a surface with this config works.
+TEST_P(EGLX11VisualHintTest, ValidVisualIDAndClear)
+{
+ // We'll test the extension with one visual ID but we don't care which one. This means we
+ // can use OSWindow to create a window and just grab its visual.
+ OSWindow *osWindow = CreateOSWindow();
+ osWindow->initialize("EGLX11VisualHintTest", 500, 500);
+ osWindow->setVisible(true);
+
+ Window xWindow = osWindow->getNativeWindow();
+
+ XWindowAttributes windowAttributes;
+ ASSERT_NE(0, XGetWindowAttributes(mDisplay, xWindow, &windowAttributes));
+ int visualId = windowAttributes.visual->visualid;
+
+ auto attributes = getDisplayAttributes(visualId);
+ EGLDisplay display =
+ mEglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
+ ASSERT_NE(EGL_NO_DISPLAY, display);
+
+ ASSERT_TRUE(EGL_TRUE == eglInitialize(display, nullptr, nullptr));
+
+ // While this is not required by the extension, test that our implementation returns only one
+ // config, with the same native visual Id that we provided.
+ int nConfigs = 0;
+ ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, nullptr, 0, &nConfigs));
+ ASSERT_EQ(1, nConfigs);
+
+ int nReturnedConfigs = 0;
+ EGLConfig config;
+ ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, &config, 1, &nReturnedConfigs));
+ ASSERT_EQ(nConfigs, nReturnedConfigs);
+
+ EGLint eglNativeId;
+ ASSERT_TRUE(EGL_TRUE == eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &eglNativeId));
+ ASSERT_EQ(visualId, eglNativeId);
+
+ // Finally, try to do a clear on the window.
+ EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ ASSERT_NE(EGL_NO_CONTEXT, context);
+
+ EGLSurface window = eglCreateWindowSurface(display, config, xWindow, nullptr);
+ ASSERT_EGL_SUCCESS();
+
+ eglMakeCurrent(display, window, window, context);
+ ASSERT_EGL_SUCCESS();
+
+ glViewport(0, 0, 500, 500);
+ glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
+
+ // Teardown
+ eglDestroySurface(display, window);
+ ASSERT_EGL_SUCCESS();
+
+ eglDestroyContext(display, context);
+ ASSERT_EGL_SUCCESS();
+
+ SafeDelete(osWindow);
+
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(display);
+}
+
+// Test that EGL_BAD_MATCH is generated when trying to create an EGL window from
+// an X11 window whose visual ID doesn't match the visual ID passed at display creation.
+TEST_P(EGLX11VisualHintTest, InvalidWindowVisualID)
+{
+ // Get the default visual ID, as a good guess of a visual id for which display
+ // creation will succeed.
+ int visualId;
+ {
+ OSWindow *osWindow = CreateOSWindow();
+ osWindow->initialize("EGLX11VisualHintTest", 500, 500);
+ osWindow->setVisible(true);
+
+ Window xWindow = osWindow->getNativeWindow();
+
+ XWindowAttributes windowAttributes;
+ ASSERT_NE(0, XGetWindowAttributes(mDisplay, xWindow, &windowAttributes));
+ visualId = windowAttributes.visual->visualid;
+
+ SafeDelete(osWindow);
+ }
+
+ auto attributes = getDisplayAttributes(visualId);
+ EGLDisplay display =
+ mEglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
+ ASSERT_NE(EGL_NO_DISPLAY, display);
+
+ ASSERT_TRUE(EGL_TRUE == eglInitialize(display, nullptr, nullptr));
+
+
+ // Initialize the window with a visual id different from the display's visual id
+ int otherVisualId = chooseDifferentVisual(visualId);
+ ASSERT_NE(visualId, otherVisualId);
+
+ OSWindow *osWindow = new X11Window(otherVisualId);
+ osWindow->initialize("EGLX11VisualHintTest", 500, 500);
+ osWindow->setVisible(true);
+
+ Window xWindow = osWindow->getNativeWindow();
+
+ // Creating the EGL window should fail with EGL_BAD_MATCH
+ int nReturnedConfigs = 0;
+ EGLConfig config;
+ ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, &config, 1, &nReturnedConfigs));
+ ASSERT_EQ(1, nReturnedConfigs);
+
+ EGLSurface window = eglCreateWindowSurface(display, config, xWindow, nullptr);
+ ASSERT_EQ(EGL_NO_SURFACE, window);
+ ASSERT_EGL_ERROR(EGL_BAD_MATCH);
+
+ SafeDelete(osWindow);
+}
+
+ANGLE_INSTANTIATE_TEST(EGLX11VisualHintTest, ES2_OPENGL());
diff --git a/gfx/angle/src/tests/egl_tests/media/yuvtest.inl b/gfx/angle/src/tests/egl_tests/media/yuvtest.inl
new file mode 100755
index 000000000..7271cf80a
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/media/yuvtest.inl
@@ -0,0 +1,1548 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by scripts/bmp_to_yuv.py using data from yuvtest.bmp
+//
+// Copyright 2016 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.
+
+static const size_t yuvtest_width = 128;
+static const size_t yuvtest_height = 128;
+static const unsigned char yuvtest_data[] =
+{
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,132,16,16,16,16,105,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,23,16,16,16,16,16,16,44,153,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,16,16,16,16,16,16,16,16,16,78,228,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,16,16,16,173,44,16,16,16,16,16,16,44,153,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,16,16,16,228,235,235,221,112,16,16,16,16,16,78,228,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,37,16,16,92,235,235,235,235,153,44,16,16,16,16,16,
+ 92,228,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,212,186,186,186,186,186,186,186,186,186,203,234,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,146,16,16,16,235,235,235,235,235,235,221,112,16,16,16,
+ 16,16,16,92,228,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,219,187,160,150,150,150,140,127,121,121,121,
+ 152,186,186,186,186,186,186,186,186,186,186,186,186,186,203,234,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,16,16,16,105,235,235,235,235,235,235,235,153,44,16,
+ 16,16,16,16,78,228,235,235,235,235,235,235,235,235,235,219,
+ 187,160,150,150,150,150,150,149,132,121,121,121,121,121,121,152,
+ 186,186,186,186,186,186,186,185,154,134,134,134,134,134,134,134,
+ 134,134,134,169,232,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,213,171,135,120,120,120,120,120,120,120,
+ 120,120,120,120,120,167,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,232,
+ 172,134,27,16,16,16,130,134,134,134,134,134,134,134,169,151,
+ 44,16,16,16,16,44,153,235,235,235,235,235,219,187,160,150,
+ 150,150,150,150,150,150,149,129,121,121,121,121,121,121,121,185,
+ 186,186,185,146,121,121,122,131,134,134,134,134,134,134,134,134,
+ 134,134,134,134,134,134,134,134,169,232,235,235,235,235,235,235,
+ 235,235,235,235,231,156,120,120,120,120,120,120,120,120,120,120,
+ 120,120,120,120,120,124,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,187,134,
+ 134,134,101,24,16,16,57,134,134,134,134,134,134,134,134,134,
+ 134,134,75,16,16,16,16,78,228,219,187,160,150,150,150,150,
+ 150,150,150,150,150,148,134,121,121,121,121,136,172,225,212,186,
+ 186,186,163,150,150,149,138,134,134,134,134,134,134,134,134,134,
+ 134,134,134,134,134,134,134,134,134,134,134,169,232,235,235,235,
+ 235,235,213,171,135,120,120,120,120,120,120,120,120,120,120,120,
+ 120,120,120,120,135,192,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,137,134,
+ 134,134,134,86,16,16,16,134,134,134,134,134,134,134,134,134,
+ 134,134,134,86,24,16,16,16,45,129,150,150,150,150,150,158,
+ 184,214,235,235,172,121,121,121,121,178,235,235,235,235,188,186,
+ 186,188,200,158,149,139,134,134,134,143,158,136,121,121,121,121,
+ 146,178,166,140,134,134,134,134,134,134,134,134,147,197,199,142,
+ 120,120,120,120,120,120,120,164,206,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,134,134,
+ 134,194,235,235,37,16,16,166,235,235,235,235,235,197,147,134,
+ 134,134,134,134,126,68,16,16,16,20,87,150,158,184,214,235,
+ 235,235,235,199,125,121,121,125,181,235,235,235,235,226,186,186,
+ 186,217,235,232,155,134,134,134,141,150,150,174,225,178,136,121,
+ 121,121,154,186,186,186,200,196,147,134,134,134,130,123,120,120,
+ 120,120,120,120,120,131,185,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,134,134,
+ 134,235,235,235,112,16,16,57,235,235,235,235,235,235,235,235,
+ 235,235,206,147,134,134,82,20,16,16,16,72,228,235,235,235,
+ 235,232,157,121,121,121,125,225,235,235,235,235,235,203,186,186,
+ 202,235,232,163,134,134,134,161,155,150,150,150,174,232,235,235,
+ 228,172,121,151,186,186,186,165,113,111,120,122,120,120,120,120,
+ 120,120,135,167,206,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,134,134,
+ 134,235,235,235,215,16,16,16,235,235,235,235,235,235,235,235,
+ 235,235,235,235,145,136,134,115,42,16,16,16,78,228,235,235,
+ 235,172,121,121,121,125,181,235,235,235,235,235,235,188,186,186,
+ 226,232,163,134,134,134,184,235,230,187,150,150,150,160,203,235,
+ 231,158,111,111,149,186,186,186,151,119,120,120,120,120,121,126,
+ 133,142,231,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,233,169,189,
+ 189,189,189,189,189,16,16,16,87,189,189,189,195,217,235,235,
+ 235,235,235,235,150,150,150,167,134,71,16,16,16,71,228,235,
+ 235,125,121,121,168,225,235,235,235,235,235,235,235,186,186,186,
+ 232,163,134,134,134,184,235,235,235,235,192,150,150,150,148,130,
+ 111,111,111,111,111,149,166,133,120,120,120,120,120,121,133,134,
+ 134,134,134,152,232,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,233,202,189,189,
+ 189,189,189,189,189,32,16,16,16,87,189,189,189,189,195,217,
+ 235,235,235,235,150,150,150,235,184,134,75,16,16,16,20,77,
+ 121,98,121,121,235,235,235,235,235,235,235,235,212,186,186,185,
+ 163,134,134,134,184,235,235,235,235,235,235,200,153,126,111,111,
+ 111,111,111,125,148,134,120,120,120,120,121,152,224,200,129,132,
+ 134,134,134,134,137,232,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,233,202,189,189,189,
+ 189,189,189,189,189,140,27,16,16,16,189,189,189,189,189,189,
+ 195,217,235,235,150,150,150,235,235,194,147,75,16,16,16,16,
+ 16,16,52,157,235,235,235,235,235,235,235,235,188,186,185,149,
+ 134,134,134,184,235,235,235,235,235,235,235,235,163,111,111,111,
+ 112,118,127,120,120,120,120,120,122,150,139,121,153,235,235,206,
+ 140,134,134,134,134,134,175,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,233,202,189,189,189,161,
+ 134,134,134,235,235,235,173,16,16,16,235,232,212,192,189,189,
+ 189,189,189,189,189,189,176,233,235,235,235,216,109,31,16,16,
+ 16,16,16,152,235,235,235,235,235,235,235,235,186,185,149,134,
+ 134,134,184,235,235,235,235,235,235,235,231,158,111,111,115,120,
+ 120,120,120,120,120,120,131,159,180,186,174,121,121,199,235,235,
+ 235,227,144,134,134,134,134,146,231,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,220,198,189,189,189,212,197,
+ 134,134,134,163,235,235,235,37,16,16,166,235,235,232,212,192,
+ 189,189,189,189,189,189,189,189,189,189,205,233,235,184,119,89,
+ 49,16,16,37,153,235,235,235,235,235,235,234,170,144,134,134,
+ 134,184,235,235,235,235,235,235,235,231,146,112,116,120,120,120,
+ 120,120,120,128,167,206,235,231,186,186,186,123,121,143,235,235,
+ 235,235,223,122,132,134,134,134,137,228,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,210,189,189,189,189,212,235,235,
+ 144,134,134,134,203,235,235,112,16,16,57,235,235,235,235,232,
+ 212,195,189,189,189,189,189,189,189,189,189,189,194,208,165,133,
+ 123,20,16,16,16,59,225,235,235,235,232,157,134,134,134,134,
+ 184,235,235,235,235,235,235,235,235,153,117,120,120,120,120,120,
+ 123,132,142,150,174,235,235,235,191,186,186,165,121,121,199,235,
+ 235,235,235,196,129,132,134,134,134,139,232,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,213,189,189,189,191,213,235,235,235,
+ 206,147,134,134,134,175,235,215,23,16,16,166,235,235,235,235,
+ 235,235,235,179,150,164,187,189,189,189,189,189,189,189,189,183,
+ 165,111,24,16,16,16,57,225,235,235,166,135,169,189,189,189,
+ 189,189,189,189,189,189,185,171,127,120,120,120,120,120,135,188,
+ 208,155,150,150,150,208,235,235,215,186,186,186,121,121,143,232,
+ 235,235,235,235,235,229,151,134,134,134,163,232,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,191,189,189,191,231,235,235,235,235,
+ 235,225,137,134,134,134,235,235,112,16,16,57,228,235,235,235,
+ 235,235,235,152,150,150,219,235,235,217,195,189,189,189,189,189,
+ 189,189,178,92,16,16,16,16,57,140,135,173,189,189,189,189,
+ 189,189,189,189,180,148,125,120,120,120,120,120,149,199,235,235,
+ 235,230,179,150,150,166,235,235,235,186,186,186,125,121,121,161,
+ 235,235,235,235,235,235,235,122,134,134,134,169,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,189,189,189,217,235,235,235,235,235,
+ 235,235,203,134,134,134,170,217,215,23,16,16,92,235,235,235,
+ 235,235,235,150,150,150,235,235,235,235,235,235,227,177,180,189,
+ 189,189,189,189,102,16,16,16,16,57,169,189,189,189,189,189,
+ 189,189,170,140,120,120,120,120,120,122,146,178,233,235,235,235,
+ 235,235,227,152,150,150,195,235,235,186,186,186,189,121,121,121,
+ 235,235,235,235,235,235,235,111,122,134,134,134,160,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,189,189,189,235,235,235,235,235,235,
+ 235,235,235,144,134,134,134,149,185,127,16,16,16,105,235,235,
+ 235,235,235,150,150,150,235,235,235,235,235,235,235,125,121,135,
+ 200,191,189,189,189,124,38,16,16,16,124,178,172,143,156,149,
+ 139,120,120,120,120,120,120,128,156,185,189,189,195,176,95,95,
+ 152,235,235,195,150,150,152,222,235,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,111,111,132,134,134,134,213,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,233,189,189,189,235,235,235,235,235,235,
+ 235,235,235,203,139,134,134,134,152,186,33,16,16,16,235,235,
+ 235,235,235,150,150,150,235,235,235,235,235,235,228,121,121,121,
+ 208,189,189,189,189,189,189,32,23,58,107,120,120,120,120,120,
+ 120,120,120,120,120,149,150,111,111,152,189,189,189,189,163,97,
+ 95,95,95,152,168,150,150,168,235,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,111,111,117,147,134,134,182,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,210,189,189,191,235,235,235,235,235,235,
+ 235,235,235,235,229,177,134,134,134,149,138,16,16,16,78,235,
+ 235,235,235,150,150,150,235,235,235,235,235,235,192,121,121,158,
+ 189,189,189,189,189,189,180,126,115,120,120,120,120,120,120,120,
+ 120,120,123,134,203,235,115,111,111,176,216,192,189,189,189,163,
+ 97,95,95,95,224,152,150,150,208,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,111,111,111,210,134,134,140,197,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,191,189,189,213,235,235,235,235,235,235,
+ 235,235,235,235,235,235,144,134,134,134,170,32,16,16,16,144,
+ 234,235,235,150,150,150,235,235,235,235,235,235,153,121,127,189,
+ 189,189,201,213,162,128,120,120,120,120,120,117,101,140,156,172,
+ 173,166,148,134,137,187,111,111,111,235,235,232,210,189,189,189,
+ 163,97,95,95,235,187,150,150,166,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,111,111,111,235,144,134,134,134,163,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,233,189,189,189,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,206,147,134,134,146,138,37,16,16,48,
+ 194,234,235,150,150,150,235,235,235,235,235,235,125,146,185,189,
+ 185,165,139,121,120,120,120,120,120,127,68,23,16,21,108,189,
+ 189,189,189,189,189,189,182,154,132,175,210,235,235,212,189,189,
+ 189,157,95,95,235,227,152,150,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,111,111,111,235,210,140,134,134,134,
+ 203,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,210,189,189,191,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,225,137,134,134,157,174,21,16,16,
+ 64,187,217,150,150,150,235,235,235,235,235,233,168,174,156,136,
+ 120,120,120,120,120,120,120,138,165,212,160,21,16,16,16,65,
+ 184,189,189,189,189,189,189,189,188,173,160,146,134,147,193,189,
+ 189,189,95,95,235,235,192,150,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,123,111,115,235,235,229,169,134,134,
+ 153,232,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,191,189,189,213,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,194,134,134,134,147,123,16,16,
+ 16,64,186,182,163,150,235,235,235,235,235,178,134,120,120,120,
+ 120,120,120,120,124,154,178,189,189,235,235,163,53,16,16,16,
+ 70,184,189,189,189,189,189,189,189,189,189,189,182,154,134,184,
+ 189,189,142,96,235,235,232,166,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,200,142,188,235,235,235,225,137,134,
+ 134,163,232,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,184,134,134,134,134,89,16,
+ 16,16,133,186,186,178,227,235,235,199,139,120,120,120,120,120,
+ 120,123,127,170,235,227,189,189,189,235,235,215,186,96,16,16,
+ 16,69,189,189,191,128,150,179,189,189,189,189,189,189,182,181,
+ 189,189,179,123,232,235,235,219,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,194,134,
+ 134,134,169,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,194,140,134,134,134,90,
+ 16,16,49,181,186,186,188,183,142,120,120,120,120,122,124,128,
+ 133,134,184,235,233,201,189,189,204,235,235,235,191,186,101,16,
+ 16,16,139,189,189,172,113,111,229,217,207,192,189,189,189,189,
+ 189,189,189,151,134,169,232,235,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,184,
+ 134,134,134,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,229,144,134,134,123,
+ 20,16,16,59,168,150,129,120,120,120,120,122,148,133,134,134,
+ 134,184,235,235,210,189,189,189,227,235,235,235,215,186,186,86,
+ 16,16,36,125,189,189,167,113,235,235,235,232,212,192,189,189,
+ 189,189,189,184,166,148,162,181,150,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 134,134,134,197,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,203,140,134,134,
+ 86,35,75,107,120,120,120,120,120,122,150,183,148,134,134,137,
+ 187,235,235,235,191,189,189,212,235,235,235,235,235,211,186,170,
+ 21,16,16,16,65,189,189,167,233,235,235,235,235,232,210,184,
+ 189,189,189,189,189,189,182,156,148,186,186,186,235,121,121,121,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 144,134,134,134,163,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,227,189,189,189,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,229,179,133,
+ 124,120,120,120,120,120,120,127,150,183,189,168,134,134,131,225,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,217,192,
+ 143,28,16,16,16,135,189,189,202,235,235,235,235,152,95,105,
+ 137,176,189,189,189,189,189,189,189,189,189,184,165,121,121,121,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 203,140,134,134,134,232,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,205,189,189,204,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,192,122,
+ 120,120,120,120,111,93,182,189,189,189,169,134,134,134,176,189,
+ 227,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,209,84,16,16,41,189,189,189,167,150,150,150,150,150,150,
+ 150,153,189,189,189,186,189,189,189,189,189,189,173,131,122,125,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,229,144,134,134,169,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,191,189,189,227,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,213,171,135,120,120,
+ 120,120,106,42,16,16,76,189,189,175,134,134,134,160,186,186,
+ 186,212,235,235,189,189,189,187,160,150,150,150,150,150,150,150,
+ 150,150,137,20,16,16,88,189,189,186,153,150,150,150,150,150,
+ 150,150,189,189,189,126,157,185,189,189,189,189,189,182,155,191,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,194,134,134,134,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,231,156,120,120,120,120,120,
+ 139,202,137,75,16,16,16,184,189,134,134,134,163,186,186,186,
+ 186,186,194,217,189,189,189,150,150,150,150,150,150,150,150,150,
+ 150,150,150,95,16,16,19,151,189,189,175,149,132,121,121,121,
+ 121,121,189,189,189,162,186,186,186,182,164,189,189,189,189,185,
+ 225,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,232,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,231,153,120,120,120,120,131,174,
+ 231,235,203,147,27,16,16,65,184,134,134,184,235,199,137,172,
+ 186,186,186,186,189,189,189,150,150,150,150,150,150,150,150,150,
+ 150,160,174,192,58,16,16,42,189,189,189,132,121,121,121,121,
+ 121,121,189,189,189,186,186,186,186,152,136,179,188,189,189,189,
+ 188,176,232,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,144,134,134,169,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,231,164,120,120,120,120,164,206,235,235,
+ 235,235,235,235,125,16,16,16,65,134,160,235,235,235,199,129,
+ 152,182,186,186,189,189,189,182,214,235,235,235,235,235,235,235,
+ 235,235,235,235,198,19,16,16,99,189,189,179,134,134,134,134,
+ 134,134,189,189,189,134,134,134,134,134,134,134,137,161,188,189,
+ 189,189,173,197,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,194,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,231,164,120,120,120,120,120,177,235,235,235,235,
+ 235,235,235,235,175,76,16,16,16,97,134,147,197,235,235,225,
+ 149,127,158,186,189,189,189,188,212,225,235,235,235,235,235,232,
+ 172,134,134,134,134,75,16,16,20,161,189,189,146,134,134,134,
+ 134,134,189,189,189,134,134,134,134,134,134,134,134,134,146,182,
+ 189,189,189,184,178,222,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,235,235,199,142,120,120,120,120,135,188,235,235,235,235,235,
+ 235,235,235,216,134,154,87,16,16,38,130,134,134,163,229,174,
+ 150,146,128,154,189,189,189,186,186,186,205,235,235,232,172,134,
+ 134,134,134,134,134,130,38,16,16,49,184,189,163,134,134,134,
+ 134,134,189,189,189,134,134,134,134,134,134,134,134,134,134,137,
+ 172,189,189,189,189,189,190,208,224,235,235,235,235,235,235,235,
+ 235,235,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 235,231,156,120,120,120,120,135,188,235,235,235,235,235,235,235,
+ 235,235,175,134,134,173,173,21,16,16,49,134,134,134,136,143,
+ 150,150,184,177,189,189,189,186,186,186,186,170,229,163,134,134,
+ 134,134,134,134,134,131,100,19,16,16,65,189,190,186,186,186,
+ 186,175,189,189,189,235,235,235,235,235,235,235,229,184,147,134,
+ 134,156,182,189,189,189,189,189,189,202,233,235,235,235,235,235,
+ 235,235,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,235,235,235,
+ 231,153,120,120,120,120,115,111,111,111,111,111,111,111,154,231,
+ 235,216,134,134,134,188,189,118,16,16,16,102,134,134,134,134,
+ 136,170,235,235,189,189,189,146,180,186,185,154,134,134,134,134,
+ 147,194,199,142,111,111,111,83,16,16,16,135,189,188,186,192,
+ 173,95,189,189,189,231,235,235,235,235,235,235,235,235,235,235,
+ 229,179,134,144,165,182,189,189,189,189,173,169,232,235,235,235,
+ 235,235,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,189,189,189,233,235,235,235,235,235,235,235,231,
+ 153,120,120,120,117,112,111,111,111,111,111,111,111,111,111,111,
+ 111,140,134,134,147,189,189,189,71,16,16,41,139,134,134,134,
+ 134,134,134,169,189,189,189,192,152,182,157,134,134,134,134,149,
+ 121,121,121,114,111,111,113,234,92,16,16,49,184,189,207,235,
+ 235,165,189,189,189,134,235,235,235,235,235,235,235,235,235,235,
+ 235,235,197,147,134,134,144,169,189,189,189,189,189,170,135,147,
+ 197,235,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,194,189,189,202,233,235,235,235,235,235,199,142,
+ 120,120,120,115,111,111,111,111,111,111,111,111,111,111,111,111,
+ 115,134,134,134,115,189,189,189,102,19,16,16,16,51,147,138,
+ 134,134,134,134,189,189,189,235,235,186,134,134,134,140,165,168,
+ 121,121,114,111,111,111,176,208,170,21,16,16,65,184,199,235,
+ 235,235,189,189,189,95,169,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,197,147,161,189,189,189,189,189,184,166,
+ 148,163,235,235,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,216,189,189,189,202,233,235,235,231,156,120,120,
+ 120,120,117,111,111,176,235,235,235,235,235,235,235,188,127,124,
+ 134,134,134,127,111,189,189,189,111,72,16,16,16,16,92,185,
+ 184,147,134,134,189,189,189,156,179,134,134,134,135,186,186,186,
+ 146,115,111,111,111,173,212,186,186,117,16,16,16,65,184,227,
+ 235,235,189,189,189,95,99,213,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,229,182,182,189,189,189,189,189,
+ 189,182,154,134,134,134,134,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,212,189,189,189,202,233,231,153,120,120,120,
+ 124,156,111,111,142,235,235,235,235,235,235,235,235,235,216,134,
+ 134,134,134,115,111,189,189,189,111,111,75,28,16,16,34,108,
+ 111,111,122,134,189,189,189,134,134,134,134,133,129,180,186,186,
+ 186,165,111,111,173,212,186,186,186,188,125,16,16,16,65,208,
+ 235,235,189,189,189,95,95,130,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,197,147,156,182,189,189,
+ 189,189,189,173,134,134,137,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,212,189,189,189,202,170,120,120,120,167,
+ 224,146,111,111,184,235,235,235,235,235,235,235,235,235,166,134,
+ 134,147,187,235,235,189,189,189,150,150,150,148,21,16,16,43,
+ 108,111,111,120,189,189,189,134,134,134,134,122,116,140,183,186,
+ 186,186,140,137,234,188,186,186,188,217,235,125,16,16,16,69,
+ 235,235,189,189,189,95,95,95,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,197,155,165,
+ 186,189,189,189,134,134,137,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,212,189,189,187,123,120,120,177,235,
+ 235,115,111,111,223,235,235,235,235,235,235,235,235,216,134,134,
+ 134,216,235,235,227,189,189,189,192,150,150,150,102,16,16,16,
+ 43,108,111,111,182,189,189,151,134,134,134,128,112,111,126,180,
+ 186,186,186,168,175,186,186,188,217,235,235,235,121,16,16,16,
+ 132,232,189,189,189,95,95,95,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 232,194,189,188,134,147,197,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,209,146,120,120,120,124,235,235,
+ 235,111,111,111,235,235,235,235,235,235,235,235,187,134,134,134,
+ 166,235,235,235,205,189,189,204,235,192,150,150,150,82,16,16,
+ 16,78,228,235,192,189,189,179,135,134,134,134,131,120,111,135,
+ 182,186,186,186,186,186,186,212,235,235,235,235,235,100,16,16,
+ 22,186,189,189,201,95,95,95,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,199,142,120,
+ 156,222,201,217,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,171,120,120,120,120,163,233,235,
+ 235,111,111,111,235,235,235,235,235,235,235,235,137,134,134,134,
+ 216,235,235,235,191,189,189,227,235,235,200,155,150,150,82,16,
+ 16,16,92,232,146,188,189,189,173,172,134,134,134,134,131,120,
+ 116,170,186,186,186,186,149,137,232,235,235,235,235,206,49,16,
+ 16,39,124,189,216,95,95,95,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,181,120,120,120,120,120,
+ 120,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,231,124,120,120,129,161,189,202,233,
+ 235,111,111,111,235,235,235,235,235,235,235,232,134,134,134,187,
+ 235,235,235,235,189,189,189,235,235,235,235,230,192,155,150,82,
+ 16,16,16,167,133,156,189,189,189,202,191,134,134,134,134,134,
+ 137,166,186,186,186,186,135,111,118,188,235,235,235,233,163,21,
+ 16,16,16,65,224,95,95,95,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,181,120,120,120,120,120,120,120,124,
+ 192,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,171,120,120,124,212,189,189,189,189,
+ 189,172,123,111,235,235,235,235,235,235,232,163,134,134,137,235,
+ 235,235,235,235,189,189,189,235,235,235,235,235,235,230,187,150,
+ 29,16,16,48,130,134,161,189,189,189,166,112,122,132,134,134,
+ 134,134,149,185,186,186,173,113,111,111,123,162,204,235,227,130,
+ 27,16,16,16,78,92,95,95,235,235,235,235,235,235,235,235,
+ 235,235,199,142,120,120,120,120,120,120,120,120,120,135,171,224,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,124,120,120,181,235,212,189,189,189,
+ 189,189,187,148,235,235,235,235,235,235,179,134,134,134,113,95,
+ 95,95,95,95,189,189,189,113,182,235,235,235,235,235,235,176,
+ 95,16,16,16,57,134,137,211,189,189,187,123,111,164,177,137,
+ 134,134,134,157,187,186,186,165,113,111,111,111,111,111,138,178,
+ 178,92,16,16,16,38,95,95,235,235,235,235,235,213,171,135,
+ 120,120,120,120,120,120,120,120,120,120,120,135,192,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,231,120,120,120,235,235,235,217,195,189,
+ 189,189,189,189,189,189,208,235,235,235,137,134,134,116,95,95,
+ 95,95,95,95,189,189,189,95,95,113,182,235,235,235,235,230,
+ 160,75,16,16,16,136,197,214,178,189,189,172,173,208,186,183,
+ 157,134,134,134,134,134,149,186,167,114,111,111,111,111,111,131,
+ 189,187,114,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 120,120,120,120,120,120,120,120,135,192,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,164,120,120,124,235,235,235,235,235,235,
+ 228,172,189,189,189,189,189,217,235,216,134,134,134,95,95,95,
+ 95,95,95,95,189,189,189,95,95,95,95,113,182,235,235,235,
+ 216,129,27,16,16,60,185,119,125,187,189,189,194,186,186,186,
+ 188,175,134,134,134,134,134,170,186,178,165,166,131,111,111,122,
+ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 120,120,135,171,224,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,213,120,120,120,181,235,235,235,235,235,235,
+ 235,111,148,179,189,189,189,189,189,189,189,184,179,119,95,95,
+ 235,235,235,235,189,189,189,165,103,95,95,95,95,126,231,235,
+ 216,134,86,16,16,16,43,111,111,149,189,189,189,188,186,188,
+ 231,235,197,147,134,134,134,139,166,186,166,135,120,120,120,120,
+ 120,120,120,120,120,120,120,120,120,120,120,120,120,135,167,206,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,160,120,120,156,235,235,235,235,235,235,235,
+ 235,111,111,111,220,192,189,189,189,189,189,189,189,189,178,130,
+ 235,235,235,235,189,189,189,235,226,165,103,95,95,95,148,187,
+ 134,134,134,74,16,16,16,81,120,199,212,189,189,189,190,216,
+ 235,235,235,235,225,137,134,134,130,126,120,120,120,120,120,120,
+ 120,120,129,147,93,19,16,16,16,43,119,162,204,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,124,120,120,213,235,235,235,235,235,235,235,
+ 235,111,111,111,235,232,212,194,189,189,189,189,189,189,189,189,
+ 189,189,195,217,189,189,189,235,235,235,226,157,95,95,118,134,
+ 134,134,134,117,55,16,16,16,70,150,190,188,189,189,189,195,
+ 217,235,235,235,235,206,134,123,120,120,120,120,120,120,120,129,
+ 161,189,189,183,103,77,22,16,16,16,37,96,111,146,231,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,
+ 235,111,111,111,235,235,235,197,134,134,160,227,210,187,189,189,
+ 189,189,189,189,189,189,189,217,235,235,235,235,139,102,134,134,
+ 134,133,122,111,102,19,16,16,16,150,151,186,188,189,189,189,
+ 189,195,187,142,120,120,120,120,120,120,121,129,152,186,189,189,
+ 189,189,189,189,95,165,206,93,16,16,16,19,66,111,123,162,
+ 204,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,231,120,120,120,235,235,235,235,235,235,235,235,
+ 235,111,111,111,235,235,232,156,134,134,194,235,235,220,144,178,
+ 189,189,189,189,189,189,189,189,194,208,224,235,223,129,134,134,
+ 132,120,111,111,113,138,16,16,16,145,171,186,186,185,147,120,
+ 120,120,120,120,120,120,120,120,122,126,133,134,151,188,189,189,
+ 189,189,189,189,139,235,235,235,139,23,16,16,16,58,111,111,
+ 111,146,231,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,171,120,120,124,235,235,235,235,235,235,235,235,
+ 235,111,111,111,231,235,179,134,134,134,225,235,235,235,157,95,
+ 95,126,210,195,189,189,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,189,189,189,32,16,16,91,120,120,120,120,120,120,
+ 120,120,120,120,120,120,129,150,183,189,189,189,189,189,189,187,
+ 133,189,189,189,208,235,235,235,235,201,64,16,16,16,55,111,
+ 111,111,146,231,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,124,120,120,181,235,235,235,235,235,235,235,235,
+ 235,123,111,111,154,235,137,134,134,187,235,235,235,235,222,99,
+ 95,95,134,231,235,189,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,189,189,189,118,81,120,120,120,120,120,120,120,120,
+ 120,120,129,150,183,189,189,189,189,189,189,189,189,189,188,162,
+ 106,189,189,189,235,235,235,235,235,235,235,37,16,16,16,16,
+ 49,108,111,123,162,204,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,184,111,111,111,229,134,134,134,235,235,235,235,235,235,178,
+ 95,95,95,134,235,194,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,176,150,129,120,120,120,120,120,120,120,120,129,161,
+ 189,189,189,189,189,189,189,189,189,189,189,189,188,165,139,134,
+ 134,189,189,189,235,235,235,235,235,235,235,173,30,16,16,16,
+ 16,28,75,111,111,111,111,154,231,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,111,111,111,194,134,134,160,235,235,235,235,235,235,235,
+ 165,95,95,95,191,222,194,189,189,189,189,188,173,159,135,118,
+ 102,109,121,120,120,120,120,120,120,120,107,55,166,227,179,150,
+ 150,150,150,167,203,189,189,189,189,189,189,184,164,170,137,134,
+ 134,189,189,189,235,235,235,235,235,235,235,235,173,44,16,16,
+ 16,16,16,16,16,49,108,111,146,231,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,123,111,112,136,134,134,194,235,235,235,235,235,235,235,
+ 235,152,95,95,95,96,132,139,188,189,189,189,178,161,142,125,
+ 120,120,120,120,120,120,120,128,159,86,16,16,57,235,235,214,
+ 163,150,150,150,174,216,195,189,189,189,189,189,189,189,188,165,
+ 134,189,189,189,134,158,210,235,235,235,235,235,235,235,235,146,
+ 30,16,16,16,16,16,28,75,111,127,188,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,184,111,124,134,134,134,225,235,235,235,235,235,235,235,
+ 235,222,99,113,134,134,134,134,151,170,150,129,120,120,120,120,
+ 120,120,120,128,167,200,179,186,186,169,21,16,16,132,235,235,
+ 235,192,150,150,150,175,173,146,135,154,178,189,189,189,189,189,
+ 184,189,189,189,134,134,134,138,216,235,235,235,235,235,235,235,
+ 221,125,44,16,16,16,16,16,16,16,55,123,162,204,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,173,133,134,134,144,231,235,235,235,235,235,235,235,
+ 235,235,164,131,126,122,120,120,120,120,120,120,120,120,120,120,
+ 127,146,162,208,223,200,186,186,186,152,68,16,16,23,201,235,
+ 235,235,187,150,150,150,119,95,95,95,95,131,196,192,189,189,
+ 189,189,189,187,134,134,134,134,133,150,232,235,235,235,235,235,
+ 235,235,235,235,146,30,16,16,16,16,16,16,49,108,127,188,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,216,134,134,134,111,154,235,235,235,235,235,235,235,
+ 235,197,124,120,120,120,120,120,120,120,120,120,118,112,114,164,
+ 189,189,189,189,189,189,188,187,158,121,118,36,16,16,44,153,
+ 235,191,121,132,150,150,150,110,95,108,161,231,235,232,210,189,
+ 189,189,189,194,170,135,133,134,134,134,144,232,235,235,235,235,
+ 235,235,235,235,235,221,125,44,16,16,16,16,16,43,108,111,
+ 146,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,169,134,134,127,111,111,111,111,111,111,111,112,116,
+ 119,120,120,120,120,120,120,120,120,117,110,101,95,95,95,95,
+ 139,178,189,189,189,189,189,189,189,170,160,124,20,16,16,16,
+ 38,95,95,96,139,150,150,150,201,235,235,235,235,235,235,217,
+ 192,189,187,186,200,235,179,134,134,134,134,146,197,235,235,235,
+ 235,235,235,235,235,235,235,235,173,44,16,16,16,16,16,49,
+ 108,111,162,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,137,134,134,125,111,111,112,116,119,120,120,120,120,
+ 120,120,120,121,121,114,111,173,235,231,200,169,143,121,95,95,
+ 95,95,113,148,189,189,189,189,189,189,189,189,129,27,16,16,
+ 16,142,121,116,156,158,150,150,160,224,235,235,235,235,235,235,
+ 235,211,186,186,186,220,235,229,152,134,134,134,134,163,232,235,
+ 235,235,235,235,235,235,235,235,235,235,235,125,16,16,16,16,
+ 28,75,115,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,200,125,119,120,120,120,120,120,120,120,
+ 120,121,126,132,111,127,184,235,235,235,235,235,235,235,235,208,
+ 95,95,95,113,186,187,188,171,189,189,189,189,189,178,16,16,
+ 16,76,184,189,189,194,179,169,162,168,222,235,235,235,235,235,
+ 235,235,206,186,186,196,235,235,235,190,140,134,134,134,163,232,
+ 235,235,235,235,235,235,235,235,235,235,235,235,153,44,16,16,
+ 16,16,65,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,131,126,135,120,120,120,120,120,120,120,134,137,
+ 130,134,147,197,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,224,213,204,180,189,32,16,
+ 16,16,65,189,189,189,189,189,189,189,189,189,189,189,189,195,
+ 217,235,231,188,186,186,220,235,235,235,229,179,134,134,134,163,
+ 232,235,235,235,235,235,235,235,235,235,235,235,235,235,146,30,
+ 16,16,16,92,228,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,120,120,120,167,235,235,235,235,199,142,120,120,
+ 120,120,120,120,120,120,120,120,120,124,167,206,235,235,179,134,
+ 134,134,216,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,213,125,98,31,
+ 16,16,16,141,189,189,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,189,188,186,186,203,234,235,235,235,184,134,134,134,
+ 147,197,235,235,235,235,235,235,235,235,235,235,235,235,235,221,
+ 37,16,16,16,92,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,131,120,120,120,120,120,120,120,120,120,120,120,
+ 120,120,120,120,120,120,120,131,171,224,235,235,235,235,137,134,
+ 134,184,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,192,125,121,
+ 59,16,16,57,228,227,220,212,198,185,189,189,189,189,189,189,
+ 189,189,189,189,189,186,186,186,200,235,235,235,235,184,134,134,
+ 134,134,156,219,235,235,235,235,235,235,235,235,235,235,235,235,
+ 173,44,16,16,16,16,105,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,203,128,120,120,120,120,120,120,120,120,120,120,
+ 120,120,120,120,122,126,206,235,235,235,235,235,235,232,134,134,
+ 134,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,210,136,
+ 111,19,16,16,78,228,235,235,235,230,176,150,150,150,195,212,
+ 195,189,189,195,208,192,186,186,186,220,235,235,235,235,194,140,
+ 134,134,134,137,187,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,37,16,16,16,16,105,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,203,135,120,120,120,120,120,135,171,224,235,
+ 235,235,235,134,134,134,235,235,235,235,235,235,235,179,134,134,
+ 137,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,228,
+ 157,78,16,16,16,78,235,235,235,235,235,190,150,150,152,222,
+ 235,235,235,235,235,235,206,186,186,196,235,235,235,235,235,229,
+ 184,137,134,134,134,163,232,235,235,235,235,235,235,235,235,235,
+ 235,235,173,44,16,16,16,16,78,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,235,235,235,235,235,235,232,137,134,134,
+ 187,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,235,
+ 235,175,68,16,16,16,166,235,235,235,235,232,166,150,150,168,
+ 232,235,235,235,235,235,231,188,186,186,220,235,235,235,235,235,
+ 235,219,156,134,134,134,163,232,235,235,235,235,235,235,235,235,
+ 235,235,235,235,173,30,16,16,16,166,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,235,235,235,235,235,235,175,134,134,137,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,235,
+ 235,232,143,59,16,16,44,201,235,235,235,235,219,152,150,150,
+ 174,232,235,235,235,235,235,208,186,186,186,200,235,235,235,235,
+ 235,235,235,182,134,134,134,163,232,235,235,235,235,235,235,235,
+ 235,235,235,235,235,173,44,16,16,16,105,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,235,235,235,235,235,229,137,134,134,187,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,235,
+ 235,235,213,114,19,16,16,46,153,235,235,235,235,198,150,150,
+ 150,174,232,235,235,235,235,231,188,186,186,186,220,235,235,235,
+ 235,235,235,235,184,134,134,134,163,232,235,235,235,235,235,235,
+ 235,235,235,235,235,235,215,23,16,16,16,105,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,235,235,235,235,235,197,134,134,160,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,235,
+ 235,235,235,203,87,16,16,16,46,199,235,235,235,235,192,150,
+ 150,150,174,232,235,235,235,235,220,192,186,186,186,200,235,235,
+ 235,235,235,235,235,184,134,134,134,163,232,235,235,235,235,235,
+ 235,235,235,235,235,235,235,166,30,16,16,16,228,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,235,235,235,235,232,156,134,134,194,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,208,
+ 95,95,95,235,186,186,186,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,115,16,16,16,96,192,235,235,235,235,192,
+ 150,150,150,174,232,235,235,235,235,231,188,186,186,186,220,235,
+ 235,235,235,235,235,235,184,134,134,134,163,232,235,235,235,235,
+ 235,235,235,235,235,235,235,235,173,30,16,16,92,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,134,134,134,232,235,235,235,172,134,134,134,225,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,139,
+ 95,95,139,235,191,186,186,220,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,101,16,16,36,118,153,232,235,235,235,
+ 192,150,150,150,174,235,235,235,235,235,220,192,186,186,196,234,
+ 235,235,235,235,235,235,235,184,134,134,134,163,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,146,16,16,23,228,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,144,134,134,163,232,235,216,134,134,134,187,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,208,95,
+ 95,95,208,235,208,186,186,196,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,215,22,16,16,46,118,153,232,235,235,
+ 235,192,150,150,150,208,235,235,235,235,235,231,188,186,186,200,
+ 235,235,235,235,235,235,235,235,184,134,134,134,187,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,153,71,153,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,194,134,134,134,169,235,169,134,134,166,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,139,95,
+ 95,139,235,235,231,186,186,186,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,146,16,16,16,46,118,153,232,235,
+ 235,235,184,150,150,166,235,235,235,235,235,235,215,186,186,186,
+ 220,235,235,235,235,235,235,235,235,182,134,134,137,219,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,184,134,134,134,175,137,134,134,216,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,208,95,95,
+ 95,208,235,235,235,186,186,186,234,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,125,16,16,16,39,118,121,168,
+ 235,235,227,152,150,150,195,235,235,235,235,235,235,206,186,186,
+ 186,203,234,235,235,235,235,235,235,232,153,134,134,144,175,210,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,144,134,134,134,134,134,134,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,139,95,95,
+ 139,235,235,235,235,191,186,186,203,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,125,16,16,16,56,121,125,
+ 235,235,235,192,150,150,152,222,235,235,235,235,235,231,188,186,
+ 186,186,203,235,235,235,235,235,235,235,216,137,134,134,134,134,
+ 166,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,206,140,134,134,134,134,137,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,226,99,95,95,
+ 208,235,235,235,235,215,186,186,186,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,125,16,16,16,98,192,
+ 235,235,235,232,166,150,150,168,235,235,235,235,235,235,220,192,
+ 186,186,186,235,235,235,235,235,235,235,235,206,147,134,134,134,
+ 134,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,206,147,134,134,147,197,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,182,95,95,130,
+ 235,235,235,235,235,235,186,186,186,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,85,16,16,30,208,
+ 235,235,235,235,219,152,150,150,216,235,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,216,179,160,
+ 197,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,130,95,95,178,
+ 235,235,235,235,235,235,186,186,186,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,221,44,16,16,64,
+ 235,235,235,235,235,184,150,150,190,235,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,182,95,95,95,222,
+ 235,235,235,235,235,235,186,186,186,234,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,187,23,16,16,
+ 132,235,235,235,235,214,150,150,150,184,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,169,95,
+ 152,235,235,235,235,235,235,235,235,235,222,103,95,95,152,235,
+ 235,235,235,235,235,235,191,186,186,203,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,125,16,16,
+ 23,201,235,235,235,235,158,150,150,152,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,99,95,
+ 95,235,235,235,235,235,235,235,235,235,143,95,95,113,231,235,
+ 235,235,235,235,235,235,215,186,186,186,234,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,228,57,16,
+ 16,64,228,235,235,235,208,160,160,203,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,95,95,
+ 95,95,152,235,235,235,235,235,235,191,99,95,95,200,235,235,
+ 235,235,235,235,235,235,235,191,186,186,203,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,194,23,
+ 16,16,78,228,235,235,235,235,235,235,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,108,95,
+ 95,95,95,95,95,95,95,95,95,95,95,95,99,235,235,235,
+ 235,235,235,235,235,235,235,215,186,186,186,234,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,139,
+ 16,16,16,78,228,235,235,235,235,235,235,235,235,235,235,235,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,196,113,
+ 95,95,95,95,95,95,95,95,95,95,95,99,169,235,235,235,
+ 235,235,235,235,235,235,235,235,191,186,186,200,234,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 125,16,16,16,78,235,235,235,235,235,235,235,235,235,235,234,
+ 186,186,186,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 196,113,95,95,95,95,95,95,95,113,157,222,235,235,235,235,
+ 235,235,235,235,235,235,235,235,215,186,186,186,200,234,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,125,16,16,16,187,235,235,235,235,235,235,235,235,234,200,
+ 186,186,188,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,211,186,186,186,200,234,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,99,16,16,119,235,235,235,235,235,235,235,234,200,186,
+ 186,186,212,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,211,186,186,186,192,217,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,180,16,16,44,228,235,235,235,235,235,235,208,186,186,
+ 186,211,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,211,186,186,186,186,
+ 200,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,37,16,16,78,228,234,205,186,186,186,186,186,186,
+ 211,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,215,190,186,186,
+ 186,220,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,234,128,16,16,16,64,181,186,186,186,186,186,186,188,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,232,203,186,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 186,186,186,186,101,16,16,16,64,181,186,186,186,186,192,217,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,231,188,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 186,186,186,186,186,101,16,16,16,66,209,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,220,
+ 192,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 186,186,186,192,215,235,125,16,16,16,78,228,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,125,16,16,16,78,228,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,125,16,16,16,78,228,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,125,16,16,16,78,228,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,125,16,16,16,78,228,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,125,16,16,16,78,
+ 228,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,125,16,16,16,
+ 78,228,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,125,16,16,
+ 16,78,228,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,125,16,
+ 16,16,16,16,105,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,125,
+ 16,16,16,16,23,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 153,44,16,44,153,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,136,128,136,128,136,128,136,128,136,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 112,145,99,159,99,159,83,176,81,153,88,131,101,84,105,73,
+ 133,114,144,129,144,129,144,129,131,138,123,143,123,143,121,143,
+ 115,143,115,143,127,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,133,121,152,95,155,90,155,90,155,90,
+ 155,90,155,90,155,90,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,122,135,
+ 107,152,118,140,128,128,111,147,103,158,103,158,103,158,107,153,
+ 115,143,122,135,128,128,128,128,128,128,112,145,94,165,74,186,
+ 71,190,71,190,71,190,87,138,105,73,105,73,110,85,120,100,
+ 144,129,120,147,88,131,100,120,103,158,103,158,103,158,103,158,
+ 103,158,103,158,103,158,103,158,107,153,115,143,127,128,128,128,
+ 128,128,133,121,153,94,183,52,183,52,183,52,183,52,183,52,
+ 183,52,183,52,179,57,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,103,157,
+ 103,158,115,143,128,128,128,128,115,143,115,143,115,143,104,156,
+ 103,158,103,158,115,143,128,128,122,135,84,175,73,187,92,167,
+ 111,146,128,128,110,85,105,73,111,87,128,128,128,128,144,129,
+ 144,129,116,140,88,172,103,158,95,166,88,148,115,99,106,76,
+ 112,83,127,120,123,143,121,143,104,156,103,158,117,139,164,78,
+ 183,52,183,52,183,52,167,73,135,118,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,103,158,
+ 103,158,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,124,132,93,167,108,151,125,131,128,128,128,128,128,128,
+ 128,128,108,81,105,73,111,88,128,128,128,128,128,128,144,129,
+ 135,128,118,139,103,158,109,150,99,159,71,190,79,181,117,139,
+ 128,126,130,118,147,137,144,129,156,135,166,89,183,52,181,53,
+ 147,100,152,95,135,118,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,123,161,
+ 128,162,128,162,128,162,128,128,128,135,128,162,128,159,128,142,
+ 128,128,128,128,71,190,71,190,109,150,122,135,128,128,127,128,
+ 127,125,105,73,121,111,128,128,128,128,128,128,131,128,144,129,
+ 118,139,103,158,109,150,128,128,128,128,113,143,74,187,113,175,
+ 154,161,154,161,159,126,170,78,183,52,181,52,157,88,122,152,
+ 103,158,103,158,121,142,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,157,128,162,
+ 115,160,115,160,128,145,128,129,128,128,128,145,128,153,128,162,
+ 128,159,128,145,99,176,89,180,128,128,117,141,123,133,128,128,
+ 128,128,124,118,128,128,128,128,128,128,128,128,144,129,129,140,
+ 103,158,109,150,128,128,128,128,128,128,128,128,147,155,159,140,
+ 171,96,179,58,183,52,180,55,164,88,130,103,108,80,128,128,
+ 117,142,114,156,103,158,108,152,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,137,128,158,128,162,128,136,
+ 104,156,103,158,124,133,128,128,128,128,128,128,128,128,128,136,
+ 128,153,128,162,128,162,128,162,128,162,128,156,128,143,110,142,
+ 113,146,128,128,128,128,127,128,128,128,127,128,117,148,103,158,
+ 109,150,128,128,128,128,128,128,128,128,160,119,176,78,183,52,
+ 179,56,140,104,124,128,128,128,143,129,144,129,105,73,124,119,
+ 128,128,129,129,121,157,103,158,109,157,127,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,162,128,161,128,136,128,128,
+ 124,132,103,157,103,158,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,71,190,120,151,128,145,128,159,128,162,128,162,
+ 123,153,127,144,128,128,125,131,123,133,107,153,123,161,128,162,
+ 128,162,128,162,131,155,155,107,180,58,183,52,176,61,152,95,
+ 123,133,81,179,71,190,128,128,131,128,144,129,105,73,107,78,
+ 128,128,128,128,128,128,124,140,103,158,106,153,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,162,128,134,128,128,128,128,
+ 128,128,124,133,103,158,115,149,135,129,128,128,128,128,128,128,
+ 128,128,128,128,71,190,128,128,128,128,128,128,128,131,115,111,
+ 127,152,128,162,128,153,128,130,128,128,123,154,135,148,140,127,
+ 151,113,163,91,183,52,183,52,168,81,145,127,128,143,114,173,
+ 119,155,125,131,71,190,86,172,128,128,144,129,123,117,105,73,
+ 128,128,128,128,128,128,128,128,141,160,103,158,106,154,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,138,128,162,128,128,128,128,128,128,
+ 128,128,128,128,116,143,103,158,110,153,134,128,128,128,128,128,
+ 128,128,128,128,71,190,128,128,128,128,128,128,123,115,105,73,
+ 128,155,128,162,128,162,131,155,155,90,179,57,183,52,183,52,
+ 183,52,176,60,158,86,155,137,154,161,128,152,128,162,124,170,
+ 100,218,100,219,102,156,71,190,119,137,144,129,128,128,105,73,
+ 128,128,128,128,128,128,128,128,154,161,114,144,103,158,123,133,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,161,128,162,128,128,128,128,128,128,
+ 128,128,128,128,128,128,113,146,103,158,121,145,129,128,128,128,
+ 134,128,128,128,71,190,128,128,128,128,128,128,109,81,116,118,
+ 129,158,142,121,158,85,183,52,183,52,168,72,148,100,140,128,
+ 131,153,118,160,116,159,139,161,131,159,125,131,128,137,128,162,
+ 124,170,100,219,128,128,71,189,76,184,144,129,128,128,105,73,
+ 128,128,128,128,128,128,128,128,154,161,128,128,104,157,103,158,
+ 124,133,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,162,128,152,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,111,148,103,158,123,142,128,128,
+ 130,128,139,128,84,178,128,128,128,128,128,128,146,102,168,81,
+ 183,52,183,52,180,55,159,98,137,143,128,128,130,128,128,128,
+ 128,147,128,162,128,162,128,162,127,161,121,161,114,159,113,154,
+ 128,162,105,196,128,128,112,144,71,190,144,129,128,128,105,73,
+ 128,128,128,128,128,128,128,128,151,157,128,128,127,129,103,157,
+ 105,155,127,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,110,149,103,158,111,148,
+ 128,128,135,128,144,129,137,128,150,97,178,60,183,52,169,67,
+ 147,100,131,122,128,128,128,162,128,156,128,128,143,129,132,128,
+ 128,128,128,155,128,161,147,161,128,147,128,155,128,162,126,161,
+ 128,162,125,161,115,143,127,128,71,190,144,129,128,128,105,73,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,123,134,
+ 103,158,107,153,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,113,146,103,158,
+ 120,137,143,106,165,85,180,57,183,52,171,76,133,128,103,158,
+ 110,150,128,128,128,153,128,162,128,131,128,128,131,128,144,129,
+ 128,128,128,128,128,150,131,161,128,128,128,128,128,136,128,154,
+ 128,162,128,162,123,161,117,155,81,180,144,129,128,128,105,73,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 104,156,103,158,119,138,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,142,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,131,122,
+ 172,67,183,52,180,55,162,87,143,131,125,159,103,158,120,135,
+ 129,128,128,128,128,162,128,162,128,128,128,128,128,128,131,128,
+ 133,128,125,131,128,128,128,162,128,157,99,159,99,159,85,204,
+ 81,192,128,162,128,162,128,162,128,162,128,162,117,128,105,74,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 124,133,104,156,103,158,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,161,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,147,102,171,68,183,52,
+ 178,58,129,124,128,128,127,134,128,162,103,158,113,150,144,129,
+ 143,128,135,128,128,162,128,162,74,186,71,190,71,190,71,190,
+ 71,190,73,187,128,128,131,137,128,162,91,180,81,153,88,131,
+ 88,131,128,162,128,162,130,125,136,145,124,153,128,162,120,154,
+ 127,131,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,123,134,103,158,127,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,162,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,129,127,156,89,183,52,172,66,152,93,
+ 129,127,124,133,120,137,128,128,128,149,106,154,128,128,116,97,
+ 133,114,144,129,128,162,128,162,92,167,99,159,99,159,99,159,
+ 99,159,107,150,125,131,128,128,126,153,128,162,104,115,104,115,
+ 104,115,128,162,128,162,123,143,123,143,105,119,116,159,127,161,
+ 127,161,123,144,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,107,153,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,162,128,162,128,128,128,128,128,128,128,128,
+ 128,128,128,128,151,96,183,52,183,52,166,74,128,128,128,128,
+ 128,128,128,128,108,152,128,135,128,128,103,157,111,148,126,129,
+ 84,155,112,102,128,162,128,162,139,128,133,128,128,128,120,137,
+ 107,152,103,158,103,158,125,131,127,128,128,161,113,159,103,158,
+ 103,158,128,162,128,162,103,158,103,158,103,158,103,158,106,158,
+ 124,161,128,162,124,159,127,143,128,132,128,128,128,128,128,128,
+ 128,128,128,128,103,158,103,158,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,162,128,162,128,128,128,128,128,128,128,128,
+ 129,127,174,64,183,52,175,81,152,129,141,144,141,144,136,139,
+ 128,128,108,152,103,158,128,160,128,128,124,132,103,158,101,160,
+ 85,176,111,146,128,162,128,162,142,126,143,129,114,142,103,158,
+ 104,156,112,134,128,159,143,157,128,128,128,133,129,160,144,129,
+ 135,142,128,162,128,162,128,128,128,128,128,128,127,129,117,141,
+ 114,144,114,159,122,161,128,162,128,162,124,145,127,128,128,128,
+ 128,128,128,128,103,158,103,158,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,160,128,162,128,128,128,128,128,128,136,116,
+ 175,63,183,52,162,128,154,161,154,161,154,161,154,161,154,161,
+ 149,160,103,158,125,157,128,162,128,155,128,128,106,151,97,164,
+ 103,158,103,158,128,162,128,162,123,112,112,151,103,158,115,149,
+ 105,73,123,106,154,161,147,151,137,129,128,128,128,149,131,144,
+ 128,128,128,162,128,162,121,149,128,128,128,128,128,128,128,128,
+ 128,128,123,133,115,143,113,148,122,161,128,162,128,162,114,159,
+ 114,149,128,128,103,158,103,158,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,135,128,162,128,157,128,128,149,100,183,52,
+ 182,53,161,133,151,157,128,128,128,128,128,128,128,128,137,145,
+ 103,158,103,158,154,161,128,162,154,161,136,138,128,128,138,141,
+ 135,152,116,159,128,162,128,162,108,151,103,158,105,132,144,129,
+ 132,111,154,161,147,153,139,128,144,129,128,128,128,128,128,149,
+ 128,128,128,162,128,162,100,217,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,127,129,122,150,121,161,128,162,
+ 128,162,120,160,103,158,103,157,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,136,128,162,128,155,183,52,169,71,
+ 130,124,154,161,134,136,128,128,128,128,128,128,128,128,107,153,
+ 103,158,122,135,128,131,128,162,85,174,71,190,113,144,128,128,
+ 144,148,154,161,129,161,128,162,103,158,103,158,140,137,146,141,
+ 144,129,147,139,131,122,144,129,139,128,128,128,128,129,128,128,
+ 128,128,128,162,128,162,100,219,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,119,141,
+ 127,145,128,162,103,158,111,148,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,144,113,183,52,183,52,128,128,
+ 128,128,154,161,128,128,128,128,128,128,128,128,110,149,103,158,
+ 117,141,128,128,128,155,128,162,128,128,88,171,71,190,113,143,
+ 128,128,128,128,118,135,128,162,112,159,103,158,106,158,132,159,
+ 149,145,144,129,144,129,145,134,127,127,128,128,128,128,128,131,
+ 128,128,128,155,128,147,100,219,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,141,110,155,90,178,59,
+ 174,64,128,140,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,182,53,182,53,139,139,128,157,
+ 128,145,152,161,128,128,128,128,128,128,127,128,103,158,103,157,
+ 128,128,128,128,128,162,128,162,128,128,128,128,113,143,83,176,
+ 125,131,128,128,103,156,122,161,128,162,128,148,116,159,103,158,
+ 106,157,129,139,144,129,148,143,151,156,140,143,131,132,128,142,
+ 128,129,128,128,128,129,100,219,128,128,128,128,128,128,128,128,
+ 128,128,136,116,155,90,155,90,183,52,183,52,183,52,171,68,
+ 138,113,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,129,127,183,52,141,110,128,136,128,159,
+ 128,162,128,161,128,145,128,138,128,128,109,151,103,158,101,204,
+ 100,219,100,219,128,162,128,162,109,190,123,145,128,128,128,128,
+ 86,173,128,128,123,133,111,148,130,161,128,161,147,153,131,136,
+ 112,151,103,158,123,144,129,139,147,143,154,161,154,161,151,157,
+ 128,160,145,107,155,90,141,135,155,90,155,90,155,90,171,68,
+ 183,52,183,52,183,52,183,52,179,57,155,90,138,113,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,172,66,183,52,128,128,128,128,128,128,
+ 128,130,135,161,128,162,128,162,128,145,115,160,112,157,100,219,
+ 114,173,114,173,128,162,128,162,101,216,100,219,109,190,127,129,
+ 119,138,120,138,128,128,133,139,152,161,128,162,129,157,144,129,
+ 137,128,111,148,103,158,103,158,136,134,143,109,166,104,169,105,
+ 183,52,183,52,183,52,183,52,183,52,183,52,183,52,172,67,
+ 155,90,152,95,130,124,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,183,52,152,95,128,128,128,128,128,128,
+ 128,128,154,161,128,133,128,153,128,162,128,162,128,162,126,165,
+ 128,145,128,142,128,162,128,162,127,131,114,173,100,219,107,184,
+ 103,158,103,158,133,134,128,128,124,158,113,153,128,162,130,157,
+ 128,134,128,128,127,129,116,141,155,88,183,52,183,52,183,52,
+ 166,84,152,114,138,172,128,129,128,128,143,146,144,148,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,129,127,183,52,128,128,128,128,128,128,128,128,
+ 128,128,154,161,128,128,127,128,103,158,113,145,128,137,121,175,
+ 128,162,128,162,128,162,128,162,128,143,128,132,117,163,103,158,
+ 105,159,141,159,152,157,128,128,128,128,92,172,140,137,145,127,
+ 155,107,164,82,183,52,183,52,181,53,145,101,118,148,128,162,
+ 128,162,128,162,104,205,130,130,128,128,128,128,135,136,153,159,
+ 144,148,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,170,70,183,52,128,128,128,128,128,128,128,128,
+ 128,128,154,161,137,139,109,151,103,158,127,129,128,128,118,157,
+ 100,219,118,169,128,145,128,162,128,162,128,162,128,162,128,162,
+ 128,162,128,162,128,162,128,138,155,90,183,52,183,52,183,52,
+ 183,52,179,59,158,101,152,114,130,156,128,162,128,162,127,161,
+ 106,197,128,162,125,136,128,128,128,128,128,128,128,128,133,134,
+ 145,150,150,156,136,138,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,183,52,183,52,128,128,128,128,128,128,128,128,
+ 128,128,154,161,154,161,103,158,106,154,128,128,128,128,128,128,
+ 107,196,100,219,123,142,128,160,128,162,128,162,124,161,130,161,
+ 127,169,150,116,171,76,183,52,183,52,179,57,155,90,133,117,
+ 99,176,99,176,127,156,128,162,128,162,128,162,126,160,106,157,
+ 103,158,128,162,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,136,138,141,144,154,160,138,140,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,183,52,183,52,128,128,128,128,128,128,128,128,
+ 128,128,145,149,139,160,103,158,122,135,128,128,128,128,128,128,
+ 128,128,100,217,101,188,103,163,119,160,143,131,159,98,174,69,
+ 183,52,183,52,172,67,159,85,152,113,128,127,128,128,128,128,
+ 104,154,71,190,79,181,122,162,120,178,126,165,128,162,128,160,
+ 116,156,128,162,103,154,112,146,126,129,128,128,128,128,128,128,
+ 128,128,128,128,128,128,130,130,141,144,138,140,136,138,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,183,52,183,52,128,128,128,128,128,128,128,128,
+ 128,128,128,128,104,158,103,158,137,139,128,128,128,128,128,128,
+ 128,128,140,114,165,75,183,52,183,52,183,52,179,60,159,99,
+ 153,112,135,146,128,149,139,139,134,115,111,87,128,128,128,128,
+ 128,128,100,182,71,190,79,198,100,219,106,197,126,141,128,154,
+ 128,162,128,162,109,135,103,156,103,156,117,129,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,132,133,152,158,
+ 137,140,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,183,52,183,52,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,131,158,154,161,162,130,168,106,171,96,
+ 181,59,183,52,172,74,168,106,155,90,135,135,105,203,100,219,
+ 106,205,117,185,129,159,128,162,128,162,123,142,127,138,128,128,
+ 124,141,104,211,92,188,71,190,95,166,128,128,128,128,128,128,
+ 128,142,141,135,142,129,122,123,105,150,103,158,111,148,127,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 143,146,149,154,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,183,52,183,52,128,128,128,128,128,128,128,128,
+ 128,128,128,128,111,148,155,99,180,62,183,52,183,52,179,57,
+ 153,92,127,126,141,144,133,134,128,128,128,128,128,128,128,128,
+ 100,219,100,219,144,129,139,138,128,145,128,153,126,154,128,129,
+ 128,128,128,149,128,162,119,165,108,171,123,150,128,145,128,145,
+ 128,134,134,128,144,129,130,128,128,128,115,143,103,158,106,153,
+ 127,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,129,129,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,180,55,183,52,155,90,155,90,164,78,183,52,
+ 183,52,183,52,183,52,183,52,171,68,144,105,128,128,109,151,
+ 103,158,125,131,128,128,128,128,128,128,128,128,128,128,128,128,
+ 100,219,100,219,144,129,144,129,128,128,128,128,126,123,109,85,
+ 123,117,128,128,128,145,128,150,126,158,128,162,128,162,128,162,
+ 128,162,128,162,131,154,144,129,134,128,128,128,122,135,103,158,
+ 104,156,118,140,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,135,117,179,57,183,52,183,52,179,57,158,86,
+ 155,90,155,90,138,111,135,118,128,128,128,128,128,128,103,158,
+ 103,157,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 100,219,100,219,144,129,144,129,128,128,128,128,128,128,125,122,
+ 109,84,128,128,128,128,128,128,128,128,108,149,71,190,87,172,
+ 128,142,128,145,129,134,141,129,144,129,128,128,128,128,123,134,
+ 109,150,103,158,110,150,127,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,128,128,128,128,128,128,120,137,103,158,
+ 122,135,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 100,219,100,219,144,129,144,129,128,128,128,128,128,128,128,128,
+ 128,128,113,91,128,128,127,125,128,128,128,128,99,159,71,190,
+ 106,151,128,128,128,128,129,128,144,129,138,128,128,128,128,128,
+ 128,128,118,140,103,158,106,153,127,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,128,128,128,128,128,128,103,157,106,154,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 100,219,100,219,144,129,144,129,128,128,128,128,128,128,128,128,
+ 128,128,126,123,121,112,128,128,117,102,128,128,128,128,85,174,
+ 71,190,106,151,128,128,128,128,138,128,144,129,138,128,128,128,
+ 128,128,128,128,122,135,103,158,106,153,127,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,127,128,128,128,119,138,103,158,122,135,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 100,219,104,205,143,129,144,129,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,127,127,128,128,113,90,127,127,128,128,
+ 85,174,71,190,106,151,128,128,128,128,138,128,144,129,137,128,
+ 128,128,128,128,128,128,122,135,103,158,106,153,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,103,158,106,153,128,128,103,158,107,153,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,116,168,
+ 100,219,125,136,133,128,144,129,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,124,120,109,81,127,127,
+ 128,128,82,177,71,190,128,128,128,128,128,128,139,128,144,129,
+ 130,128,128,128,128,128,128,128,122,135,103,158,110,149,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,122,135,103,158,108,152,103,158,125,131,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,100,219,
+ 104,205,128,128,128,128,144,129,133,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,125,122,105,73,
+ 128,128,125,131,71,190,86,172,128,128,128,128,128,128,144,129,
+ 144,129,133,128,128,128,128,128,128,128,115,143,103,158,108,152,
+ 119,138,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,113,146,103,158,104,156,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,122,148,100,219,
+ 125,136,128,128,128,128,144,129,144,129,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,121,111,
+ 128,128,128,128,99,159,71,190,122,135,128,128,128,128,130,128,
+ 144,129,144,129,128,128,128,128,128,128,128,128,117,141,108,151,
+ 111,148,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,103,207,100,219,
+ 128,128,128,128,128,128,144,129,144,129,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,71,190,84,175,128,128,128,128,128,128,
+ 144,129,144,129,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,108,193,
+ 105,200,128,128,128,128,128,128,128,128,117,162,100,219,119,156,
+ 128,128,128,128,128,128,139,128,144,129,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,93,165,74,186,128,128,128,128,128,128,
+ 144,129,144,129,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,101,215,
+ 100,219,105,200,114,173,114,173,114,173,100,217,100,217,128,128,
+ 128,128,128,128,128,128,128,128,144,129,141,129,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 144,129,144,129,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,124,141,
+ 110,186,100,219,100,219,100,219,100,219,106,199,121,149,128,128,
+ 128,128,128,128,128,128,128,128,139,128,144,129,134,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 144,129,144,129,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,140,128,144,129,135,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,142,129,
+ 144,129,131,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,139,128,144,129,
+ 142,129,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,136,128,144,129,144,129,144,129,
+ 132,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,134,128,
+ 144,129,144,129,144,129,144,129,144,129,144,129,144,129,144,129,
+ 144,129,144,129,140,129,128,128,130,128,139,128,136,128,135,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 135,128,136,128,136,128,136,128,136,128,136,128,136,128,136,128,
+ 136,128,136,128,131,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+}; \ No newline at end of file