Skip to content

Support reMarkable OS 3.28: swapBuffers dropped EPContentType - #1

Open
joaodelapace wants to merge 1 commit into
MaximeRivest:mainfrom
joaodelapace:fix/paperpro-os-3.28-swapbuffers
Open

joaodelapace wants to merge 1 commit into
MaximeRivest:mainfrom
joaodelapace:fix/paperpro-os-3.28-swapbuffers

Conversation

@joaodelapace

Copy link
Copy Markdown

Support reMarkable OS 3.28: swapBuffers dropped EPContentType

Symptom

On a Paper Pro running OS 3.28, takeover apps start and connect but the
e-ink panel never updates. The log shows:

quill: framebuffer 1620x2160 stride=6528 format=4
riddle: display quill/takeover (1620x2160 stride 6528)
quill: EPFramebuffer::swapBuffers unavailable
riddle: the diary is open

Everything initializes (EPFramebuffer::instance resolves, the framebuffer is
found, pen/power grab, oracle works) — only the frame swap fails, so pixels are
written but never flushed to the display.

Root cause

quill_vendor::swap resolves a single hard-coded mangled symbol. On OS 3.28
reMarkable removed the EPContentType parameter from swapBuffers.
Dumping the device's own libqsgepaper.so:

firmware mangled symbol signature
≤ 3.27 _ZN13EPFramebuffer11swapBuffersE5QRect13EPContentType12EPScreenMode6QFlagsINS_10UpdateFlagEE swapBuffers(QRect, EPContentType, EPScreenMode, QFlags<UpdateFlag>)
≥ 3.28 _ZN13EPFramebuffer11swapBuffersE5QRect12EPScreenMode6QFlagsINS_10UpdateFlagEE swapBuffers(QRect, EPScreenMode, QFlags<UpdateFlag>)

3.28 also adds EPFramebuffer::setBuffers(std::tuple<QImage, QImage>), i.e.
the content type is now carried by the registered buffers instead of by the
swap call. EPFramebuffer::instance is unchanged on both, which is why only
the swap failed.

Fix

Resolve whichever overload the running firmware exports and call it with the
matching argument layout. The ≤3.27 path is byte-for-byte the old behavior; the
3.28 path drops content_type and passes mode/flags in the correct
positions. Enums and QFlags are 4-byte trivially-copyable and travel as int
in their AArch64 registers, exactly as the existing typedef already assumed.

Testing

  • Hardware-verified on a Paper Pro running OS 3.28 (device: reMarkable Ferrari).
    Mono live ink renders and a full round-trip works (riddle "The Diary" draws
    and replies).
  • Backward compatible: the ≤3.27 path is unchanged (same symbol, same five
    args, same guard/return).

Caveat (please review)

Color rendering on 3.28 is not yet hardware-verified. This diff passes the
correct EPScreenMode to the 3.28 overload but does not (yet) call the new
setBuffers(tuple<QImage,QImage>). If 3.28 requires a second buffer to be
registered for color, a follow-up wiring setBuffers may be needed. Mono — the
path riddle uses for live ink — is confirmed working.

OS 3.28 removed the EPContentType parameter from EPFramebuffer::swapBuffers,
so the single hard-coded mangled symbol no longer resolves and the panel
never updates ("EPFramebuffer::swapBuffers unavailable"). Dumping the device
libqsgepaper.so:

  <=3.27  swapBuffers(QRect, EPContentType, EPScreenMode, QFlags<UpdateFlag>)
  >=3.28  swapBuffers(QRect,                EPScreenMode, QFlags<UpdateFlag>)

(3.28 also adds setBuffers(std::tuple<QImage,QImage>); the content axis moved
to the buffers.) Resolve whichever overload the firmware exports and call it
with the matching argument layout. The <=3.27 path is byte-for-byte unchanged;
the 3.28 path drops content_type and places mode/flags in the correct
registers. Hardware-verified for mono live ink on a Paper Pro (reMarkable
Ferrari) running OS 3.28.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant