Skip to content

Commit ef45a64

Browse files
faxe1008nashif
authored andcommitted
drivers: display: sdl: Add elliptical masking of display area
Adds `SDL_DISPLAY_ROUNDED_MASK` and `SDL_DISPLAY_ROUNDED_MASK_COLOR` Kconfig options to mask a elliptical area of the display. This is useful for prototyping alignments for rounded displays. Signed-off-by: Fabian Blatz <[email protected]>
1 parent 636df43 commit ef45a64

File tree

4 files changed

+118
-17
lines changed

4 files changed

+118
-17
lines changed

drivers/display/Kconfig.sdl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ config SDL_DISPLAY_COLOR_TINT
100100
Can be used to simulate colored monochrome displays, like R8 (L8 + tint 0xff0000).
101101
Byte order: RGB_888
102102

103+
config SDL_DISPLAY_ROUNDED_MASK
104+
bool "Use rounded mask"
105+
help
106+
If enabled, a rounded mask will be applied to the display output.
107+
This is useful to simulate rounded displays.
108+
109+
config SDL_DISPLAY_ROUNDED_MASK_COLOR
110+
hex "Rounded mask color"
111+
default 0x000000
112+
help
113+
The color of the rounded mask.
114+
Byte order: RGB_888
115+
103116
config SDL_DISPLAY_THREAD_PRIORITY
104117
int "SDL display thread priority"
105118
default MAIN_THREAD_PRIORITY

drivers/display/display_sdl.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ struct sdl_display_task {
4343
};
4444
};
4545

46-
4746
struct sdl_display_config {
4847
uint16_t height;
4948
uint16_t width;
@@ -57,6 +56,7 @@ struct sdl_display_data {
5756
void *texture;
5857
void *read_texture;
5958
void *background_texture;
59+
void *round_disp_mask;
6060
bool display_on;
6161
enum display_pixel_format current_pixel_format;
6262
uint8_t *buf;
@@ -88,14 +88,13 @@ static void exec_sdl_task(const struct device *dev, const struct sdl_display_tas
8888
task->write.x, task->write.y, disp_data->renderer,
8989
disp_data->mutex, disp_data->texture,
9090
disp_data->background_texture, disp_data->buf,
91-
disp_data->display_on,
92-
task->write.desc->frame_incomplete,
93-
CONFIG_SDL_DISPLAY_COLOR_TINT);
91+
disp_data->display_on, task->write.desc->frame_incomplete,
92+
CONFIG_SDL_DISPLAY_COLOR_TINT, disp_data->round_disp_mask);
9493
break;
9594
case SDL_BLANKING_OFF:
96-
sdl_display_blanking_off_bottom(disp_data->renderer, disp_data->texture,
97-
disp_data->background_texture,
98-
CONFIG_SDL_DISPLAY_COLOR_TINT);
95+
sdl_display_blanking_off_bottom(
96+
disp_data->renderer, disp_data->texture, disp_data->background_texture,
97+
CONFIG_SDL_DISPLAY_COLOR_TINT, disp_data->round_disp_mask);
9998
break;
10099
case SDL_BLANKING_ON:
101100
sdl_display_blanking_on_bottom(disp_data->renderer);
@@ -125,7 +124,9 @@ static void sdl_task_thread(void *p1, void *p2, void *p3)
125124
&disp_data->texture, &disp_data->read_texture, &disp_data->background_texture,
126125
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_1,
127126
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_COLOR_2,
128-
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_SIZE);
127+
CONFIG_SDL_DISPLAY_TRANSPARENCY_GRID_CELL_SIZE,
128+
COND_CODE_1(CONFIG_SDL_DISPLAY_ROUNDED_MASK, (&disp_data->round_disp_mask), (NULL)),
129+
CONFIG_SDL_DISPLAY_ROUNDED_MASK_COLOR);
129130

130131
k_sem_give(&disp_data->task_sem);
131132

@@ -781,7 +782,7 @@ static void sdl_display_cleanup(struct sdl_display_data *disp_data)
781782
{
782783
sdl_display_cleanup_bottom(&disp_data->window, &disp_data->renderer, &disp_data->mutex,
783784
&disp_data->texture, &disp_data->read_texture,
784-
&disp_data->background_texture);
785+
&disp_data->background_texture, &disp_data->round_disp_mask);
785786
}
786787

787788
static DEVICE_API(display, sdl_display_api) = {

drivers/display/display_sdl_bottom.c

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,66 @@
1313
#include <SDL.h>
1414
#include "nsi_tracing.h"
1515

16+
static int sdl_create_rounded_display_mask(uint16_t width, uint16_t height, uint32_t mask_color,
17+
void **round_disp_mask, void *renderer)
18+
{
19+
*round_disp_mask = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
20+
SDL_TEXTUREACCESS_STREAMING, width, height);
21+
if (*round_disp_mask == NULL) {
22+
nsi_print_warning("Failed to create SDL mask texture: %s", SDL_GetError());
23+
return -1;
24+
}
25+
SDL_SetTextureBlendMode(*round_disp_mask, SDL_BLENDMODE_BLEND);
26+
27+
void *mask_data;
28+
int mask_pitch;
29+
int err;
30+
31+
err = SDL_LockTexture(*round_disp_mask, NULL, &mask_data, &mask_pitch);
32+
if (err != 0) {
33+
nsi_print_warning("Failed to lock mask texture: %d", err);
34+
return -1;
35+
}
36+
37+
/* Create ellipse mask */
38+
float cx = width / 2.0f;
39+
float cy = height / 2.0f;
40+
float rx = width / 2.0f;
41+
float ry = height / 2.0f;
42+
43+
for (int py = 0; py < height; py++) {
44+
uint32_t *row = (uint32_t *)((uint8_t *)mask_data + mask_pitch * py);
45+
46+
for (int px = 0; px < width; px++) {
47+
/* Calculate normalized distance from center */
48+
float dx = (px - cx) / rx;
49+
float dy = (py - cy) / ry;
50+
float distance = dx * dx + dy * dy;
51+
52+
/* Inside ellipse: transparent, outside: mask color with full opacity */
53+
if (distance <= 1.0f) {
54+
row[px] = 0x00000000; /* Transparent */
55+
} else {
56+
uint32_t r = (mask_color >> 16) & 0xff;
57+
uint32_t g = (mask_color >> 8) & 0xff;
58+
uint32_t b = mask_color & 0xff;
59+
60+
row[px] = (0xFF << 24) | (r << 16) | (g << 8) | b;
61+
}
62+
}
63+
}
64+
SDL_UnlockTexture(*round_disp_mask);
65+
66+
return 0;
67+
}
68+
1669
int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
1770
bool use_accelerator, void **window, const void *window_user_data,
1871
const char *title, void **renderer, void **mutex, void **texture,
1972
void **read_texture, void **background_texture,
2073
uint32_t transparency_grid_color1, uint32_t transparency_grid_color2,
21-
uint16_t transparency_grid_cell_size)
74+
uint16_t transparency_grid_cell_size, void **round_disp_mask,
75+
uint32_t mask_color)
2276
{
2377
/* clang-format off */
2478
*window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
@@ -98,6 +152,16 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
98152
}
99153
SDL_UnlockTexture(*background_texture);
100154

155+
/* Create ellipse mask texture if rounded mask is enabled */
156+
if (round_disp_mask != NULL) {
157+
err = sdl_create_rounded_display_mask(width, height, mask_color, round_disp_mask,
158+
*renderer);
159+
if (err != 0) {
160+
nsi_print_warning("Failed to create rounded display mask");
161+
return -1;
162+
}
163+
}
164+
101165
SDL_SetRenderDrawColor(*renderer, 0, 0, 0, 0xFF);
102166
SDL_RenderClear(*renderer);
103167
SDL_RenderCopy(*renderer, *background_texture, NULL, NULL);
@@ -109,7 +173,7 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
109173
void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
110174
const uint16_t y, void *renderer, void *mutex, void *texture,
111175
void *background_texture, uint8_t *buf, bool display_on,
112-
bool frame_incomplete, uint32_t color_tint)
176+
bool frame_incomplete, uint32_t color_tint, void *round_disp_mask)
113177
{
114178
SDL_Rect rect;
115179
int err;
@@ -136,6 +200,13 @@ void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const
136200
color_tint & 0xff);
137201
SDL_RenderCopy(renderer, texture, NULL, NULL);
138202
SDL_SetTextureColorMod(texture, 255, 255, 255);
203+
204+
if (round_disp_mask != NULL) {
205+
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_MOD);
206+
SDL_RenderCopy(renderer, round_disp_mask, NULL, NULL);
207+
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
208+
}
209+
139210
SDL_RenderPresent(renderer);
140211
}
141212

@@ -177,7 +248,7 @@ int sdl_display_read_bottom(const uint16_t height, const uint16_t width,
177248
}
178249

179250
void sdl_display_blanking_off_bottom(void *renderer, void *texture, void *background_texture,
180-
uint32_t color_tint)
251+
uint32_t color_tint, void *round_disp_mask)
181252
{
182253
SDL_RenderClear(renderer);
183254
SDL_RenderCopy(renderer, background_texture, NULL, NULL);
@@ -187,6 +258,14 @@ void sdl_display_blanking_off_bottom(void *renderer, void *texture, void *backgr
187258
color_tint & 0xff);
188259
SDL_RenderCopy(renderer, texture, NULL, NULL);
189260
SDL_SetTextureColorMod(texture, 255, 255, 255);
261+
262+
/* Apply ellipse mask if enabled */
263+
if (round_disp_mask != NULL) {
264+
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_MOD);
265+
SDL_RenderCopy(renderer, round_disp_mask, NULL, NULL);
266+
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
267+
}
268+
190269
SDL_RenderPresent(renderer);
191270
}
192271

@@ -197,8 +276,14 @@ void sdl_display_blanking_on_bottom(void *renderer)
197276
}
198277

199278
void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
200-
void **read_texture, void **background_texture)
279+
void **read_texture, void **background_texture,
280+
void **round_disp_mask)
201281
{
282+
if (*round_disp_mask != NULL) {
283+
SDL_DestroyTexture(*round_disp_mask);
284+
*round_disp_mask = NULL;
285+
}
286+
202287
if (*background_texture != NULL) {
203288
SDL_DestroyTexture(*background_texture);
204289
*background_texture = NULL;

drivers/display/display_sdl_bottom.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,21 @@ int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
2525
const char *title, void **renderer, void **mutex, void **texture,
2626
void **read_texture, void **background_texture,
2727
uint32_t transparency_grid_color1, uint32_t transparency_grid_color2,
28-
uint16_t transparency_grid_cell_size);
28+
uint16_t transparency_grid_cell_size, void **round_disp_mask,
29+
uint32_t mask_color);
2930
void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
3031
const uint16_t y, void *renderer, void *mutex, void *texture,
3132
void *background_texture, uint8_t *buf, bool display_on,
32-
bool frame_incomplete, uint32_t color_tint);
33+
bool frame_incomplete, uint32_t color_tint, void *round_disp_mask);
3334
int sdl_display_read_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
3435
const uint16_t y, void *renderer, void *buf, uint16_t pitch,
3536
void *mutex, void *texture, void *read_texture);
3637
void sdl_display_blanking_off_bottom(void *renderer, void *texture, void *background_texture,
37-
uint32_t color_tint);
38+
uint32_t color_tint, void *round_disp_mask);
3839
void sdl_display_blanking_on_bottom(void *renderer);
3940
void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
40-
void **read_texture, void **background_texture);
41+
void **read_texture, void **background_texture,
42+
void **round_disp_mask);
4143

4244
#ifdef __cplusplus
4345
}

0 commit comments

Comments
 (0)