diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer_gl.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer_gl.h index bf6bb09b5129f..28b6530ce5d8d 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer_gl.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer_gl.h @@ -9,7 +9,7 @@ #include -#include "flutter/testing/test_gl_surface.h" +#include "flutter/testing/test_gl_context.h" namespace flutter::testing { diff --git a/shell/platform/embedder/tests/embedder_test_compositor_gl.h b/shell/platform/embedder/tests/embedder_test_compositor_gl.h index 2569b910e4981..b3b9647b05a23 100644 --- a/shell/platform/embedder/tests/embedder_test_compositor_gl.h +++ b/shell/platform/embedder/tests/embedder_test_compositor_gl.h @@ -10,7 +10,7 @@ #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/tests/embedder_test_compositor.h" -#include "flutter/testing/test_gl_surface.h" +#include "flutter/testing/test_gl_context.h" namespace flutter { namespace testing { diff --git a/shell/platform/embedder/tests/embedder_test_context_gl.h b/shell/platform/embedder/tests/embedder_test_context_gl.h index 85581783940ec..a16cbca55d1ea 100644 --- a/shell/platform/embedder/tests/embedder_test_context_gl.h +++ b/shell/platform/embedder/tests/embedder_test_context_gl.h @@ -7,7 +7,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context.h" -#include "flutter/testing/test_gl_surface.h" +#include "flutter/testing/test_gl_context.h" namespace flutter { namespace testing { diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 8bf238a242970..1a4dc09fe07e7 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -223,8 +223,12 @@ if (use_swiftshader) { testonly = true sources = [ + "test_gl_context.cc", + "test_gl_context.h", "test_gl_surface.cc", "test_gl_surface.h", + "test_gl_utils.cc", + "test_gl_utils.h", ] deps = [ diff --git a/testing/test_gl_context.cc b/testing/test_gl_context.cc new file mode 100644 index 0000000000000..3e3b329d933ba --- /dev/null +++ b/testing/test_gl_context.cc @@ -0,0 +1,128 @@ +// Copyright 2013 The Flutter 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 "flutter/testing/test_gl_context.h" + +#include +#include +#include + +#include + +#include "flutter/fml/logging.h" +#include "flutter/testing/test_gl_utils.h" + +namespace flutter::testing { + +namespace { +bool HasExtension(const char* extensions, const char* name) { + const char* r = strstr(extensions, name); + auto len = strlen(name); + // check that the extension name is terminated by space or null terminator + return r != nullptr && (r[len] == ' ' || r[len] == 0); +} + +void CheckSwanglekExtensions() { + const char* extensions = ::eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + FML_CHECK(HasExtension(extensions, "EGL_EXT_platform_base")) << extensions; + FML_CHECK(HasExtension(extensions, "EGL_ANGLE_platform_angle_vulkan")) + << extensions; + FML_CHECK(HasExtension(extensions, + "EGL_ANGLE_platform_angle_device_type_swiftshader")) + << extensions; +} + +EGLDisplay CreateSwangleDisplay() { + CheckSwanglekExtensions(); + + PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT = + reinterpret_cast( + eglGetProcAddress("eglGetPlatformDisplayEXT")); + FML_CHECK(egl_get_platform_display_EXT) + << "eglGetPlatformDisplayEXT not available."; + + const EGLint display_config[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE, + EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, + EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE, + EGL_NONE, + }; + + return egl_get_platform_display_EXT( + EGL_PLATFORM_ANGLE_ANGLE, + reinterpret_cast(EGL_DEFAULT_DISPLAY), + display_config); +} +} // namespace + +TestEGLContext::TestEGLContext() { + display = CreateSwangleDisplay(); + FML_CHECK(display != EGL_NO_DISPLAY); + + auto result = ::eglInitialize(display, nullptr, nullptr); + FML_CHECK(result == EGL_TRUE) << GetEGLError(); + + config = {0}; + + EGLint num_config = 0; + const EGLint attribute_list[] = {EGL_RED_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_ALPHA_SIZE, + 8, + EGL_SURFACE_TYPE, + EGL_PBUFFER_BIT, + EGL_CONFORMANT, + EGL_OPENGL_ES2_BIT, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; + + result = ::eglChooseConfig(display, attribute_list, &config, 1, &num_config); + FML_CHECK(result == EGL_TRUE) << GetEGLError(); + FML_CHECK(num_config == 1) << GetEGLError(); + + { + const EGLint context_attributes[] = { + EGL_CONTEXT_CLIENT_VERSION, // + 2, // + EGL_NONE // + }; + + onscreen_context = + ::eglCreateContext(display, // display connection + config, // config + EGL_NO_CONTEXT, // sharegroup + context_attributes // context attributes + ); + FML_CHECK(onscreen_context != EGL_NO_CONTEXT) << GetEGLError(); + + offscreen_context = + ::eglCreateContext(display, // display connection + config, // config + onscreen_context, // sharegroup + context_attributes // context attributes + ); + FML_CHECK(offscreen_context != EGL_NO_CONTEXT) << GetEGLError(); + } +} + +TestEGLContext::~TestEGLContext() { + auto result = ::eglDestroyContext(display, onscreen_context); + FML_CHECK(result == EGL_TRUE) << GetEGLError(); + + result = ::eglDestroyContext(display, offscreen_context); + FML_CHECK(result == EGL_TRUE) << GetEGLError(); + + result = ::eglTerminate(display); + FML_CHECK(result == EGL_TRUE); +} + +} // namespace flutter::testing diff --git a/testing/test_gl_context.h b/testing/test_gl_context.h new file mode 100644 index 0000000000000..3cced3554ecc8 --- /dev/null +++ b/testing/test_gl_context.h @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter 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 FLUTTER_TESTING_TEST_GL_CONTEXT_H_ +#define FLUTTER_TESTING_TEST_GL_CONTEXT_H_ + +namespace flutter::testing { + +struct TestEGLContext { + explicit TestEGLContext(); + + ~TestEGLContext(); + + using EGLDisplay = void*; + using EGLContext = void*; + using EGLConfig = void*; + + EGLDisplay display; + EGLContext onscreen_context; + EGLContext offscreen_context; + + // EGLConfig is technically a property of the surfaces, no the context, + // but it's not that well separated in EGL (e.g. when + // EGL_KHR_no_config_context is not supported), so we just store it here. + EGLConfig config; +}; + +} // namespace flutter::testing + +#endif // FLUTTER_TESTING_TEST_GL_CONTEXT_H_ diff --git a/testing/test_gl_surface.cc b/testing/test_gl_surface.cc index d49c7abe21249..06af8ac172684 100644 --- a/testing/test_gl_surface.cc +++ b/testing/test_gl_surface.cc @@ -5,15 +5,13 @@ #include "flutter/testing/test_gl_surface.h" #include -#include -#include #include -#include +#include #include -#include "flutter/fml/build_config.h" #include "flutter/fml/logging.h" +#include "flutter/testing/test_gl_utils.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/core/SkSurface.h" @@ -26,175 +24,6 @@ namespace flutter::testing { -static std::string GetEGLError() { - std::stringstream stream; - - auto error = ::eglGetError(); - - stream << "EGL Result: '"; - - switch (error) { - case EGL_SUCCESS: - stream << "EGL_SUCCESS"; - break; - case EGL_NOT_INITIALIZED: - stream << "EGL_NOT_INITIALIZED"; - break; - case EGL_BAD_ACCESS: - stream << "EGL_BAD_ACCESS"; - break; - case EGL_BAD_ALLOC: - stream << "EGL_BAD_ALLOC"; - break; - case EGL_BAD_ATTRIBUTE: - stream << "EGL_BAD_ATTRIBUTE"; - break; - case EGL_BAD_CONTEXT: - stream << "EGL_BAD_CONTEXT"; - break; - case EGL_BAD_CONFIG: - stream << "EGL_BAD_CONFIG"; - break; - case EGL_BAD_CURRENT_SURFACE: - stream << "EGL_BAD_CURRENT_SURFACE"; - break; - case EGL_BAD_DISPLAY: - stream << "EGL_BAD_DISPLAY"; - break; - case EGL_BAD_SURFACE: - stream << "EGL_BAD_SURFACE"; - break; - case EGL_BAD_MATCH: - stream << "EGL_BAD_MATCH"; - break; - case EGL_BAD_PARAMETER: - stream << "EGL_BAD_PARAMETER"; - break; - case EGL_BAD_NATIVE_PIXMAP: - stream << "EGL_BAD_NATIVE_PIXMAP"; - break; - case EGL_BAD_NATIVE_WINDOW: - stream << "EGL_BAD_NATIVE_WINDOW"; - break; - case EGL_CONTEXT_LOST: - stream << "EGL_CONTEXT_LOST"; - break; - default: - stream << "Unknown"; - } - - stream << "' (0x" << std::hex << error << std::dec << ")."; - return stream.str(); -} - -static bool HasExtension(const char* extensions, const char* name) { - const char* r = strstr(extensions, name); - auto len = strlen(name); - // check that the extension name is terminated by space or null terminator - return r != nullptr && (r[len] == ' ' || r[len] == 0); -} - -static void CheckSwanglekExtensions() { - const char* extensions = ::eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - FML_CHECK(HasExtension(extensions, "EGL_EXT_platform_base")) << extensions; - FML_CHECK(HasExtension(extensions, "EGL_ANGLE_platform_angle_vulkan")) - << extensions; - FML_CHECK(HasExtension(extensions, - "EGL_ANGLE_platform_angle_device_type_swiftshader")) - << extensions; -} - -static EGLDisplay CreateSwangleDisplay() { - CheckSwanglekExtensions(); - - PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT = - reinterpret_cast( - eglGetProcAddress("eglGetPlatformDisplayEXT")); - FML_CHECK(egl_get_platform_display_EXT) - << "eglGetPlatformDisplayEXT not available."; - - const EGLint display_config[] = { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE, - EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, - EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE, - EGL_NONE, - }; - - return egl_get_platform_display_EXT( - EGL_PLATFORM_ANGLE_ANGLE, - reinterpret_cast(EGL_DEFAULT_DISPLAY), - display_config); -} - -TestEGLContext::TestEGLContext() { - display = CreateSwangleDisplay(); - FML_CHECK(display != EGL_NO_DISPLAY); - - auto result = ::eglInitialize(display, nullptr, nullptr); - FML_CHECK(result == EGL_TRUE) << GetEGLError(); - - config = {0}; - - EGLint num_config = 0; - const EGLint attribute_list[] = {EGL_RED_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_ALPHA_SIZE, - 8, - EGL_SURFACE_TYPE, - EGL_PBUFFER_BIT, - EGL_CONFORMANT, - EGL_OPENGL_ES2_BIT, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, - EGL_NONE}; - - result = ::eglChooseConfig(display, attribute_list, &config, 1, &num_config); - FML_CHECK(result == EGL_TRUE) << GetEGLError(); - FML_CHECK(num_config == 1) << GetEGLError(); - - { - const EGLint context_attributes[] = { - EGL_CONTEXT_CLIENT_VERSION, // - 2, // - EGL_NONE // - }; - - onscreen_context = - ::eglCreateContext(display, // display connection - config, // config - EGL_NO_CONTEXT, // sharegroup - context_attributes // context attributes - ); - FML_CHECK(onscreen_context != EGL_NO_CONTEXT) << GetEGLError(); - - offscreen_context = - ::eglCreateContext(display, // display connection - config, // config - onscreen_context, // sharegroup - context_attributes // context attributes - ); - FML_CHECK(offscreen_context != EGL_NO_CONTEXT) << GetEGLError(); - } -} - -TestEGLContext::~TestEGLContext() { - auto result = ::eglDestroyContext(display, onscreen_context); - FML_CHECK(result == EGL_TRUE) << GetEGLError(); - - result = ::eglDestroyContext(display, offscreen_context); - FML_CHECK(result == EGL_TRUE) << GetEGLError(); - - result = ::eglTerminate(display); - FML_CHECK(result == EGL_TRUE); -} - TestGLOnscreenOnlySurface::TestGLOnscreenOnlySurface( std::shared_ptr context, SkISize size) diff --git a/testing/test_gl_surface.h b/testing/test_gl_surface.h index 12b14c935d2ee..bcb4c476bfeed 100644 --- a/testing/test_gl_surface.h +++ b/testing/test_gl_surface.h @@ -8,31 +8,12 @@ #include #include "flutter/fml/macros.h" - +#include "flutter/testing/test_gl_context.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" namespace flutter::testing { -struct TestEGLContext { - explicit TestEGLContext(); - - ~TestEGLContext(); - - using EGLDisplay = void*; - using EGLContext = void*; - using EGLConfig = void*; - - EGLDisplay display; - EGLContext onscreen_context; - EGLContext offscreen_context; - - // EGLConfig is technically a property of the surfaces, no the context, - // but it's not that well separated in EGL (e.g. when - // EGL_KHR_no_config_context is not supported), so we just store it here. - EGLConfig config; -}; - class TestGLOnscreenOnlySurface { public: explicit TestGLOnscreenOnlySurface(SkISize surface_size); diff --git a/testing/test_gl_utils.cc b/testing/test_gl_utils.cc new file mode 100644 index 0000000000000..7bc319f7aa884 --- /dev/null +++ b/testing/test_gl_utils.cc @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter 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 "flutter/testing/test_gl_utils.h" + +#include + +#include + +namespace flutter::testing { + +std::string GetEGLError() { + std::stringstream stream; + + auto error = ::eglGetError(); + + stream << "EGL Result: '"; + + switch (error) { + case EGL_SUCCESS: + stream << "EGL_SUCCESS"; + break; + case EGL_NOT_INITIALIZED: + stream << "EGL_NOT_INITIALIZED"; + break; + case EGL_BAD_ACCESS: + stream << "EGL_BAD_ACCESS"; + break; + case EGL_BAD_ALLOC: + stream << "EGL_BAD_ALLOC"; + break; + case EGL_BAD_ATTRIBUTE: + stream << "EGL_BAD_ATTRIBUTE"; + break; + case EGL_BAD_CONTEXT: + stream << "EGL_BAD_CONTEXT"; + break; + case EGL_BAD_CONFIG: + stream << "EGL_BAD_CONFIG"; + break; + case EGL_BAD_CURRENT_SURFACE: + stream << "EGL_BAD_CURRENT_SURFACE"; + break; + case EGL_BAD_DISPLAY: + stream << "EGL_BAD_DISPLAY"; + break; + case EGL_BAD_SURFACE: + stream << "EGL_BAD_SURFACE"; + break; + case EGL_BAD_MATCH: + stream << "EGL_BAD_MATCH"; + break; + case EGL_BAD_PARAMETER: + stream << "EGL_BAD_PARAMETER"; + break; + case EGL_BAD_NATIVE_PIXMAP: + stream << "EGL_BAD_NATIVE_PIXMAP"; + break; + case EGL_BAD_NATIVE_WINDOW: + stream << "EGL_BAD_NATIVE_WINDOW"; + break; + case EGL_CONTEXT_LOST: + stream << "EGL_CONTEXT_LOST"; + break; + default: + stream << "Unknown"; + } + + stream << "' (0x" << std::hex << error << std::dec << ")."; + return stream.str(); +} + +} // namespace flutter::testing diff --git a/testing/test_gl_utils.h b/testing/test_gl_utils.h new file mode 100644 index 0000000000000..66f7948f75412 --- /dev/null +++ b/testing/test_gl_utils.h @@ -0,0 +1,16 @@ +// Copyright 2013 The Flutter 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 FLUTTER_TESTING_TEST_GL_UTILS_H_ +#define FLUTTER_TESTING_TEST_GL_UTILS_H_ + +#include + +namespace flutter::testing { + +std::string GetEGLError(); + +} // namespace flutter::testing + +#endif // FLUTTER_TESTING_TEST_GL_UTILS_H_