mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-12 09:28:10 +00:00
fixup! refactor(core): extract framebuffer queue for reuse
This commit is contained in:
parent
a6db55dc5d
commit
ac2b244107
@ -1,33 +1,48 @@
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <sys/irq.h>
|
||||
|
||||
#include "fb_queue.h"
|
||||
|
||||
int16_t fb_queue_get_for_copy(volatile frame_buffer_queue_t *queue) {
|
||||
if (queue->entry[queue->wix] != FB_STATE_PREPARING) {
|
||||
int16_t fb_queue_get_for_copy(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
int16_t wix = queue->wix;
|
||||
if (queue->entry[wix] != FB_STATE_PREPARING) {
|
||||
// No refresh needed as the frame buffer is not in
|
||||
// the state to be copied to the display
|
||||
irq_unlock(key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return queue->wix;
|
||||
irq_unlock(key);
|
||||
return wix;
|
||||
}
|
||||
|
||||
int16_t fb_queue_get_for_write(volatile frame_buffer_queue_t *queue) {
|
||||
int16_t fb_queue_get_for_write(frame_buffer_queue_t *queue) {
|
||||
frame_buffer_state_t state;
|
||||
|
||||
// We have to wait if the buffer was passed for copying
|
||||
// to the interrupt handler
|
||||
do {
|
||||
irq_key_t key = irq_lock();
|
||||
state = queue->entry[queue->wix];
|
||||
irq_unlock(key);
|
||||
|
||||
} while (state == FB_STATE_READY || state == FB_STATE_COPYING);
|
||||
|
||||
irq_key_t key = irq_lock();
|
||||
queue->entry[queue->wix] = FB_STATE_PREPARING;
|
||||
irq_unlock(key);
|
||||
|
||||
return queue->wix;
|
||||
}
|
||||
|
||||
int16_t fb_queue_get_for_transfer(volatile frame_buffer_queue_t *queue) {
|
||||
int16_t fb_queue_get_for_transfer(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
|
||||
if (queue->rix >= FRAME_BUFFER_COUNT) {
|
||||
// This is an invalid state, and we should never get here
|
||||
irq_unlock(key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -38,12 +53,15 @@ int16_t fb_queue_get_for_transfer(volatile frame_buffer_queue_t *queue) {
|
||||
|
||||
case FB_STATE_COPYING:
|
||||
// Currently we are copying a data to the display.
|
||||
|
||||
irq_unlock(key);
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case FB_STATE_READY:
|
||||
// Now it's proper time to copy the data to the display
|
||||
queue->entry[queue->rix] = FB_STATE_COPYING;
|
||||
irq_unlock(key);
|
||||
return queue->rix;
|
||||
|
||||
// NOTE: when copying is done, this queue slot is marked empty
|
||||
@ -51,29 +69,36 @@ int16_t fb_queue_get_for_transfer(volatile frame_buffer_queue_t *queue) {
|
||||
|
||||
default:
|
||||
// This is an invalid state, and we should never get here
|
||||
irq_unlock(key);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool fb_queue_set_done(volatile frame_buffer_queue_t *queue) {
|
||||
bool fb_queue_set_done(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
if (queue->rix >= FRAME_BUFFER_COUNT) {
|
||||
// This is an invalid state, and we should never get here
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queue->entry[queue->rix] == FB_STATE_COPYING) {
|
||||
queue->entry[queue->rix] = FB_STATE_EMPTY;
|
||||
queue->rix = (queue->rix + 1) % FRAME_BUFFER_COUNT;
|
||||
irq_unlock(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fb_queue_set_switched(volatile frame_buffer_queue_t *queue) {
|
||||
bool fb_queue_set_switched(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
if (queue->rix >= FRAME_BUFFER_COUNT) {
|
||||
// This is an invalid state, and we should never get here
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -83,28 +108,35 @@ bool fb_queue_set_switched(volatile frame_buffer_queue_t *queue) {
|
||||
}
|
||||
queue->aix = queue->rix;
|
||||
queue->rix = (queue->rix + 1) % FRAME_BUFFER_COUNT;
|
||||
irq_unlock(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fb_queue_set_ready_for_transfer(volatile frame_buffer_queue_t *queue) {
|
||||
bool fb_queue_set_ready_for_transfer(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
if (queue->wix >= FRAME_BUFFER_COUNT) {
|
||||
// This is an invalid state, and we should never get here
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queue->entry[queue->rix] == FB_STATE_PREPARING) {
|
||||
queue->entry[queue->rix] = FB_STATE_READY;
|
||||
queue->wix = (queue->wix + 1) % FRAME_BUFFER_COUNT;
|
||||
irq_unlock(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
void fb_queue_reset(volatile frame_buffer_queue_t *queue) {
|
||||
void fb_queue_reset(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
// Reset the buffer queue so we can eventually continue
|
||||
// safely in thread mode
|
||||
queue->wix = 0;
|
||||
@ -112,17 +144,21 @@ void fb_queue_reset(volatile frame_buffer_queue_t *queue) {
|
||||
for (int i = 0; i < FRAME_BUFFER_COUNT; i++) {
|
||||
queue->entry[i] = FB_STATE_EMPTY;
|
||||
}
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
bool fb_queue_is_processed(volatile frame_buffer_queue_t *queue) {
|
||||
bool fb_queue_is_processed(frame_buffer_queue_t *queue) {
|
||||
irq_key_t key = irq_lock();
|
||||
for (int i = 0; i < FRAME_BUFFER_COUNT; i++) {
|
||||
frame_buffer_state_t state = queue->entry[i];
|
||||
if (state == FB_STATE_READY ||
|
||||
(state == FB_STATE_COPYING && i != queue->aix)) {
|
||||
irq_unlock(key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
// Queue entries
|
||||
volatile frame_buffer_state_t entry[FRAME_BUFFER_COUNT];
|
||||
frame_buffer_state_t entry[FRAME_BUFFER_COUNT];
|
||||
// Active index
|
||||
// (accessed & updated in the context of the interrupt handlers
|
||||
int16_t aix;
|
||||
@ -56,18 +56,29 @@ typedef struct {
|
||||
|
||||
} frame_buffer_queue_t;
|
||||
|
||||
int16_t fb_queue_get_for_copy(volatile frame_buffer_queue_t *queue);
|
||||
// Get the frame buffer index for copying to display
|
||||
// Call from main thread only
|
||||
int16_t fb_queue_get_for_copy(frame_buffer_queue_t *queue);
|
||||
|
||||
int16_t fb_queue_get_for_write(volatile frame_buffer_queue_t *queue);
|
||||
// Get the frame buffer index for writing
|
||||
// Call from main thread only
|
||||
int16_t fb_queue_get_for_write(frame_buffer_queue_t *queue);
|
||||
|
||||
int16_t fb_queue_get_for_transfer(volatile frame_buffer_queue_t *queue);
|
||||
// Get the frame buffer index for transfer
|
||||
int16_t fb_queue_get_for_transfer(frame_buffer_queue_t *queue);
|
||||
|
||||
bool fb_queue_set_done(volatile frame_buffer_queue_t *queue);
|
||||
// Mark the frame buffer as done, thus no longer used
|
||||
bool fb_queue_set_done(frame_buffer_queue_t *queue);
|
||||
|
||||
bool fb_queue_set_switched(volatile frame_buffer_queue_t *queue);
|
||||
// Mark the frame buffer as switched, thus actively used by display
|
||||
bool fb_queue_set_switched(frame_buffer_queue_t *queue);
|
||||
|
||||
bool fb_queue_set_ready_for_transfer(volatile frame_buffer_queue_t *queue);
|
||||
// Mark the frame buffer as ready to be copied to the display
|
||||
// Call from main thread only
|
||||
bool fb_queue_set_ready_for_transfer(frame_buffer_queue_t *queue);
|
||||
|
||||
void fb_queue_reset(volatile frame_buffer_queue_t *queue);
|
||||
// Reset the queue state
|
||||
void fb_queue_reset(frame_buffer_queue_t *queue);
|
||||
|
||||
bool fb_queue_is_processed(volatile frame_buffer_queue_t *queue);
|
||||
// Check if all frame buffers are processed
|
||||
bool fb_queue_is_processed(frame_buffer_queue_t *queue);
|
||||
|
@ -210,26 +210,8 @@ void display_refresh(void) {
|
||||
mpu_set_active_fb(NULL, 0);
|
||||
|
||||
#ifndef BOARDLOADER
|
||||
if (is_mode_exception()) {
|
||||
// Disable scheduling of any new background copying
|
||||
NVIC_DisableIRQ(DISPLAY_TE_INTERRUPT_NUM);
|
||||
// Wait for next TE signal. During this time the
|
||||
// display might be updated in the background
|
||||
wait_for_te_signal();
|
||||
// Stop any background copying even if it is not finished yet
|
||||
bg_copy_abort();
|
||||
// Copy the frame buffer to the display manually
|
||||
copy_fb_to_display(fb_idx);
|
||||
// Reset the buffer queue so we can eventually continue
|
||||
// safely in thread mode
|
||||
fb_queue_reset(&drv->queue);
|
||||
|
||||
// Enable normal processing again
|
||||
NVIC_EnableIRQ(DISPLAY_TE_INTERRUPT_NUM);
|
||||
} else {
|
||||
// Mark the buffer ready to switch to
|
||||
fb_queue_set_ready_for_transfer(&drv->queue);
|
||||
}
|
||||
// Mark the buffer ready to switch to
|
||||
fb_queue_set_ready_for_transfer(&drv->queue);
|
||||
|
||||
#else // BOARDLOADER
|
||||
wait_for_te_signal();
|
||||
|
@ -19,7 +19,7 @@ typedef struct {
|
||||
// Framebuffer queue
|
||||
// (accessed & updated in the context of the main thread
|
||||
// and the interrupt context)
|
||||
volatile frame_buffer_queue_t queue;
|
||||
frame_buffer_queue_t queue;
|
||||
#endif
|
||||
|
||||
// Current display orientation (0, 90, 180, 270)
|
||||
|
Loading…
Reference in New Issue
Block a user