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