libdragon icon indicating copy to clipboard operation
libdragon copied to clipboard

display: Support arbitrary resolutions

Open sp1187 opened this issue 2 years ago • 1 comments

This PR adds support for custom resolutions by changing the replacing the existing resolution_t enum type with a struct type of the same name that includes width, height and interlacing as its values, which is then sent as an argument to display_init like before. The new implementation includes some asserts to protect against invalid settings that do not work on real hardware.

There is still one bug left to resolve. When changing resolutions frequently, it seems that some resolutions will break the VI output in real hardware and leave it in a corrupt state that remains even after soft reset. This can be reproduced that applying this patch to the test example that I made for testing the feature and then press D-pad right, then D-pad down (which should correspond to 322x241).

diff --git a/examples/test/test.c b/examples/test/test.c
index b211a01e..b25fd846 100644
--- a/examples/test/test.c
+++ b/examples/test/test.c
@@ -70,10 +70,8 @@ int main(void)
         /*Fill the screen */
         graphics_fill_screen( disp, 0 );
 
-        sprintf(tStr, "Video mode: %lu\n", *((uint32_t *)0x80000300));
+        sprintf(tStr, "Size: %lux%lu\n", res.width, res.height);
         graphics_draw_text( disp, 20, 20, tStr );
-        sprintf(tStr, "Status: %08lX\n", *((uint32_t *)0xa4400000));
-        graphics_draw_text( disp, 20, 30, tStr );
 
         /* Full bright color */
         graphics_draw_box(disp, 20, 40, 20, 20, graphics_make_color(255, 0, 0, 255));
@@ -125,32 +123,28 @@ int main(void)
         if( keys.c[0].up )
         {
             display_close();
-
-            res = RESOLUTION_640x480;
+            res.height--;
             display_init( res, bit, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE );
         }
 
         if( keys.c[0].down )
         {
             display_close();
-
-            res = RESOLUTION_320x240;
+            res.height++;
             display_init( res, bit, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE );
         }
 
         if( keys.c[0].left )
         {
             display_close();
-
-            bit = DEPTH_16_BPP;
+            res.width -= 2;
             display_init( res, bit, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE );
         }
 
         if( keys.c[0].right )
         {
             display_close();
-
-            bit = DEPTH_32_BPP;
+            res.width += 2;
             display_init( res, bit, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE );
         }
     }

sp1187 avatar Oct 15 '22 19:10 sp1187

Seems that waiting for vblank before updating the VI settings was enough to avoid the VI crash, I updated the PR to have waits in display_init and display_close.

sp1187 avatar Oct 27 '22 16:10 sp1187

Merged manually, thanks

rasky avatar Nov 13 '22 14:11 rasky