From 78535d2343d07ad456a123ffb5b5c617320712c6 Mon Sep 17 00:00:00 2001 From: Colin James Wood <82226641+NighthowlerStudios@users.noreply.github.com> Date: Tue, 21 Jul 2026 17:20:58 +0100 Subject: [PATCH] [rlsw] First batch of embedded optimizations and compiler requirements Pico 2 (#5994) * pico doesn't implement time.h * add option for RLSW to hold a back buffer, and give it a sw method to swap * Remove unused pointer and give swSwapColorBuffers a default nop-behaviour * Fix compilation by removing old colorBackBuffer setters * use the correct logger * return line * rename RLSW_BACKBUFFER to SW_DOUBLE_BUFFERING --- src/external/rlsw.h | 34 ++++++++++++++++++++++++++++++++++ src/rcore.c | 11 ++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index db10bf2b4..00f1d97ec 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -677,6 +677,7 @@ SWAPI bool swResize(int w, int h); SWAPI void swReadPixels(int x, int y, int w, int h, SWformat format, SWtype type, void *pixels); SWAPI void swBlitPixels(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc, SWformat format, SWtype type, void *pixels); SWAPI void *swGetColorBuffer(int *width, int *height); // Restored for ESP-IDF compatibility +SWAPI void swSwapColorBuffers(void); // Swap software renderer color/back buffers by pointer only SWAPI void swEnable(SWstate state); SWAPI void swDisable(SWstate state); @@ -993,6 +994,9 @@ typedef struct { typedef struct { sw_texture_t color; // Default framebuffer color texture +#ifdef SW_DOUBLE_BUFFERING + sw_texture_t backColor; // Back buffer for multicore. +#endif sw_texture_t depth; // Default framebuffer depth texture } sw_default_framebuffer_t; @@ -1061,6 +1065,7 @@ typedef struct { sw_handle_t boundFramebufferId; // Framebuffer currently bound sw_texture_t *colorBuffer; // Color buffer currently bound + // NOTE: don't need backBuffer because it's already in the sw_default_framebuffer_t struct. sw_texture_t *depthBuffer; // Depth buffer currently bound sw_pool_t framebufferPool; // Framebuffer object pool @@ -2583,6 +2588,13 @@ static inline bool sw_default_framebuffer_alloc(sw_default_framebuffer_t *fb, in return false; } +#ifdef SW_DOUBLE_BUFFERING + if (!sw_texture_alloc(&fb->backColor, NULL, w, h, SW_FRAMEBUFFER_COLOR_FORMAT)) + { + return false; + } +#endif + if (!sw_texture_alloc(&fb->depth, NULL, w, h, SW_FRAMEBUFFER_DEPTH_FORMAT)) { return false; @@ -2595,6 +2607,9 @@ static inline void sw_default_framebuffer_free(sw_default_framebuffer_t *fb) { sw_texture_free(&fb->color); sw_texture_free(&fb->depth); +#ifdef SW_DOUBLE_BUFFERING + sw_texture_free(&fb->backColor); +#endif } static inline void sw_framebuffer_fill_color(sw_texture_t *colorBuffer, const float color[4]) @@ -4160,6 +4175,22 @@ void *swGetColorBuffer(int *width, int *height) return RLSW.framebuffer.color.pixels; } + +void swSwapColorBuffers(void) +{ +#ifdef SW_DOUBLE_BUFFERING + sw_texture_t tmp = RLSW.framebuffer.color; + RLSW.framebuffer.color = RLSW.framebuffer.backColor; + RLSW.framebuffer.backColor = tmp; + + // Only needs to know about current colorBuffer. + RLSW.colorBuffer = &RLSW.framebuffer.color; +#else + SW_LOG("WARNING: RLSW: swSwapColorBuffers not enabled (#define SW_DOUBLE_BUFFERING with a compiler option to enable).\n"); +#endif +} + + void swEnable(SWstate state) { switch (state) @@ -4335,6 +4366,8 @@ void swClear(uint32_t bitmask) sw_framebuffer_fill_color(RLSW.colorBuffer, RLSW.clearColor); } + // Don't clear back buffer, it might be locked by another core. + if ((bitmask & (SW_DEPTH_BUFFER_BIT)) && (RLSW.depthBuffer != NULL) && (RLSW.depthBuffer->pixels != NULL)) { sw_framebuffer_fill_depth(RLSW.depthBuffer, RLSW.clearDepth); @@ -5266,6 +5299,7 @@ void swBindFramebuffer(uint32_t id) RLSW.boundFramebufferId = id; RLSW.colorBuffer = sw_pool_get(&RLSW.texturePool, fb->colorAttachment); + // No back buffer available for binding rendertextures. RLSW.depthBuffer = sw_pool_get(&RLSW.texturePool, fb->depthAttachment); } diff --git a/src/rcore.c b/src/rcore.c index 450a4cec5..27b80b3c9 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -110,7 +110,12 @@ #include // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()] #include // Required for: strlen(), strcmp(), strrchr(), memset(), memcpy(), strcat() #include // Required for: va_list, va_start(), va_end() [Used in TraceLog()] + +#ifndef PICO_RP2350 #include // Required for: time() [Used in InitTimer()] +#else +#include "pico/rand.h" // Pico doesn't implement time, and will implement its own hardware timer elsewhere. However, we need something to get a random seed from... +#endif #include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] #if defined(PLATFORM_MEMORY) || defined(PLATFORM_WEB) @@ -713,8 +718,12 @@ void InitWindow(int width, int height, const char *title) CORE.Time.frameCounter = 0; CORE.Window.shouldClose = false; - // Initialize random seed + // Initialize random seed using available timer source instead of standard time() on embedded platforms + #ifndef PICO_RP2350 SetRandomSeed((unsigned int)time(NULL)); + #else + SetRandomSeed(get_rand_32()); + #endif TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory()); }