1From c42392c80a7e145999d0a86ae775068451b7963f Mon Sep 17 00:00:00 2001 2From: Jiajian Wu <jair.wu@rock-chips.com> 3Date: Wed, 26 Apr 2023 22:05:53 +0800 4Subject: [PATCH] sdl: sdl_gpu: support screen rotation 5 6Signed-off-by: Jiajian Wu <jair.wu@rock-chips.com> 7--- 8 sdl/sdl_common.c | 43 +++++++++++++++++++++++++++-------- 9 sdl/sdl_gpu.c | 59 ++++++++++++++++++++++++++++++++++++++++++------ 10 2 files changed, 85 insertions(+), 17 deletions(-) 11 12diff --git a/sdl/sdl_common.c b/sdl/sdl_common.c 13index b34c7fee..b35bd83b 100644 14--- a/sdl/sdl_common.c 15+++ b/sdl/sdl_common.c 16@@ -38,6 +38,7 @@ static char buf[KEYBOARD_BUFFER_SIZE]; 17 /********************** 18 * GLOBAL FUNCTIONS 19 **********************/ 20+extern int monitor_rotated(void); 21 /** 22 * Get the current position and state of the mouse 23 * @param indev_drv pointer to the related input device driver 24@@ -113,6 +114,8 @@ int quit_filter(void * userdata, SDL_Event * event) 25 26 void mouse_handler(SDL_Event * event) 27 { 28+ int rotated = monitor_rotated(); 29+ int16_t x, y; 30 switch(event->type) { 31 case SDL_MOUSEBUTTONUP: 32 if(event->button.button == SDL_BUTTON_LEFT) 33@@ -121,31 +124,51 @@ void mouse_handler(SDL_Event * event) 34 case SDL_MOUSEBUTTONDOWN: 35 if(event->button.button == SDL_BUTTON_LEFT) { 36 left_button_down = true; 37- last_x = event->motion.x / SDL_ZOOM; 38- last_y = event->motion.y / SDL_ZOOM; 39+ x = event->motion.x / SDL_ZOOM; 40+ y = event->motion.y / SDL_ZOOM; 41 } 42 break; 43 case SDL_MOUSEMOTION: 44- last_x = event->motion.x / SDL_ZOOM; 45- last_y = event->motion.y / SDL_ZOOM; 46+ x = event->motion.x / SDL_ZOOM; 47+ y = event->motion.y / SDL_ZOOM; 48 break; 49 50 case SDL_FINGERUP: 51 left_button_down = false; 52- last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 53- last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 54+ x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 55+ y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 56 break; 57 case SDL_FINGERDOWN: 58 left_button_down = true; 59- last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 60- last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 61+ x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 62+ y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 63 break; 64 case SDL_FINGERMOTION: 65- last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 66- last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 67+ x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; 68+ y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; 69 break; 70 } 71 72+ switch (rotated) 73+ { 74+ case LV_DISP_ROT_NONE: 75+ default: 76+ last_x = x; 77+ last_y = y; 78+ break; 79+ case LV_DISP_ROT_90: 80+ last_x = y; 81+ last_y = LV_VER_RES - x; 82+ break; 83+ case LV_DISP_ROT_180: 84+ last_x = LV_HOR_RES - x; 85+ last_y = LV_VER_RES - y; 86+ break; 87+ case LV_DISP_ROT_270: 88+ last_x = LV_HOR_RES - y; 89+ last_y = x; 90+ break; 91+ } 92 } 93 94 95diff --git a/sdl/sdl_gpu.c b/sdl/sdl_gpu.c 96index 51ce536c..f7960bec 100644 97--- a/sdl/sdl_gpu.c 98+++ b/sdl/sdl_gpu.c 99@@ -50,8 +50,11 @@ typedef struct { 100 lv_draw_sdl_drv_param_t drv_param; 101 lv_coord_t hor_res; 102 lv_coord_t ver_res; 103+ lv_coord_t d_hor_res; 104+ lv_coord_t d_ver_res; 105 SDL_Window * window; 106 SDL_Texture * texture; 107+ int rotated; 108 }monitor_t; 109 110 /********************** 111@@ -93,17 +96,20 @@ void sdl_init(void) 112 113 void sdl_disp_drv_init(lv_disp_drv_t * disp_drv, lv_coord_t hor_res, lv_coord_t ver_res) 114 { 115+ int rotated = disp_drv->rotated <= LV_DISP_ROT_270 ? disp_drv->rotated : LV_DISP_ROT_NONE; 116 monitor_t *m = lv_mem_alloc(sizeof(monitor_t)); 117 m->hor_res = hor_res; 118 m->ver_res = ver_res; 119+ m->rotated = rotated; 120 window_create(m); 121 hor_res = m->hor_res; 122 ver_res = m->ver_res; 123 lv_disp_drv_init(disp_drv); 124 disp_drv->direct_mode = 1; 125 disp_drv->flush_cb = monitor_flush; 126- disp_drv->hor_res = hor_res; 127- disp_drv->ver_res = ver_res; 128+ disp_drv->hor_res = m->d_hor_res; 129+ disp_drv->ver_res = m->d_ver_res; 130+ disp_drv->rotated = LV_DISP_ROT_NONE; 131 lv_disp_draw_buf_t *disp_buf = lv_mem_alloc(sizeof(lv_disp_draw_buf_t)); 132 lv_disp_draw_buf_init(disp_buf, m->texture, NULL, hor_res * ver_res); 133 disp_drv->draw_buf = disp_buf; 134@@ -144,14 +150,25 @@ void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_colo 135 void sdl_display_resize(lv_disp_t *disp, int width, int height) 136 { 137 lv_disp_drv_t *driver = disp->driver; 138+ monitor_t *m = (monitor_t *)driver->user_data; 139 SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) driver->user_data)->renderer; 140 if (driver->draw_buf->buf1) { 141 SDL_DestroyTexture(driver->draw_buf->buf1); 142 } 143- SDL_Texture *texture = lv_draw_sdl_create_screen_texture(renderer, width, height); 144+ if (m->rotated == LV_DISP_ROT_90 || 145+ m->rotated == LV_DISP_ROT_270) { 146+ m->d_hor_res = height; 147+ m->d_ver_res = width; 148+ } else { 149+ m->d_hor_res = width; 150+ m->d_ver_res = height; 151+ } 152+ m->hor_res = width; 153+ m->ver_res = height; 154+ SDL_Texture *texture = lv_draw_sdl_create_screen_texture(renderer, m->d_hor_res, m->d_ver_res); 155 lv_disp_draw_buf_init(driver->draw_buf, texture, NULL, width * height); 156- driver->hor_res = (lv_coord_t) width; 157- driver->ver_res = (lv_coord_t) height; 158+ driver->hor_res = (lv_coord_t) m->d_hor_res; 159+ driver->ver_res = (lv_coord_t) m->d_ver_res; 160 SDL_RendererInfo renderer_info; 161 SDL_GetRendererInfo(renderer, &renderer_info); 162 SDL_assert(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE); 163@@ -233,6 +250,20 @@ static void sdl_event_handler(lv_timer_t * t) 164 } 165 } 166 167+int monitor_rotated(void) 168+{ 169+ int rotated = LV_DISP_ROT_NONE; 170+ 171+ lv_disp_t *cur = lv_disp_get_next(NULL); 172+ if (cur) { 173+ lv_disp_t * tmp = cur; 174+ monitor_t * m = tmp->driver->user_data; 175+ rotated = m->rotated; 176+ } 177+ 178+ return rotated; 179+} 180+ 181 static void monitor_sdl_clean_up(void) 182 { 183 for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; ) { 184@@ -258,6 +289,15 @@ static void window_create(monitor_t * m) 185 m->ver_res = rect.h; 186 } 187 188+ if (m->rotated == LV_DISP_ROT_90 || 189+ m->rotated == LV_DISP_ROT_270) { 190+ m->d_hor_res = m->ver_res; 191+ m->d_ver_res = m->hor_res; 192+ } else { 193+ m->d_hor_res = m->hor_res; 194+ m->d_ver_res = m->ver_res; 195+ } 196+ 197 m->window = SDL_CreateWindow("TFT Simulator", 198 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 199 m->hor_res * SDL_ZOOM, m->ver_res * SDL_ZOOM, 200@@ -265,7 +305,7 @@ static void window_create(monitor_t * m) 201 202 m->drv_param.renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_ACCELERATED); 203 204- m->texture = lv_draw_sdl_create_screen_texture(m->drv_param.renderer, m->hor_res, m->ver_res); 205+ m->texture = lv_draw_sdl_create_screen_texture(m->drv_param.renderer, m->d_hor_res, m->d_ver_res); 206 /* For first frame */ 207 SDL_SetRenderTarget(m->drv_param.renderer, m->texture); 208 } 209@@ -275,6 +315,7 @@ static void window_update(lv_disp_drv_t *disp_drv, void * buf) 210 SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) disp_drv->user_data)->renderer; 211 monitor_t *m = (monitor_t *)disp_drv->user_data; 212 SDL_Texture *texture = buf; 213+ SDL_Rect dst; 214 SDL_SetRenderTarget(renderer, NULL); 215 SDL_RenderClear(renderer); 216 #if LV_COLOR_SCREEN_TRANSP 217@@ -284,10 +325,14 @@ static void window_update(lv_disp_drv_t *disp_drv, void * buf) 218 SDL_RenderDrawRect(renderer, &r); 219 #endif 220 221+ dst.x = (m->hor_res - m->d_hor_res) / 2; 222+ dst.y = (m->ver_res - m->d_ver_res) / 2; 223+ dst.w = m->d_hor_res; 224+ dst.h = m->d_ver_res; 225 /*Update the renderer with the texture containing the rendered image*/ 226 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); 227 SDL_RenderSetClipRect(renderer, NULL); 228- SDL_RenderCopy(renderer, texture, NULL, NULL); 229+ SDL_RenderCopyEx(renderer, texture, NULL, &dst, 90.0 * m->rotated, NULL, SDL_FLIP_NONE); 230 SDL_RenderPresent(renderer); 231 SDL_SetRenderTarget(renderer, texture); 232 } 233-- 2342.25.1 235 236