Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 013cd2a

Browse files
committed
Tests (partial)
Also addresses nits from code review. Testing will be complete once I figure out how to stub `eglGetProcAddress` in the tests.
1 parent 1b77228 commit 013cd2a

10 files changed

+161
-58
lines changed

shell/platform/linux/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ executable("flutter_linux_unittests") {
150150
"fl_standard_message_codec_test.cc",
151151
"fl_standard_method_codec_test.cc",
152152
"fl_string_codec_test.cc",
153+
"fl_texture_registrar_test.cc",
153154
"fl_value_test.cc",
154155
"testing/fl_test.cc",
155156
"testing/mock_egl.cc",

shell/platform/linux/fl_binary_messenger_test.cc

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,8 @@
66
#include "gtest/gtest.h"
77

88
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
9-
#include "flutter/shell/platform/linux/fl_engine_private.h"
109
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
11-
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
12-
13-
// Creates a mock engine that responds to platform messages.
14-
static FlEngine* make_mock_engine() {
15-
g_autoptr(FlDartProject) project = fl_dart_project_new();
16-
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
17-
g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
18-
g_autoptr(GError) engine_error = nullptr;
19-
EXPECT_TRUE(fl_engine_start(engine, &engine_error));
20-
EXPECT_EQ(engine_error, nullptr);
21-
22-
return static_cast<FlEngine*>(g_object_ref(engine));
23-
}
10+
#include "flutter/shell/platform/linux/testing/fl_test.h"
2411

2512
// Checks sending nullptr for a message works.
2613
TEST(FlBinaryMessengerTest, SendNullptrMessage) {

shell/platform/linux/fl_engine.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
// found in the LICENSE file.
44

55
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
6-
#include "flutter/shell/platform/embedder/embedder.h"
76
#include "flutter/shell/platform/linux/fl_engine_private.h"
87

8+
#include "flutter/shell/platform/embedder/embedder.h"
99
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
1010
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
1111
#include "flutter/shell/platform/linux/fl_renderer.h"
@@ -596,13 +596,14 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self,
596596
bool fl_engine_mark_texture_frame_available(FlEngine* self,
597597
int64_t texture_id) {
598598
g_return_val_if_fail(FL_IS_ENGINE(self), false);
599-
return !FlutterEngineMarkExternalTextureFrameAvailable(self->engine,
600-
texture_id);
599+
return FlutterEngineMarkExternalTextureFrameAvailable(self->engine,
600+
texture_id) == kSuccess;
601601
}
602602

603603
bool fl_engine_register_external_texture(FlEngine* self, int64_t texture_id) {
604604
g_return_val_if_fail(FL_IS_ENGINE(self), false);
605-
return !FlutterEngineRegisterExternalTexture(self->engine, texture_id);
605+
return FlutterEngineRegisterExternalTexture(self->engine, texture_id) ==
606+
kSuccess;
606607
}
607608

608609
void fl_engine_unregister_external_texture(FlEngine* self, int64_t texture_id) {

shell/platform/linux/fl_external_texture_gl.cc

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,35 @@
88
#include <GL/gl.h>
99
#include <gmodule.h>
1010

11+
struct {
12+
bool valid;
13+
void (*genTextures)(GLsizei n, GLuint* textures);
14+
void (*bindTexture)(GLenum target, GLuint texture);
15+
void (*texParameteri)(GLenum target, GLenum pname, GLenum param);
16+
void (*texImage2D)(GLenum target,
17+
GLint level,
18+
GLint internalformat,
19+
GLsizei width,
20+
GLsizei height,
21+
GLint border,
22+
GLenum format,
23+
GLenum type,
24+
const void* data);
25+
void (*deleteTextures)(GLsizei n, const GLuint* textures);
26+
} gl;
27+
1128
struct _FlExternalTextureGl {
1229
GLuint gl_texture_id;
1330
FlTextureCallback callback;
14-
struct {
15-
bool valid;
16-
void (*genTextures)(GLsizei n, GLuint* textures);
17-
void (*bindTexture)(GLenum target, GLuint texture);
18-
void (*texParameteri)(GLenum target, GLenum pname, GLenum param);
19-
void (*texImage2D)(GLenum target,
20-
GLint level,
21-
GLint internalformat,
22-
GLsizei width,
23-
GLsizei height,
24-
GLint border,
25-
GLenum format,
26-
GLenum type,
27-
const void* data);
28-
void (*deleteTextures)(GLsizei n, const GLuint* textures);
29-
} gl;
3031
void* user_data;
3132
};
3233

3334
G_DEFINE_TYPE(FlExternalTextureGl, fl_external_texture_gl, G_TYPE_OBJECT)
3435

3536
static void fl_external_texture_gl_dispose(GObject* object) {
3637
FlExternalTextureGl* self = FL_EXTERNAL_TEXTURE_GL(object);
37-
if (self->gl.valid) {
38-
self->gl.deleteTextures(1, &self->gl_texture_id);
38+
if (gl.valid) {
39+
gl.deleteTextures(1, &self->gl_texture_id);
3940
}
4041

4142
G_OBJECT_CLASS(fl_external_texture_gl_parent_class)->dispose(object);
@@ -66,27 +67,27 @@ bool fl_external_texture_gl_populate_texture(
6667
opengl_texture->name = self->gl_texture_id;
6768
opengl_texture->format = GL_RGBA8;
6869
opengl_texture->destruction_callback = nullptr;
69-
opengl_texture->user_data = static_cast<void*>(self);
70+
opengl_texture->user_data = nullptr;
7071
opengl_texture->width = real_width;
7172
opengl_texture->height = real_height;
7273

7374
return true;
7475
}
7576

7677
void fl_external_texture_gl_load_funcs(FlExternalTextureGl* self) {
77-
self->gl.genTextures = reinterpret_cast<void (*)(GLsizei, GLuint*)>(
78+
gl.genTextures = reinterpret_cast<void (*)(GLsizei, GLuint*)>(
7879
eglGetProcAddress("glGenTextures"));
79-
self->gl.bindTexture = reinterpret_cast<void (*)(GLenum, GLuint)>(
80+
gl.bindTexture = reinterpret_cast<void (*)(GLenum, GLuint)>(
8081
eglGetProcAddress("glBindTexture"));
81-
self->gl.texParameteri = reinterpret_cast<void (*)(GLenum, GLenum, GLenum)>(
82+
gl.texParameteri = reinterpret_cast<void (*)(GLenum, GLenum, GLenum)>(
8283
eglGetProcAddress("glTexParameteri"));
83-
self->gl.texImage2D =
84+
gl.texImage2D =
8485
reinterpret_cast<void (*)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint,
8586
GLenum, GLenum, const void*)>(
8687
eglGetProcAddress("glTexImage2D"));
87-
self->gl.deleteTextures = reinterpret_cast<void (*)(GLsizei, const GLuint*)>(
88+
gl.deleteTextures = reinterpret_cast<void (*)(GLsizei, const GLuint*)>(
8889
eglGetProcAddress("glDeleteTextures"));
89-
self->gl.valid = true;
90+
gl.valid = true;
9091
}
9192

9293
bool fl_external_texture_gl_copy_pixel_buffer(FlExternalTextureGl* self,
@@ -100,24 +101,22 @@ bool fl_external_texture_gl_copy_pixel_buffer(FlExternalTextureGl* self,
100101
*width = pixel_buffer->width;
101102
*height = pixel_buffer->height;
102103

103-
if (!self->gl.valid) {
104+
if (!gl.valid) {
104105
fl_external_texture_gl_load_funcs(self);
105106
}
106107
if (self->gl_texture_id == 0) {
107-
self->gl.genTextures(1, &self->gl_texture_id);
108-
self->gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id);
109-
self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
110-
GL_CLAMP_TO_BORDER);
111-
self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
112-
GL_CLAMP_TO_BORDER);
113-
self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
114-
self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
108+
gl.genTextures(1, &self->gl_texture_id);
109+
gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id);
110+
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
111+
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
112+
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
113+
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
115114
} else {
116-
self->gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id);
115+
gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id);
117116
}
118-
self->gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width,
119-
pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
120-
pixel_buffer->buffer);
117+
gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width,
118+
pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
119+
pixel_buffer->buffer);
121120
return true;
122121
}
123122

shell/platform/linux/fl_external_texture_gl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_EXTERNAL_TEXURE_GL_H
77

88
#include <glib-object.h>
9+
910
#include "flutter/shell/platform/embedder/embedder.h"
1011
#include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h"
1112

shell/platform/linux/fl_texture_registrar.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
// found in the LICENSE file.
44

55
#include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h"
6+
7+
#include <gmodule.h>
8+
69
#include "flutter/shell/platform/embedder/embedder.h"
710
#include "flutter/shell/platform/linux/fl_engine_private.h"
811
#include "flutter/shell/platform/linux/fl_external_texture_gl.h"
912
#include "flutter/shell/platform/linux/fl_texture_registrar_private.h"
1013

11-
#include <gmodule.h>
12-
1314
struct _FlTextureRegistrar {
1415
GObject parent_instance;
1516

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2020 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 "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h"
6+
#include "flutter/shell/platform/embedder/embedder.h"
7+
#include "flutter/shell/platform/linux/fl_external_texture_gl.h"
8+
#include "flutter/shell/platform/linux/fl_texture_registrar_private.h"
9+
#include "flutter/shell/platform/linux/testing/fl_test.h"
10+
#include "gtest/gtest.h"
11+
12+
#include <gmodule.h>
13+
14+
// Implements eglGetProcAddress but returns dummy functions.
15+
// static void* eglGetProcAddress(const char* name) {
16+
// return reinterpret_cast<void*>(+[]() {});
17+
// }
18+
19+
// Test that registering a texture works.
20+
TEST(FlTextureRegistrarTest, RegisterTexture) {
21+
g_autoptr(FlEngine) engine = make_mock_engine();
22+
FlTextureRegistrar* registrar = fl_texture_registrar_new(engine);
23+
fl_texture_registrar_register_texture(registrar, nullptr, nullptr);
24+
}
25+
26+
// Test that unregistering a texture works.
27+
TEST(FlTextureRegistrarTest, UnregisterTexture) {
28+
g_autoptr(FlEngine) engine = make_mock_engine();
29+
FlTextureRegistrar* registrar = fl_texture_registrar_new(engine);
30+
int64_t id =
31+
fl_texture_registrar_register_texture(registrar, nullptr, nullptr);
32+
fl_texture_registrar_unregister_texture(registrar, id);
33+
}
34+
35+
// Test that marking a texture frame available works.
36+
TEST(FlTextureRegistrarTest, MarkTextureFrameAvailable) {
37+
g_autoptr(FlEngine) engine = make_mock_engine();
38+
FlTextureRegistrar* registrar = fl_texture_registrar_new(engine);
39+
int64_t id =
40+
fl_texture_registrar_register_texture(registrar, nullptr, nullptr);
41+
fl_texture_registrar_mark_texture_frame_available(registrar, id);
42+
}
43+
44+
// TODO(anirudhb): Re-enable after figuring out how to stub out
45+
// eglGetProcAddress. Also write tests for #FlExternalTextureGl as well.
46+
//
47+
// Test that populating an OpenGL texture works.
48+
// TEST(FlTextureRegistrarTest, PopulateTexture) {
49+
// g_autoptr(FlEngine) engine = make_mock_engine();
50+
// FlTextureRegistrar* registrar = fl_texture_registrar_new(engine);
51+
// const uint8_t buffer[] = {0x7a, 0x8a, 0x9a, 0xaa};
52+
// FlPixelBuffer pixel_buffer;
53+
// pixel_buffer.buffer = buffer;
54+
// pixel_buffer.width = 2;
55+
// pixel_buffer.height = 2;
56+
// FlTextureCallback callback = [](size_t width, size_t height,
57+
// void* user_data) -> const FlPixelBuffer* {
58+
// FlPixelBuffer* pixel_buffer = static_cast<FlPixelBuffer*>(user_data);
59+
// EXPECT_EQ(width, pixel_buffer->width);
60+
// EXPECT_EQ(height, pixel_buffer->height);
61+
// return pixel_buffer;
62+
// };
63+
// int64_t id =
64+
// fl_texture_registrar_register_texture(registrar, callback,
65+
// &pixel_buffer);
66+
// FlutterOpenGLTexture opengl_texture;
67+
// EXPECT_TRUE(fl_texture_registrar_populate_texture(
68+
// registrar, id, pixel_buffer.width, pixel_buffer.height,
69+
// &opengl_texture));
70+
// EXPECT_EQ(opengl_texture.width, pixel_buffer.width);
71+
// EXPECT_EQ(opengl_texture.height, pixel_buffer.height);
72+
// }

shell/platform/linux/testing/fl_test.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
#include "flutter/shell/platform/linux/testing/fl_test.h"
66

7+
#include <gmodule.h>
8+
9+
// Doesn't work if included in the next block.
10+
#include "gtest/gtest.h"
11+
12+
#include "flutter/shell/platform/linux/fl_engine_private.h"
13+
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
14+
715
static uint8_t hex_digit_to_int(char value) {
816
if (value >= '0' && value <= '9')
917
return value - '0';
@@ -39,3 +47,15 @@ gchar* bytes_to_hex_string(GBytes* bytes) {
3947
g_string_append_printf(hex_string, "%02x", data[i]);
4048
return g_string_free(hex_string, FALSE);
4149
}
50+
51+
// Creates a mock engine that responds to platform messages.
52+
FlEngine* make_mock_engine() {
53+
g_autoptr(FlDartProject) project = fl_dart_project_new();
54+
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
55+
g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
56+
g_autoptr(GError) engine_error = nullptr;
57+
EXPECT_TRUE(fl_engine_start(engine, &engine_error));
58+
EXPECT_EQ(engine_error, nullptr);
59+
60+
return static_cast<FlEngine*>(g_object_ref(engine));
61+
}

shell/platform/linux/testing/fl_test.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_TEST_H_
66
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_TEST_H_
77

8+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
9+
810
#include <glib.h>
911
#include <stdint.h>
1012

@@ -18,6 +20,9 @@ GBytes* hex_string_to_bytes(const gchar* hex_string);
1820
// Helper function to convert GBytes into a hexadecimal string (e.g. "01feab")
1921
gchar* bytes_to_hex_string(GBytes* bytes);
2022

23+
// Creates a mock engine that responds to platform messages.
24+
FlEngine* make_mock_engine();
25+
2126
G_END_DECLS
2227

2328
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEST_H_

shell/platform/linux/testing/mock_engine.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@
99
#include "gtest/gtest.h"
1010

1111
#include <string.h>
12+
#include <iterator>
13+
#include <unordered_map>
14+
15+
struct _FlutterEngineTexture {
16+
bool hasNewFrame;
17+
};
1218

1319
struct _FlutterEngine {
1420
bool running;
1521
FlutterPlatformMessageCallback platform_message_callback;
1622
FlutterTaskRunnerPostTaskCallback platform_post_task_callback;
1723
void* user_data;
24+
std::unordered_map<int64_t, _FlutterEngineTexture> textures;
1825

1926
_FlutterEngine(FlutterPlatformMessageCallback platform_message_callback,
2027
FlutterTaskRunnerPostTaskCallback platform_post_task_callback,
@@ -393,17 +400,26 @@ FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine)
393400
FlutterEngineResult FlutterEngineRegisterExternalTexture(
394401
FLUTTER_API_SYMBOL(FlutterEngine) engine,
395402
int64_t texture_identifier) {
403+
_FlutterEngineTexture texture;
404+
texture.hasNewFrame = false;
405+
engine->textures[texture_identifier] = texture;
396406
return kSuccess;
397407
}
398408

399409
FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable(
400410
FLUTTER_API_SYMBOL(FlutterEngine) engine,
401411
int64_t texture_identifier) {
412+
auto val = engine->textures.find(texture_identifier);
413+
if (val == std::end(engine->textures)) {
414+
return kInvalidArguments;
415+
}
416+
val->second.hasNewFrame = true;
402417
return kSuccess;
403418
}
404419

405420
FlutterEngineResult FlutterEngineUnregisterExternalTexture(
406421
FLUTTER_API_SYMBOL(FlutterEngine) engine,
407422
int64_t texture_identifier) {
423+
engine->textures.erase(texture_identifier);
408424
return kSuccess;
409425
}

0 commit comments

Comments
 (0)