Skip to content

Commit 1a6936f

Browse files
committed
ui: introduce double buffering
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".
1 parent 3d65f25 commit 1a6936f

File tree

27 files changed

+244
-126
lines changed

27 files changed

+244
-126
lines changed

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ set(DBB-FIRMWARE-USB-SOURCES ${DBB-FIRMWARE-USB-SOURCES} PARENT_SCOPE)
5353
set(DBB-FIRMWARE-UI-SOURCES
5454
${CMAKE_SOURCE_DIR}/src/screen.c
5555
${CMAKE_SOURCE_DIR}/src/ui/graphics/graphics.c
56+
${CMAKE_SOURCE_DIR}/src/ui/canvas.c
5657
${CMAKE_SOURCE_DIR}/src/ui/graphics/lock_animation.c
5758
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
5859
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
@@ -114,6 +115,7 @@ set(DBB-BOOTLOADER-SOURCES
114115
${CMAKE_SOURCE_DIR}/src/memory/memory_spi.c
115116
${CMAKE_SOURCE_DIR}/src/queue.c
116117
${CMAKE_SOURCE_DIR}/src/usb/usb_processing.c
118+
${CMAKE_SOURCE_DIR}/src/ui/canvas.c
117119
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
118120
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
119121
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X10.c

src/bootloader/bootloader.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <screen.h>
2727
#include <stdint.h>
2828
#include <string.h>
29+
#include <ui/canvas.h>
2930
#include <ui/components/ui_images.h>
3031
#include <ui/fonts/arial_fonts.h>
3132
#include <ui/graphics/graphics.h>
@@ -328,15 +329,14 @@ static void _render_message(const char* message, int duration)
328329
{
329330
char print[100];
330331
snprintf(print, sizeof(print), "%s", message);
331-
UG_ClearBuffer();
332332
UG_PutString(0, 0, print, false);
333-
UG_SendBuffer();
333+
canvas_commit();
334+
oled_blit();
334335
delay_ms(duration);
335336
}
336337

337338
void bootloader_render_default_screen(void)
338339
{
339-
UG_ClearBuffer();
340340
_load_logo();
341341
#if PLATFORM_BITBOX02PLUS == 1
342342
UG_PutString(0, SCREEN_HEIGHT - 9 * 2 - 5, "See the BitBoxApp", false);
@@ -354,7 +354,8 @@ void bootloader_render_default_screen(void)
354354
}
355355
UG_PutString(0, SCREEN_HEIGHT - 9, "See the BitBoxApp", false);
356356
#endif
357-
UG_SendBuffer();
357+
canvas_commit();
358+
oled_blit();
358359
}
359360

360361
#if PLATFORM_BITBOX02PLUS
@@ -368,7 +369,6 @@ void bootloader_render_ble_confirm_screen(bool confirmed)
368369
uint32_t pairing_code_int = (*(uint32_t*)&bootloader_pairing_code_bytes[0]) % 1000000;
369370
char code_str[10] = {0};
370371
snprintf(code_str, sizeof(code_str), "%06u", (unsigned)pairing_code_int);
371-
UG_ClearBuffer();
372372
uint16_t check_width = IMAGE_DEFAULT_CHECKMARK_HEIGHT + IMAGE_DEFAULT_CHECKMARK_HEIGHT / 2 - 1;
373373
if (confirmed) {
374374
UG_PutString(15, 0, "Confirm on app", false);
@@ -380,13 +380,13 @@ void bootloader_render_ble_confirm_screen(bool confirmed)
380380
UG_FontSelect(&font_monogram_5X9);
381381
UG_PutString(45, SCREEN_HEIGHT / 2 - 9, code_str, false);
382382
UG_FontSelect(&font_font_a_9X9);
383-
UG_SendBuffer();
383+
canvas_commit();
384+
oled_blit();
384385
}
385386
#endif
386387

387388
static void _render_progress(float progress)
388389
{
389-
UG_ClearBuffer();
390390
_load_logo();
391391
if (progress > 0) {
392392
char label[5] = {0};
@@ -401,7 +401,8 @@ static void _render_progress(float progress)
401401
msg = "INSTALLING";
402402
}
403403
UG_PutString(SCREEN_WIDTH / 2 - 3, SCREEN_HEIGHT - 9 * 2, msg, false);
404-
UG_SendBuffer();
404+
canvas_commit();
405+
oled_blit();
405406
}
406407

407408
static void _render_hash(const char* title, const uint8_t* hash)
@@ -433,7 +434,6 @@ static void _render_hash(const char* title, const uint8_t* hash)
433434
&hash_hex[48]);
434435

435436
for (uint8_t i = 1; i <= seconds; i++) {
436-
UG_ClearBuffer();
437437
UG_PutString(0, 0, title, false);
438438

439439
snprintf(timer_buf, sizeof(timer_buf), "%ds", seconds - i);
@@ -449,7 +449,8 @@ static void _render_hash(const char* title, const uint8_t* hash)
449449

450450
UG_FontSelect(f_regular);
451451

452-
UG_SendBuffer();
452+
canvas_commit();
453+
oled_blit();
453454
delay_ms(1000);
454455
}
455456
bootloader_render_default_screen();
@@ -1013,7 +1014,6 @@ static void _check_init(boot_data_t* data)
10131014
#ifdef BOOTLOADER_DEVDEVICE
10141015
static bool _devdevice_enter(secbool_u32 firmware_verified)
10151016
{
1016-
UG_ClearBuffer();
10171017
UG_PutString(0, 0, " <Enter bootloader>", false);
10181018
UG_PutString(0, SCREEN_HEIGHT / 2 - 11, "DEV DEVICE", false);
10191019
UG_PutString(0, SCREEN_HEIGHT / 2 + 2, "NOT FOR VALUE", false);
@@ -1043,7 +1043,8 @@ static bool _devdevice_enter(secbool_u32 firmware_verified)
10431043
UG_DrawLine(xpos + 5, ypos, xpos, ypos + 5, C_WHITE);
10441044
UG_DrawLine(xpos - 2, ypos + 3, xpos, ypos + 5, C_WHITE);
10451045
}
1046-
UG_SendBuffer();
1046+
canvas_commit();
1047+
oled_blit();
10471048
while (true) {
10481049
do {
10491050
qtouch_process();

src/bootloader/startup.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <rust/rust.h>
2323
#include <screen.h>
2424
#include <string.h>
25+
#include <ui/canvas.h>
2526
#include <ui/oled/oled.h>
2627
#include <usb/class/hid/hww/hid_hww.h>
2728
#include <usb/usb_processing.h>
@@ -83,7 +84,7 @@ int main(void)
8384
bootloader_init();
8485
platform_init();
8586
__stack_chk_guard = rand_sync_read32(&RAND_0);
86-
screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
87+
screen_init(oled_set_pixel, oled_mirror);
8788
#if defined(BOOTLOADER_DEVDEVICE) || PLATFORM_BITBOX02PLUS == 1
8889
qtouch_init();
8990
#endif
@@ -189,7 +190,6 @@ int main(void)
189190

190191
if (qtouch_is_scroller_active(top_slider)) {
191192
bool ok;
192-
UG_ClearBuffer();
193193
if (qtouch_get_scroller_position(top_slider) < 127) {
194194
bootloader_render_default_screen();
195195
ok = false;
@@ -218,7 +218,8 @@ int main(void)
218218
ringbuffer_put(&uart_write_queue, tmp[i]);
219219
}
220220
bootloader_pairing_request = false;
221-
UG_SendBuffer();
221+
canvas_commit();
222+
oled_blit();
222223
}
223224
}
224225
#endif

src/factorysetup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ int main(void)
577577
system_init();
578578
platform_init();
579579
__stack_chk_guard = common_stack_chk_guard();
580-
screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
580+
screen_init(oled_set_pixel, oled_mirror);
581581
screen_splash();
582582
common_main();
583583

src/firmware.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ int main(void)
4141
system_init();
4242
platform_init();
4343
__stack_chk_guard = common_stack_chk_guard();
44-
screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
44+
screen_init(oled_set_pixel, oled_mirror);
4545
screen_splash();
4646
qtouch_init();
4747
common_main();

src/firmware_main_loop.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "workflow/orientation_screen.h"
3636
#include <rust/rust.h>
3737
#include <ui/fonts/monogram_5X9.h>
38+
#include <ui/oled/oled.h>
3839
#include <utils_ringbuffer.h>
3940
#if APP_U2F == 1
4041
#include "u2f.h"

src/reset.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
#include "system.h"
2424
#include "uart.h"
2525
#include <screen.h>
26+
#include <ui/canvas.h>
2627

2728
#ifndef TESTING
2829
#include "securechip/securechip.h"
2930
#include <driver_init.h>
3031
#include <hal_delay.h>
3132
#include <ui/components/status.h>
33+
#include <ui/oled/oled.h>
3234
#include <ui/ugui/ugui.h>
3335
#endif
3436

@@ -41,9 +43,10 @@ static void _show_reset_label(bool status)
4143
{
4244
const char* msg = "Device reset";
4345
component_t* comp = status_create(msg, status, NULL, NULL);
44-
screen_clear();
46+
canvas_clear();
4547
comp->f->render(comp);
46-
UG_SendBuffer();
48+
canvas_commit();
49+
oled_blit();
4750
comp->f->cleanup(comp);
4851
delay_ms(3000);
4952
}

src/rust/bitbox02-rust/src/general/screen.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414

1515
use core::time::Duration;
1616

17-
use bitbox02::{delay, ug_clear_buffer, ug_font_select_9x9, ug_put_string, ug_send_buffer};
17+
use bitbox02::{canvas_clear, canvas_commit, delay, oled_blit, ug_font_select_9x9, ug_put_string};
1818

1919
pub fn print_debug_internal(duration: Duration, msg: &str) {
20-
ug_clear_buffer();
20+
canvas_clear();
2121
ug_font_select_9x9();
2222
ug_put_string(0, 0, msg, false);
23-
ug_send_buffer();
23+
canvas_commit();
24+
oled_blit();
2425
delay(duration);
2526
}
2627

src/rust/bitbox02-sys/build.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ const ALLOWLIST_TYPES: &[&str] = &[
5353
];
5454

5555
const ALLOWLIST_FNS: &[&str] = &[
56-
"UG_ClearBuffer",
5756
"UG_FontSelect",
5857
"UG_PutString",
59-
"UG_SendBuffer",
6058
"bip32_derive_xpub",
6159
"bitbox02_smarteeprom_init",
6260
"bitbox_secp256k1_dleq_prove",
6361
"bitbox_secp256k1_dleq_verify",
62+
"canvas_clear",
63+
"canvas_commit",
6464
"confirm_create",
6565
"confirm_transaction_address_create",
6666
"confirm_transaction_fee_create",
@@ -113,6 +113,7 @@ const ALLOWLIST_FNS: &[&str] = &[
113113
"memory_get_platform",
114114
"memory_get_securechip_type",
115115
"memory_spi_get_active_ble_firmware_version",
116+
"oled_blit",
116117
"spi_mem_protected_area_write",
117118
"menu_create",
118119
"fake_memory_factoryreset",
@@ -198,6 +199,7 @@ const BITBOX02_SOURCES: &[&str] = &[
198199
"src/u2f.c",
199200
"src/u2f/u2f_app.c",
200201
"src/u2f/u2f_packet.c",
202+
"src/ui/canvas.c",
201203
"src/ui/components/button.c",
202204
"src/ui/components/confirm_button.c",
203205
"src/ui/components/confirm_gesture.c",
@@ -403,6 +405,7 @@ pub fn main() -> Result<(), &'static str> {
403405
"test/hardware-fakes/src/fake_component.c",
404406
"test/hardware-fakes/src/fake_diskio.c",
405407
"test/hardware-fakes/src/fake_memory.c",
408+
"test/hardware-fakes/src/fake_oled.c",
406409
"test/hardware-fakes/src/fake_qtouch.c",
407410
"test/hardware-fakes/src/fake_screen.c",
408411
"test/hardware-fakes/src/fake_securechip.c",

src/rust/bitbox02-sys/wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <securechip/securechip.h>
3030
#include <system.h>
3131
#include <time.h>
32+
#include <ui/canvas.h>
3233
#include <ui/components/confirm.h>
3334
#include <ui/components/confirm_transaction.h>
3435
#include <ui/components/empty.h>

0 commit comments

Comments
 (0)