Flutter Linux Embedder
fl_renderer_test.cc
Go to the documentation of this file.
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 "gtest/gtest.h"
6 
7 #include "flutter/fml/logging.h"
9 #include "flutter/shell/platform/linux/testing/fl_test_gtk_logs.h"
10 #include "flutter/shell/platform/linux/testing/mock_epoxy.h"
11 #include "flutter/shell/platform/linux/testing/mock_renderer.h"
12 
13 #include <epoxy/egl.h>
14 
15 TEST(FlRendererTest, BackgroundColor) {
16  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
17 
18  ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
19  EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
20  ON_CALL(epoxy, glGetString(GL_VENDOR))
21  .WillByDefault(
22  ::testing::Return(reinterpret_cast<const GLubyte*>("Intel")));
23  EXPECT_CALL(epoxy, glClearColor(0.2, 0.3, 0.4, 0.5));
24 
25  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
26  fl_renderer_setup(FL_RENDERER(renderer));
27  fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
28  FlutterBackingStoreConfig config = {
29  .struct_size = sizeof(FlutterBackingStoreConfig),
30  .size = {.width = 1024, .height = 1024}};
31  FlutterBackingStore backing_store;
32  fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
33  &backing_store);
34  const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
35  .type = kFlutterLayerContentTypeBackingStore,
36  .backing_store = &backing_store,
37  .size = {.width = 1024, .height = 1024}};
38  const FlutterLayer* layers[] = {&layer0};
39  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
40  GdkRGBA background_color = {
41  .red = 0.2, .green = 0.3, .blue = 0.4, .alpha = 0.5};
42  fl_renderer_render(FL_RENDERER(renderer), 0, 1024, 1024, &background_color);
43 }
44 
45 TEST(FlRendererTest, RestoresGLState) {
46  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
47 
48  constexpr int kWidth = 100;
49  constexpr int kHeight = 100;
50 
51  flutter::testing::fl_ensure_gtk_init();
52  g_autoptr(FlDartProject) project = fl_dart_project_new();
53  g_autoptr(FlView) view = fl_view_new(project);
54  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
55  g_autoptr(FlFramebuffer) framebuffer =
56  fl_framebuffer_new(GL_RGB, kWidth, kHeight);
57 
58  fl_renderer_add_view(FL_RENDERER(renderer), 0, view);
59  fl_renderer_wait_for_frame(FL_RENDERER(renderer), kWidth, kHeight);
60 
61  FlutterBackingStore backing_store;
62  backing_store.type = kFlutterBackingStoreTypeOpenGL;
63  backing_store.open_gl.framebuffer.user_data = framebuffer;
64 
65  FlutterLayer layer;
66  layer.type = kFlutterLayerContentTypeBackingStore;
67  layer.backing_store = &backing_store;
68  layer.offset = {0, 0};
69  layer.size = {kWidth, kHeight};
70 
71  std::array<const FlutterLayer*, 1> layers = {&layer};
72 
73  constexpr GLuint kFakeTextureName = 123;
74  glBindTexture(GL_TEXTURE_2D, kFakeTextureName);
75 
76  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers.data(),
77  layers.size());
78  GdkRGBA background_color = {
79  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
80  fl_renderer_render(FL_RENDERER(renderer), 0, kWidth, kHeight,
81  &background_color);
82 
83  GLuint texture_2d_binding;
84  glGetIntegerv(GL_TEXTURE_BINDING_2D,
85  reinterpret_cast<GLint*>(&texture_2d_binding));
86  EXPECT_EQ(texture_2d_binding, kFakeTextureName);
87 
88  g_object_ref_sink(view);
89 }
90 
91 static constexpr double kExpectedRefreshRate = 120.0;
92 static gdouble renderer_get_refresh_rate(FlRenderer* renderer) {
93  return kExpectedRefreshRate;
94 }
95 
96 TEST(FlRendererTest, RefreshRate) {
97  flutter::testing::fl_ensure_gtk_init();
98  g_autoptr(FlDartProject) project = fl_dart_project_new();
99  g_autoptr(FlMockRenderer) renderer =
100  fl_mock_renderer_new(&renderer_get_refresh_rate);
101 
102  gdouble result_refresh_rate =
103  fl_renderer_get_refresh_rate(FL_RENDERER(renderer));
104  EXPECT_DOUBLE_EQ(result_refresh_rate, kExpectedRefreshRate);
105 }
106 
107 TEST(FlRendererTest, BlitFramebuffer) {
108  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
109 
110  // OpenGL 3.0
111  ON_CALL(epoxy, glGetString(GL_VENDOR))
112  .WillByDefault(
113  ::testing::Return(reinterpret_cast<const GLubyte*>("Intel")));
114  ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
115  EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
116 
117  EXPECT_CALL(epoxy, glBlitFramebuffer);
118 
119  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
120  fl_renderer_setup(FL_RENDERER(renderer));
121  fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
122  FlutterBackingStoreConfig config = {
123  .struct_size = sizeof(FlutterBackingStoreConfig),
124  .size = {.width = 1024, .height = 1024}};
125  FlutterBackingStore backing_store;
126  fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
127  &backing_store);
128  const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
129  .type = kFlutterLayerContentTypeBackingStore,
130  .backing_store = &backing_store,
131  .size = {.width = 1024, .height = 1024}};
132  const FlutterLayer* layers[] = {&layer0};
133  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
134  GdkRGBA background_color = {
135  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
136  fl_renderer_render(FL_RENDERER(renderer), 0, 1024, 1024, &background_color);
137 }
138 
139 TEST(FlRendererTest, BlitFramebufferExtension) {
140  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
141 
142  // OpenGL 2.0 with GL_EXT_framebuffer_blit extension
143  ON_CALL(epoxy, glGetString(GL_VENDOR))
144  .WillByDefault(
145  ::testing::Return(reinterpret_cast<const GLubyte*>("Intel")));
146  ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
147  EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
148  EXPECT_CALL(epoxy, epoxy_has_gl_extension(::testing::_))
149  .WillRepeatedly(::testing::Return(false));
150  EXPECT_CALL(epoxy, epoxy_has_gl_extension(
151  ::testing::StrEq("GL_EXT_framebuffer_blit")))
152  .WillRepeatedly(::testing::Return(true));
153 
154  EXPECT_CALL(epoxy, glBlitFramebuffer);
155 
156  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
157  fl_renderer_setup(FL_RENDERER(renderer));
158  fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
159  FlutterBackingStoreConfig config = {
160  .struct_size = sizeof(FlutterBackingStoreConfig),
161  .size = {.width = 1024, .height = 1024}};
162  FlutterBackingStore backing_store;
163  fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
164  &backing_store);
165  const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
166  .type = kFlutterLayerContentTypeBackingStore,
167  .backing_store = &backing_store,
168  .size = {.width = 1024, .height = 1024}};
169  const FlutterLayer* layers[] = {&layer0};
170  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
171  GdkRGBA background_color = {
172  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
173  fl_renderer_render(FL_RENDERER(renderer), 0, 1024, 1024, &background_color);
174 }
175 
176 TEST(FlRendererTest, NoBlitFramebuffer) {
177  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
178 
179  // OpenGL 2.0
180  ON_CALL(epoxy, glGetString(GL_VENDOR))
181  .WillByDefault(
182  ::testing::Return(reinterpret_cast<const GLubyte*>("Intel")));
183  ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
184  EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
185 
186  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
187  fl_renderer_setup(FL_RENDERER(renderer));
188  fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
189  FlutterBackingStoreConfig config = {
190  .struct_size = sizeof(FlutterBackingStoreConfig),
191  .size = {.width = 1024, .height = 1024}};
192  FlutterBackingStore backing_store;
193  fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
194  &backing_store);
195  const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
196  .type = kFlutterLayerContentTypeBackingStore,
197  .backing_store = &backing_store,
198  .size = {.width = 1024, .height = 1024}};
199  const FlutterLayer* layers[] = {&layer0};
200  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
201  GdkRGBA background_color = {
202  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
203  fl_renderer_render(FL_RENDERER(renderer), 0, 1024, 1024, &background_color);
204 }
205 
206 TEST(FlRendererTest, BlitFramebufferNvidia) {
207  ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
208 
209  // OpenGL 3.0, but on NVIDIA driver so temporarily disabled due to
210  // https://github.com/flutter/flutter/issues/152099
211  ON_CALL(epoxy, glGetString(GL_VENDOR))
212  .WillByDefault(
213  ::testing::Return(reinterpret_cast<const GLubyte*>("NVIDIA")));
214  ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
215  EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
216 
217  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
218  fl_renderer_setup(FL_RENDERER(renderer));
219  fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
220  FlutterBackingStoreConfig config = {
221  .struct_size = sizeof(FlutterBackingStoreConfig),
222  .size = {.width = 1024, .height = 1024}};
223  FlutterBackingStore backing_store;
224  fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
225  &backing_store);
226  const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
227  .type = kFlutterLayerContentTypeBackingStore,
228  .backing_store = &backing_store,
229  .size = {.width = 1024, .height = 1024}};
230  const FlutterLayer* layers[] = {&layer0};
231  fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
232  GdkRGBA background_color = {
233  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
234  fl_renderer_render(FL_RENDERER(renderer), 0, 1024, 1024, &background_color);
235 }
fl_renderer_wait_for_frame
void fl_renderer_wait_for_frame(FlRenderer *self, int target_width, int target_height)
Definition: fl_renderer.cc:409
fl_renderer_present_layers
gboolean fl_renderer_present_layers(FlRenderer *self, FlutterViewId view_id, const FlutterLayer **layers, size_t layers_count)
Definition: fl_renderer.cc:429
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
fl_renderer_get_refresh_rate
gdouble fl_renderer_get_refresh_rate(FlRenderer *self)
Definition: fl_renderer.cc:355
renderer_get_refresh_rate
static gdouble renderer_get_refresh_rate(FlRenderer *renderer)
Definition: fl_renderer_test.cc:92
fl_dart_project_new
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
Definition: fl_dart_project.cc:50
fl_framebuffer_new
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height)
Definition: fl_framebuffer.cc:42
fl_view_new
G_MODULE_EXPORT FlView * fl_view_new(FlDartProject *project)
Definition: fl_view.cc:829
fl_framebuffer.h
kExpectedRefreshRate
static constexpr double kExpectedRefreshRate
Definition: fl_renderer_test.cc:91
view
FlView * view
Definition: fl_application.cc:35
fl_renderer_add_view
void fl_renderer_add_view(FlRenderer *self, FlutterViewId view_id, FlView *view)
Definition: fl_renderer.cc:314
TEST
TEST(FlRendererTest, BackgroundColor)
Definition: fl_renderer_test.cc:15
fl_renderer_render
void fl_renderer_render(FlRenderer *self, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
Definition: fl_renderer.cc:501
fl_renderer_create_backing_store
gboolean fl_renderer_create_backing_store(FlRenderer *self, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
Definition: fl_renderer.cc:367
fl_renderer_setup
void fl_renderer_setup(FlRenderer *self)
Definition: fl_renderer.cc:484