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"
16 #include "flutter/shell/platform/linux/testing/mock_epoxy.h"
17 #include "flutter/shell/platform/linux/testing/mock_renderable.h"
19 #include <epoxy/egl.h>
21 TEST(FlCompositorOpenGLTest, Render) {
22 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
29 g_autoptr(FlCompositorOpenGL) compositor =
34 constexpr
size_t width = 100;
35 constexpr
size_t height = 100;
38 FlutterBackingStore backing_store = {
39 .type = kFlutterBackingStoreTypeOpenGL,
40 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
41 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
42 .backing_store = &backing_store,
45 const FlutterLayer*
layers[1] = {&layer};
50 size_t frame_width, frame_height;
53 EXPECT_EQ(frame_width,
width);
54 EXPECT_EQ(frame_height,
height);
57 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
58 g_autofree
unsigned char* image_data =
59 static_cast<unsigned char*
>(malloc(
height * stride));
60 cairo_surface_t* surface = cairo_image_surface_create_for_data(
61 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
62 cairo_t* cr = cairo_create(surface);
64 cairo_surface_destroy(surface);
68 TEST(FlCompositorOpenGLTest, Resize) {
69 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
76 g_autoptr(FlCompositorOpenGL) compositor =
81 constexpr
size_t width1 = 90;
82 constexpr
size_t height1 = 90;
85 FlutterBackingStore backing_store1 = {
86 .type = kFlutterBackingStoreTypeOpenGL,
87 .open_gl = {.framebuffer = {.user_data = framebuffer1}}};
88 FlutterLayer layer1 = {.type = kFlutterLayerContentTypeBackingStore,
89 .backing_store = &backing_store1,
91 .size = {width1, height1}};
92 const FlutterLayer* layers1[1] = {&layer1};
98 constexpr
size_t width2 = 100;
99 constexpr
size_t height2 = 100;
102 FlutterBackingStore backing_store2 = {
103 .type = kFlutterBackingStoreTypeOpenGL,
104 .open_gl = {.framebuffer = {.user_data = framebuffer2}}};
105 FlutterLayer layer2 = {.type = kFlutterLayerContentTypeBackingStore,
106 .backing_store = &backing_store2,
108 .size = {width2, height2}};
109 const FlutterLayer* layers2[1] = {&layer2};
110 fml::AutoResetWaitableEvent latch;
117 int stride2 = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width2);
118 g_autofree
unsigned char* image_data =
119 static_cast<unsigned char*
>(malloc(height2 * stride2));
120 cairo_surface_t* surface = cairo_image_surface_create_for_data(
121 image_data, CAIRO_FORMAT_ARGB32, width2, height2, stride2);
122 cairo_t* cr = cairo_create(surface);
124 cairo_surface_destroy(surface);
130 TEST(FlCompositorOpenGLTest, RestoresGLState) {
131 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
137 constexpr
size_t width = 100;
138 constexpr
size_t height = 100;
141 ON_CALL(epoxy, glGetString(GL_VENDOR))
143 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
144 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
145 ON_CALL(epoxy, epoxy_gl_version).WillByDefault(::testing::Return(30));
148 g_autoptr(FlCompositorOpenGL) compositor =
154 FlutterBackingStore backing_store = {
155 .type = kFlutterBackingStoreTypeOpenGL,
156 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
157 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
158 .backing_store = &backing_store,
161 const FlutterLayer*
layers[1] = {&layer};
163 constexpr GLuint kFakeTextureName = 123;
164 glBindTexture(GL_TEXTURE_2D, kFakeTextureName);
166 glEnable(GL_SCISSOR_TEST);
172 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
173 g_autofree
unsigned char* image_data =
174 static_cast<unsigned char*
>(malloc(
height * stride));
175 cairo_surface_t* surface = cairo_image_surface_create_for_data(
176 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
177 cairo_t* cr = cairo_create(surface);
179 cairo_surface_destroy(surface);
182 GLuint texture_2d_binding;
183 glGetIntegerv(GL_TEXTURE_BINDING_2D,
184 reinterpret_cast<GLint*
>(&texture_2d_binding));
185 EXPECT_EQ(texture_2d_binding, kFakeTextureName);
186 EXPECT_EQ(glIsEnabled(GL_BLEND), GL_FALSE);
187 EXPECT_EQ(glIsEnabled(GL_SCISSOR_TEST), GL_TRUE);
190 TEST(FlCompositorOpenGLTest, BlitFramebuffer) {
191 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
197 constexpr
size_t width = 100;
198 constexpr
size_t height = 100;
201 ON_CALL(epoxy, glGetString(GL_VENDOR))
203 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
204 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
205 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
207 EXPECT_CALL(epoxy, glBlitFramebuffer);
210 g_autoptr(FlCompositorOpenGL) compositor =
216 FlutterBackingStore backing_store = {
217 .type = kFlutterBackingStoreTypeOpenGL,
218 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
219 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
220 .backing_store = &backing_store,
223 const FlutterLayer*
layers[1] = {&layer};
229 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
230 g_autofree
unsigned char* image_data =
231 static_cast<unsigned char*
>(malloc(
height * stride));
232 cairo_surface_t* surface = cairo_image_surface_create_for_data(
233 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
234 cairo_t* cr = cairo_create(surface);
236 cairo_surface_destroy(surface);
240 TEST(FlCompositorOpenGLTest, BlitFramebufferExtension) {
241 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
247 constexpr
size_t width = 100;
248 constexpr
size_t height = 100;
251 ON_CALL(epoxy, glGetString(GL_VENDOR))
253 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
254 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
255 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
256 EXPECT_CALL(epoxy, epoxy_has_gl_extension(::testing::_))
257 .WillRepeatedly(::testing::Return(
false));
258 EXPECT_CALL(epoxy, epoxy_has_gl_extension(
259 ::testing::StrEq(
"GL_EXT_framebuffer_blit")))
260 .WillRepeatedly(::testing::Return(
true));
262 EXPECT_CALL(epoxy, glBlitFramebuffer);
265 g_autoptr(FlCompositorOpenGL) compositor =
271 FlutterBackingStore backing_store = {
272 .type = kFlutterBackingStoreTypeOpenGL,
273 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
274 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
275 .backing_store = &backing_store,
278 const FlutterLayer*
layers[1] = {&layer};
284 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
285 g_autofree
unsigned char* image_data =
286 static_cast<unsigned char*
>(malloc(
height * stride));
287 cairo_surface_t* surface = cairo_image_surface_create_for_data(
288 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
289 cairo_t* cr = cairo_create(surface);
291 cairo_surface_destroy(surface);
295 TEST(FlCompositorOpenGLTest, NoBlitFramebuffer) {
296 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
302 constexpr
size_t width = 100;
303 constexpr
size_t height = 100;
306 ON_CALL(epoxy, glGetString(GL_VENDOR))
308 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
309 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
310 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
313 g_autoptr(FlCompositorOpenGL) compositor =
319 FlutterBackingStore backing_store = {
320 .type = kFlutterBackingStoreTypeOpenGL,
321 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
322 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
323 .backing_store = &backing_store,
326 const FlutterLayer*
layers[1] = {&layer};
332 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
333 g_autofree
unsigned char* image_data =
334 static_cast<unsigned char*
>(malloc(
height * stride));
335 cairo_surface_t* surface = cairo_image_surface_create_for_data(
336 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
337 cairo_t* cr = cairo_create(surface);
339 cairo_surface_destroy(surface);
343 TEST(FlCompositorOpenGLTest, BlitFramebufferNvidia) {
344 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
350 constexpr
size_t width = 100;
351 constexpr
size_t height = 100;
355 ON_CALL(epoxy, glGetString(GL_VENDOR))
357 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"NVIDIA")));
358 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
359 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
362 g_autoptr(FlCompositorOpenGL) compositor =
368 FlutterBackingStore backing_store = {
369 .type = kFlutterBackingStoreTypeOpenGL,
370 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
371 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
372 .backing_store = &backing_store,
375 const FlutterLayer*
layers[1] = {&layer};
381 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
382 g_autofree
unsigned char* image_data =
383 static_cast<unsigned char*
>(malloc(
height * stride));
384 cairo_surface_t* surface = cairo_image_surface_create_for_data(
385 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
386 cairo_t* cr = cairo_create(surface);
388 cairo_surface_destroy(surface);
g_autoptr(FlEngine) engine
FlRenderable * renderable
gboolean fl_compositor_render(FlCompositor *self, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
void fl_compositor_get_frame_size(FlCompositor *self, size_t *width, size_t *height)
gboolean fl_compositor_present_layers(FlCompositor *self, const FlutterLayer **layers, size_t layers_count)
FlCompositorOpenGL * fl_compositor_opengl_new(FlTaskRunner *task_runner, FlOpenGLManager *opengl_manager, gboolean shareable)
G_BEGIN_DECLS FlOpenGLManager * opengl_manager
TEST(FlCompositorOpenGLTest, Render)
const FlutterLayer ** layers
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
void fl_engine_set_implicit_view(FlEngine *self, FlRenderable *renderable)
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height, gboolean shareable)
FlOpenGLManager * fl_opengl_manager_new()
FlTaskRunner * fl_task_runner_new(FlEngine *engine)