Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Extract TestGLContext to separate translation unit #56647

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <memory>

#include "flutter/testing/test_gl_surface.h"
#include "flutter/testing/test_gl_context.h"

namespace flutter::testing {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/embedder/tests/embedder_test_context_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions testing/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
128 changes: 128 additions & 0 deletions testing/test_gl_context.cc
Original file line number Diff line number Diff line change
@@ -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 <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
31 changes: 31 additions & 0 deletions testing/test_gl_context.h
Original file line number Diff line number Diff line change
@@ -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_
175 changes: 2 additions & 173 deletions testing/test_gl_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@
#include "flutter/testing/test_gl_surface.h"

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <GLES2/gl2.h>

#include <sstream>
#include <memory>
#include <string>

#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"
Expand All @@ -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<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);
}

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<TestEGLContext> context,
SkISize size)
Expand Down
Loading