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

Commit 7f2d56b

Browse files
authored
Extract TestGLContext to separate translation unit (#56647)
For consistency with the Test.*Context classes for other backends, which live in their own implementation file with their own header, extract TestEGLContext to its own header and TU so that in cases where only a TestEGLContext is required (e.g. EmbedderTestBackingStoreProducerGL), we don't need to include all the various test GL surface classes as well. GetEGLError is used by both TestEGLContext and the TestGLSurface classes, so moves to its own utils file. No tests because this is a refactoring with no semantic changes, and the code itself is test code. Issue: flutter/flutter#158998 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 635dee8 commit 7f2d56b

10 files changed

+259
-196
lines changed

shell/platform/embedder/tests/embedder_test_backingstore_producer_gl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#include <memory>
1111

12-
#include "flutter/testing/test_gl_surface.h"
12+
#include "flutter/testing/test_gl_context.h"
1313

1414
namespace flutter::testing {
1515

shell/platform/embedder/tests/embedder_test_compositor_gl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "flutter/fml/macros.h"
1111
#include "flutter/shell/platform/embedder/embedder.h"
1212
#include "flutter/shell/platform/embedder/tests/embedder_test_compositor.h"
13-
#include "flutter/testing/test_gl_surface.h"
13+
#include "flutter/testing/test_gl_context.h"
1414

1515
namespace flutter {
1616
namespace testing {

shell/platform/embedder/tests/embedder_test_context_gl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "flutter/shell/platform/embedder/tests/embedder_test_context.h"
99

10-
#include "flutter/testing/test_gl_surface.h"
10+
#include "flutter/testing/test_gl_context.h"
1111

1212
namespace flutter {
1313
namespace testing {

testing/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,12 @@ if (use_swiftshader) {
223223
testonly = true
224224

225225
sources = [
226+
"test_gl_context.cc",
227+
"test_gl_context.h",
226228
"test_gl_surface.cc",
227229
"test_gl_surface.h",
230+
"test_gl_utils.cc",
231+
"test_gl_utils.h",
228232
]
229233

230234
deps = [

testing/test_gl_context.cc

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/testing/test_gl_context.h"
6+
7+
#include <EGL/egl.h>
8+
#include <EGL/eglext.h>
9+
#include <EGL/eglplatform.h>
10+
11+
#include <cstring>
12+
13+
#include "flutter/fml/logging.h"
14+
#include "flutter/testing/test_gl_utils.h"
15+
16+
namespace flutter::testing {
17+
18+
namespace {
19+
bool HasExtension(const char* extensions, const char* name) {
20+
const char* r = strstr(extensions, name);
21+
auto len = strlen(name);
22+
// check that the extension name is terminated by space or null terminator
23+
return r != nullptr && (r[len] == ' ' || r[len] == 0);
24+
}
25+
26+
void CheckSwanglekExtensions() {
27+
const char* extensions = ::eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
28+
FML_CHECK(HasExtension(extensions, "EGL_EXT_platform_base")) << extensions;
29+
FML_CHECK(HasExtension(extensions, "EGL_ANGLE_platform_angle_vulkan"))
30+
<< extensions;
31+
FML_CHECK(HasExtension(extensions,
32+
"EGL_ANGLE_platform_angle_device_type_swiftshader"))
33+
<< extensions;
34+
}
35+
36+
EGLDisplay CreateSwangleDisplay() {
37+
CheckSwanglekExtensions();
38+
39+
PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT =
40+
reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
41+
eglGetProcAddress("eglGetPlatformDisplayEXT"));
42+
FML_CHECK(egl_get_platform_display_EXT)
43+
<< "eglGetPlatformDisplayEXT not available.";
44+
45+
const EGLint display_config[] = {
46+
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
47+
EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE,
48+
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
49+
EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE,
50+
EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
51+
EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE,
52+
EGL_NONE,
53+
};
54+
55+
return egl_get_platform_display_EXT(
56+
EGL_PLATFORM_ANGLE_ANGLE,
57+
reinterpret_cast<EGLNativeDisplayType*>(EGL_DEFAULT_DISPLAY),
58+
display_config);
59+
}
60+
} // namespace
61+
62+
TestEGLContext::TestEGLContext() {
63+
display = CreateSwangleDisplay();
64+
FML_CHECK(display != EGL_NO_DISPLAY);
65+
66+
auto result = ::eglInitialize(display, nullptr, nullptr);
67+
FML_CHECK(result == EGL_TRUE) << GetEGLError();
68+
69+
config = {0};
70+
71+
EGLint num_config = 0;
72+
const EGLint attribute_list[] = {EGL_RED_SIZE,
73+
8,
74+
EGL_GREEN_SIZE,
75+
8,
76+
EGL_BLUE_SIZE,
77+
8,
78+
EGL_ALPHA_SIZE,
79+
8,
80+
EGL_SURFACE_TYPE,
81+
EGL_PBUFFER_BIT,
82+
EGL_CONFORMANT,
83+
EGL_OPENGL_ES2_BIT,
84+
EGL_RENDERABLE_TYPE,
85+
EGL_OPENGL_ES2_BIT,
86+
EGL_NONE};
87+
88+
result = ::eglChooseConfig(display, attribute_list, &config, 1, &num_config);
89+
FML_CHECK(result == EGL_TRUE) << GetEGLError();
90+
FML_CHECK(num_config == 1) << GetEGLError();
91+
92+
{
93+
const EGLint context_attributes[] = {
94+
EGL_CONTEXT_CLIENT_VERSION, //
95+
2, //
96+
EGL_NONE //
97+
};
98+
99+
onscreen_context =
100+
::eglCreateContext(display, // display connection
101+
config, // config
102+
EGL_NO_CONTEXT, // sharegroup
103+
context_attributes // context attributes
104+
);
105+
FML_CHECK(onscreen_context != EGL_NO_CONTEXT) << GetEGLError();
106+
107+
offscreen_context =
108+
::eglCreateContext(display, // display connection
109+
config, // config
110+
onscreen_context, // sharegroup
111+
context_attributes // context attributes
112+
);
113+
FML_CHECK(offscreen_context != EGL_NO_CONTEXT) << GetEGLError();
114+
}
115+
}
116+
117+
TestEGLContext::~TestEGLContext() {
118+
auto result = ::eglDestroyContext(display, onscreen_context);
119+
FML_CHECK(result == EGL_TRUE) << GetEGLError();
120+
121+
result = ::eglDestroyContext(display, offscreen_context);
122+
FML_CHECK(result == EGL_TRUE) << GetEGLError();
123+
124+
result = ::eglTerminate(display);
125+
FML_CHECK(result == EGL_TRUE);
126+
}
127+
128+
} // namespace flutter::testing

testing/test_gl_context.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_TESTING_TEST_GL_CONTEXT_H_
6+
#define FLUTTER_TESTING_TEST_GL_CONTEXT_H_
7+
8+
namespace flutter::testing {
9+
10+
struct TestEGLContext {
11+
explicit TestEGLContext();
12+
13+
~TestEGLContext();
14+
15+
using EGLDisplay = void*;
16+
using EGLContext = void*;
17+
using EGLConfig = void*;
18+
19+
EGLDisplay display;
20+
EGLContext onscreen_context;
21+
EGLContext offscreen_context;
22+
23+
// EGLConfig is technically a property of the surfaces, no the context,
24+
// but it's not that well separated in EGL (e.g. when
25+
// EGL_KHR_no_config_context is not supported), so we just store it here.
26+
EGLConfig config;
27+
};
28+
29+
} // namespace flutter::testing
30+
31+
#endif // FLUTTER_TESTING_TEST_GL_CONTEXT_H_

testing/test_gl_surface.cc

Lines changed: 2 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
#include "flutter/testing/test_gl_surface.h"
66

77
#include <EGL/egl.h>
8-
#include <EGL/eglext.h>
9-
#include <EGL/eglplatform.h>
108
#include <GLES2/gl2.h>
119

12-
#include <sstream>
10+
#include <memory>
1311
#include <string>
1412

15-
#include "flutter/fml/build_config.h"
1613
#include "flutter/fml/logging.h"
14+
#include "flutter/testing/test_gl_utils.h"
1715
#include "third_party/skia/include/core/SkColorSpace.h"
1816
#include "third_party/skia/include/core/SkColorType.h"
1917
#include "third_party/skia/include/core/SkSurface.h"
@@ -26,175 +24,6 @@
2624

2725
namespace flutter::testing {
2826

29-
static std::string GetEGLError() {
30-
std::stringstream stream;
31-
32-
auto error = ::eglGetError();
33-
34-
stream << "EGL Result: '";
35-
36-
switch (error) {
37-
case EGL_SUCCESS:
38-
stream << "EGL_SUCCESS";
39-
break;
40-
case EGL_NOT_INITIALIZED:
41-
stream << "EGL_NOT_INITIALIZED";
42-
break;
43-
case EGL_BAD_ACCESS:
44-
stream << "EGL_BAD_ACCESS";
45-
break;
46-
case EGL_BAD_ALLOC:
47-
stream << "EGL_BAD_ALLOC";
48-
break;
49-
case EGL_BAD_ATTRIBUTE:
50-
stream << "EGL_BAD_ATTRIBUTE";
51-
break;
52-
case EGL_BAD_CONTEXT:
53-
stream << "EGL_BAD_CONTEXT";
54-
break;
55-
case EGL_BAD_CONFIG:
56-
stream << "EGL_BAD_CONFIG";
57-
break;
58-
case EGL_BAD_CURRENT_SURFACE:
59-
stream << "EGL_BAD_CURRENT_SURFACE";
60-
break;
61-
case EGL_BAD_DISPLAY:
62-
stream << "EGL_BAD_DISPLAY";
63-
break;
64-
case EGL_BAD_SURFACE:
65-
stream << "EGL_BAD_SURFACE";
66-
break;
67-
case EGL_BAD_MATCH:
68-
stream << "EGL_BAD_MATCH";
69-
break;
70-
case EGL_BAD_PARAMETER:
71-
stream << "EGL_BAD_PARAMETER";
72-
break;
73-
case EGL_BAD_NATIVE_PIXMAP:
74-
stream << "EGL_BAD_NATIVE_PIXMAP";
75-
break;
76-
case EGL_BAD_NATIVE_WINDOW:
77-
stream << "EGL_BAD_NATIVE_WINDOW";
78-
break;
79-
case EGL_CONTEXT_LOST:
80-
stream << "EGL_CONTEXT_LOST";
81-
break;
82-
default:
83-
stream << "Unknown";
84-
}
85-
86-
stream << "' (0x" << std::hex << error << std::dec << ").";
87-
return stream.str();
88-
}
89-
90-
static bool HasExtension(const char* extensions, const char* name) {
91-
const char* r = strstr(extensions, name);
92-
auto len = strlen(name);
93-
// check that the extension name is terminated by space or null terminator
94-
return r != nullptr && (r[len] == ' ' || r[len] == 0);
95-
}
96-
97-
static void CheckSwanglekExtensions() {
98-
const char* extensions = ::eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
99-
FML_CHECK(HasExtension(extensions, "EGL_EXT_platform_base")) << extensions;
100-
FML_CHECK(HasExtension(extensions, "EGL_ANGLE_platform_angle_vulkan"))
101-
<< extensions;
102-
FML_CHECK(HasExtension(extensions,
103-
"EGL_ANGLE_platform_angle_device_type_swiftshader"))
104-
<< extensions;
105-
}
106-
107-
static EGLDisplay CreateSwangleDisplay() {
108-
CheckSwanglekExtensions();
109-
110-
PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT =
111-
reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
112-
eglGetProcAddress("eglGetPlatformDisplayEXT"));
113-
FML_CHECK(egl_get_platform_display_EXT)
114-
<< "eglGetPlatformDisplayEXT not available.";
115-
116-
const EGLint display_config[] = {
117-
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
118-
EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE,
119-
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
120-
EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE,
121-
EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
122-
EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE,
123-
EGL_NONE,
124-
};
125-
126-
return egl_get_platform_display_EXT(
127-
EGL_PLATFORM_ANGLE_ANGLE,
128-
reinterpret_cast<EGLNativeDisplayType*>(EGL_DEFAULT_DISPLAY),
129-
display_config);
130-
}
131-
132-
TestEGLContext::TestEGLContext() {
133-
display = CreateSwangleDisplay();
134-
FML_CHECK(display != EGL_NO_DISPLAY);
135-
136-
auto result = ::eglInitialize(display, nullptr, nullptr);
137-
FML_CHECK(result == EGL_TRUE) << GetEGLError();
138-
139-
config = {0};
140-
141-
EGLint num_config = 0;
142-
const EGLint attribute_list[] = {EGL_RED_SIZE,
143-
8,
144-
EGL_GREEN_SIZE,
145-
8,
146-
EGL_BLUE_SIZE,
147-
8,
148-
EGL_ALPHA_SIZE,
149-
8,
150-
EGL_SURFACE_TYPE,
151-
EGL_PBUFFER_BIT,
152-
EGL_CONFORMANT,
153-
EGL_OPENGL_ES2_BIT,
154-
EGL_RENDERABLE_TYPE,
155-
EGL_OPENGL_ES2_BIT,
156-
EGL_NONE};
157-
158-
result = ::eglChooseConfig(display, attribute_list, &config, 1, &num_config);
159-
FML_CHECK(result == EGL_TRUE) << GetEGLError();
160-
FML_CHECK(num_config == 1) << GetEGLError();
161-
162-
{
163-
const EGLint context_attributes[] = {
164-
EGL_CONTEXT_CLIENT_VERSION, //
165-
2, //
166-
EGL_NONE //
167-
};
168-
169-
onscreen_context =
170-
::eglCreateContext(display, // display connection
171-
config, // config
172-
EGL_NO_CONTEXT, // sharegroup
173-
context_attributes // context attributes
174-
);
175-
FML_CHECK(onscreen_context != EGL_NO_CONTEXT) << GetEGLError();
176-
177-
offscreen_context =
178-
::eglCreateContext(display, // display connection
179-
config, // config
180-
onscreen_context, // sharegroup
181-
context_attributes // context attributes
182-
);
183-
FML_CHECK(offscreen_context != EGL_NO_CONTEXT) << GetEGLError();
184-
}
185-
}
186-
187-
TestEGLContext::~TestEGLContext() {
188-
auto result = ::eglDestroyContext(display, onscreen_context);
189-
FML_CHECK(result == EGL_TRUE) << GetEGLError();
190-
191-
result = ::eglDestroyContext(display, offscreen_context);
192-
FML_CHECK(result == EGL_TRUE) << GetEGLError();
193-
194-
result = ::eglTerminate(display);
195-
FML_CHECK(result == EGL_TRUE);
196-
}
197-
19827
TestGLOnscreenOnlySurface::TestGLOnscreenOnlySurface(
19928
std::shared_ptr<TestEGLContext> context,
20029
SkISize size)

0 commit comments

Comments
 (0)