blob: 3e3b329d933ba566f40a59498331a4e48eb6b3f7 [file] [log] [blame]
// 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 <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <cstring>
#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<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
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<EGLNativeDisplayType*>(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