Minor dev documentatioon tweaks (#5518)

* Made Porting not so hilariously outdated.
* Minor tweaks to the macOS build instructions and the various quirks involved in getting it to behave (and accompanying actual build fixes).
pull/5525/head
NiLuJe 5 years ago committed by GitHub
parent d1cd5e7ad4
commit eae105bb72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +1 @@
Subproject commit d9a685c6817d073a9fc0cd231e567a998250a9c6 Subproject commit a1fc4e43b7cce7a76b13224e145f9bada343d8ea

@ -33,7 +33,7 @@ Install the `libstdc++-static`, `SDL` and `SDL-devel` packages using DNF:
sudo dnf install libstdc++-static SDL SDL-devel sudo dnf install libstdc++-static SDL SDL-devel
``` ```
### MacOS ### macOS
Install the prerequisites using [Homebrew](https://brew.sh/): Install the prerequisites using [Homebrew](https://brew.sh/):
@ -43,12 +43,14 @@ sdl2 lua@5.1 luarocks gettext pkg-config wget md5sha1sum
echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> "$HOME"/.bash_profile echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> "$HOME"/.bash_profile
``` ```
If you run into a gettext error while building glib, try `brew link --force gettext` to override the built-in Mac OS BSD gettext with GNU GetText. If you run into a gettext error while building glib, try `brew link --force gettext` to override the built-in macOS BSD gettext with GNU gettext.
*Note:* in Mojave (10.14) you need to set a minimum deployment version higher than 10.04. Otherwise you'll get the error `ld: library not found for -lgcc_s.10.4`. *Note:* With current XCode versions, you *will* need to set a minimum deployment version higher than `10.04`. Otherwise, you'll hit various linking errors related to missing unwinding libraries/symbols.
On Mojave, `10.09` has been known to behave with XCode 10, And `10.14` with XCode 11. When in doubt, go with your current macOS version.
``` ```
export MACOSX_DEPLOYMENT_TARGET=10.09 export MACOSX_DEPLOYMENT_TARGET=10.09
``` ```
*Note:* On Catalina (10.15), you will currently *NOT* want to deploy for `10.15`, as [XCode is currently broken in that configuration](https://forums.developer.apple.com/thread/121887)! (i.e., deploy for `10.14` instead).
## Getting the source ## Getting the source
@ -107,7 +109,7 @@ Once you have the emulator ready to rock you can [build for other platforms too]
## Testing ## Testing
You may need to check out the [circleci config file][circleci-conf] to setup up You may need to check out the [circleci config file][circleci-conf] to setup up
a proper testing environment. a proper testing environment.
Briefly, you need to install `luarocks` and then install `busted` and `ansicolors` with `luarocks`. The "eng" language data file for tesseract-ocr is also need to test OCR functionality. Finally, make sure that `luajit` in your system is at least of version 2.0.2. Briefly, you need to install `luarocks` and then install `busted` and `ansicolors` with `luarocks`. The "eng" language data file for tesseract-ocr is also need to test OCR functionality. Finally, make sure that `luajit` in your system is at least of version 2.0.2.

@ -2,72 +2,83 @@
This page aims to provide guidance on how to port KOReader to other platforms. This page aims to provide guidance on how to port KOReader to other platforms.
There are mainly two modules that you need to take care of: input and output. There are mainly two modules that you need to take care of: input and output.
After you finish these two, KOReader should have no problem running on your After you finish these two, KOReader should have no problem running on your platform.
platform. Feel free to open issues in our issue tracker if you need further help on this topic :) Feel free to open issues in our issue tracker if you need further help on this topic :)
## Output Module ## Output Module
KOReader uses framebuffer to control EInk devices, so the output module here is ### Current mxcfb eInk devices
[base/ffi/framebuffer_einkfb.lua](https://github.com/koreader/koreader-base/blob/master/ffi/framebuffer_einkfb.lua).
KOReader uses the Linux framebuffer to control eInk devices, so the output module for mxcfb (i.e., those based on Freescale/NXP hardware) devices is [`base/ffi/framebuffer_mxcfb.lua`](https://github.com/koreader/koreader-base/blob/master/ffi/framebuffer_mxcfb.lua).
Most common bitdepths are supported, although no devices should actually be using anything other than 8bpp, 16bpp and 32bpp.
For 8bpp, we assume the grayscale palette is NOT inverted.
At 32bpp, we generally assume the pixel format is BGRA, and we honor Alpha, despite it being effectively ignored by the display (see Kobos).
At 16bpp, we assume the pixel format is RGB565.
For obvious performance reasons, we prefer 8bpp, and we will attempt to enforce that on devices which are not natively running at that depth (i.e., [on Kobos](https://github.com/koreader/koreader/blob/d1cd5e7ad4283611c57007b2c2d3dd5f7dab7057/platform/kobo/koreader.sh#L138-L186)).
As explained below, the same considerations should be kept in mind regarding the effective 16c palette of eInk screens.
When we're in control of the data, we attempt to always use "perfect" in-palette colors (c.f., the [COLOR constants](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/blitbuffer.lua#L1881-L1889) in the BlitBuffer module).
Otherwise, when there'd be signficiant gain in doing so (i.e., when displaying mainly image content), we attempt to make use of [dithering](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/blitbuffer.lua#L227-L271), ideally [offloaded to the hardware](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/framebuffer_mxcfb.lua#L412-L423) when supported.
The actual framebuffer content is then refreshed (i.e., displayed) via device-specific ioctls, making the best effort in using device-specific capabilities, whether that be [optimized waveform modes](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/framebuffer_mxcfb.lua#L643-L655), hardware dithering or [hardware inversion](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/framebuffer_mxcfb.lua#L253-L256).
### Legacy einkfb eInk devices
KOReader uses the Linux framebuffer to control eInk devices, so the output module for legacy einkfb devices is [`base/ffi/framebuffer_einkfb.lua`](https://github.com/koreader/koreader-base/blob/master/ffi/framebuffer_einkfb.lua).
Following are the framebuffers that `framebuffer_einkfb.lua` currently supports: Following are the framebuffers that `framebuffer_einkfb.lua` currently supports:
* 4BPP inverted framebuffer * 4bpp framebuffer (palette is always inverted)
* 16 scale 8BPP inverted framebuffer * 16c 8bpp framebuffer (inverted grayscale palette)
* 16 scale 8BPP framebuffer
For 4BPP framebuffer, it means every pixel is represented with 4 bits, so we For 4bpp framebuffers, it means every pixel is represented with 4 bits, so we have 2 pixels in 1 byte.
have 2 pixels in 1 byte. So the color depth is 16. The inverted part means all That also effectively limits the palette to 16 colors.
the bits are flipped in the framebuffer. For example, two pixels `[0x00, 0xf0]` The inverted part means that every pixel's color value is flipped (`^ 0xFF`).
will be stored as `0xff0f` in framebuffer. For example, two pixels `0x00` and `0xF0` will be flipped to `0xFF` and `0x0F`, before being packed to accomodate the framebuffer's pixel format (here, [into a single byte](https://github.com/NiLuJe/FBInk/blob/4f0230b17c480cdc75dd5497fddf33937781c812/fbink.c#L106-L133)).
For 16 scale 8BPP framebuffer, it means each pixel is instead stored in 1 byte, For 8bpp framebuffers, it means each pixel is instead stored in 1 byte, making addressing much simpler.
but the color depth is still 16 (4bits). Since 1 byte has 8 bits, so to fill The effective color palette of the display is still limited to 16 shades of gray: it will do a decimating quantization pass on its own on refresh.
up the remaining space, the most significant 4 bits is a copy of the least So, while a black pixel will indeed be `0x00`, any color value < `0x11` (the next effective shade of gray in the [palette](https://github.com/NiLuJe/FBInk/blob/4f0230b17c480cdc75dd5497fddf33937781c812/fbink_internal.h#L327-L334)) will be displayed as pure black, too.
significant one. For example, pixel with grey scale 15 will be represented as If the palette is expected to be inverted, then all the bits are flipped in the same way as done on a 4bpp framebuffer.
`0xffff`. If it's a inverted 16 scale 8BPP framebuffer, then all the bits are In practice, [this is always the case](https://github.com/koreader/koreader-base/blob/a1fc4e43b7cce7a76b13224e145f9bada343d8ea/ffi/framebuffer_linux.lua#L242-L245).
flipped in the same way as 4BPP inverted framebuffer does.
If your device's framebuffer does not fit into any of the categories above, The actual framebuffer content is then refreshed (i.e., displayed) via device-specific ioctls.
then you need to add a new transformation function in `framebuffer_einkfb.lua`.
The `framebuffer_einkfb.lua` module works in following ways for non 4BPP framebuffers: ## Blitter Module
* a shadow buffer is created and structured as 4BPP inverted framebuffer. All the intermediary buffers are handled in a pixel format that matches the output module in use as closely as possible.
* all updates on screen bitmap are temporally written into the shadow buffer. The magic happens in [`base/ffi/blitbuffer.lua`](https://github.com/koreader/koreader-base/blob/master/ffi/blitbuffer.lua), with some help from the [LinuxFB](https://github.com/koreader/koreader-base/blob/master/ffi/framebuffer_linux.lua) frontend to the output modules.
* each time we want to reflect the updated bitmap on screen, we translate the shadow buffer into a format that the real framebuffer understands and write into the mapped memory region. (varies on devices)
* call ioctl system call to refresh EInk screen. (varies on devices)
KOReader will handle the 4BPP shadow buffer for you, all you need to do is to Note that on most devices, a [C version](https://github.com/koreader/koreader-base/blob/master/blitbuffer.c) is used instead for more consistent performance.
teach `framebuffer_einkfb.lua` how to control the EInk screen and translate the 4BPP inverted Which version is more easily readable to a newcomer is up for debate, so, don't hesitate to cross-reference ;).
bitmap into the format that your framebuffer understands. Feature-parity should be complete, with the exception of 4bpp support in the C version.
If you need a bit of guidance, you can also take a look at [FBInk](https://github.com/NiLuJe/FBInk), and/or ping [@NiLuJe](https://github.com/NiLuJe) on gitter.
## Input Module ## Input Module
We have a `input.c` module in [koreader-base][kb-framework] that reads input We have an [`input.c`](https://github.com/koreader/koreader-base/blob/master/input/input.c) module in [koreader-base][kb-framework] that reads input events from Linux's input system and passes it on to the Lua frontend.
events from Linux's input system and pass to Lua frontend. Basically, you don't Basically, you don't need to change that module because it should support most of the events.
need to change on that module because it should support most of the events.
For this part, the file you have to hack on is [`koreader/frontend/ui/input.lua`](https://github.com/koreader/koreader/blob/master/frontend/ui/input.lua). For this part, the file you have to hack on is [`koreader/frontend/ui/input.lua`](https://github.com/koreader/koreader/blob/master/frontend/ui/input.lua).
Firstly, you need to tell which input device to open on KOReader start. All the Firstly, you need to tell which input device to open on KOReader start. All the input devices are opened in `Input:init()` function.
input devices are opened in `Input:init()` function.
Next, you might need to define `Input:eventAdjustHook()` function in Next, you might need to define `Input:eventAdjustHook()` function in `Input:init()` method.
`Input:init()` method. We use this hook function to translates events into a We use this hook function to translate events into a format that KOReader understands.
format that KOReader understands. You can look at the KindleTouch initialization code for real example. You can look at the KindleTouch initialization code for a real-world example.
For Kobo devices (Mini, Touch, Glo and Aura HD) the function `Input:eventAdjustHook()` was skipped and the functions `Input:init()` and `Input:handleTypeBTouchEv` were changed to allow the single touch protocol. For Kobo Aura with multitouch support an extra function `Input:handlePhoenixTouchEv` was added. For some Kobo devices (Mini, Touch, Glo and Aura HD) the function `Input:eventAdjustHook()` was skipped and the functions `Input:init()` and `Input:handleTypeBTouchEv()` were changed to accomodate for the single touch protocol.
For the Kobo Aura (and others with the same kernel quirks) with multitouch support, an extra function `Input:handlePhoenixTouchEv()` was added.
Linux supports two kinds of Multi-touch protocols: Linux supports two kinds of Multi-touch protocols:
* <http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt> * <http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt>
Currently, KOReader supports gesture detection of protocol B, so if your device sends out Currently, KOReader supports gesture detection of protocol B, so if your device sends out protocol A, you need to make a variant of function `Input:handleTouchEv()` (like `Input:handleTypeBTouchEv()` and `Input:handlePhoenixTouchEv()`) and simulate protocol B.
protocol A, you need to make a variant of function `Input:handleTouchEv()` (like `Input:handleTypeBTouchEv` and `Input:handlePhoenixTouchEv`) and simulate protocol B. You are also welcome to send a PR that adds protocol A support to KOReader.
Also you are welcome to send a PR that adds protocol A support to KOReader.
More information on Linux's input system: More information on Linux's input system:
@ -75,3 +86,5 @@ More information on Linux's input system:
* <http://www.kernel.org/doc/Documentation/input/input.txt> * <http://www.kernel.org/doc/Documentation/input/input.txt>
[kb-framework]:https://github.com/koreader/koreader-base [kb-framework]:https://github.com/koreader/koreader-base
<!-- kate: indent-mode cstyle; indent-width 4; replace-tabs on; remove-trailing-spaces none; -->

Loading…
Cancel
Save