-
Notifications
You must be signed in to change notification settings - Fork 110
ui: introduce double buffering #1595
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
base: master
Are you sure you want to change the base?
Conversation
a4a1968
to
8bdd80f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly uncomfortable with the removal of the screen clearing before rendering/flushing, as it's a bit hard to reason about if the working buffer is really clean (from a previous commit) in all these cases.
src/ui/canvas.c
Outdated
|
||
void canvas_commit(void) | ||
{ | ||
_canvas_active = (_canvas_active + 1) % 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeepSeek
Potential Race Conditions:
- The volatile
_canvas_active
switch isn't atomic. On 32-bit MCUs, this could cause torn buffer states if interrupted during update. Consider using atomic operations or disabling interrupts briefly duringcanvas_commit()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you are not just writing the value, you are reading it too.
/* | ||
* Initialize canvases | ||
*/ | ||
void canvas_init(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeepSeek:
Buffer Initialization:
canvas_init()
is declared in canvas.h but not implemented.
src/ui/canvas.c
Outdated
@@ -0,0 +1,47 @@ | |||
// Copyright 2025 Shift Cryptosecurity AG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong name 🤓
src/ui/canvas.c
Outdated
#include <string.h> | ||
#include <ui/canvas.h> | ||
|
||
// This is sometimes updated from interrupts :( to be undone eventually |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you know what "sometimes" means exactly, please specify for clarity. BIP39 unlock? More?
"to be undone" you mean the volatile
qualifier right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, volatile can be removed when we simplify all interrupts to just set flags.
src/ui/canvas.h
Outdated
@@ -0,0 +1,58 @@ | |||
// Copyright 2025 Shift Cryptosecurity AG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
test/hardware-fakes/src/fake_oled.c
Outdated
@@ -0,0 +1,15 @@ | |||
// Copyright 2025 Shift Cryptosecurity AG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
I guess I could return a dirty buffer and keep all the clears instead. I have no strong opinion, just thought it would be nicer like this. (if you didn't commit/switch the buffers the current buffer will never be drawn, so I guess it would be hard to miss?) |
1a6936f
to
edfe7fe
Compare
Create a new module called "canvas" which is responsible for double buffering. Double buffering is required to enable asynchronous transfer of the frame buffer. While the "active" frame buffer is being transferred to the oled in the background, the ui will render to a "working" frame buffer. When the rendering is complete the buffers are flipped with "canvas_commit".
edfe7fe
to
5f7bb4f
Compare
Create a new module called "canvas" which is responsible for double buffering. Double buffering is required to enable asynchronous transfer of the frame buffer. While the "active" frame buffer is being transferred to the oled in the background, the ui will render to a "working" frame buffer. When the rendering is complete the buffers are flipped with "canvas_commit".
I tested with both ssd1312 and sh1107 screens.