Skip to content

feature/omxplayer-runtime-rotation #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ project(flutter-pi LANGUAGES C)
message(STATUS "Generator .............. ${CMAKE_GENERATOR}")
message(STATUS "Build Type ............. ${CMAKE_BUILD_TYPE}")

OPTION(OMXPLAYER_SUPPORTS_RUNTIME_ROTATION "Whether omxplayer supports runtime rotation." OFF)

if(NOT FLUTTER_EMBEDDER_HEADER)

include(FetchContent)
Expand Down Expand Up @@ -179,6 +181,9 @@ endif()
if (BUILD_OMXPLAYER_VIDEO_PLAYER_PLUGIN)
target_compile_definitions(flutter-pi PRIVATE "BUILD_OMXPLAYER_VIDEO_PLAYER_PLUGIN")
endif()
if (OMXPLAYER_SUPPORTS_RUNTIME_ROTATION)
target_compile_definitions(flutter-pi PRIVATE "OMXPLAYER_SUPPORTS_RUNTIME_ROTATION")
endif()

target_link_options(flutter-pi PRIVATE
-rdynamic
Expand Down
87 changes: 69 additions & 18 deletions include/compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@
#include <collection.h>
#include <modesetting.h>

struct platform_view_params;

typedef int (*platform_view_mount_cb)(
int64_t view_id,
struct drmdev_atomic_req *req,
const FlutterPlatformViewMutation **mutations,
size_t num_mutations,
int offset_x,
int offset_y,
int width,
int height,
const struct platform_view_params *params,
int zpos,
void *userdata
);
Expand All @@ -31,29 +28,83 @@ typedef int (*platform_view_unmount_cb)(
typedef int (*platform_view_update_view_cb)(
int64_t view_id,
struct drmdev_atomic_req *req,
const FlutterPlatformViewMutation **mutations,
size_t num_mutations,
int offset_x,
int offset_y,
int width,
int height,
const struct platform_view_params *params,
int zpos,
void *userdata
);

typedef int (*platform_view_present_cb)(
int64_t view_id,
struct drmdev_atomic_req *req,
const FlutterPlatformViewMutation **mutations,
size_t num_mutations,
int offset_x,
int offset_y,
int width,
int height,
const struct platform_view_params *params,
int zpos,
void *userdata
);

struct point {
double x, y;
};

struct quad {
struct point top_left, top_right, bottom_left, bottom_right;
};

struct aa_rect {
struct point offset, size;
};

static inline struct aa_rect get_aa_bounding_rect(const struct quad _rect) {
double l = min(min(min(_rect.top_left.x, _rect.top_right.x), _rect.bottom_left.x), _rect.bottom_right.x);
double r = max(max(max(_rect.top_left.x, _rect.top_right.x), _rect.bottom_left.x), _rect.bottom_right.x);
double t = min(min(min(_rect.top_left.y, _rect.top_right.y), _rect.bottom_left.y), _rect.bottom_right.y);
double b = max(max(max(_rect.top_left.y, _rect.top_right.y), _rect.bottom_left.y), _rect.bottom_right.y);

return (struct aa_rect) {
.offset.x = l,
.offset.y = t,
.size.x = r - l,
.size.y = b - t
};
}

static inline struct quad get_quad(const struct aa_rect rect) {
return (struct quad) {
.top_left = rect.offset,
.top_right.x = rect.offset.x + rect.size.x,
.top_right.y = rect.offset.y,
.bottom_left.x = rect.offset.x,
.bottom_left.y = rect.offset.y + rect.size.y,
.bottom_right.x = rect.offset.x + rect.size.x,
.bottom_right.y = rect.offset.y + rect.size.y
};
}

static inline void apply_transform_to_point(const FlutterTransformation transform, struct point *point) {
apply_flutter_transformation(transform, &point->x, &point->y);
}

static inline void apply_transform_to_quad(const FlutterTransformation transform, struct quad *rect) {
apply_transform_to_point(transform, &rect->top_left);
apply_transform_to_point(transform, &rect->top_right);
apply_transform_to_point(transform, &rect->bottom_left);
apply_transform_to_point(transform, &rect->bottom_right);
}

static inline struct quad apply_transform_to_aa_rect(const FlutterTransformation transform, const struct aa_rect rect) {
struct quad _quad = get_quad(rect);
apply_transform_to_quad(transform, &_quad);
return _quad;
}


struct platform_view_params {
struct quad rect;
double rotation;
struct clip_rect *clip_rects;
size_t n_clip_rects;
double opacity;
};

struct compositor {
struct drmdev *drmdev;

Expand Down
20 changes: 12 additions & 8 deletions include/plugins/omxplayer_video_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,22 @@ struct omxplayer_mgr_task {
union {
struct {
int orientation;
char *omxplayer_dbus_name;
bool omxplayer_online;
union {
struct {
char *omxplayer_dbus_name;
bool omxplayer_online;
};
struct {
bool visible;
int offset_x, offset_y;
int width, height;
int zpos;
};
};
};
bool loop;
float volume;
int64_t position;
struct {
bool visible;
int offset_x, offset_y;
int width, height;
int zpos;
};
};
};

Expand Down
145 changes: 127 additions & 18 deletions src/compositor.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include <math.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
Expand Down Expand Up @@ -935,6 +937,89 @@ static int execute_simulate_page_flip_event(void *userdata) {
return 0;
}

static void fill_platform_view_params(
struct platform_view_params *params_out,
const FlutterPoint *offset,
const FlutterSize *size,
const FlutterPlatformViewMutation **mutations,
size_t n_mutations,
const FlutterTransformation *display_to_view_transform,
const FlutterTransformation *view_to_display_transform,
double device_pixel_ratio
) {
/**
* inversion for
* ```
* const auto transformed_layer_bounds =
* root_surface_transformation_.mapRect(layer_bounds);
* ```
*/

struct quad quad = apply_transform_to_aa_rect(
*display_to_view_transform,
(struct aa_rect) {
.offset.x = offset->x,
.offset.y = offset->y,
.size.x = size->width,
.size.y = size->height
}
);

struct aa_rect rect = get_aa_bounding_rect(quad);

/**
* inversion for
* ```
* const auto layer_bounds =
* SkRect::MakeXYWH(params.finalBoundingRect().x(),
* params.finalBoundingRect().y(),
* params.sizePoints().width() * device_pixel_ratio_,
* params.sizePoints().height() * device_pixel_ratio_
* );
* ```
*/

rect.size.x /= device_pixel_ratio;
rect.size.y /= device_pixel_ratio;

// okay, now we have the params.finalBoundingRect().x() in aa_back_transformed.x and
// params.finalBoundingRect().y() in aa_back_transformed.y.
// those are flutter view coordinates, so we still need to transform them to display coordinates.

// However, there are also calculated as a side-product of calculating the size of the quadrangle.
// So we'll avoid calculating them for now. Calculation of the size may fail when the offset
// given to `SceneBuilder.addPlatformView` (https://api.flutter.dev/flutter/dart-ui/SceneBuilder/addPlatformView.html)
// is not zero. (Don't really know what to do in that case)

rect.offset.x = 0;
rect.offset.y = 0;
quad = get_quad(rect);

double rotation = 0, opacity = 1;
for (int i = n_mutations - 1; i >= 0; i--) {
if (mutations[i]->type == kFlutterPlatformViewMutationTypeTransformation) {
apply_transform_to_quad(mutations[i]->transformation, &quad);

double rotz = atan2(mutations[i]->transformation.skewX, mutations[i]->transformation.scaleX) * 180.0 / M_PI;
if (rotz < 0) {
rotz += 360;
}

rotation += rotz;
} else if (mutations[i]->type == kFlutterPlatformViewMutationTypeOpacity) {
opacity *= mutations[i]->opacity;
}
}

rotation = fmod(rotation, 360.0);

params_out->rect = quad;
params_out->opacity = 0;
params_out->rotation = rotation;
params_out->clip_rects = NULL;
params_out->n_clip_rects = 0;
}

/// PRESENT FUNCS
static bool on_present_layers(
const FlutterLayer **layers,
Expand Down Expand Up @@ -1125,6 +1210,8 @@ static bool on_present_layers(
if (ok != 0) {
fprintf(stderr, "[compositor] Could not unmount platform view. unmount: %s\n", strerror(ok));
}

cb_data->was_present_last_frame = false;
}
}

Expand All @@ -1141,15 +1228,22 @@ static bool on_present_layers(
}
}

struct platform_view_params params;
fill_platform_view_params(
&params,
&layer->offset,
&layer->size,
layer->platform_view->mutations,
layer->platform_view->mutations_count,
&flutterpi.view.display_to_view_transform,
&flutterpi.view.view_to_display_transform,
flutterpi.display.pixel_ratio
);

ok = cb_data->update_view(
cb_data->view_id,
req,
layer->platform_view->mutations,
layer->platform_view->mutations_count,
(int) round(layer->offset.x),
(int) round(layer->offset.y),
(int) round(layer->size.width),
(int) round(layer->size.height),
&params,
zpos,
cb_data->userdata
);
Expand Down Expand Up @@ -1179,16 +1273,23 @@ static bool on_present_layers(
}
}

struct platform_view_params params;
fill_platform_view_params(
&params,
&layer->offset,
&layer->size,
layer->platform_view->mutations,
layer->platform_view->mutations_count,
&flutterpi.view.display_to_view_transform,
&flutterpi.view.view_to_display_transform,
flutterpi.display.pixel_ratio
);

if (cb_data->mount != NULL) {
ok = cb_data->mount(
layer->platform_view->identifier,
req,
layer->platform_view->mutations,
layer->platform_view->mutations_count,
(int) round(layer->offset.x),
(int) round(layer->offset.y),
(int) round(layer->size.width),
(int) round(layer->size.height),
&params,
zpos,
cb_data->userdata
);
Expand All @@ -1197,6 +1298,7 @@ static bool on_present_layers(
}
}

cb_data->was_present_last_frame = true;
cb_data->last_zpos = zpos;
cb_data->last_size = layer->size;
cb_data->last_offset = layer->offset;
Expand Down Expand Up @@ -1299,15 +1401,22 @@ static bool on_present_layers(
cb_data = get_cbs_for_view_id_locked(layers[i]->platform_view->identifier);

if ((cb_data != NULL) && (cb_data->present != NULL)) {
struct platform_view_params params;
fill_platform_view_params(
&params,
&layers[i]->offset,
&layers[i]->size,
layers[i]->platform_view->mutations,
layers[i]->platform_view->mutations_count,
&flutterpi.view.display_to_view_transform,
&flutterpi.view.view_to_display_transform,
flutterpi.display.pixel_ratio
);

ok = cb_data->present(
cb_data->view_id,
req,
layers[i]->platform_view->mutations,
layers[i]->platform_view->mutations_count,
(int) round(layers[i]->offset.x),
(int) round(layers[i]->offset.y),
(int) round(layers[i]->size.width),
(int) round(layers[i]->size.height),
&params,
i + min_zpos,
cb_data->userdata
);
Expand Down
Loading