Skip to content

Commit d32cc23

Browse files
committed
rg_display: Replaced rg_display_sync(false) with rg_dysplay_is_busy()
rg_display_sync now has the same meaning as lcd_sync eg it should sync or flip the framebuffer because we're done drawing it. Maybe it should be called flip, in fact. Anyway this will improve performance once rg_gui adopts it, instead of calling lcd_sync after each writes (causing over 50 blits to draw one frame of menu)
1 parent 1d0025d commit d32cc23

File tree

13 files changed

+50
-30
lines changed

13 files changed

+50
-30
lines changed

components/retro-go/rg_display.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ static void display_task(void *arg)
366366
if (msg.type == RG_TASK_MSG_STOP)
367367
break;
368368

369+
const rg_surface_t *update = msg.dataPtr;
370+
371+
if (display.source.width != update->width || display.source.height != update->height)
372+
{
373+
display.source.width = update->width;
374+
display.source.height = update->height;
375+
display.changed = true;
376+
}
377+
369378
if (display.changed)
370379
{
371380
update_viewport_scaling();
@@ -380,7 +389,7 @@ static void display_task(void *arg)
380389
display.changed = false;
381390
}
382391

383-
write_update(msg.dataPtr);
392+
write_update(update);
384393
// draw_on_screen_display(0, display.screen.height);
385394
rg_task_receive(&msg, -1);
386395

@@ -393,7 +402,9 @@ void rg_display_force_redraw(void)
393402
display.changed = true;
394403
// memset(screen_line_checksum, 0, sizeof(screen_line_checksum));
395404
rg_system_event(RG_EVENT_REDRAW, NULL);
396-
rg_display_sync(true);
405+
// Wait for the redraw to be complete, if any was initiated!
406+
while (rg_display_is_busy())
407+
rg_task_yield();
397408
}
398409

399410
const rg_display_t *rg_display_get_info(void)
@@ -509,25 +520,20 @@ void rg_display_submit(const rg_surface_t *update, uint32_t flags)
509520
if (!update || !update->data)
510521
return;
511522

512-
if (display.source.width != update->width || display.source.height != update->height)
513-
{
514-
rg_display_sync(true);
515-
display.source.width = update->width;
516-
display.source.height = update->height;
517-
display.changed = true;
518-
}
519-
520523
rg_task_send(display_task_queue, &(rg_task_msg_t){.dataPtr = update}, -1);
521524

522525
counters.blockTime += rg_system_timer() - time_start;
523526
counters.totalFrames++;
524527
}
525528

526-
bool rg_display_sync(bool block)
529+
bool rg_display_is_busy(void)
527530
{
528-
while (block && rg_task_messages_waiting(display_task_queue))
529-
continue; // We should probably yield?
530-
return !rg_task_messages_waiting(display_task_queue);
531+
return rg_task_messages_waiting(display_task_queue) != 0;
532+
}
533+
534+
void rg_display_sync(void)
535+
{
536+
lcd_sync();
531537
}
532538

533539
// FIXME: We need to add a way to group writes and indicate completion, so that the display driver will blit/flip only
@@ -550,8 +556,11 @@ void rg_display_write_rect(int left, int top, int width, int height, int stride,
550556
// This will work for now because we rarely draw from different threads (so all we need is ensure
551557
// that we're not interrupting a display update). But what we SHOULD be doing is acquire a lock
552558
// before every call to lcd_set_window and release it only after the last call to lcd_send_buffer.
553-
if (!(flags & RG_DISPLAY_WRITE_NOSYNC))
554-
rg_display_sync(true);
559+
if ((flags & RG_DISPLAY_WRITE_NOSYNC) == 0)
560+
{
561+
while (rg_display_is_busy())
562+
rg_task_yield();
563+
}
555564

556565
// This isn't really necessary but it makes sense to invalidate
557566
// the lines we're about to overwrite...
@@ -666,9 +675,10 @@ bool rg_display_set_geometry(int width, int height, const rg_margins_t *margins)
666675
// update_viewport_scaling(); // This will be implicitly done by the display task
667676
rg_gui_update_geometry(); // Let the GUI know that the geometry has changed
668677
rg_system_event(RG_EVENT_GEOMETRY, 0); // Let everybody know that the geometry has changed
669-
RG_LOGI("Screen: resolution=%dx%d, effective=%dx%d, format=%d",
670-
display.screen.real_width, display.screen.real_height,
671-
display.screen.width, display.screen.height, display.screen.format);
678+
RG_LOGI("Screen: resolution=%dx%d (eff. %dx%d), margins=(%d %d %d %d), format=%d",
679+
display.screen.real_width, display.screen.real_height, display.screen.width, display.screen.height,
680+
display.screen.margins.left, display.screen.margins.top, display.screen.margins.right, display.screen.margins.bottom,
681+
display.screen.format);
672682
return true;
673683
}
674684

components/retro-go/rg_display.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum
4040
{
4141
RG_DISPLAY_WRITE_NOSYNC = (1 << 0),
4242
RG_DISPLAY_WRITE_NOSWAP = (1 << 1),
43+
RG_DISPLAY_WRITE_DIRECT = (1 << 2),
4344
};
4445

4546
typedef struct
@@ -107,9 +108,12 @@ void rg_display_write_rect(int left, int top, int width, int height, int stride,
107108
void rg_display_clear_rect(int left, int top, int width, int height, uint16_t color_le);
108109
void rg_display_clear_except(int left, int top, int width, int height, uint16_t color_le);
109110
void rg_display_clear(uint16_t color_le);
110-
bool rg_display_sync(bool block);
111+
bool rg_display_is_busy(void);
111112
void rg_display_force_redraw(void);
112113
void rg_display_submit(const rg_surface_t *update, uint32_t flags);
114+
// rg_display_sync syncs our internal state to the display. With ILI9341/ST7789 it's a no-op because all writes
115+
// are direct. With other drivers it is used to signal that the internal framebuffer should be sent to the LCD.
116+
void rg_display_sync(void);
113117

114118
rg_display_counters_t rg_display_get_counters(void);
115119
const rg_display_t *rg_display_get_info(void);

components/retro-go/rg_gui.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,7 @@ void rg_gui_debug_menu(void)
22152215
rg_system_set_log_level(RG_LOG_DEBUG);
22162216
break;
22172217
case 0x100:
2218+
rg_display_clear(C_BLACK);
22182219
rg_display_set_geometry(
22192220
RG_MAX(64, (rand() % RG_SCREEN_WIDTH) & ~0x3),
22202221
RG_MAX(64, (rand() % RG_SCREEN_HEIGHT) & ~0x3),

gwenesis/main/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,9 @@ void app_main(void)
470470
{
471471
for (int i = 0; i < 256; ++i)
472472
currentUpdate->palette[i] = (CRAM565[i] << 8) | (CRAM565[i] >> 8);
473-
slowFrame = !rg_display_sync(false);
474473
currentUpdate->width = screen_width;
475474
currentUpdate->height = screen_height;
475+
slowFrame = rg_display_is_busy(); // Previous frame is still not done, hence slowFrame...
476476
rg_display_submit(currentUpdate, 0);
477477
}
478478

launcher/main/gui.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,9 @@ void gui_scroll_list(tab_t *tab, scroll_whence_t mode, int arg)
372372

373373
void gui_redraw(void)
374374
{
375-
rg_display_sync(true);
375+
while (rg_display_is_busy())
376+
rg_task_yield(); // Wait for gui.surface to be released
377+
376378
rg_gui_set_surface(gui.surface);
377379

378380
tab_t *tab = gui_get_current_tab();

prboom-go/main/main.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,15 @@ void I_UpdateNoBlit(void)
137137
void I_FinishUpdate(void)
138138
{
139139
rg_display_submit(update, 0);
140-
rg_display_sync(true); // Wait for update->buffer to be released
141140
}
142141

143142
bool I_StartDisplay(void)
144143
{
144+
// Wait for the frame buffer to be released before we start drawing to it
145+
while (rg_display_is_busy())
146+
rg_task_yield();
145147
return true;
148+
// return !rg_display_is_busy();
146149
}
147150

148151
void I_EndDisplay(void)

retro-core/main/main_gbc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static rg_gui_event_t rtc_update_cb(rg_gui_option_t *option, rg_gui_event_t even
219219
static void video_callback(void *buffer)
220220
{
221221
int64_t startTime = rg_system_timer();
222-
slowFrame = !rg_display_sync(false);
222+
slowFrame = rg_display_is_busy();
223223
rg_display_submit(currentUpdate, 0);
224224
video_time += rg_system_timer() - startTime;
225225
}

retro-core/main/main_gw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ void gw_main(void)
275275

276276
// Our refresh rate is 128Hz, which is way too fast for our display
277277
// so make sure the previous frame is done sending before queuing a new one
278-
if (rg_display_sync(false) && drawFrame)
278+
if (!rg_display_is_busy() && drawFrame)
279279
{
280280
gw_system_blit(currentUpdate->data);
281281
rg_display_submit(currentUpdate, 0);

retro-core/main/main_lynx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ extern "C" void lynx_main(void)
259259

260260
if (drawFrame)
261261
{
262-
slowFrame = !rg_display_sync(false);
262+
slowFrame = rg_display_is_busy();
263263
rg_display_submit(currentUpdate, 0);
264264
currentUpdate = updates[currentUpdate == updates[0]];
265265
gPrimaryFrameBuffer = (UBYTE*)currentUpdate->data;

retro-core/main/main_nes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ static rg_gui_event_t palette_update_cb(rg_gui_option_t *option, rg_gui_event_t
150150

151151
static void blit_screen(uint8 *bmp)
152152
{
153-
slowFrame = bmp && !rg_display_sync(false);
153+
slowFrame = bmp && rg_display_is_busy();
154154
// A rolling average should be used for autocrop == 1, it causes jitter in some games...
155155
// int crop_h = (autocrop == 2) || (autocrop == 1 && nes->ppu->left_bg_counter > 210) ? 8 : 0;
156156
int crop_v = (overscan) ? nes->overscan : 0;

0 commit comments

Comments
 (0)