20#include "gmock/gmock.h"
21#include "gtest/gtest.h"
27using ::testing::AnyNumber;
28using ::testing::Return;
30void MockGetIntegerv(GLenum
name,
int* value) {
31 if (
name == GL_NUM_EXTENSIONS) {
38const 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*
>(
"");
48const 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*
>(
"");
56GLenum MockGetError() {
60void MockGetIntegervWithMSAA(GLenum
name,
int* value) {
61 if (
name == GL_NUM_EXTENSIONS) {
68const unsigned char* MockGetStringiWithMSAA(GLenum
name,
int index) {
69 static constexpr const char* extensions[] = {
70 "GL_ANGLE_framebuffer_blit",
"GL_EXT_multisampled_render_to_texture"};
71 if (
name == GL_EXTENSIONS && index < 2) {
72 return reinterpret_cast<const unsigned char*
>(extensions[index]);
74 return reinterpret_cast<const unsigned char*
>(
"");
80 std::string function_name{
name};
82 if (function_name ==
"glGetString") {
83 return reinterpret_cast<void*
>(&MockGetString);
84 }
else if (function_name ==
"glGetStringi") {
85 return reinterpret_cast<void*
>(&MockGetStringi);
86 }
else if (function_name ==
"glGetIntegerv") {
87 return reinterpret_cast<void*
>(&MockGetIntegerv);
88 }
else if (function_name ==
"glGetError") {
89 return reinterpret_cast<void*
>(&MockGetError);
91 return reinterpret_cast<void*
>(&DoNothing);
96 [](
const char*
name) {
97 std::string_view function_name{
name};
99 if (function_name ==
"glGetStringi") {
100 return reinterpret_cast<void*
>(&MockGetStringiWithMSAA);
101 }
else if (function_name ==
"glGetIntegerv") {
102 return reinterpret_cast<void*
>(&MockGetIntegervWithMSAA);
104 return kMockResolver(
name);
107class CompositorOpenGLTest :
public WindowsTest {
109 CompositorOpenGLTest() =
default;
110 virtual ~CompositorOpenGLTest() =
default;
113 FlutterWindowsEngine*
engine() {
return engine_.get(); }
114 FlutterWindowsView*
view() {
return view_.get(); }
115 egl::MockManager* egl_manager() {
return egl_manager_; }
116 egl::MockContext* render_context() {
return render_context_.get(); }
119 void UseHeadlessEngine() {
120 auto egl_manager = std::make_unique<egl::MockManager>();
121 render_context_ = std::make_unique<egl::MockContext>();
122 egl_manager_ = egl_manager.get();
124 EXPECT_CALL(*egl_manager_, render_context)
126 .WillRepeatedly(Return(render_context_.get()));
128 FlutterWindowsEngineBuilder builder{GetContext()};
130 engine_ = builder.Build();
131 EngineModifier modifier{engine_.get()};
132 modifier.SetEGLManager(std::move(egl_manager));
135 void UseEngineWithView(
bool add_surface =
true) {
138 auto window = std::make_unique<MockWindowBindingHandler>();
139 EXPECT_CALL(*
window.get(), SetView).Times(1);
140 EXPECT_CALL(*
window.get(), GetWindowHandle).WillRepeatedly(Return(
nullptr));
142 view_ = std::make_unique<FlutterWindowsView>(
kImplicitViewId, engine_.get(),
147 auto surface = std::make_unique<egl::MockWindowSurface>();
150 EXPECT_CALL(*surface_, Destroy).Times(AnyNumber());
152 ViewModifier modifier{view_.get()};
153 modifier.SetSurface(std::move(surface));
158 std::unique_ptr<FlutterWindowsEngine> engine_;
159 std::unique_ptr<FlutterWindowsView> view_;
160 std::unique_ptr<egl::MockContext> render_context_;
162 egl::MockManager* egl_manager_;
169TEST_F(CompositorOpenGLTest, CreateBackingStore) {
178 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
179 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
180 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
183TEST_F(CompositorOpenGLTest, CreateBackingStoreImpellerNoMSAA) {
186 static int framebuffer_texture2d_calls = 0;
187 static int framebuffer_texture2d_multisample_calls = 0;
188 framebuffer_texture2d_calls = 0;
189 framebuffer_texture2d_multisample_calls = 0;
192 [](
const char*
name) ->
void* {
193 std::string_view function_name{
name};
194 if (function_name ==
"glFramebufferTexture2D") {
195 return reinterpret_cast<void*
>(
196 +[](GLenum, GLenum, GLenum, GLuint, GLint) {
197 framebuffer_texture2d_calls++;
199 }
else if (function_name ==
"glFramebufferTexture2DMultisampleEXT") {
200 return reinterpret_cast<void*
>(
201 +[](GLenum, GLenum, GLenum, GLuint, GLint, GLsizei) {
202 framebuffer_texture2d_multisample_calls++;
205 return kMockResolver(
name);
213 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
214 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
215 EXPECT_EQ(framebuffer_texture2d_calls, 1);
216 EXPECT_EQ(framebuffer_texture2d_multisample_calls, 0);
217 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
220TEST_F(CompositorOpenGLTest, CreateBackingStoreImpellerMSAA) {
223 static int framebuffer_texture2d_calls = 0;
224 static int framebuffer_texture2d_multisample_calls = 0;
225 framebuffer_texture2d_calls = 0;
226 framebuffer_texture2d_multisample_calls = 0;
229 [](
const char*
name) ->
void* {
230 std::string_view function_name{
name};
231 if (function_name ==
"glFramebufferTexture2D") {
232 return reinterpret_cast<void*
>(
233 +[](GLenum, GLenum, GLenum, GLuint, GLint) {
234 framebuffer_texture2d_calls++;
236 }
else if (function_name ==
"glFramebufferTexture2DMultisampleEXT") {
237 return reinterpret_cast<void*
>(
238 +[](GLenum, GLenum, GLenum, GLuint, GLint, GLsizei) {
239 framebuffer_texture2d_multisample_calls++;
242 return kMockResolverWithMSAA(
name);
250 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
251 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
252 EXPECT_EQ(framebuffer_texture2d_calls, 0);
253 EXPECT_EQ(framebuffer_texture2d_multisample_calls, 1);
254 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
257TEST_F(CompositorOpenGLTest, InitializationFailure) {
266 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
false));
267 EXPECT_FALSE(compositor.CreateBackingStore(config, &backing_store));
270TEST_F(CompositorOpenGLTest, InitializationRequiresBlit) {
274 std::string function_name{
name};
276 if (function_name ==
"glBlitFramebuffer" ||
277 function_name ==
"glBlitFramebufferANGLE") {
278 return (
void*)
nullptr;
281 return kMockResolver(
name);
290 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
291 ASSERT_FALSE(compositor.CreateBackingStore(config, &backing_store));
303 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
304 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
311 EXPECT_CALL(*
surface(), IsValid).WillRepeatedly(Return(
true));
312 EXPECT_CALL(*
surface(), MakeCurrent).WillOnce(Return(
true));
313 EXPECT_CALL(*
surface(), SwapBuffers).WillOnce(Return(
true));
314 EXPECT_TRUE(compositor.Present(
view(), &layer_ptr, 1));
316 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
319TEST_F(CompositorOpenGLTest, PresentEmpty) {
327 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
328 EXPECT_CALL(*
surface(), IsValid).WillRepeatedly(Return(
true));
329 EXPECT_CALL(*
surface(), MakeCurrent).WillOnce(Return(
true));
330 EXPECT_CALL(*
surface(), SwapBuffers).WillOnce(Return(
true));
331 EXPECT_TRUE(compositor.Present(
view(),
nullptr, 0));
334TEST_F(CompositorOpenGLTest, NoSurfaceIgnored) {
335 UseEngineWithView(
false);
343 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
344 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
351 EXPECT_FALSE(compositor.Present(
view(), &layer_ptr, 1));
353 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
356TEST_F(CompositorOpenGLTest, PresentUsingANGLEBlitExtension) {
359 bool resolved_ANGLE_blit =
false;
361 [&resolved_ANGLE_blit](
const char*
name) {
362 std::string function_name{
name};
364 if (function_name ==
"glBlitFramebuffer") {
365 return (
void*)
nullptr;
366 }
else if (function_name ==
"glBlitFramebufferANGLE") {
367 resolved_ANGLE_blit =
true;
368 return reinterpret_cast<void*
>(&DoNothing);
371 return kMockResolver(
name);
380 EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(
true));
381 ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
388 EXPECT_CALL(*
surface(), IsValid).WillRepeatedly(Return(
true));
389 EXPECT_CALL(*
surface(), MakeCurrent).WillOnce(Return(
true));
390 EXPECT_CALL(*
surface(), SwapBuffers).WillOnce(Return(
true));
391 EXPECT_TRUE(compositor.Present(
view(), &layer_ptr, 1));
392 EXPECT_TRUE(resolved_ANGLE_blit);
394 ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
std::function< void *(const char *function_name)> Resolver
@ kFlutterLayerContentTypeBackingStore
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST_F(DisplayListTest, Defaults)
constexpr int64_t kImplicitViewId
DEF_SWITCHES_START aot vmservice shared library name
FlutterLayerContentType type
const FlutterBackingStore * backing_store