@@ -128,6 +128,10 @@ struct key_map_entry key_map[] = {
128128
129129struct display_info {
130130 struct gpu_resource resource ;
131+ struct gpu_resource cursor ;
132+ int cursor_x , cursor_y ;
133+ uint32_t cursor_sdl_format ;
134+ int render_type ;
131135 uint32_t sdl_format ;
132136 SDL_mutex * img_mtx ;
133137 SDL_cond * img_cond ;
@@ -203,6 +207,7 @@ static int window_thread(void *data)
203207{
204208 struct display_info * display = (struct display_info * ) data ;
205209 struct gpu_resource * resource = & display -> resource ;
210+ struct gpu_resource * cursor = & display -> cursor ;
206211
207212 /* Create SDL window */
208213 display -> window = SDL_CreateWindow ("semu" , SDL_WINDOWPOS_UNDEFINED ,
@@ -232,6 +237,8 @@ static int window_thread(void *data)
232237 ((struct display_info * ) data )-> ev_thread =
233238 SDL_CreateThread (event_thread , NULL , data );
234239
240+ SDL_Texture * cursor_texture = NULL ;
241+
235242 while (1 ) {
236243 SDL_LockMutex (display -> img_mtx );
237244
@@ -240,15 +247,40 @@ static int window_thread(void *data)
240247 SDL_COND_TIMEOUT ))
241248 ;
242249
243- /* Render image */
244- display -> surface = SDL_CreateRGBSurfaceWithFormatFrom (
245- resource -> image , resource -> width , resource -> height ,
246- resource -> bits_per_pixel , resource -> stride , display -> sdl_format );
247- display -> texture =
248- SDL_CreateTextureFromSurface (display -> renderer , display -> surface );
249- SDL_RenderCopy (display -> renderer , display -> texture , NULL , NULL );
250- SDL_RenderPresent (display -> renderer );
251- SDL_DestroyTexture (display -> texture );
250+ if (display -> render_type == RENDER_PRIMARY_PLANE ) {
251+ /* Render main plane */
252+ display -> surface = SDL_CreateRGBSurfaceWithFormatFrom (
253+ resource -> image , resource -> width , resource -> height ,
254+ resource -> bits_per_pixel , resource -> stride ,
255+ display -> sdl_format );
256+ display -> texture = SDL_CreateTextureFromSurface (display -> renderer ,
257+ display -> surface );
258+ SDL_RenderCopy (display -> renderer , display -> texture , NULL , NULL );
259+ SDL_RenderPresent (display -> renderer );
260+ SDL_DestroyTexture (display -> texture );
261+ SDL_FreeSurface (display -> surface );
262+ } else if (display -> render_type == RENDER_CURSOR_PLANE ) {
263+ SDL_Rect cursor_rect = {
264+ .x = display -> cursor_x ,
265+ .y = display -> cursor_y ,
266+ .w = cursor -> width ,
267+ .h = cursor -> height ,
268+ };
269+
270+ display -> surface = SDL_CreateRGBSurfaceWithFormatFrom (
271+ cursor -> image , cursor -> width , cursor -> height ,
272+ cursor -> bits_per_pixel , cursor -> stride ,
273+ display -> cursor_sdl_format );
274+
275+ cursor_texture = SDL_CreateTextureFromSurface (display -> renderer ,
276+ display -> surface );
277+ SDL_SetTextureBlendMode (display -> texture , SDL_BLENDMODE_BLEND );
278+ SDL_RenderCopy (display -> renderer , cursor_texture , NULL ,
279+ & cursor_rect );
280+ SDL_RenderPresent (display -> renderer );
281+ SDL_DestroyTexture (cursor_texture );
282+ SDL_FreeSurface (display -> surface );
283+ }
252284
253285 SDL_UnlockMutex (display -> img_mtx );
254286 }
@@ -314,6 +346,39 @@ static bool virtio_gpu_to_sdl_format(uint32_t virtio_gpu_format,
314346 }
315347}
316348
349+ void cursor_update (struct gpu_resource * resource , int scanout_id , int x , int y )
350+ {
351+ displays [scanout_id ].render_type = RENDER_CURSOR_PLANE ;
352+ displays [scanout_id ].cursor_x = x ;
353+ displays [scanout_id ].cursor_y = y ;
354+
355+ /* Resource update */
356+ memcpy (& displays [scanout_id ].cursor , resource , sizeof (struct gpu_resource ));
357+
358+ /* TODO: Cursor image copy (which involves stride calculation, ARGB
359+ * ordering, etc.) Without saving the cursor image properlly, the cursor can
360+ * not be rendered correctly on the screen. The user should currently only
361+ * expect to see a black square moving on the screen) */
362+
363+ bool legal_format = virtio_gpu_to_sdl_format (
364+ resource -> format , & displays [scanout_id ].cursor_sdl_format );
365+
366+ if (legal_format ) {
367+ SDL_CondSignal (displays [scanout_id ].img_cond );
368+ } else {
369+ exit (2 );
370+ }
371+ }
372+
373+ void cursor_move (int scanout_id , int x , int y )
374+ {
375+ displays [scanout_id ].render_type = RENDER_CURSOR_PLANE ;
376+ displays [scanout_id ].cursor_x = x ;
377+ displays [scanout_id ].cursor_y = y ;
378+
379+ SDL_CondSignal (displays [scanout_id ].img_cond );
380+ }
381+
317382void window_render (struct gpu_resource * resource )
318383{
319384 int id = resource -> scanout_id ;
0 commit comments