Skip to content

Commit 3af9db6

Browse files
authored
Merge pull request #18 from ardera/input-rework
integrate input rework
2 parents 26ca9ca + e590390 commit 3af9db6

File tree

3 files changed

+514
-264
lines changed

3 files changed

+514
-264
lines changed

README.md

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ You can now theoretically run every flutter app you want using flutter-pi, also
66

77
_The difference between extensions and plugins is that extensions don't include any native code, they are just pure dart. Plugins (like the [connectivity plugin](https://github.com/flutter/plugins/tree/master/packages/connectivity)) include platform-specific code._
88

9+
**Note:** flutter-pi should also work just fine on other 32-bit platforms, if they have Kernel-Modesetting and Direct-Rendering-Infrastructure support. (64-bit support is trivial, just haven't got around to implement it yet)
10+
911
## Contents
1012

1113
1. **[Running your App on the Raspberry Pi](#running-your-app-on-the-raspberry-pi)**
@@ -44,7 +46,9 @@ void main() {
4446
```
4547

4648
### Building the Asset bundle
47-
Then to build the asset bundle, run the following commands. I'm using flutter_gallery in this example. (note that the flutter_gallery example **does not work** with flutter-pi, since it includes plugins that have no platform-side implementation for the raspberry pi yet)
49+
Then to build the asset bundle, run the following commands. You **need** to use a flutter SDK that's compatible to the engine version you're using.
50+
51+
I'm using `flutter_gallery` in this example. (note that the `flutter_gallery` example **does not work** with flutter-pi, since it includes plugins that have no platform-side implementation for the raspberry pi yet)
4852
```bash
4953
cd flutter/examples/flutter_gallery
5054
flutter build bundle
@@ -53,25 +57,42 @@ flutter build bundle
5357
After that `flutter/examples/flutter_gallery/build/flutter_assets` would be a valid path to pass as an argument to flutter-pi.
5458

5559
### Running your App with flutter-pi
56-
flutter-pi doesn't support the legacy GL driver anymore. You need to activate the anholt v3d driver in raspi-config. Go to `raspi-config -> Advanced -> GL Driver` and select fake-KMS. Full-KMS is a bit buggy and doesn't work with the Raspberry Pi 7" display (or generally, any DSI display).
57-
58-
For some reason performance is much better when you give the VideCore only 16MB of RAM in fake-kms. I don't know why.
59-
60-
Also, you need to tell flutter-pi which input device to use and whether it's a touchscreen or mouse. Input devices are typically located at `/dev/input/...`. Just run `evtest` (`sudo apt install evtest`) to find out which exact path you should use. Currently only one input device is supported by flutter-pi. In the future, I will probably let flutter-pi search for an input device by itself.
61-
62-
Run using
63-
```bash
64-
./flutter-pi [flutter-pi options...] /path/to/assets/bundle/directory [flutter engine arguments...]
60+
flutter-pi doesn't support the legacy broadcom-proprietary graphics stack anymore. You need to activate the V3D / VC4-V3D driver in raspi-config. Go to `raspi-config -> Advanced -> GL Driver` and select fake-KMS. Full-KMS is a bit buggy and doesn't work with the Raspberry Pi 7" display (or generally, any DSI display).
61+
62+
For Raspberry Pi's older than the 4B Model, it's best to give the GPU as little RAM as possible in `raspi-config` (16MB), since the V3D / VC4-V3D driver doesn't need GPU RAM anymore. The Pi 4 automatically adjusts the memory split at runtime.
63+
64+
```txt
65+
USAGE:
66+
flutter-pi [options] <asset bundle path> [flutter engine options...]
67+
68+
OPTIONS:
69+
-i <glob pattern> Appends all files matching this glob pattern
70+
to the list of input (touchscreen, mouse, touchpad)
71+
devices. Brace and tilde expansion is enabled.
72+
Every file that matches this pattern, but is not
73+
a valid touchscreen / -pad or mouse is silently
74+
ignored.
75+
If no -i options are given, all files matching
76+
"/dev/input/event*" will be used as inputs.
77+
This should be what you want in most cases.
78+
Note that you need to properly escape each glob pattern
79+
you use as a parameter so it isn't implicitly expanded
80+
by your shell.
81+
82+
-h Show this help and exit.
83+
84+
EXAMPLES:
85+
flutter-pi -i "/dev/input/event{0,1}" -i "/dev/input/event{2,3}" /home/helloworld_flutterassets
86+
flutter-pi -i "/dev/input/mouse*" /home/pi/helloworld_flutterassets
87+
flutter-pi /home/pi/helloworld_flutterassets
6588
```
6689

67-
`[flutter-pi options...]` are:
68-
- `-t /path/to/device` where `/path/to/device` is a path to a touchscreen input device (typically `/dev/input/event0` or similiar)
69-
- `-m /path/to/device` where `/path/to/device` is a path to a mouse input device (typically `/dev/input/mouse0` or `/dev/input/event0` or similiar)
70-
71-
`/path/to/assets/bundle/directory` is the path of the flutter asset bundle directory (i.e. the directory containing the kernel_blob.bin)
90+
Also, `<asset bundle path>` is the path of the flutter asset bundle directory (i.e. the directory containing `kernel_blob.bin`)
7291
of the flutter app you're trying to run.
7392

74-
`[flutter engine arguments...]` will be passed as commandline arguments to the flutter engine. You can find a list of commandline options for the flutter engine [Here](https://github.com/flutter/engine/blob/master/shell/common/switches.h).
93+
`[flutter engine options...]` will be passed as commandline arguments to the flutter engine. You can find a list of commandline options for the flutter engine [Here](https://github.com/flutter/engine/blob/master/shell/common/switches.h).
94+
95+
It seems that sometimes, when running on the Pi 4, you need to run flutter-pi as root. At other times, it works fine without root. Don't know why that may be. If root is needed and flutter-pi is run without root, mesa will select _llvmpipe_ as the driver, and flutter-pi will issue a warning (and probably crash right after that).
7596

7697
## Dependencies
7798
### flutter engine
@@ -106,7 +127,5 @@ Performance is actually better than I expected. With most of the apps inside the
106127
## Touchscreen Bug
107128
~~If you use the official 7 inch touchscreen, performance will feel much worse while dragging something. This seems to be some bug in the touchscreen driver. The embedder / userspace only gets around 25 touch events a second, meaning that while dragging something (like in tabbed_app_bar.dart), the position of the object being dragged is only updated 25 times a second. This results in the app looking like it runs at 25fps. The touchscreen could do up to 100 touch updates a second though.~~
108129

109-
[This has been fixed.](https://github.com/raspberrypi/linux/issues/3227) If you want to get the fix, you can run [rpi-update](https://github.com/hexxeh/rpi-update), which will update your firmware & operating system to the newest version.
110-
111-
Still, there's some delta between you touching the touchscreen and a touch event arriving at userspace. This is because of the implementation of the touch driver in the firmware & in the linux kernel. I think on average, there's a delay of 17ms. If I have enough time in the future, I'll try to build a better touchscreen driver to lower the delay.
130+
[This has been fixed.](https://github.com/raspberrypi/linux/issues/3227) Still, there's some delta between you touching the touchscreen and a touch event arriving at userspace. This is because of the implementation of the touch driver in the firmware & in the linux kernel. I think on average, there's a delay of 17ms. If I have enough time in the future, I'll try to build a better touchscreen driver to lower the delay.
112131

include/flutter-pi.h

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef _FLUTTERPI_H
22
#define _FLUTTERPI_H
33

4+
#include <limits.h>
5+
#include <linux/input.h>
46
#include <stdbool.h>
57
#include <xf86drm.h>
68
#include <xf86drmMode.h>
@@ -9,8 +11,8 @@
911

1012
#define EGL_PLATFORM_GBM_KHR 0x31D7
1113

12-
struct FlutterPiTask {
13-
struct FlutterPiTask* next;
14+
struct flutterpi_task {
15+
struct flutterpi_task* next;
1416
bool is_vblank_event;
1517
union {
1618
FlutterTask task;
@@ -19,18 +21,83 @@ struct FlutterPiTask {
1921
uint64_t target_time;
2022
};
2123

22-
struct TouchscreenSlot {
23-
int id;
24-
int x;
25-
int y;
26-
FlutterPointerPhase phase;
27-
};
28-
2924
struct drm_fb {
3025
struct gbm_bo *bo;
3126
uint32_t fb_id;
3227
};
3328

34-
FlutterEngine engine;
29+
// position & pointer phase of a mouse pointer / multitouch slot
30+
// A 10-finger multi-touch display has 10 slots and each of them have their own position, tracking id, etc.
31+
// All mouses / touchpads share the same mouse pointer.
32+
struct mousepointer_mtslot {
33+
// the MT tracking ID used to track this touch.
34+
int id;
35+
int32_t flutter_slot_id;
36+
double x, y;
37+
FlutterPointerPhase phase;
38+
};
39+
40+
#define INPUT_BUSTYPE_FRIENDLY_NAME(bustype) ( \
41+
(bustype) == BUS_PCI ? "PCI/e" : \
42+
(bustype) == BUS_USB ? "USB" : \
43+
(bustype) == BUS_BLUETOOTH ? "Bluetooth" : \
44+
(bustype) == BUS_VIRTUAL ? "virtual" : \
45+
(bustype) == BUS_I2C ? "I2C" : \
46+
(bustype) == BUS_HOST ? "Host-Interface" : \
47+
(bustype) == BUS_SPI ? "SPI" : "other")
48+
49+
#define FLUTTER_BUTTON_FROM_EVENT_CODE(code) ((uint16_t) \
50+
(code) == BTN_LEFT ? kFlutterPointerButtonMousePrimary : \
51+
(code) == BTN_RIGHT ? kFlutterPointerButtonMouseSecondary : \
52+
(code) == BTN_MIDDLE ? kFlutterPointerButtonMouseMiddle : \
53+
(code) == BTN_FORWARD ? kFlutterPointerButtonMouseForward : \
54+
(code) == BTN_BACK ? kFlutterPointerButtonMouseBack : \
55+
(code) == BTN_TOUCH ? (1 << 8) : 0)
56+
57+
#define POINTER_PHASE_AS_STRING(phase) ( \
58+
(phase) == kCancel ? "kCancel" : \
59+
(phase) == kUp ? "kUp" : \
60+
(phase) == kDown ? "kDown" : \
61+
(phase) == kMove ? "kMove" : \
62+
(phase) == kAdd ? "kAdd" : \
63+
(phase) == kRemove ? "kRemove" : \
64+
(phase) == kHover ? "kHover" : "???")
65+
66+
#define ISSET(uint32bitmap, bit) (uint32bitmap[(bit)/32] & (1 << ((bit) & 0x1F)))
67+
68+
struct input_device {
69+
char path[PATH_MAX];
70+
char name[256];
71+
struct input_id input_id;
72+
int fd;
73+
74+
// the pointer device kind reported to the flutter engine
75+
FlutterPointerDeviceKind kind;
76+
77+
// this should be true for mouse and touchpad, false for touchscreens / stylus
78+
bool is_pointer;
79+
bool is_direct;
80+
81+
// for EV_ABS devices (touchscreens, some touchpads)
82+
struct input_absinfo xinfo, yinfo;
83+
84+
// n_slots is > 1 for Multi-Touch devices (most touchscreens)
85+
// just because n_slots is 0 and slots is NULL, doesn't mean active_slot is NULL.
86+
// mouse devices own 0 slots (since they all share a global slot), and still have an active_slot.
87+
size_t n_mtslots;
88+
size_t i_active_mtslot;
89+
struct mousepointer_mtslot *mtslots;
90+
//struct mousepointer_mtslot *active_mtslot;
91+
92+
// currently pressed buttons (for mouse, touchpad, stylus)
93+
// (active_buttons & 0xFF) will be the value of the "buttons" field
94+
// of the FlutterPointerEvent being sent to flutter
95+
uint16_t active_buttons;
96+
};
97+
98+
// we have one global mouse pointer, even if multiple mouses are attached
99+
extern struct mousepointer_mtslot mousepointer;
100+
101+
extern FlutterEngine engine;
35102

36103
#endif

0 commit comments

Comments
 (0)