6 #include "gtest/gtest.h"
8 #include "flutter/common/constants.h"
9 #include "flutter/fml/logging.h"
10 #include "flutter/fml/synchronization/waitable_event.h"
14 #include "flutter/shell/platform/linux/testing/mock_epoxy.h"
15 #include "flutter/shell/platform/linux/testing/mock_renderable.h"
17 #include <epoxy/egl.h>
19 TEST(FlCompositorOpenGLTest, BackgroundColor) {
20 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
24 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
25 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
26 ON_CALL(epoxy, glGetString(GL_VENDOR))
28 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
29 EXPECT_CALL(epoxy, glClearColor(0.2, 0.3, 0.4, 0.5));
31 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
36 FlutterBackingStoreConfig config = {
37 .struct_size =
sizeof(FlutterBackingStoreConfig),
38 .size = {.width = 1024, .height = 1024}};
39 FlutterBackingStore backing_store;
43 fml::AutoResetWaitableEvent latch;
47 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
48 .
type = kFlutterLayerContentTypeBackingStore,
49 .backing_store = &backing_store,
50 .size = {.width = 1024, .height = 1024}};
51 const FlutterLayer* layers[] = {&layer0};
54 flutter::kFlutterImplicitViewId, layers, 1);
58 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
59 g_main_context_iteration(
nullptr,
true);
62 GdkRGBA background_color = {
63 .red = 0.2, .green = 0.3, .blue = 0.4, .alpha = 0.5};
65 1024, &background_color);
72 TEST(FlCompositorOpenGLTest, RestoresGLState) {
73 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
77 constexpr
int kWidth = 100;
78 constexpr
int kHeight = 100;
80 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
82 g_autoptr(FlFramebuffer) framebuffer =
88 FlutterBackingStore backing_store;
89 backing_store.type = kFlutterBackingStoreTypeOpenGL;
90 backing_store.open_gl.framebuffer.user_data = framebuffer;
93 layer.type = kFlutterLayerContentTypeBackingStore;
94 layer.backing_store = &backing_store;
95 layer.offset = {0, 0};
96 layer.size = {kWidth, kHeight};
98 std::array<const FlutterLayer*, 1> layers = {&layer};
100 constexpr GLuint kFakeTextureName = 123;
101 glBindTexture(GL_TEXTURE_2D, kFakeTextureName);
103 fml::AutoResetWaitableEvent latch;
108 flutter::kFlutterImplicitViewId, layers.data(),
113 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
114 g_main_context_iteration(
nullptr,
true);
117 GdkRGBA background_color = {
118 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
120 kWidth, kHeight, &background_color);
122 GLuint texture_2d_binding;
123 glGetIntegerv(GL_TEXTURE_BINDING_2D,
124 reinterpret_cast<GLint*
>(&texture_2d_binding));
125 EXPECT_EQ(texture_2d_binding, kFakeTextureName);
132 TEST(FlCompositorOpenGLTest, BlitFramebuffer) {
133 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
138 ON_CALL(epoxy, glGetString(GL_VENDOR))
140 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
141 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
142 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
144 EXPECT_CALL(epoxy, glBlitFramebuffer);
146 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
151 FlutterBackingStoreConfig config = {
152 .struct_size =
sizeof(FlutterBackingStoreConfig),
153 .size = {.width = 1024, .height = 1024}};
154 FlutterBackingStore backing_store;
158 fml::AutoResetWaitableEvent latch;
162 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
163 .
type = kFlutterLayerContentTypeBackingStore,
164 .backing_store = &backing_store,
165 .size = {.width = 1024, .height = 1024}};
166 const FlutterLayer* layers[] = {&layer0};
168 flutter::kFlutterImplicitViewId, layers, 1);
172 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
173 g_main_context_iteration(
nullptr,
true);
176 GdkRGBA background_color = {
177 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
179 1024, &background_color);
184 TEST(FlCompositorOpenGLTest, BlitFramebufferExtension) {
185 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
190 ON_CALL(epoxy, glGetString(GL_VENDOR))
192 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
193 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
194 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
195 EXPECT_CALL(epoxy, epoxy_has_gl_extension(::testing::_))
196 .WillRepeatedly(::testing::Return(
false));
197 EXPECT_CALL(epoxy, epoxy_has_gl_extension(
198 ::testing::StrEq(
"GL_EXT_framebuffer_blit")))
199 .WillRepeatedly(::testing::Return(
true));
201 EXPECT_CALL(epoxy, glBlitFramebuffer);
203 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
208 FlutterBackingStoreConfig config = {
209 .struct_size =
sizeof(FlutterBackingStoreConfig),
210 .size = {.width = 1024, .height = 1024}};
211 FlutterBackingStore backing_store;
215 fml::AutoResetWaitableEvent latch;
219 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
220 .
type = kFlutterLayerContentTypeBackingStore,
221 .backing_store = &backing_store,
222 .size = {.width = 1024, .height = 1024}};
223 const FlutterLayer* layers[] = {&layer0};
225 flutter::kFlutterImplicitViewId, layers, 1);
229 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
230 g_main_context_iteration(
nullptr,
true);
232 GdkRGBA background_color = {
233 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
235 1024, &background_color);
241 TEST(FlCompositorOpenGLTest, NoBlitFramebuffer) {
242 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
247 ON_CALL(epoxy, glGetString(GL_VENDOR))
249 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
250 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
251 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
253 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
258 FlutterBackingStoreConfig config = {
259 .struct_size =
sizeof(FlutterBackingStoreConfig),
260 .size = {.width = 1024, .height = 1024}};
261 FlutterBackingStore backing_store;
265 fml::AutoResetWaitableEvent latch;
269 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
270 .
type = kFlutterLayerContentTypeBackingStore,
271 .backing_store = &backing_store,
272 .size = {.width = 1024, .height = 1024}};
273 const FlutterLayer* layers[] = {&layer0};
275 flutter::kFlutterImplicitViewId, layers, 1);
279 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
280 g_main_context_iteration(
nullptr,
true);
283 GdkRGBA background_color = {
284 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
286 1024, &background_color);
293 TEST(FlCompositorOpenGLTest, BlitFramebufferNvidia) {
294 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
300 ON_CALL(epoxy, glGetString(GL_VENDOR))
302 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"NVIDIA")));
303 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
304 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
306 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
311 FlutterBackingStoreConfig config = {
312 .struct_size =
sizeof(FlutterBackingStoreConfig),
313 .size = {.width = 1024, .height = 1024}};
314 FlutterBackingStore backing_store;
318 fml::AutoResetWaitableEvent latch;
322 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
323 .
type = kFlutterLayerContentTypeBackingStore,
324 .backing_store = &backing_store,
325 .size = {.width = 1024, .height = 1024}};
326 const FlutterLayer* layers[] = {&layer0};
328 flutter::kFlutterImplicitViewId, layers, 1);
332 while (fl_mock_renderable_get_redraw_count(renderable) == 0) {
333 g_main_context_iteration(
nullptr,
true);
336 GdkRGBA background_color = {
337 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
339 1024, &background_color);
346 TEST(FlCompositorOpenGLTest, MultiView) {
347 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
352 ON_CALL(epoxy, glGetString(GL_VENDOR))
354 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
355 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
356 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
358 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
359 g_autoptr(FlMockRenderable) secondary_renderable = fl_mock_renderable_new();
366 1.0,
nullptr,
nullptr,
nullptr);
369 EXPECT_EQ(fl_mock_renderable_get_redraw_count(renderable),
370 static_cast<size_t>(0));
371 EXPECT_EQ(fl_mock_renderable_get_redraw_count(secondary_renderable),
372 static_cast<size_t>(0));
374 FlutterBackingStoreConfig config = {
375 .struct_size =
sizeof(FlutterBackingStoreConfig),
376 .size = {.width = 1024, .height = 1024}};
377 FlutterBackingStore backing_store;
381 fml::AutoResetWaitableEvent latch;
385 const FlutterLayer layer0 = {.struct_size =
sizeof(FlutterLayer),
386 .
type = kFlutterLayerContentTypeBackingStore,
387 .backing_store = &backing_store,
388 .size = {.width = 1024, .height = 1024}};
389 const FlutterLayer* layers[] = {&layer0};
394 while (fl_mock_renderable_get_redraw_count(secondary_renderable) == 0) {
395 g_main_context_iteration(
nullptr,
true);
398 EXPECT_EQ(fl_mock_renderable_get_redraw_count(renderable),
399 static_cast<size_t>(0));
400 EXPECT_EQ(fl_mock_renderable_get_redraw_count(secondary_renderable),
401 static_cast<size_t>(1));
gboolean fl_compositor_present_layers(FlCompositor *self, FlutterViewId view_id, const FlutterLayer **layers, size_t layers_count)
void fl_compositor_wait_for_frame(FlCompositor *self, int target_width, int target_height)
gboolean fl_compositor_create_backing_store(FlCompositor *self, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
void fl_compositor_opengl_setup(FlCompositorOpenGL *self)
FlCompositorOpenGL * fl_compositor_opengl_new(FlEngine *engine)
void fl_compositor_opengl_render(FlCompositorOpenGL *self, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
TEST(FlCompositorOpenGLTest, BackgroundColor)
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
void fl_engine_set_implicit_view(FlEngine *self, FlRenderable *renderable)
FlutterViewId fl_engine_add_view(FlEngine *self, FlRenderable *renderable, size_t width, size_t height, double pixel_ratio, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height)
G_BEGIN_DECLS FlutterViewId view_id