diff --git a/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.adb b/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.adb index 0b9a4017e..e0e252dd4 100644 --- a/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.adb +++ b/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.adb @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------ -- -- --- Copyright (C) 2015-2016, AdaCore -- +-- Copyright (C) 2015-2026, AdaCore -- -- -- -- Redistribution and use in source and binary forms, with or without -- -- modification, are permitted provided that the following conditions are -- @@ -235,6 +235,24 @@ package body STM32.LTDC is end if; end Reload_Config; + ------------------------- + -- Reload_Config_Async -- + ------------------------- + + procedure Reload_Config_Async is + begin + Sync.Apply_On_VSync; + end Reload_Config_Async; + + --------------------- + -- Wait_For_Reload -- + --------------------- + + procedure Wait_For_Reload is + begin + Sync.Wait; + end Wait_For_Reload; + ------------------ -- To_LTDC_Mode -- ------------------ diff --git a/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.ads b/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.ads index 214cfa274..bd0cb4979 100644 --- a/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.ads +++ b/arch/ARM/STM32/drivers/ltdc/stm32-ltdc.ads @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------ -- -- --- Copyright (C) 2015, AdaCore -- +-- Copyright (C) 2015-2026, AdaCore -- -- -- -- Redistribution and use in source and binary forms, with or without -- -- modification, are permitted provided that the following conditions are -- @@ -110,6 +110,35 @@ package STM32.LTDC is procedure Reload_Config (Immediate : Boolean := False); + procedure Reload_Config_Async; + -- Request a register reload at the next vertical blank and return + -- immediately, without waiting for the LTDC to apply it. The caller + -- can then do other useful work while the LTDC finishes scanning + -- the current frame and performs the reload at vertical blank, + -- rather than stalling on a hardware-paced wait whose length is + -- determined by display timing rather than by anything the caller + -- controls. + -- + -- The now-hidden buffer remains live to the LTDC until the swap + -- takes effect, so the caller must leave that buffer untouched + -- until Wait_For_Reload returns. + -- + -- Prefer the synchronous Reload_Config (Immediate => False) when + -- the next operation must read or write the now-hidden buffer + -- (for example a Copy_Back of the newly visible image into the + -- new hidden buffer): it blocks until the LTDC confirms the + -- reload, so the buffer the caller treats as hidden really is no + -- longer being scanned out. Use Reload_Config (Immediate => True) + -- only at setup or configuration time, when an unconditional + -- reload that is not aligned to vertical blank is acceptable. + + procedure Wait_For_Reload; + -- Block until the LTDC has applied a reload previously requested by + -- Reload_Config_Async. Returns immediately if no reload is pending. Call + -- before any operation that needs the new buffer to be visible, or that + -- must write into the now-hidden buffer that the LTDC may still be + -- scanning. + function To_LTDC_Mode (HAL_Mode : HAL.Framebuffer.FB_Color_Mode) return STM32.LTDC.Pixel_Format; -- Convert HAL.Framebuffer color mode to LTDC color mode diff --git a/boards/stm32_common/ltdc/framebuffer_ltdc.adb b/boards/stm32_common/ltdc/framebuffer_ltdc.adb index c49af8282..06e1924af 100644 --- a/boards/stm32_common/ltdc/framebuffer_ltdc.adb +++ b/boards/stm32_common/ltdc/framebuffer_ltdc.adb @@ -486,6 +486,29 @@ package body Framebuffer_LTDC is end loop; end Update_Layers; + ------------------------ + -- Update_Layer_Async -- + ------------------------ + + procedure Update_Layer_Async + (Display : in out Frame_Buffer; + Layer : Positive) + is + begin + Internal_Update_Layer (Display, Layer); + STM32.LTDC.Reload_Config_Async; + end Update_Layer_Async; + + --------------------- + -- Wait_For_Update -- + --------------------- + + procedure Wait_For_Update (Display : in out Frame_Buffer) is + pragma Unreferenced (Display); + begin + STM32.LTDC.Wait_For_Reload; + end Wait_For_Update; + ---------------- -- Color_Mode -- ---------------- diff --git a/boards/stm32_common/ltdc/framebuffer_ltdc.ads b/boards/stm32_common/ltdc/framebuffer_ltdc.ads index 989df6b43..7810f44c8 100644 --- a/boards/stm32_common/ltdc/framebuffer_ltdc.ads +++ b/boards/stm32_common/ltdc/framebuffer_ltdc.ads @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------ -- -- --- Copyright (C) 2015-2016, AdaCore -- +-- Copyright (C) 2015-2026, AdaCore -- -- -- -- Redistribution and use in source and binary forms, with or without -- -- modification, are permitted provided that the following conditions are -- @@ -138,6 +138,33 @@ package Framebuffer_LTDC is -- Updates all initialized layers at once with their respective hidden -- buffer + procedure Update_Layer_Async + (Display : in out Frame_Buffer; + Layer : Positive) + with Pre => Initialized (Display, Layer); + -- Like Update_Layer (without Copy_Back) but returns without waiting + -- for the LTDC to apply the swap. The caller can then do other + -- useful work while the LTDC finishes scanning the current frame + -- and performs the reload at vertical blank, rather than stalling + -- on a hardware-paced wait whose length is determined by display + -- timing. + -- + -- Until the swap takes effect the LTDC keeps scanning what is now + -- the hidden buffer, so callers must not write to it until + -- Wait_For_Update has returned. There is no Copy_Back option: + -- copying into the now-hidden buffer would race with the + -- in-progress scanout. + -- + -- Prefer the synchronous Update_Layer when the next operation must + -- read or write the now-hidden buffer (for example Update_Layer + -- with Copy_Back => True): it blocks until the LTDC has applied + -- the swap, so the buffer the caller treats as hidden really is + -- no longer being scanned out. + + procedure Wait_For_Update (Display : in out Frame_Buffer); + -- Block until any reload requested by Update_Layer_Async has been + -- applied by the LTDC. No-op if no reload is pending. + overriding function Color_Mode (Display : Frame_Buffer; Layer : Positive) return HAL.Framebuffer.FB_Color_Mode