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