Skip to content

Commit e000e57

Browse files
authored
Merge pull request #180 from ardera/feature/omxplayer-runtime-rotation
feature/omxplayer-runtime-rotation
2 parents 57b6788 + 7a38bbc commit e000e57

File tree

7 files changed

+284
-638
lines changed

7 files changed

+284
-638
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ project(flutter-pi LANGUAGES C VERSION "1.0.0")
3434
message(STATUS "Generator .............. ${CMAKE_GENERATOR}")
3535
message(STATUS "Build Type ............. ${CMAKE_BUILD_TYPE}")
3636

37+
OPTION(OMXPLAYER_SUPPORTS_RUNTIME_ROTATION "Whether omxplayer supports runtime rotation." OFF)
38+
3739
if(NOT FLUTTER_EMBEDDER_HEADER)
3840

3941
include(FetchContent)
@@ -179,6 +181,9 @@ endif()
179181
if (BUILD_OMXPLAYER_VIDEO_PLAYER_PLUGIN)
180182
target_compile_definitions(flutter-pi PRIVATE "BUILD_OMXPLAYER_VIDEO_PLAYER_PLUGIN")
181183
endif()
184+
if (OMXPLAYER_SUPPORTS_RUNTIME_ROTATION)
185+
target_compile_definitions(flutter-pi PRIVATE "OMXPLAYER_SUPPORTS_RUNTIME_ROTATION")
186+
endif()
182187

