mirror of
https://github.com/stasenso/rp_pico_display_engine.git
synced 2026-06-26 21:32:41 +03:00
docs(scenarios): add usage scenarios for paint contract
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
|||||||
|
# Сценарии использования display engine
|
||||||
|
|
||||||
|
В движке используется явный контракт рисования:
|
||||||
|
- `display_begin_paint_try()` или `display_begin_paint_blocking()` открывает кадр и даёт буфер.
|
||||||
|
- `display_end_paint()` закрывает кадр и сразу отправляет его на экран.
|
||||||
|
|
||||||
|
Главное правило: каждый успешный `begin` должен завершаться `display_end_paint()`.
|
||||||
|
|
||||||
|
## 1. Обновление 50 Гц без разрывов (рекомендуется)
|
||||||
|
|
||||||
|
Что получить:
|
||||||
|
- Тик 50 Гц от таймера.
|
||||||
|
- Если экран занят, кадр пропускается.
|
||||||
|
- Без разрывов и без блокировки основного цикла.
|
||||||
|
|
||||||
|
Конфигурация:
|
||||||
|
- `mode = DISPLAY_MODE_SAFE`
|
||||||
|
- `buffer_count = 1` или `2`
|
||||||
|
|
||||||
|
Последовательность:
|
||||||
|
1. `display_init(&cfg)`
|
||||||
|
2. В `main` на каждом тике:
|
||||||
|
- `buf = display_begin_paint_try()`
|
||||||
|
- если `buf == NULL` -> пропуск тика
|
||||||
|
- рисование
|
||||||
|
- `display_end_paint()`
|
||||||
|
|
||||||
|
## 2. Простой блокирующий цикл
|
||||||
|
|
||||||
|
Что получить:
|
||||||
|
- Максимально короткий код без проверок `NULL`.
|
||||||
|
|
||||||
|
Конфигурация:
|
||||||
|
- `mode = DISPLAY_MODE_SAFE`
|
||||||
|
- обычно `buffer_count = 1`
|
||||||
|
|
||||||
|
Последовательность:
|
||||||
|
1. `display_init(&cfg)`
|
||||||
|
2. В цикле:
|
||||||
|
- `buf = display_begin_paint_blocking()`
|
||||||
|
- рисование
|
||||||
|
- `display_end_paint()`
|
||||||
|
|
||||||
|
Минус:
|
||||||
|
- Поток может ждать буфер и временно не выполнять другую работу.
|
||||||
|
|
||||||
|
## 3. Неблокирующая анимация/UI
|
||||||
|
|
||||||
|
Что получить:
|
||||||
|
- Главный цикл всегда остаётся отзывчивым.
|
||||||
|
|
||||||
|
Конфигурация:
|
||||||
|
- `mode = DISPLAY_MODE_SAFE`
|
||||||
|
- лучше `buffer_count = 2`
|
||||||
|
|
||||||
|
Последовательность:
|
||||||
|
1. `display_init(&cfg)`
|
||||||
|
2. В цикле:
|
||||||
|
- `buf = display_begin_paint_try()`
|
||||||
|
- если `buf == NULL` -> делаем другую логику и идём дальше
|
||||||
|
- рисование
|
||||||
|
- `display_end_paint()`
|
||||||
|
|
||||||
|
## 4. RAW-режим (низкоуровневый ручной контроль)
|
||||||
|
|
||||||
|
Что получить:
|
||||||
|
- Полный ручной контроль swap в RAW-режиме.
|
||||||
|
|
||||||
|
Конфигурация:
|
||||||
|
- `mode = DISPLAY_MODE_RAW`
|
||||||
|
- `buffer_count = 2`
|
||||||
|
|
||||||
|
Последовательность:
|
||||||
|
1. `buf = display_begin_paint_try()`
|
||||||
|
2. если `buf == NULL` -> пропуск итерации
|
||||||
|
3. рисование
|
||||||
|
4. `display_swap_buffers()`
|
||||||
|
5. `display_end_paint()`
|
||||||
|
|
||||||
|
Примечание:
|
||||||
|
- В RAW swap остаётся ручным, а отправка кадра выполняется через `display_end_paint()`.
|
||||||
|
|
||||||
|
## 5. Что нельзя делать
|
||||||
|
|
||||||
|
1. Делать второй `begin`, не закрыв первый `display_end_paint()`.
|
||||||
|
2. Забывать `display_end_paint()` после успешного `begin`.
|
||||||
|
3. Вызывать `display_submit()` вручную внутри открытой paint-секции.
|
||||||
|
|
||||||
|
## 6. Шаблон 50 Гц
|
||||||
|
|
||||||
|
```c
|
||||||
|
static volatile bool frame_tick_due = false;
|
||||||
|
|
||||||
|
static bool frame_timer_cb(repeating_timer_t* t) {
|
||||||
|
(void)t;
|
||||||
|
frame_tick_due = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (!frame_tick_due) {
|
||||||
|
__asm volatile ("wfi");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
frame_tick_due = false;
|
||||||
|
|
||||||
|
uint16_t* buf = display_begin_paint_try();
|
||||||
|
if (!buf) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw(buf)
|
||||||
|
|
||||||
|
bool ok = display_end_paint();
|
||||||
|
hard_assert(ok);
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user