3030#include <sys/logging.h>
3131#include <sys/systask.h>
3232
33- #include <SDL2/SDL.h>
34- #include <SDL2/SDL_blendmode.h>
35- #include <SDL2/SDL_image.h>
36- #include <SDL2/SDL_render.h>
33+ #include <SDL3/SDL.h>
34+ #include <SDL3/SDL_blendmode.h>
35+ #include <SDL3/SDL_render.h>
36+ #include <SDL3_image/SDL_image.h>
37+ #include <stdlib.h>
3738
3839#include "profile.h"
3940
@@ -109,7 +110,7 @@ bool display_init(display_content_mode_t mode) {
109110 return true;
110111 }
111112
112- if (SDL_Init (SDL_INIT_VIDEO ) != 0 ) {
113+ if (! SDL_Init (SDL_INIT_VIDEO | SDL_INIT_HAPTIC | SDL_INIT_EVENTS ) ) {
113114 LOG_ERR ("%s" , SDL_GetError ());
114115 error_shutdown ("SDL_Init error" );
115116 }
@@ -123,21 +124,19 @@ bool display_init(display_content_mode_t mode) {
123124 window_title_alloc = NULL ;
124125 }
125126
126- drv -> window =
127- SDL_CreateWindow (window_title , SDL_WINDOWPOS_UNDEFINED ,
128- SDL_WINDOWPOS_UNDEFINED , WINDOW_WIDTH , WINDOW_HEIGHT ,
127+ drv -> window = SDL_CreateWindow (window_title , WINDOW_WIDTH , WINDOW_HEIGHT ,
129128#ifdef TREZOR_EMULATOR_RASPI
130- SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN
129+ SDL_WINDOW_FULLSCREEN
131130#else
132- SDL_WINDOW_SHOWN
131+ 0 // windows are visible by default in SDL3
133132#endif
134- );
133+ );
135134 free (window_title_alloc );
136135 if (!drv -> window ) {
137136 LOG_ERR ("%s" , SDL_GetError ());
138137 error_shutdown ("SDL_CreateWindow error" );
139138 }
140- drv -> renderer = SDL_CreateRenderer (drv -> window , -1 , SDL_RENDERER_SOFTWARE );
139+ drv -> renderer = SDL_CreateRenderer (drv -> window , NULL );
141140 if (!drv -> renderer ) {
142141 LOG_ERR ("%s" , SDL_GetError ());
143142 SDL_DestroyWindow (drv -> window );
@@ -146,9 +145,10 @@ bool display_init(display_content_mode_t mode) {
146145 SDL_SetRenderDrawColor (drv -> renderer , 0 , 0 , 0 , 255 );
147146 SDL_RenderClear (drv -> renderer );
148147
149- drv -> buffer = SDL_CreateRGBSurface (0 , DISPLAY_RESX , DISPLAY_RESY , COLOR_DEPTH ,
150- COLOR_MASK_R , COLOR_MASK_G , COLOR_MASK_B ,
151- COLOR_MASK_A );
148+ drv -> buffer = SDL_CreateSurface (
149+ DISPLAY_RESX , DISPLAY_RESY ,
150+ SDL_GetPixelFormatForMasks (COLOR_DEPTH , COLOR_MASK_R , COLOR_MASK_G ,
151+ COLOR_MASK_B , COLOR_MASK_A ));
152152 drv -> texture = SDL_CreateTexture (drv -> renderer , PIXEL_FORMAT ,
153153 SDL_TEXTUREACCESS_STREAMING , DISPLAY_RESX ,
154154 DISPLAY_RESY );
@@ -162,31 +162,31 @@ bool display_init(display_content_mode_t mode) {
162162#define CONCAT_LEN (name ) CONCAT_LEN_HELPER(name)
163163#ifdef BACKGROUND_FILE
164164#include BACKGROUND_FILE
165- drv -> background = IMG_LoadTexture_RW (
165+ drv -> background = IMG_LoadTexture_IO (
166166 drv -> renderer ,
167- SDL_RWFromMem (BACKGROUND_NAME , CONCAT_LEN (BACKGROUND_NAME )), 0 );
167+ SDL_IOFromMem (BACKGROUND_NAME , CONCAT_LEN (BACKGROUND_NAME )), true );
168168#endif
169169#ifdef FOREGROUND_FILE
170170#include FOREGROUND_FILE
171- drv -> foreground = IMG_LoadTexture_RW (
171+ drv -> foreground = IMG_LoadTexture_IO (
172172 drv -> renderer ,
173- SDL_RWFromMem (FOREGROUND_NAME , CONCAT_LEN (FOREGROUND_NAME )), 0 );
173+ SDL_IOFromMem (FOREGROUND_NAME , CONCAT_LEN (FOREGROUND_NAME )), true );
174174 if (drv -> foreground ) {
175175 SDL_SetTextureBlendMode (drv -> foreground , SDL_BLENDMODE_BLEND );
176176 // check that foreground dimensions match the window size which is important
177177 // for cutouts
178- int fw , fh ;
179- if (SDL_QueryTexture (drv -> foreground , NULL , NULL , & fw , & fh ) == 0 ) {
180- if (fw != WINDOW_WIDTH || fh != WINDOW_HEIGHT ) {
178+ float fw , fh ;
179+ if (SDL_GetTextureSize (drv -> foreground , & fw , & fh )) {
180+ if (( int ) fw != WINDOW_WIDTH || ( int ) fh != WINDOW_HEIGHT ) {
181181 LOG_ERR (
182182 "Foreground texture size (%dx%d) does not match window size "
183183 "(%dx%d)" ,
184- fw , fh , WINDOW_WIDTH , WINDOW_HEIGHT );
184+ ( int ) fw , ( int ) fh , WINDOW_WIDTH , WINDOW_HEIGHT );
185185 error_shutdown ("Foreground texture size mismatch" );
186186 }
187187 } else {
188- LOG_ERR ("SDL_QueryTexture failed: %s" , SDL_GetError ());
189- error_shutdown ("SDL_QueryTexture error" );
188+ LOG_ERR ("SDL_GetTextureSize failed: %s" , SDL_GetError ());
189+ error_shutdown ("SDL_GetTextureSize error" );
190190 }
191191 }
192192#endif
@@ -235,8 +235,8 @@ void display_deinit(display_content_mode_t mode) {
235235
236236 gfx_bitblt_deinit ();
237237
238- SDL_FreeSurface (drv -> prev_saved );
239- SDL_FreeSurface (drv -> buffer );
238+ SDL_DestroySurface (drv -> prev_saved );
239+ SDL_DestroySurface (drv -> buffer );
240240 if (drv -> background != NULL ) {
241241 SDL_DestroyTexture (drv -> background );
242242 }
@@ -416,22 +416,22 @@ void draw_rgb_led() {
416416 for (int y = - radius ; y <= radius ; y ++ ) {
417417 for (int x = - radius ; x <= radius ; x ++ ) {
418418 if (x * x + y * y <= radius * radius ) {
419- SDL_RenderDrawPoint (drv -> renderer , center_x + x , center_y + y );
419+ SDL_RenderPoint (drv -> renderer , center_x + x , center_y + y );
420420 }
421421 }
422422 }
423423 SDL_SetRenderDrawColor (drv -> renderer , 0 , 0 , 0 , 255 );
424424}
425425#endif // USE_RGB_LED
426426
427- static SDL_Rect screen_rect (void ) {
427+ static SDL_FRect screen_rect (void ) {
428428 display_driver_t * drv = & g_display_driver ;
429429 if (drv -> background || drv -> foreground ) {
430- return (SDL_Rect ){TOUCH_OFFSET_X , TOUCH_OFFSET_Y , DISPLAY_RESX ,
431- DISPLAY_RESY };
430+ return (SDL_FRect ){TOUCH_OFFSET_X , TOUCH_OFFSET_Y , DISPLAY_RESX ,
431+ DISPLAY_RESY };
432432 } else {
433- return (SDL_Rect ){EMULATOR_BORDER , EMULATOR_BORDER , DISPLAY_RESX ,
434- DISPLAY_RESY };
433+ return (SDL_FRect ){EMULATOR_BORDER , EMULATOR_BORDER , DISPLAY_RESX ,
434+ DISPLAY_RESY };
435435 }
436436}
437437
@@ -447,8 +447,8 @@ static void display_refresh_internal(void) {
447447#endif
448448
449449 if (drv -> background ) {
450- const SDL_Rect r = {0 , 0 , WINDOW_WIDTH , WINDOW_HEIGHT };
451- SDL_RenderCopy (drv -> renderer , drv -> background , NULL , & r );
450+ const SDL_FRect r = {0 , 0 , WINDOW_WIDTH , WINDOW_HEIGHT };
451+ SDL_RenderTexture (drv -> renderer , drv -> background , NULL , & r );
452452 } else {
453453 SDL_RenderClear (drv -> renderer );
454454 }
@@ -458,13 +458,13 @@ static void display_refresh_internal(void) {
458458#define BACKLIGHT_NORMAL 150
459459 SDL_SetTextureAlphaMod (
460460 drv -> texture , MIN (255 , 255 * drv -> backlight_level / BACKLIGHT_NORMAL ));
461- const SDL_Rect r = screen_rect ();
462- SDL_RenderCopyEx (drv -> renderer , drv -> texture , NULL , & r ,
463- drv -> orientation_angle , NULL , 0 );
461+ const SDL_FRect r = screen_rect ();
462+ SDL_RenderTextureRotated (drv -> renderer , drv -> texture , NULL , & r ,
463+ drv -> orientation_angle , NULL , 0 );
464464
465465 if (drv -> foreground ) {
466- const SDL_Rect fr = {0 , 0 , WINDOW_WIDTH , WINDOW_HEIGHT };
467- SDL_RenderCopy (drv -> renderer , drv -> foreground , NULL , & fr );
466+ const SDL_FRect fr = {0 , 0 , WINDOW_WIDTH , WINDOW_HEIGHT };
467+ SDL_RenderTexture (drv -> renderer , drv -> foreground , NULL , & fr );
468468 }
469469
470470#ifdef USE_RGB_LED
@@ -597,19 +597,20 @@ void display_save(const char *prefix) {
597597 static char filename [256 ];
598598 // take a cropped view of the screen contents
599599 const SDL_Rect rect = {0 , 0 , DISPLAY_RESX , DISPLAY_RESY };
600- SDL_Surface * crop = SDL_CreateRGBSurface (
601- drv -> buffer -> flags , rect .w , rect .h , drv -> buffer -> format -> BitsPerPixel ,
602- drv -> buffer -> format -> Rmask , drv -> buffer -> format -> Gmask ,
603- drv -> buffer -> format -> Bmask , drv -> buffer -> format -> Amask );
600+ SDL_Surface * crop = SDL_CreateSurface (rect .w , rect .h , drv -> buffer -> format );
601+ if (crop == NULL ) {
602+ LOG_ERR ("SDL_CreateSurface failed: %s" , SDL_GetError ());
603+ return ;
604+ }
604605 SDL_BlitSurface (drv -> buffer , & rect , crop , NULL );
605606 // compare with previous screen, skip if equal
606607 if (drv -> prev_saved != NULL ) {
607608 if (memcmp (drv -> prev_saved -> pixels , crop -> pixels , crop -> pitch * crop -> h ) ==
608609 0 ) {
609- SDL_FreeSurface (crop );
610+ SDL_DestroySurface (crop );
610611 return ;
611612 }
612- SDL_FreeSurface (drv -> prev_saved );
613+ SDL_DestroySurface (drv -> prev_saved );
613614 }
614615 // save to png
615616 snprintf (filename , sizeof (filename ), "%s%08d.png" , prefix , count ++ );
@@ -624,7 +625,7 @@ void display_clear_save(void) {
624625 return ;
625626 }
626627
627- SDL_FreeSurface (drv -> prev_saved );
628+ SDL_DestroySurface (drv -> prev_saved );
628629 drv -> prev_saved = NULL ;
629630}
630631
@@ -636,7 +637,7 @@ static void display_draw_suspend_overlay_internal(void) {
636637 return ;
637638 }
638639
639- SDL_Rect screen = screen_rect ();
640+ SDL_FRect screen = screen_rect ();
640641 // create a blue texture
641642 SDL_Texture * overlay =
642643 SDL_CreateTexture (drv -> renderer , SDL_PIXELFORMAT_RGBA8888 ,
@@ -649,24 +650,33 @@ static void display_draw_suspend_overlay_internal(void) {
649650 SDL_RenderClear (drv -> renderer );
650651
651652 // draw the suspend overlay png in the middle of the texture
652- SDL_Texture * suspend_text = IMG_LoadTexture_RW (
653+ SDL_Texture * suspend_text = IMG_LoadTexture_IO (
653654 drv -> renderer ,
654- SDL_RWFromMem (_suspend_overlay_text_data , _suspend_overlay_text_len ), 0 );
655- int text_width , text_height ;
656- SDL_QueryTexture (suspend_text , NULL , NULL , & text_width , & text_height );
657- SDL_Rect middle = {(screen .w - text_width ) / 2 , (screen .h - text_height ) / 2 ,
658- text_width , text_height };
659- SDL_RenderCopy (drv -> renderer , suspend_text , NULL , & middle );
655+ SDL_IOFromMem (_suspend_overlay_text_data , _suspend_overlay_text_len ),
656+ true);
657+ if (suspend_text == NULL ) {
658+ LOG_ERR ("Failed to load suspend overlay texture: %s" , SDL_GetError ());
659+ goto cleanup ;
660+ }
661+ float text_width = 0.0f , text_height = 0.0f ;
662+ if (!SDL_GetTextureSize (suspend_text , & text_width , & text_height )) {
663+ LOG_ERR ("SDL_GetTextureSize failed: %s" , SDL_GetError ());
664+ goto cleanup ;
665+ }
666+ SDL_FRect middle = {(screen .w - text_width ) / 2 , (screen .h - text_height ) / 2 ,
667+ text_width , text_height };
668+ SDL_RenderTexture (drv -> renderer , suspend_text , NULL , & middle );
660669 SDL_RenderPresent (drv -> renderer );
661670
662671 // render to the screen
663672 SDL_SetRenderTarget (drv -> renderer , NULL );
664- SDL_RenderCopy (drv -> renderer , overlay , NULL , & screen );
673+ SDL_RenderTexture (drv -> renderer , overlay , NULL , & screen );
665674 SDL_RenderPresent (drv -> renderer );
666675
667- // cleanup
676+ cleanup :
668677 SDL_DestroyTexture (suspend_text );
669678 SDL_DestroyTexture (overlay );
679+ SDL_SetRenderTarget (drv -> renderer , NULL );
670680 SDL_SetRenderDrawColor (drv -> renderer , 0 , 0 , 0 , 255 );
671681}
672682
0 commit comments