Skip to content

Commit e1d6642

Browse files
committed
rg_gui: rg_gui_copy_buffer optimization
When transparency isn't needed we can use memcpy which is 10-15% faster.
1 parent 5ce9cc2 commit e1d6642

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

components/retro-go/rg_gui.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,15 @@ void rg_gui_set_surface(rg_surface_t *surface)
239239
gui.screen_buffer = surface ? surface->data : NULL;
240240
}
241241

242-
void rg_gui_copy_buffer(int left, int top, int width, int height, int stride, const void *buffer)
242+
void rg_gui_copy_buffer(int left, int top, int width, int height, int stride, const uint16_t *buffer, bool transparency)
243243
{
244244
left = get_horizontal_position(left, width);
245245
top = get_vertical_position(top, height);
246+
width = RG_MIN(width, gui.screen_width - left);
247+
height = RG_MIN(height, gui.screen_height - top);
248+
249+
if (width <= 0 || height <= 0)
250+
return;
246251

247252
if (left >= gui.screen_width || top >= gui.screen_height)
248253
{
@@ -255,16 +260,20 @@ void rg_gui_copy_buffer(int left, int top, int width, int height, int stride, co
255260
if (stride < width)
256261
stride = width * 2;
257262

258-
width = RG_MIN(width, gui.screen_width - left);
259-
height = RG_MIN(height, gui.screen_height - top);
260-
261263
for (int y = 0; y < height; ++y)
262264
{
263265
uint16_t *dst = gui.screen_buffer + (top + y) * gui.screen_width + left;
264266
const uint16_t *src = (void *)buffer + y * stride;
265-
for (int x = 0; x < width; ++x)
266-
if (src[x] != C_TRANSPARENT)
267-
dst[x] = src[x];
267+
if (transparency)
268+
{
269+
for (int x = 0; x < width; ++x)
270+
if (src[x] != C_TRANSPARENT)
271+
dst[x] = src[x];
272+
}
273+
else
274+
{
275+
memcpy(dst, src, width * 2);
276+
}
268277
}
269278
}
270279
else
@@ -358,6 +367,7 @@ rg_rect_t rg_gui_draw_text(int x_pos, int y_pos, int width, const char *text, //
358367
int monospace = ((flags & RG_TEXT_MONOSPACE) || font->type == 0) ? font->width : 0;
359368
int line_height = font_height + padding * 2;
360369
int line_count = 0;
370+
bool transparency = color_fg == C_TRANSPARENT || color_bg == C_TRANSPARENT;
361371
// int16_t line_breaks[64], line_width_cache[64];
362372

363373
if (!text || *text == 0)
@@ -460,7 +470,7 @@ rg_rect_t rg_gui_draw_text(int x_pos, int y_pos, int width, const char *text, //
460470
}
461471

462472
if (!(flags & RG_TEXT_DUMMY_DRAW))
463-
rg_gui_copy_buffer(x_pos, y_pos + y_offset, draw_width, line_height, 0, draw_buffer);
473+
rg_gui_copy_buffer(x_pos, y_pos + y_offset, draw_width, line_height, 0, draw_buffer, transparency);
464474

465475
y_offset += line_height;
466476

@@ -483,11 +493,12 @@ void rg_gui_draw_rect(int x_pos, int y_pos, int width, int height, int border_si
483493
if (border_size > 0)
484494
{
485495
uint16_t *draw_buffer = get_draw_buffer(border_size, RG_MAX(width, height), border_color);
496+
bool transparency = border_color == C_TRANSPARENT;
486497

487-
rg_gui_copy_buffer(x_pos, y_pos, width, border_size, 0, draw_buffer); // Top
488-
rg_gui_copy_buffer(x_pos, y_pos + height - border_size, width, border_size, 0, draw_buffer); // Bottom
489-
rg_gui_copy_buffer(x_pos, y_pos, border_size, height, 0, draw_buffer); // Left
490-
rg_gui_copy_buffer(x_pos + width - border_size, y_pos, border_size, height, 0, draw_buffer); // Right
498+
rg_gui_copy_buffer(x_pos, y_pos, width, border_size, 0, draw_buffer, transparency); // Top
499+
rg_gui_copy_buffer(x_pos, y_pos + height - border_size, width, border_size, 0, draw_buffer, transparency); // Bottom
500+
rg_gui_copy_buffer(x_pos, y_pos, border_size, height, 0, draw_buffer, transparency); // Left
501+
rg_gui_copy_buffer(x_pos + width - border_size, y_pos, border_size, height, 0, draw_buffer, transparency); // Right
491502

492503
x_pos += border_size;
493504
y_pos += border_size;
@@ -498,8 +509,9 @@ void rg_gui_draw_rect(int x_pos, int y_pos, int width, int height, int border_si
498509
if (width > 0 && height > 0 && fill_color != C_NONE)
499510
{
500511
uint16_t *draw_buffer = get_draw_buffer(width, RG_MIN(height, 16), fill_color);
512+
bool transparency = fill_color == C_TRANSPARENT;
501513
for (int y = 0; y < height; y += 16)
502-
rg_gui_copy_buffer(x_pos, y_pos + y, width, RG_MIN(height - y, 16), 0, draw_buffer);
514+
rg_gui_copy_buffer(x_pos, y_pos + y, width, RG_MIN(height - y, 16), 0, draw_buffer, transparency);
503515
}
504516
}
505517

@@ -508,14 +520,14 @@ void rg_gui_draw_image(int x_pos, int y_pos, int width, int height, bool resampl
508520
if (img && resample && (width && height) && (width != img->width || height != img->height))
509521
{
510522
rg_image_t *new_img = rg_surface_resize(img, width, height);
511-
rg_gui_copy_buffer(x_pos, y_pos, width, height, new_img->width * 2, new_img->data);
523+
rg_gui_copy_buffer(x_pos, y_pos, width, height, new_img->width * 2, new_img->data, true);
512524
rg_surface_free(new_img);
513525
}
514526
else if (img)
515527
{
516528
int draw_width = width ? RG_MIN(width, img->width) : img->width;
517529
int draw_height = height ? RG_MIN(height, img->height) : img->height;
518-
rg_gui_copy_buffer(x_pos, y_pos, draw_width, draw_height, img->width * 2, img->data);
530+
rg_gui_copy_buffer(x_pos, y_pos, draw_width, draw_height, img->width * 2, img->data, true);
519531
}
520532
else // We fill a rect to show something is missing instead of abort...
521533
{

components/retro-go/rg_gui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ bool rg_gui_set_theme(const char *name);
119119
const char *rg_gui_get_theme_name(void);
120120
rg_image_t *rg_gui_get_theme_image(const char *name);
121121
rg_color_t rg_gui_get_theme_color(const char *section, const char *key, rg_color_t default_value);
122-
void rg_gui_copy_buffer(int left, int top, int width, int height, int stride, const void *buffer);
122+
void rg_gui_copy_buffer(int left, int top, int width, int height, int stride, const uint16_t *buffer, bool transparency);
123123

124124
rg_rect_t rg_gui_draw_text(int x_pos, int y_pos, int width, const char *text, // const rg_font_t *font,
125125
rg_color_t color_fg, rg_color_t color_bg, uint32_t flags);

0 commit comments

Comments
 (0)