183188
target_link_options(flutter-pi PRIVATE
184189
-rdynamic

include/compositor.h

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,12 @@
99
#include <collection.h>
1010
#include <modesetting.h>
1111

12+
struct platform_view_params;
13+
1214
typedef int (*platform_view_mount_cb)(
1315
int64_t view_id,
1416
struct drmdev_atomic_req *req,
15-
const FlutterPlatformViewMutation **mutations,
16-
size_t num_mutations,
17-
int offset_x,
18-
int offset_y,
19-
int width,
20-
int height,
17+
const struct platform_view_params *params,
2118
int zpos,
2219
void *userdata
2320
);
@@ -31,29 +28,83 @@ typedef int (*platform_view_unmount_cb)(
3128
typedef int (*platform_view_update_view_cb)(
3229
int64_t view_id,
3330
struct drmdev_atomic_req *req,
34-
const FlutterPlatformViewMutation **mutations,
35-
size_t num_mutations,
36-
int offset_x,
37-
int offset_y,
38-
int width,
39-
int height,
31+
const struct platform_view_params *params,
4032
int zpos,
4133
void *userdata
4234
);
4335

4436
typedef int (*platform_view_present_cb)(
4537
int64_t view_id,
4638
struct drmdev_atomic_req *req,
47-
const FlutterPlatformViewMutation **mutations,
48-
size_t num_mutations,
49-
int offset_x,
50-
int offset_y,
51-
int width,
52-
int height,
39+
const struct platform_view_params *params,
5340
int zpos,
5441
void *userdata
5542
);
5643

44+
struct point {
45+
double x, y;
46+
};
47+
48+
struct quad {
49+
struct point top_left, top_right, bottom_left, bottom_right;
50+
};
51+
52+
struct aa_rect {
53+
struct point offset, size;
54+
};
55+
56+
static inline struct aa_rect get_aa_bounding_rect(const struct quad _rect) {
57+
double l = min(min(min(_rect.top_left.x, _rect.top_right.x), _rect.bottom_left.x), _rect.bottom_right.x);
58+
double r = max(max(max(_rect.top_left.x, _rect.top_right.x), _rect.bottom_left.x), _rect.bottom_right.x);
59+
double t = min(min(min(_rect.top_left.y, _rect.top_right.y), _rect.bottom_left.y), _rect.bottom_right.y);
60+
double b = max(max(max(_rect.top_left.y, _rect.top_right.y), _rect.bottom_left.y), _rect.bottom_right.y);
61+
62+
return (struct aa_rect) {
63+
.offset.x = l,
64+
.offset.y = t,
65+
.size.x = r - l,
66+
.size.y = b - t
67+
};
68+
}
69+
70+
static inline struct quad get_quad(const struct aa_rect rect) {
71+
return (struct quad) {
72+
.top_left = rect.offset,
73+
.top_right.x = rect.offset.x + rect.size.x,
74+
.top_right.y = rect.offset.y,
75+
.bottom_left.x = rect.offset.x,
76+
.bottom_left.y = rect.offset.y + rect.size.y,
77+
.bottom_right.x = rect.offset.x + rect.size.x,
78+
.bottom_right.y = rect.offset.y + rect.size.y
79+
};
80+
}
81+
82+
static inline void apply_transform_to_point(const FlutterTransformation transform, struct point *point) {
83+
apply_flutter_transformation(transform, &point->x, &point->y);
84+
}
85+
86+
static inline void apply_transform_to_quad(const FlutterTransformation transform, struct quad *rect) {
87+
apply_transform_to_point(transform, &rect->top_left);
88+
apply_transform_to_point(transform, &rect->top_right);
89+
apply_transform_to_point(transform, &rect->bottom_left);
90+
apply_transform_to_point(transform, &rect->bottom_right);
91+
}
92+
93+
static inline struct quad apply_transform_to_aa_rect(const FlutterTransformation transform, const struct aa_rect rect) {
94+
struct quad _quad = get_quad(rect);
95+
apply_transform_to_quad(transform, &_quad);
96+
return _quad;
97+
}
98+
99+
100+
struct platform_view_params {
101+
struct quad rect;
102+
double rotation;
103+
struct clip_rect *clip_rects;
104+
size_t n_clip_rects;
105+
double opacity;
106+
};
107+
57108
struct compositor {
58109
struct drmdev *drmdev;
59110

include/plugins/omxplayer_video_player.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,22 @@ struct omxplayer_mgr_task {
6060
union {
6161
struct {
6262
int orientation;
63-
char *omxplayer_dbus_name;
64-
bool omxplayer_online;
63+
union {
64+
struct {
65+
char *omxplayer_dbus_name;
66+
bool omxplayer_online;
67+
};
68+
struct {
69+
bool visible;
70+
int offset_x, offset_y;
71+
int width, height;
72+
int zpos;
73+
};
74+
};
6575
};
6676
bool loop;
6777
float volume;
6878
int64_t position;
69-
struct {
70-
bool visible;
71-
int offset_x, offset_y;
72-
int width, height;
73-
int zpos;
74-
};
7579
};
7680
};
7781

src/compositor.c

Lines changed: 127 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
#define _GNU_SOURCE
12
#include <stdio.h>
23
#include <errno.h>
34
#include <sys/mman.h>
5+
#include <math.h>
46

57
#include <xf86drm.h>
68
#include <xf86drmMode.h>
@@ -950,6 +952,89 @@ static int execute_simulate_page_flip_event(void *userdata) {
950952
return 0;
951953
}
952954

955+
static void fill_platform_view_params(
956+
struct platform_view_params *params_out,
957+
const FlutterPoint *offset,
958+
const FlutterSize *size,
959+
const FlutterPlatformViewMutation **mutations,
960+
size_t n_mutations,
961+
const FlutterTransformation *display_to_view_transform,
962+
const FlutterTransformation *view_to_display_transform,
963+
double device_pixel_ratio
964+
) {
965+
/**
966+
* inversion for
967+
* ```
968+
* const auto transformed_layer_bounds =
969+
* root_surface_transformation_.mapRect(layer_bounds);
970+
* ```
971+
*/
972+
973+
struct quad quad = apply_transform_to_aa_rect(
974+
*display_to_view_transform,
975+
(struct aa_rect) {
976+
.offset.x = offset->x,
977+
.offset.y = offset->y,
978+
.size.x = size->width,
979+
.size.y = size->height
980+
}
981+
);
982+
983+
struct aa_rect rect = get_aa_bounding_rect(quad);
984+
985+
/**
986+
* inversion for
987+
* ```
988+
* const auto layer_bounds =
989+
* SkRect::MakeXYWH(params.finalBoundingRect().x(),
990+
* params.finalBoundingRect().y(),
991+
* params.sizePoints().width() * device_pixel_ratio_,
992+
* params.sizePoints().height() * device_pixel_ratio_
993+
* );
994+
* ```
995+
*/
996+
997+
rect.size.x /= device_pixel_ratio;
998+
rect.size.y /= device_pixel_ratio;
999+
1000+
// okay, now we have the params.finalBoundingRect().x() in aa_back_transformed.x and
1001+
// params.finalBoundingRect().y() in aa_back_transformed.y.
1002+
// those are flutter view coordinates, so we still need to transform them to display coordinates.
1003+
1004+
// However, there are also calculated as a side-product of calculating the size of the quadrangle.
1005+
// So we'll avoid calculating them for now. Calculation of the size may fail when the offset
1006+
// given to `SceneBuilder.addPlatformView` (https://api.flutter.dev/flutter/dart-ui/SceneBuilder/addPlatformView.html)
1007+
// is not zero. (Don't really know what to do in that case)
1008+
1009+
rect.offset.x = 0;
1010+
rect.offset.y = 0;
1011+
quad = get_quad(rect);
1012+
1013+
double rotation = 0, opacity = 1;
1014+
for (int i = n_mutations - 1; i >= 0; i--) {
1015+
if (mutations[i]->type == kFlutterPlatformViewMutationTypeTransformation) {
1016+
apply_transform_to_quad(mutations[i]->transformation, &quad);
1017+
1018+
double rotz = atan2(mutations[i]->transformation.skewX, mutations[i]->transformation.scaleX) * 180.0 / M_PI;
1019+
if (rotz < 0) {
1020+
rotz += 360;
1021+
}
1022+
1023+
rotation += rotz;
1024+
} else if (mutations[i]->type == kFlutterPlatformViewMutationTypeOpacity) {
1025+
opacity *= mutations[i]->opacity;
1026+
}
1027+
}
1028+
1029+
rotation = fmod(rotation, 360.0);
1030+
1031+
params_out->rect = quad;
1032+
params_out->opacity = 0;
1033+
params_out->rotation = rotation;
1034+
params_out->clip_rects = NULL;
1035+
params_out->n_clip_rects = 0;
1036+
}
1037+
9531038
/// PRESENT FUNCS
9541039
static bool on_present_layers(
9551040
const FlutterLayer **layers,
@@ -1140,6 +1225,8 @@ static bool on_present_layers(
11401225
if (ok != 0) {
11411226
fprintf(stderr, "[compositor] Could not unmount platform view. unmount: %s\n", strerror(ok));
11421227
}
1228+
1229+
cb_data->was_present_last_frame = false;
11431230
}
11441231
}
11451232

@@ -1156,15 +1243,22 @@ static bool on_present_layers(
11561243
}
11571244
}
11581245

1246+
struct platform_view_params params;
1247+
fill_platform_view_params(
1248+
&params,
1249+
&layer->offset,
1250+
&layer->size,
1251+
layer->platform_view->mutations,
1252+
layer->platform_view->mutations_count,
1253+
&flutterpi.view.display_to_view_transform,
1254+
&flutterpi.view.view_to_display_transform,
1255+
flutterpi.display.pixel_ratio
1256+
);
1257+
11591258
ok = cb_data->update_view(
11601259
cb_data->view_id,
11611260
req,
1162-
layer->platform_view->mutations,
1163-
layer->platform_view->mutations_count,
1164-
(int) round(layer->offset.x),
1165-
(int) round(layer->offset.y),
1166-
(int) round(layer->size.width),
1167-
(int) round(layer->size.height),
1261+
&params,
11681262
zpos,
11691263
cb_data->userdata
11701264
);
@@ -1194,16 +1288,23 @@ static bool on_present_layers(
11941288
}
11951289
}
11961290

1291+
struct platform_view_params params;
1292+
fill_platform_view_params(
1293+
&params,
1294+
&layer->offset,
1295+
&layer->size,
1296+
layer->platform_view->mutations,
1297+
layer->platform_view->mutations_count,
1298+
&flutterpi.view.display_to_view_transform,
1299+
&flutterpi.view.view_to_display_transform,
1300+
flutterpi.display.pixel_ratio
1301+
);
1302+
11971303
if (cb_data->mount != NULL) {
11981304
ok = cb_data->mount(
11991305
layer->platform_view->identifier,
12001306
req,
1201-
layer->platform_view->mutations,
1202-
layer->platform_view->mutations_count,
1203-
(int) round(layer->offset.x),
1204-
(int) round(layer->offset.y),
1205-
(int) round(layer->size.width),
1206-
(int) round(layer->size.height),
1307+
&params,
12071308
zpos,
12081309
cb_data->userdata
12091310
);
@@ -1212,6 +1313,7 @@ static bool on_present_layers(
12121313
}
12131314
}
12141315

1316+
cb_data->was_present_last_frame = true;
12151317
cb_data->last_zpos = zpos;
12161318
cb_data->last_size = layer->size;
12171319
cb_data->last_offset = layer->offset;
@@ -1314,15 +1416,22 @@ static bool on_present_layers(
13141416
cb_data = get_cbs_for_view_id_locked(layers[i]->platform_view->identifier);
13151417

13161418
if ((cb_data != NULL) && (cb_data->present != NULL)) {
1419+
struct platform_view_params params;
1420+
fill_platform_view_params(
1421+
&params,
1422+
&layers[i]->offset,
1423+
&layers[i]->size,
1424+
layers[i]->platform_view->mutations,
1425+
layers[i]->platform_view->mutations_count,
1426+
&flutterpi.view.display_to_view_transform,
1427+
&flutterpi.view.view_to_display_transform,
1428+
flutterpi.display.pixel_ratio
1429+
);
1430+
13171431
ok = cb_data->present(
13181432
cb_data->view_id,
13191433
req,
1320-
layers[i]->platform_view->mutations,
1321-
layers[i]->platform_view->mutations_count,
1322-
(int) round(layers[i]->offset.x),
1323-
(int) round(layers[i]->offset.y),
1324-
(int) round(layers[i]->size.width),
1325-
(int) round(layers[i]->size.height),
1434+
&params,
13261435
i + min_zpos,
13271436
cb_data->userdata
13281437
);

0 commit comments

Comments
 (0)