mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-27 02:12:35 +00:00
fix(core/emulator): use a gamma lookup table for better fadein/fadeout performance
This commit is contained in:
parent
6e85d61688
commit
2dd44786d5
@ -32,7 +32,7 @@
|
|||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
|
|
||||||
extern void main_clean_exit();
|
extern void main_clean_exit();
|
||||||
extern float DISPLAY_GAMMA;
|
extern float display_gamma(float);
|
||||||
|
|
||||||
void __attribute__((noreturn)) trezor_shutdown(void) {
|
void __attribute__((noreturn)) trezor_shutdown(void) {
|
||||||
printf("SHUTDOWN\n");
|
printf("SHUTDOWN\n");
|
||||||
@ -163,6 +163,7 @@ uint32_t hal_ticks_ms() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
|
static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
|
||||||
|
float gamma = display_gamma(0);
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
trezor_shutdown();
|
trezor_shutdown();
|
||||||
@ -182,13 +183,15 @@ static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
|
|||||||
// Left and right arrows controlling display gamma
|
// Left and right arrows controlling display gamma
|
||||||
// Only for TT (in button models, arrows do different things)
|
// Only for TT (in button models, arrows do different things)
|
||||||
case SDLK_LEFT:
|
case SDLK_LEFT:
|
||||||
DISPLAY_GAMMA = fmaxf(0.0f, DISPLAY_GAMMA - 0.05f);
|
gamma = fmaxf(0.0001f, gamma - 0.05f);
|
||||||
printf("DISPLAY_GAMMA: %0.2f\n", DISPLAY_GAMMA);
|
printf("DISPLAY_GAMMA: %0.2f\n", gamma);
|
||||||
|
display_gamma(gamma);
|
||||||
display_refresh();
|
display_refresh();
|
||||||
return 0;
|
return 0;
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
DISPLAY_GAMMA = fminf(8.0f, DISPLAY_GAMMA + 0.05f);
|
gamma = fminf(8.0f, gamma + 0.05f);
|
||||||
printf("DISPLAY_GAMMA: %0.2f\n", DISPLAY_GAMMA);
|
printf("DISPLAY_GAMMA: %0.2f\n", gamma);
|
||||||
|
display_gamma(gamma);
|
||||||
display_refresh();
|
display_refresh();
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,14 +75,17 @@ static SDL_Surface *PREV_SAVED;
|
|||||||
static int DISPLAY_BACKLIGHT = -1;
|
static int DISPLAY_BACKLIGHT = -1;
|
||||||
static int DISPLAY_ORIENTATION = -1;
|
static int DISPLAY_ORIENTATION = -1;
|
||||||
float DISPLAY_GAMMA = 0.55f;
|
float DISPLAY_GAMMA = 0.55f;
|
||||||
// Will depend on SDL_VIDEODRIVER env variable
|
|
||||||
static bool DO_GAMMA_CORRECTION = true;
|
|
||||||
int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY;
|
int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY;
|
||||||
int sdl_touch_offset_x, sdl_touch_offset_y;
|
int sdl_touch_offset_x, sdl_touch_offset_y;
|
||||||
|
|
||||||
// Using RGB565 (16-bit) color format.
|
// Using RGB565 (16-bit) color format.
|
||||||
typedef uint16_t pixel_color;
|
typedef uint16_t pixel_color;
|
||||||
|
|
||||||
|
// Will depend on SDL_VIDEODRIVER env variable
|
||||||
|
static bool DO_GAMMA_CORRECTION = true;
|
||||||
|
static pixel_color GAMMA_LUT[0x10000];
|
||||||
|
|
||||||
// this is just for compatibility with DMA2D using algorithms
|
// this is just for compatibility with DMA2D using algorithms
|
||||||
uint8_t *const DISPLAY_DATA_ADDRESS = 0;
|
uint8_t *const DISPLAY_DATA_ADDRESS = 0;
|
||||||
|
|
||||||
@ -98,31 +101,46 @@ static struct {
|
|||||||
} pos;
|
} pos;
|
||||||
} PIXELWINDOW;
|
} PIXELWINDOW;
|
||||||
|
|
||||||
pixel_color gamma_correct(pixel_color c) {
|
static pixel_color gamma_correct(pixel_color c, float gamma) {
|
||||||
// NOTE: 0x1f/31 and 0x3f/63 are maximum values of RGB components
|
// NOTE: 0x1f/31 and 0x3f/63 are maximum values of RGB components
|
||||||
// given the color is 16-bit (5 bits for R, 6 bits for G, 5 bits for B).
|
// given the color is 16-bit (5 bits for R, 6 bits for G, 5 bits for B).
|
||||||
int r = (c >> 11) & 0x1f;
|
int r = (c >> 11) & 0x1f;
|
||||||
int g = (c >> 5) & 0x3f;
|
int g = (c >> 5) & 0x3f;
|
||||||
int b = c & 0x1f;
|
int b = c & 0x1f;
|
||||||
|
|
||||||
r = (int)round(pow(r / 31.0, DISPLAY_GAMMA) * 31.0);
|
r = (int)round(pow(r / 31.0, gamma) * 31.0);
|
||||||
g = (int)round(pow(g / 63.0, DISPLAY_GAMMA) * 63.0);
|
g = (int)round(pow(g / 63.0, gamma) * 63.0);
|
||||||
b = (int)round(pow(b / 31.0, DISPLAY_GAMMA) * 31.0);
|
b = (int)round(pow(b / 31.0, gamma) * 31.0);
|
||||||
|
|
||||||
return (r << 11) | (g << 5) | b;
|
return (r << 11) | (g << 5) | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gamma_correct_buffer_to_display(void) {
|
static void prepare_gamma_lut(float gamma) {
|
||||||
|
for (int i = 0; i < 0x10000; i++) {
|
||||||
|
GAMMA_LUT[i] = gamma_correct(i, gamma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gamma_correct_buffer_to_display(void) {
|
||||||
// Gamma correct all the pixels in BUFFER_TO_DISPLAY.
|
// Gamma correct all the pixels in BUFFER_TO_DISPLAY.
|
||||||
pixel_color *pixels = (pixel_color *)BUFFER_TO_DISPLAY->pixels;
|
pixel_color *pixels = (pixel_color *)BUFFER_TO_DISPLAY->pixels;
|
||||||
for (int y = 0; y < BUFFER_TO_DISPLAY->h; y++) {
|
for (int y = 0; y < BUFFER_TO_DISPLAY->h; y++) {
|
||||||
for (int x = 0; x < BUFFER_TO_DISPLAY->w; x++) {
|
for (int x = 0; x < BUFFER_TO_DISPLAY->w; x++) {
|
||||||
int index = y * BUFFER_TO_DISPLAY->pitch / 2 + x;
|
int index = y * BUFFER_TO_DISPLAY->pitch / 2 + x;
|
||||||
pixels[index] = gamma_correct(pixels[index]);
|
pixels[index] = GAMMA_LUT[pixels[index]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float display_gamma(float gamma) {
|
||||||
|
float prev_gamma = DISPLAY_GAMMA;
|
||||||
|
if (gamma != 0) {
|
||||||
|
DISPLAY_GAMMA = gamma;
|
||||||
|
prepare_gamma_lut(gamma);
|
||||||
|
}
|
||||||
|
return prev_gamma;
|
||||||
|
}
|
||||||
|
|
||||||
void display_pixeldata(pixel_color c) {
|
void display_pixeldata(pixel_color c) {
|
||||||
#if defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R
|
#if defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R
|
||||||
// set to white if highest bits of all R, G, B values are set to 1
|
// set to white if highest bits of all R, G, B values are set to 1
|
||||||
@ -185,6 +203,7 @@ void display_init(void) {
|
|||||||
DO_GAMMA_CORRECTION = false;
|
DO_GAMMA_CORRECTION = false;
|
||||||
} else {
|
} else {
|
||||||
DO_GAMMA_CORRECTION = true;
|
DO_GAMMA_CORRECTION = true;
|
||||||
|
prepare_gamma_lut(DISPLAY_GAMMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *window_title = NULL;
|
char *window_title = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user