drivers: display_sdl: add alpha support
While the driver was already capable of processing `ARGB8888` data, it did not actually show the alpha value in any way. This change adds a checkerboard background that shows transparent regions. Signed-off-by: Martin Stumpf <finomnis@gmail.com>
This commit is contained in:
parent
86a126dba4
commit
02d562e9b8
4 changed files with 84 additions and 12 deletions
|
|
@ -59,4 +59,22 @@ config SDL_DISPLAY_MONO_MSB_FIRST
|
|||
If selected, set the MSB to represent the first pixel.
|
||||
This applies when the pixel format is MONO01/MONO10.
|
||||
|
||||
config SDL_DISPLAY_TRANSPARENCY_GRID_CELL_SIZE
|
||||
int "Transparency grid cell size"
|
||||
default 8
|
||||
help
|
||||
The size of the checkerboard pattern squares, in pixels.
|
||||
|
||||
config SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_1
|
||||
hex "Transparency grid cell color 1"
|
||||
default 0xcccccc
|
||||
help
|
||||
The color of the odd cells in the transparency grid.
|
||||
|
||||
config SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_2
|
||||
hex "Transparency grid cell color 2"
|
||||
default 0xbbbbbb
|
||||
help
|
||||
The color of the even cells in the transparency grid.
|
||||
|
||||
endif # SDL_DISPLAY
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct sdl_display_data {
|
|||
void *mutex;
|
||||
void *texture;
|
||||
void *read_texture;
|
||||
void *background_texture;
|
||||
bool display_on;
|
||||
enum display_pixel_format current_pixel_format;
|
||||
uint8_t *buf;
|
||||
|
|
@ -80,7 +81,10 @@ static int sdl_display_init(const struct device *dev)
|
|||
int rc = sdl_display_init_bottom(config->height, config->width, sdl_display_zoom_pct,
|
||||
use_accelerator, &disp_data->window, &disp_data->renderer,
|
||||
&disp_data->mutex, &disp_data->texture,
|
||||
&disp_data->read_texture);
|
||||
&disp_data->read_texture, &disp_data->background_texture,
|
||||
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_1,
|
||||
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_2,
|
||||
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_SIZE);
|
||||
|
||||
if (rc != 0) {
|
||||
LOG_ERR("Failed to create SDL display");
|
||||
|
|
@ -261,7 +265,8 @@ static int sdl_display_write(const struct device *dev, const uint16_t x,
|
|||
}
|
||||
|
||||
sdl_display_write_bottom(desc->height, desc->width, x, y, disp_data->renderer,
|
||||
disp_data->mutex, disp_data->texture, disp_data->buf,
|
||||
disp_data->mutex, disp_data->texture,
|
||||
disp_data->background_texture, disp_data->buf,
|
||||
disp_data->display_on, desc->frame_incomplete);
|
||||
|
||||
return 0;
|
||||
|
|
@ -431,7 +436,8 @@ static int sdl_display_blanking_off(const struct device *dev)
|
|||
|
||||
disp_data->display_on = true;
|
||||
|
||||
sdl_display_blanking_off_bottom(disp_data->renderer, disp_data->texture);
|
||||
sdl_display_blanking_off_bottom(disp_data->renderer, disp_data->texture,
|
||||
disp_data->background_texture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -491,7 +497,8 @@ static int sdl_display_set_pixel_format(const struct device *dev,
|
|||
static void sdl_display_cleanup(struct sdl_display_data *disp_data)
|
||||
{
|
||||
sdl_display_cleanup_bottom(&disp_data->window, &disp_data->renderer, &disp_data->mutex,
|
||||
&disp_data->texture, &disp_data->read_texture);
|
||||
&disp_data->texture, &disp_data->read_texture,
|
||||
&disp_data->background_texture);
|
||||
}
|
||||
|
||||
static const struct display_driver_api sdl_display_api = {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
||||
bool use_accelerator, void **window, void **renderer, void **mutex,
|
||||
void **texture, void **read_texture)
|
||||
void **texture, void **read_texture, void **background_texture,
|
||||
uint32_t transparency_grid_color1, uint32_t transparency_grid_color2,
|
||||
uint16_t transparency_grid_cell_size)
|
||||
{
|
||||
*window = SDL_CreateWindow("Zephyr Display", SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED, width * zoom_pct / 100,
|
||||
|
|
@ -51,6 +53,7 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
|||
nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
SDL_SetTextureBlendMode(*texture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
*read_texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_TARGET, width, height);
|
||||
|
|
@ -59,8 +62,41 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*background_texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
if (*background_texture == NULL) {
|
||||
nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *background_data;
|
||||
int background_pitch;
|
||||
int err;
|
||||
|
||||
err = SDL_LockTexture(*background_texture, NULL, &background_data, &background_pitch);
|
||||
if (err != 0) {
|
||||
nsi_print_warning("Failed to lock background texture: %d", err);
|
||||
return -1;
|
||||
}
|
||||
for (int y = 0; y < height; y++) {
|
||||
uint32_t *row = (uint32_t *)((uint8_t *)background_data + background_pitch * y);
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
bool x_cell_even = ((x / transparency_grid_cell_size) % 2) == 0;
|
||||
bool y_cell_even = ((y / transparency_grid_cell_size) % 2) == 0;
|
||||
|
||||
if (x_cell_even == y_cell_even) {
|
||||
row[x] = transparency_grid_color1 | 0xff000000;
|
||||
} else {
|
||||
row[x] = transparency_grid_color2 | 0xff000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_UnlockTexture(*background_texture);
|
||||
|
||||
SDL_SetRenderDrawColor(*renderer, 0, 0, 0, 0xFF);
|
||||
SDL_RenderClear(*renderer);
|
||||
SDL_RenderCopy(*renderer, *background_texture, NULL, NULL);
|
||||
SDL_RenderPresent(*renderer);
|
||||
|
||||
return 0;
|
||||
|
|
@ -68,7 +104,8 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
|||
|
||||
void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
|
||||
const uint16_t y, void *renderer, void *mutex, void *texture,
|
||||
uint8_t *buf, bool display_on, bool frame_incomplete)
|
||||
void *background_texture, uint8_t *buf, bool display_on,
|
||||
bool frame_incomplete)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
int err;
|
||||
|
|
@ -88,6 +125,7 @@ void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const
|
|||
|
||||
if (display_on && !frame_incomplete) {
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, background_texture, NULL, NULL);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
|
@ -127,9 +165,10 @@ int sdl_display_read_bottom(const uint16_t height, const uint16_t width,
|
|||
return err;
|
||||
}
|
||||
|
||||
void sdl_display_blanking_off_bottom(void *renderer, void *texture)
|
||||
void sdl_display_blanking_off_bottom(void *renderer, void *texture, void *background_texture)
|
||||
{
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, background_texture, NULL, NULL);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
|
@ -141,8 +180,13 @@ void sdl_display_blanking_on_bottom(void *renderer)
|
|||
}
|
||||
|
||||
void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
|
||||
void **read_texture)
|
||||
void **read_texture, void **background_texture)
|
||||
{
|
||||
if (*background_texture != NULL) {
|
||||
SDL_DestroyTexture(*background_texture);
|
||||
*background_texture = NULL;
|
||||
}
|
||||
|
||||
if (*read_texture != NULL) {
|
||||
SDL_DestroyTexture(*read_texture);
|
||||
*read_texture = NULL;
|
||||
|
|
|
|||
|
|
@ -22,17 +22,20 @@ extern "C" {
|
|||
|
||||
int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
||||
bool use_accelerator, void **window, void **renderer, void **mutex,
|
||||
void **texture, void **read_texture);
|
||||
void **texture, void **read_texture, void **background_texture,
|
||||
uint32_t transparency_grid_color1, uint32_t transparency_grid_color2,
|
||||
uint16_t transparency_grid_cell_size);
|
||||
void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
|
||||
const uint16_t y, void *renderer, void *mutex, void *texture,
|
||||
uint8_t *buf, bool display_on, bool frame_incomplete);
|
||||
void *background_texture, uint8_t *buf, bool display_on,
|
||||
bool frame_incomplete);
|
||||
int sdl_display_read_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
|
||||
const uint16_t y, void *renderer, void *buf, uint16_t pitch,
|
||||
void *mutex, void *texture, void *read_texture);
|
||||
void sdl_display_blanking_off_bottom(void *renderer, void *texture);
|
||||
void sdl_display_blanking_off_bottom(void *renderer, void *texture, void *background_texture);
|
||||
void sdl_display_blanking_on_bottom(void *renderer);
|
||||
void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
|
||||
void **read_texture);
|
||||
void **read_texture, void **background_texture);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue