diff mbox series

[3/5] sandbox: video: Move sync rate limit into SDL code

Message ID 20230821181339.4135800-4-alpernebiyasak@gmail.com
State Under Review
Delegated to: Anatolij Gustschin
Headers show
Series sandbox: video: Refactor out of uclass, try partial screen updates | expand

Commit Message

Alper Nebi Yasak Aug. 21, 2023, 6:13 p.m. UTC
As a first step of removing sandbox-specific code from the video uclass,
move the sync rate limiter into the SDL code. We lose the ability to
immediately force a screen refresh, but can retry until it does.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
---

 arch/sandbox/cpu/sdl.c         | 9 +++++++++
 arch/sandbox/include/asm/sdl.h | 4 +++-
 drivers/video/video-uclass.c   | 8 +++-----
 3 files changed, 15 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index 590e406517bf..48fae20b4c2d 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -48,6 +48,7 @@  struct buf_info {
  * @screen: SDL window to use
  * @src_depth: Number of bits per pixel in the source frame buffer (that we read
  * from and render to SDL)
+ * @last_sync: Timestamp of last display update in milliseconds
  */
 static struct sdl_info {
 	int width;
@@ -67,6 +68,7 @@  static struct sdl_info {
 	SDL_Renderer *renderer;
 	SDL_Window *screen;
 	int src_depth;
+	int last_sync;
 } sdl;
 
 static void sandbox_sdl_poll_events(void)
@@ -148,6 +150,7 @@  int sandbox_sdl_init_display(int width, int height, int log2_bpp,
 		sdl.vis_width = sdl.width;
 		sdl.vis_height = sdl.height;
 	}
+	sdl.last_sync = 0;
 
 	if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
 		printf("Unable to init hinting: %s", SDL_GetError());
@@ -245,6 +248,10 @@  int sandbox_sdl_sync(void *lcd_base)
 
 	if (!sdl.texture)
 		return 0;
+
+	if (SDL_GetTicks() - sdl.last_sync < 100)
+		return -EAGAIN;
+
 	SDL_RenderClear(sdl.renderer);
 	ret = copy_to_texture(lcd_base);
 	if (ret) {
@@ -268,6 +275,8 @@  int sandbox_sdl_sync(void *lcd_base)
 	SDL_RenderDrawRect(sdl.renderer, &rect);
 
 	SDL_RenderPresent(sdl.renderer);
+	sdl.last_sync = SDL_GetTicks();
+
 	sandbox_sdl_poll_events();
 
 	return 0;
diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h
index ee4991f7c24a..1ace7d1a1217 100644
--- a/arch/sandbox/include/asm/sdl.h
+++ b/arch/sandbox/include/asm/sdl.h
@@ -37,10 +37,12 @@  int sandbox_sdl_remove_display(void);
  * sandbox_sdl_sync() - Sync current U-Boot LCD frame buffer to SDL
  *
  * This must be called periodically to update the screen for SDL so that the
- * user can see it.
+ * user can see it. It is internally rate limited to 10 Hz to avoid using
+ * system resources too much.
  *
  * @lcd_base: Base of frame buffer
  * Return: 0 if screen was updated, -ENODEV is there is no screen.
+ *	   -EAGAIN if screen was not updated due to sync rate limit.
  */
 int sandbox_sdl_sync(void *lcd_base);
 
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index accf486509cb..d867185da539 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -455,16 +455,14 @@  int video_sync(struct udevice *vid, bool force)
 	video_flush_dcache(vid);
 
 #if defined(CONFIG_VIDEO_SANDBOX_SDL)
-	static ulong last_sync;
 	void *fb = priv->fb;
 
 	if (IS_ENABLED(CONFIG_VIDEO_COPY))
 		fb = priv->copy_fb;
 
-	if (force || get_timer(last_sync) > 100) {
-		sandbox_sdl_sync(fb);
-		last_sync = get_timer(0);
-	}
+	ret = sandbox_sdl_sync(fb);
+	while (force && ret == -EAGAIN)
+		ret = sandbox_sdl_sync(fb);
 #endif
 
 	if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) {