8 #include "flutter/impeller/renderer/backend/gles/gles.h"
12 #include "flutter/shell/platform/windows/testing/egl/mock_context.h"
13 #include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
14 #include "flutter/shell/platform/windows/testing/egl/mock_window_surface.h"
15 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
16 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
17 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
18 #include "flutter/shell/platform/windows/testing/view_modifier.h"
19 #include "flutter/shell/platform/windows/testing/windows_test.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
27 using ::testing::AnyNumber;
28 using ::testing::Return;
30 void MockGetIntegerv(GLenum name,
int* value) {
31 if (name == GL_NUM_EXTENSIONS) {
38 const unsigned char* MockGetString(GLenum name) {
41 case GL_SHADING_LANGUAGE_VERSION:
42 return reinterpret_cast<const unsigned char*
>(
"3.0");
44 return reinterpret_cast<const unsigned char*
>(
"");
48 const unsigned char* MockGetStringi(GLenum name,
int index) {
49 if (name == GL_EXTENSIONS) {
50 return reinterpret_cast<const unsigned char*
>(
"GL_ANGLE_framebuffer_blit");
52 return reinterpret_cast<const unsigned char*
>(
"");
56 GLenum MockGetError() {
62 const impeller::ProcTableGLES::Resolver kMockResolver = [](
const char* name) {
63 std::string function_name{name};
65 if (function_name ==
"glGetString") {
66 return reinterpret_cast<void*
>(&MockGetString);
67 }
else if (function_name ==
"glGetStringi") {
68 return reinterpret_cast<void*
>(&MockGetStringi);
69 }
else if (function_name ==
"glGetIntegerv") {
70 return reinterpret_cast<void*
>(&MockGetIntegerv);
71 }
else if (function_name ==
"glGetError") {
72 return reinterpret_cast<void*
>(&MockGetError);
74 return reinterpret_cast<void*
>(&DoNothing);
78 class CompositorOpenGLTest :
public WindowsTest {
80 CompositorOpenGLTest() =
default;
81 virtual ~CompositorOpenGLTest() =
default;
84 FlutterWindowsEngine* engine() {
return engine_.get(); }
85 FlutterWindowsView* view() {
return view_.get(); }
86 egl::MockManager* egl_manager() {
return egl_manager_; }
87 egl::MockContext* render_context() {
return render_context_.get(); }
88 egl::MockWindowSurface* surface() {
return surface_; }
90 void UseHeadlessEngine() {
91 auto egl_manager = std::make_unique<egl::MockManager>();
92 render_context_ = std::make_unique<egl::MockContext>();
93 egl_manager_ = egl_manager.get();
95 EXPECT_CALL(*egl_manager_, render_context)
97 .WillRepeatedly(Return(render_context_.get()));
99 FlutterWindowsEngineBuilder builder{GetContext()};
101 engine_ = builder.Build();
102 EngineModifier modifier{engine_.get()};
103 modifier.SetEGLManager(std::move(egl_manager));
106 void UseEngineWithView(
bool add_surface =
true) {
109 auto window = std::make_unique<MockWindowBindingHandler>();
110 EXPECT_CALL(*window.get(), SetView).Times(1);
111 EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(
nullptr));
113 view_ = std::make_unique<FlutterWindowsView>(
kImplicitViewId, engine_.get(),
117 auto surface = std::make_unique<egl::MockWindowSurface>();
118 surface_ = surface.get();
120 EXPECT_CALL(*surface_, Destroy).Times(AnyNumber());
122 ViewModifier modifier{view_.get()};
123 modifier.SetSurface(std::move(surface));
128 std::unique_ptr<FlutterWindowsEngine> engine_;
129 std::unique_ptr<FlutterWindowsView> view_;
130 std::unique_ptr<egl::MockContext> render_context_;
131 egl::MockWindowSurface* surface_;
132 egl::MockManager* egl_manager_;
134 FML_DISALLOW_COPY_AND_ASSIGN(CompositorOpenGLTest);
139 TEST_F(CompositorOpenGLTest, CreateBackingStore) {
145 FlutterBackingStoreConfig config = {};
146 FlutterBackingStore backing_store = {};
148 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
149 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
150 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
153 TEST_F(CompositorOpenGLTest, CreateBackingStoreImpeller) {
159 FlutterBackingStoreConfig config = {};
160 FlutterBackingStore backing_store = {};
162 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
163 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
164 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
167 TEST_F(CompositorOpenGLTest, InitializationFailure) {
173 FlutterBackingStoreConfig config = {};
174 FlutterBackingStore backing_store = {};
176 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
false));
177 EXPECT_FALSE(compositor.CreateBackingStore(config, &backing_store));
180 TEST_F(CompositorOpenGLTest, InitializationRequiresBlit) {
183 const impeller::ProcTableGLES::Resolver resolver = [](
const char* name) {
184 std::string function_name{name};
186 if (function_name ==
"glBlitFramebuffer" ||
187 function_name ==
"glBlitFramebufferANGLE") {
188 return (
void*)
nullptr;
191 return kMockResolver(name);
197 FlutterBackingStoreConfig config = {};
198 FlutterBackingStore backing_store = {};
200 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
201 ASSERT_FALSE(compositor.CreateBackingStore(config, &backing_store));
210 FlutterBackingStoreConfig config = {};
211 FlutterBackingStore backing_store = {};
213 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
214 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
216 FlutterLayer layer = {};
217 layer.type = kFlutterLayerContentTypeBackingStore;
218 layer.backing_store = &backing_store;
219 const FlutterLayer* layer_ptr = &layer;
221 EXPECT_CALL(*surface(), IsValid).WillRepeatedly(Return(
true));
222 EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(
true));
223 EXPECT_CALL(*surface(), SwapBuffers).WillOnce(Return(
true));
224 EXPECT_TRUE(compositor.Present(view(), &layer_ptr, 1));
226 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
229 TEST_F(CompositorOpenGLTest, PresentEmpty) {
237 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
238 EXPECT_CALL(*surface(), IsValid).WillRepeatedly(Return(
true));
239 EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(
true));
240 EXPECT_CALL(*surface(), SwapBuffers).WillOnce(Return(
true));
241 EXPECT_TRUE(compositor.Present(view(),
nullptr, 0));
244 TEST_F(CompositorOpenGLTest, NoSurfaceIgnored) {
245 UseEngineWithView(
false);
250 FlutterBackingStoreConfig config = {};
251 FlutterBackingStore backing_store = {};
253 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
254 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
256 FlutterLayer layer = {};
257 layer.type = kFlutterLayerContentTypeBackingStore;
258 layer.backing_store = &backing_store;
259 const FlutterLayer* layer_ptr = &layer;
261 EXPECT_FALSE(compositor.Present(view(), &layer_ptr, 1));
263 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
266 TEST_F(CompositorOpenGLTest, PresentUsingANGLEBlitExtension) {
269 bool resolved_ANGLE_blit =
false;
270 const impeller::ProcTableGLES::Resolver resolver =
271 [&resolved_ANGLE_blit](
const char* name) {
272 std::string function_name{name};
274 if (function_name ==
"glBlitFramebuffer") {
275 return (
void*)
nullptr;
276 }
else if (function_name ==
"glBlitFramebufferANGLE") {
277 resolved_ANGLE_blit =
true;
278 return reinterpret_cast<void*
>(&DoNothing);
281 return kMockResolver(name);
287 FlutterBackingStoreConfig config = {};
288 FlutterBackingStore backing_store = {};
290 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
291 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
293 FlutterLayer layer = {};
294 layer.type = kFlutterLayerContentTypeBackingStore;
295 layer.backing_store = &backing_store;
296 const FlutterLayer* layer_ptr = &layer;
298 EXPECT_CALL(*surface(), IsValid).WillRepeatedly(Return(
true));
299 EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(
true));
300 EXPECT_CALL(*surface(), SwapBuffers).WillOnce(Return(
true));
301 EXPECT_TRUE(compositor.Present(view(), &layer_ptr, 1));
302 EXPECT_TRUE(resolved_ANGLE_blit);
304 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
TEST_F(CompositorOpenGLTest, CreateBackingStore)
constexpr FlutterViewId kImplicitViewId