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;
28 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
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};
51 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
52 g_autofree
unsigned char* image_data =
53 static_cast<unsigned char*
>(malloc(
height * stride));
54 cairo_surface_t* surface = cairo_image_surface_create_for_data(
55 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
56 cairo_t* cr = cairo_create(surface);
58 cairo_surface_destroy(surface);
62 TEST(FlCompositorOpenGLTest, Resize) {
63 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
69 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
70 g_autoptr(FlCompositorOpenGL) compositor =
75 constexpr
size_t width1 = 90;
76 constexpr
size_t height1 = 90;
79 FlutterBackingStore backing_store1 = {
80 .type = kFlutterBackingStoreTypeOpenGL,
81 .open_gl = {.framebuffer = {.user_data = framebuffer1}}};
82 FlutterLayer layer1 = {.type = kFlutterLayerContentTypeBackingStore,
83 .backing_store = &backing_store1,
85 .size = {width1, height1}};
86 const FlutterLayer* layers1[1] = {&layer1};
92 constexpr
size_t width2 = 100;
93 constexpr
size_t height2 = 100;
96 FlutterBackingStore backing_store2 = {
97 .type = kFlutterBackingStoreTypeOpenGL,
98 .open_gl = {.framebuffer = {.user_data = framebuffer2}}};
99 FlutterLayer layer2 = {.type = kFlutterLayerContentTypeBackingStore,
100 .backing_store = &backing_store2,
102 .size = {width2, height2}};
103 const FlutterLayer* layers2[1] = {&layer2};
104 fml::AutoResetWaitableEvent latch;
111 int stride2 = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width2);
112 g_autofree
unsigned char* image_data =
113 static_cast<unsigned char*
>(malloc(height2 * stride2));
114 cairo_surface_t* surface = cairo_image_surface_create_for_data(
115 image_data, CAIRO_FORMAT_ARGB32, width2, height2, stride2);
116 cairo_t* cr = cairo_create(surface);
118 cairo_surface_destroy(surface);
124 TEST(FlCompositorOpenGLTest, RestoresGLState) {
125 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
131 constexpr
size_t width = 100;
132 constexpr
size_t height = 100;
135 ON_CALL(epoxy, glGetString(GL_VENDOR))
137 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
138 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
139 ON_CALL(epoxy, epoxy_gl_version).WillByDefault(::testing::Return(30));
141 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
142 g_autoptr(FlCompositorOpenGL) compositor =
148 FlutterBackingStore backing_store = {
149 .type = kFlutterBackingStoreTypeOpenGL,
150 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
151 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
152 .backing_store = &backing_store,
155 const FlutterLayer*
layers[1] = {&layer};
157 constexpr GLuint kFakeTextureName = 123;
158 glBindTexture(GL_TEXTURE_2D, kFakeTextureName);
160 glEnable(GL_SCISSOR_TEST);
166 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
167 g_autofree
unsigned char* image_data =
168 static_cast<unsigned char*
>(malloc(
height * stride));
169 cairo_surface_t* surface = cairo_image_surface_create_for_data(
170 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
171 cairo_t* cr = cairo_create(surface);
173 cairo_surface_destroy(surface);
176 GLuint texture_2d_binding;
177 glGetIntegerv(GL_TEXTURE_BINDING_2D,
178 reinterpret_cast<GLint*
>(&texture_2d_binding));
179 EXPECT_EQ(texture_2d_binding, kFakeTextureName);
180 EXPECT_EQ(glIsEnabled(GL_BLEND), GL_FALSE);
181 EXPECT_EQ(glIsEnabled(GL_SCISSOR_TEST), GL_TRUE);
184 TEST(FlCompositorOpenGLTest, BlitFramebuffer) {
185 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
191 constexpr
size_t width = 100;
192 constexpr
size_t height = 100;
195 ON_CALL(epoxy, glGetString(GL_VENDOR))
197 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
198 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
199 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
201 EXPECT_CALL(epoxy, glBlitFramebuffer);
203 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
204 g_autoptr(FlCompositorOpenGL) compositor =
210 FlutterBackingStore backing_store = {
211 .type = kFlutterBackingStoreTypeOpenGL,
212 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
213 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
214 .backing_store = &backing_store,
217 const FlutterLayer*
layers[1] = {&layer};
223 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
224 g_autofree
unsigned char* image_data =
225 static_cast<unsigned char*
>(malloc(
height * stride));
226 cairo_surface_t* surface = cairo_image_surface_create_for_data(
227 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
228 cairo_t* cr = cairo_create(surface);
230 cairo_surface_destroy(surface);
234 TEST(FlCompositorOpenGLTest, BlitFramebufferExtension) {
235 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
241 constexpr
size_t width = 100;
242 constexpr
size_t height = 100;
245 ON_CALL(epoxy, glGetString(GL_VENDOR))
247 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
248 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
249 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
250 EXPECT_CALL(epoxy, epoxy_has_gl_extension(::testing::_))
251 .WillRepeatedly(::testing::Return(
false));
252 EXPECT_CALL(epoxy, epoxy_has_gl_extension(
253 ::testing::StrEq(
"GL_EXT_framebuffer_blit")))
254 .WillRepeatedly(::testing::Return(
true));
256 EXPECT_CALL(epoxy, glBlitFramebuffer);
258 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
259 g_autoptr(FlCompositorOpenGL) compositor =
265 FlutterBackingStore backing_store = {
266 .type = kFlutterBackingStoreTypeOpenGL,
267 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
268 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
269 .backing_store = &backing_store,
272 const FlutterLayer*
layers[1] = {&layer};
278 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
279 g_autofree
unsigned char* image_data =
280 static_cast<unsigned char*
>(malloc(
height * stride));
281 cairo_surface_t* surface = cairo_image_surface_create_for_data(
282 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
283 cairo_t* cr = cairo_create(surface);
285 cairo_surface_destroy(surface);
289 TEST(FlCompositorOpenGLTest, NoBlitFramebuffer) {
290 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
296 constexpr
size_t width = 100;
297 constexpr
size_t height = 100;
300 ON_CALL(epoxy, glGetString(GL_VENDOR))
302 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"Intel")));
303 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
304 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
306 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
307 g_autoptr(FlCompositorOpenGL) compositor =
313 FlutterBackingStore backing_store = {
314 .type = kFlutterBackingStoreTypeOpenGL,
315 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
316 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
317 .backing_store = &backing_store,
320 const FlutterLayer*
layers[1] = {&layer};
326 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
327 g_autofree
unsigned char* image_data =
328 static_cast<unsigned char*
>(malloc(
height * stride));
329 cairo_surface_t* surface = cairo_image_surface_create_for_data(
330 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
331 cairo_t* cr = cairo_create(surface);
333 cairo_surface_destroy(surface);
337 TEST(FlCompositorOpenGLTest, BlitFramebufferNvidia) {
338 ::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
344 constexpr
size_t width = 100;
345 constexpr
size_t height = 100;
349 ON_CALL(epoxy, glGetString(GL_VENDOR))
351 ::testing::Return(
reinterpret_cast<const GLubyte*
>(
"NVIDIA")));
352 ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(
true));
353 EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
355 g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
356 g_autoptr(FlCompositorOpenGL) compositor =
362 FlutterBackingStore backing_store = {
363 .type = kFlutterBackingStoreTypeOpenGL,
364 .open_gl = {.framebuffer = {.user_data = framebuffer}}};
365 FlutterLayer layer = {.type = kFlutterLayerContentTypeBackingStore,
366 .backing_store = &backing_store,
369 const FlutterLayer*
layers[1] = {&layer};
375 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
376 g_autofree
unsigned char* image_data =
377 static_cast<unsigned char*
>(malloc(
height * stride));
378 cairo_surface_t* surface = cairo_image_surface_create_for_data(
379 image_data, CAIRO_FORMAT_ARGB32,
width,
height, stride);
380 cairo_t* cr = cairo_create(surface);
382 cairo_surface_destroy(surface);
gboolean fl_compositor_render(FlCompositor *self, cairo_t *cr, GdkWindow *window)
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_autoptr(GMutexLocker) locker
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)