1- //! Showcase: Interactive Draw Task Graph & Partial Band-Buffer Rendering
1+ //! Showcase: Draw Task Graph & Partial Band-Buffer Rendering
22//!
33//! Demonstrates:
44//! 1. Queuing retained-mode drawing commands into a fixed-capacity `DrawTaskQueue`.
55//! 2. Dispatching drawing tasks through pluggable `DrawUnit` hardware/software units.
6- //! 3. Band-buffered rendering using `PartialBandBuffer` (narrow horizontal slices) directly
7- //! to an interactive SDL2 desktop window.
6+ //! 3. Band-buffered rendering using `PartialBandBuffer` (narrow horizontal slices).
87//!
9- //! ### Controls:
10- //! - **Space**: Add / cycle draw tasks in the queue
8+ //! ### Interactive Controls (when desktop window is available) :
9+ //! - **Space**: Step / animate progress bar
1110//! - **Esc / Q**: Exit
1211
1312use core:: convert:: Infallible ;
@@ -30,7 +29,6 @@ use embedded_gui::{
3029const W : u32 = 320 ;
3130const H : u32 = 240 ;
3231
33- /// Frame buffer wrapping SimulatorDisplay that supports WindowedDrawTarget.
3432struct WindowedSimulator {
3533 display : SimulatorDisplay < Rgb565 > ,
3634 window_count : usize ,
@@ -74,11 +72,20 @@ impl WindowedDrawTarget for WindowedSimulator {
7472}
7573
7674fn main ( ) {
77- println ! ( "=== embedded-gui: Interactive Draw Task Graph & Band Buffer Showcase ===" ) ;
78- println ! ( "Controls:" ) ;
79- println ! ( " [Space] - Animate / cycle draw task progress" ) ;
80- println ! ( " [Esc/Q] - Exit" ) ;
75+ println ! ( "=== embedded-gui: Draw Task Graph & Band Buffer Showcase ===" ) ;
8176
77+ let res = std:: panic:: catch_unwind ( || {
78+ run_interactive_window ( ) ;
79+ } ) ;
80+
81+ if res. is_err ( ) {
82+ println ! ( "\n [Notice: SDL2 desktop window could not be opened in current terminal session]" ) ;
83+ println ! ( "[Rendering in standalone console simulation mode...]\n " ) ;
84+ run_console_showcase ( ) ;
85+ }
86+ }
87+
88+ fn run_interactive_window ( ) {
8289 let mut sim = WindowedSimulator :: new ( ) ;
8390 let settings = OutputSettingsBuilder :: new ( ) . scale ( 3 ) . build ( ) ;
8491 let mut window = Window :: new ( "Draw Task Graph & Band Buffer (320x240)" , & settings) ;
@@ -101,134 +108,14 @@ fn main() {
101108 }
102109 }
103110
104- // Animate progress smoothly
105111 if progress >= 240 {
106112 dir = -2 ;
107113 } else if progress <= 20 {
108114 dir = 2 ;
109115 }
110116 progress = ( progress as i32 + dir) . max ( 0 ) as u32 ;
111117
112- // 1. Build a queue of draw tasks
113- let mut queue = DrawTaskQueue :: < 16 > :: new ( ) ;
114-
115- // Background fill task
116- queue
117- . push ( DrawTask :: Fill {
118- rect : Rect :: new ( 0 , 0 , W , H ) ,
119- color : Rgb565 :: new ( 2 , 4 , 6 ) ,
120- radius : 0 ,
121- opacity : 255 ,
122- } )
123- . expect ( "Task queued" ) ;
124-
125- // Top Status Header
126- queue
127- . push ( DrawTask :: Fill {
128- rect : Rect :: new ( 0 , 0 , W , 22 ) ,
129- color : Rgb565 :: new ( 4 , 8 , 14 ) ,
130- radius : 0 ,
131- opacity : 255 ,
132- } )
133- . expect ( "Task queued" ) ;
134-
135- queue
136- . push ( DrawTask :: Label {
137- rect : Rect :: new ( 12 , 5 , 200 , 14 ) ,
138- text : "BAND BUFFER RENDER ENGINE" ,
139- style : TextStyle :: new ( Rgb565 :: CSS_CYAN ) ,
140- } )
141- . expect ( "Task queued" ) ;
142-
143- // Main Panel Card
144- queue
145- . push ( DrawTask :: Fill {
146- rect : Rect :: new ( 20 , 36 , 280 , 90 ) ,
147- color : Rgb565 :: new ( 6 , 12 , 18 ) ,
148- radius : 6 ,
149- opacity : 255 ,
150- } )
151- . expect ( "Task queued" ) ;
152-
153- queue
154- . push ( DrawTask :: Border {
155- rect : Rect :: new ( 20 , 36 , 280 , 90 ) ,
156- border : Border :: one ( Rgb565 :: CSS_DARK_CYAN ) ,
157- radius : 6 ,
158- } )
159- . expect ( "Task queued" ) ;
160-
161- // Card Label
162- queue
163- . push ( DrawTask :: Label {
164- rect : Rect :: new ( 35 , 48 , 250 , 16 ) ,
165- text : "SRAM CONSUMPTION: 12.8 KB" ,
166- style : TextStyle :: new ( Rgb565 :: CSS_WHITE ) ,
167- } )
168- . expect ( "Task queued" ) ;
169-
170- queue
171- . push ( DrawTask :: Label {
172- rect : Rect :: new ( 35 , 66 , 250 , 14 ) ,
173- text : "Transfers 12 bands of 20 lines each" ,
174- style : TextStyle :: new ( Rgb565 :: new ( 15 , 30 , 20 ) ) ,
175- } )
176- . expect ( "Task queued" ) ;
177-
178- // Progress Bar Background & Active Fill
179- queue
180- . push ( DrawTask :: Fill {
181- rect : Rect :: new ( 35 , 94 , 250 , 14 ) ,
182- color : Rgb565 :: new ( 3 , 6 , 9 ) ,
183- radius : 3 ,
184- opacity : 255 ,
185- } )
186- . expect ( "Task queued" ) ;
187-
188- queue
189- . push ( DrawTask :: Fill {
190- rect : Rect :: new ( 35 , 94 , progress, 14 ) ,
191- color : Rgb565 :: CSS_GREEN ,
192- radius : 3 ,
193- opacity : 255 ,
194- } )
195- . expect ( "Task queued" ) ;
196-
197- // Secondary Info Card
198- queue
199- . push ( DrawTask :: Fill {
200- rect : Rect :: new ( 20 , 138 , 280 , 80 ) ,
201- color : Rgb565 :: new ( 6 , 12 , 18 ) ,
202- radius : 6 ,
203- opacity : 255 ,
204- } )
205- . expect ( "Task queued" ) ;
206-
207- queue
208- . push ( DrawTask :: Border {
209- rect : Rect :: new ( 20 , 138 , 280 , 80 ) ,
210- border : Border :: one ( Rgb565 :: new ( 12 , 24 , 18 ) ) ,
211- radius : 6 ,
212- } )
213- . expect ( "Task queued" ) ;
214-
215- queue
216- . push ( DrawTask :: Label {
217- rect : Rect :: new ( 35 , 152 , 250 , 16 ) ,
218- text : "HARDWARE DMA STREAMING" ,
219- style : TextStyle :: new ( Rgb565 :: CSS_GOLD ) ,
220- } )
221- . expect ( "Task queued" ) ;
222-
223- queue
224- . push ( DrawTask :: Label {
225- rect : Rect :: new ( 35 , 172 , 250 , 14 ) ,
226- text : "Windowed SPI/8080 transfers direct to LCD" ,
227- style : TextStyle :: new ( Rgb565 :: new ( 20 , 40 , 30 ) ) ,
228- } )
229- . expect ( "Task queued" ) ;
230-
231- // 2. Render using PartialBandBuffer (20 lines per band = 12.8 KB RAM)
118+ let queue = build_queue ( progress) ;
232119 let screen = Rect :: new ( 0 , 0 , W , H ) ;
233120 let mut band_buffer = PartialBandBuffer :: < { 320 * 20 } > :: new ( 320 , 20 ) ;
234121
@@ -240,3 +127,96 @@ fn main() {
240127 std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 16 ) ) ;
241128 }
242129}
130+
131+ fn run_console_showcase ( ) {
132+ let mut sim = WindowedSimulator :: new ( ) ;
133+ let queue = build_queue ( 175 ) ;
134+ let screen = Rect :: new ( 0 , 0 , W , H ) ;
135+ let mut band_buffer = PartialBandBuffer :: < { 320 * 20 } > :: new ( 320 , 20 ) ;
136+
137+ band_buffer
138+ . render_tasks_banded ( screen, screen, & queue, & mut sim, Some ( Rgb565 :: new ( 2 , 4 , 6 ) ) )
139+ . expect ( "Render succeeded" ) ;
140+
141+ println ! ( "Queued {} draw tasks in task graph." , queue. len( ) ) ;
142+ println ! (
143+ "Rendered 320x240 screen in 12 bands using {} window transfers." ,
144+ sim. window_count
145+ ) ;
146+ println ! ( "Band buffer rendering completed successfully!" ) ;
147+ }
148+
149+ fn build_queue ( progress : u32 ) -> DrawTaskQueue < ' static , 16 > {
150+ let mut queue = DrawTaskQueue :: < 16 > :: new ( ) ;
151+
152+ queue
153+ . push ( DrawTask :: Fill {
154+ rect : Rect :: new ( 0 , 0 , W , H ) ,
155+ color : Rgb565 :: new ( 2 , 4 , 6 ) ,
156+ radius : 0 ,
157+ opacity : 255 ,
158+ } )
159+ . unwrap ( ) ;
160+
161+ queue
162+ . push ( DrawTask :: Fill {
163+ rect : Rect :: new ( 0 , 0 , W , 22 ) ,
164+ color : Rgb565 :: new ( 4 , 8 , 14 ) ,
165+ radius : 0 ,
166+ opacity : 255 ,
167+ } )
168+ . unwrap ( ) ;
169+
170+ queue
171+ . push ( DrawTask :: Label {
172+ rect : Rect :: new ( 12 , 5 , 200 , 14 ) ,
173+ text : "BAND BUFFER RENDER ENGINE" ,
174+ style : TextStyle :: new ( Rgb565 :: CSS_CYAN ) ,
175+ } )
176+ . unwrap ( ) ;
177+
178+ queue
179+ . push ( DrawTask :: Fill {
180+ rect : Rect :: new ( 20 , 36 , 280 , 90 ) ,
181+ color : Rgb565 :: new ( 6 , 12 , 18 ) ,
182+ radius : 6 ,
183+ opacity : 255 ,
184+ } )
185+ . unwrap ( ) ;
186+
187+ queue
188+ . push ( DrawTask :: Border {
189+ rect : Rect :: new ( 20 , 36 , 280 , 90 ) ,
190+ border : Border :: one ( Rgb565 :: CSS_DARK_CYAN ) ,
191+ radius : 6 ,
192+ } )
193+ . unwrap ( ) ;
194+
195+ queue
196+ . push ( DrawTask :: Label {
197+ rect : Rect :: new ( 35 , 48 , 250 , 16 ) ,
198+ text : "SRAM CONSUMPTION: 12.8 KB" ,
199+ style : TextStyle :: new ( Rgb565 :: CSS_WHITE ) ,
200+ } )
201+ . unwrap ( ) ;
202+
203+ queue
204+ . push ( DrawTask :: Fill {
205+ rect : Rect :: new ( 35 , 94 , 250 , 14 ) ,
206+ color : Rgb565 :: new ( 3 , 6 , 9 ) ,
207+ radius : 3 ,
208+ opacity : 255 ,
209+ } )
210+ . unwrap ( ) ;
211+
212+ queue
213+ . push ( DrawTask :: Fill {
214+ rect : Rect :: new ( 35 , 94 , progress, 14 ) ,
215+ color : Rgb565 :: CSS_GREEN ,
216+ radius : 3 ,
217+ opacity : 255 ,
218+ } )
219+ . unwrap ( ) ;
220+
221+ queue
222+ }
0 commit comments