]> Git Repo - qemu.git/blobdiff - ui/sdl2.c
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-220615-3' into staging
[qemu.git] / ui / sdl2.c
index 59b67a6b3cfac7678ae79958d8a143e454c3b71c..5cb75aa364090aa5f1c90d3c8cea422c3c1ce548 100644 (file)
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
  */
 /* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
 
-/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */
-#undef WIN32_LEAN_AND_MEAN
-
-#include <SDL.h>
-#include <SDL_syswm.h>
-
 #include "qemu-common.h"
 #include "ui/console.h"
 #include "ui/input.h"
@@ -68,7 +62,7 @@ static struct sdl2_console *get_scon_from_window(uint32_t window_id)
     return NULL;
 }
 
-static void sdl2_window_create(struct sdl2_console *scon)
+void sdl2_window_create(struct sdl2_console *scon)
 {
     int flags = 0;
 
@@ -92,10 +86,13 @@ static void sdl2_window_create(struct sdl2_console *scon)
                                          surface_height(scon->surface),
                                          flags);
     scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
+    if (scon->opengl) {
+        scon->winctx = SDL_GL_GetCurrentContext();
+    }
     sdl_update_caption(scon);
 }
 
-static void sdl2_window_destroy(struct sdl2_console *scon)
+void sdl2_window_destroy(struct sdl2_console *scon)
 {
     if (!scon->real_window) {
         return;
@@ -107,7 +104,7 @@ static void sdl2_window_destroy(struct sdl2_console *scon)
     scon->real_window = NULL;
 }
 
-static void sdl2_window_resize(struct sdl2_console *scon)
+void sdl2_window_resize(struct sdl2_console *scon)
 {
     if (!scon->real_window) {
         return;
@@ -118,46 +115,15 @@ static void sdl2_window_resize(struct sdl2_console *scon)
                       surface_height(scon->surface));
 }
 
-static void sdl_switch(DisplayChangeListener *dcl,
-                       DisplaySurface *new_surface)
+static void sdl2_redraw(struct sdl2_console *scon)
 {
-    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-    DisplaySurface *old_surface = scon->surface;
-    int format = 0;
-
-    scon->surface = new_surface;
-
-    if (scon->texture) {
-        SDL_DestroyTexture(scon->texture);
-        scon->texture = NULL;
-    }
-
-    if (!new_surface) {
-        sdl2_window_destroy(scon);
-        return;
+    if (scon->opengl) {
+#ifdef CONFIG_OPENGL
+        sdl2_gl_redraw(scon);
+#endif
+    } else {
+        sdl2_2d_redraw(scon);
     }
-
-    if (!scon->real_window) {
-        sdl2_window_create(scon);
-    } else if (old_surface &&
-               ((surface_width(old_surface)  != surface_width(new_surface)) ||
-                (surface_height(old_surface) != surface_height(new_surface)))) {
-        sdl2_window_resize(scon);
-    }
-
-    SDL_RenderSetLogicalSize(scon->real_renderer,
-                             surface_width(new_surface),
-                             surface_height(new_surface));
-
-    if (surface_bits_per_pixel(scon->surface) == 16) {
-        format = SDL_PIXELFORMAT_RGB565;
-    } else if (surface_bits_per_pixel(scon->surface) == 32) {
-        format = SDL_PIXELFORMAT_ARGB8888;
-    }
-    scon->texture = SDL_CreateTexture(scon->real_renderer, format,
-                                      SDL_TEXTUREACCESS_STREAMING,
-                                      surface_width(new_surface),
-                                      surface_height(new_surface));
 }
 
 static void sdl_update_caption(struct sdl2_console *scon)
@@ -358,8 +324,7 @@ static void toggle_full_screen(struct sdl2_console *scon)
         }
         SDL_SetWindowFullscreen(scon->real_window, 0);
     }
-    graphic_hw_invalidate(scon->dcl.con);
-    graphic_hw_update(scon->dcl.con);
+    sdl2_redraw(scon);
 }
 
 static void handle_keydown(SDL_Event *ev)
@@ -407,8 +372,10 @@ static void handle_keydown(SDL_Event *ev)
         case SDL_SCANCODE_U:
             sdl2_window_destroy(scon);
             sdl2_window_create(scon);
-            graphic_hw_invalidate(scon->dcl.con);
-            graphic_hw_update(scon->dcl.con);
+            if (!scon->opengl) {
+                /* re-create scon->texture */
+                sdl2_2d_switch(&scon->dcl, scon->surface);
+            }
             gui_keysym = 1;
             break;
 #if 0
@@ -427,8 +394,7 @@ static void handle_keydown(SDL_Event *ev)
                 fprintf(stderr, "%s: scale to %dx%d\n",
                         __func__, width, height);
                 sdl_scale(scon, width, height);
-                graphic_hw_invalidate(NULL);
-                graphic_hw_update(NULL);
+                sdl2_redraw(scon);
                 gui_keysym = 1;
             }
 #endif
@@ -551,10 +517,13 @@ static void handle_mousewheel(SDL_Event *ev)
     qemu_input_event_sync();
 }
 
-static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
+static void handle_windowevent(SDL_Event *ev)
 {
-    int w, h;
-    struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
+    struct sdl2_console *scon = get_scon_from_window(ev->window.windowID);
+
+    if (!scon) {
+        return;
+    }
 
     switch (ev->window.event) {
     case SDL_WINDOWEVENT_RESIZED:
@@ -565,12 +534,10 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
             info.height = ev->window.data2;
             dpy_set_ui_info(scon->dcl.con, &info);
         }
-        graphic_hw_invalidate(scon->dcl.con);
-        graphic_hw_update(scon->dcl.con);
+        sdl2_redraw(scon);
         break;
     case SDL_WINDOWEVENT_EXPOSED:
-        SDL_GetWindowSize(SDL_GetWindowFromID(ev->window.windowID), &w, &h);
-        sdl2_2d_update(dcl, 0, 0, w, h);
+        sdl2_redraw(scon);
         break;
     case SDL_WINDOWEVENT_FOCUS_GAINED:
     case SDL_WINDOWEVENT_ENTER:
@@ -584,10 +551,10 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
         }
         break;
     case SDL_WINDOWEVENT_RESTORED:
-        update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
+        update_displaychangelistener(&scon->dcl, GUI_REFRESH_INTERVAL_DEFAULT);
         break;
     case SDL_WINDOWEVENT_MINIMIZED:
-        update_displaychangelistener(dcl, 500);
+        update_displaychangelistener(&scon->dcl, 500);
         break;
     case SDL_WINDOWEVENT_CLOSE:
         if (!no_quit) {
@@ -595,12 +562,21 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
             qemu_system_shutdown_request();
         }
         break;
+    case SDL_WINDOWEVENT_SHOWN:
+        if (scon->hidden) {
+            SDL_HideWindow(scon->real_window);
+        }
+        break;
+    case SDL_WINDOWEVENT_HIDDEN:
+        if (!scon->hidden) {
+            SDL_ShowWindow(scon->real_window);
+        }
+        break;
     }
 }
 
-static void sdl_refresh(DisplayChangeListener *dcl)
+void sdl2_poll_events(struct sdl2_console *scon)
 {
-    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
     SDL_Event ev1, *ev = &ev1;
 
     if (scon->last_vm_running != runstate_is_running()) {
@@ -608,8 +584,6 @@ static void sdl_refresh(DisplayChangeListener *dcl)
         sdl_update_caption(scon);
     }
 
-    graphic_hw_update(dcl->con);
-
     while (SDL_PollEvent(ev)) {
         switch (ev->type) {
         case SDL_KEYDOWN:
@@ -638,7 +612,7 @@ static void sdl_refresh(DisplayChangeListener *dcl)
             handle_mousewheel(ev);
             break;
         case SDL_WINDOWEVENT:
-            handle_windowevent(dcl, ev);
+            handle_windowevent(ev);
             break;
         default:
             break;
@@ -708,14 +682,44 @@ static void sdl_cleanup(void)
 }
 
 static const DisplayChangeListenerOps dcl_2d_ops = {
-    .dpy_name          = "sdl2-2d",
-    .dpy_gfx_update    = sdl2_2d_update,
-    .dpy_gfx_switch    = sdl_switch,
-    .dpy_refresh       = sdl_refresh,
-    .dpy_mouse_set     = sdl_mouse_warp,
-    .dpy_cursor_define = sdl_mouse_define,
+    .dpy_name             = "sdl2-2d",
+    .dpy_gfx_update       = sdl2_2d_update,
+    .dpy_gfx_switch       = sdl2_2d_switch,
+    .dpy_gfx_check_format = sdl2_2d_check_format,
+    .dpy_refresh          = sdl2_2d_refresh,
+    .dpy_mouse_set        = sdl_mouse_warp,
+    .dpy_cursor_define    = sdl_mouse_define,
 };
 
+#ifdef CONFIG_OPENGL
+static const DisplayChangeListenerOps dcl_gl_ops = {
+    .dpy_name                = "sdl2-gl",
+    .dpy_gfx_update          = sdl2_gl_update,
+    .dpy_gfx_switch          = sdl2_gl_switch,
+    .dpy_gfx_check_format    = console_gl_check_format,
+    .dpy_refresh             = sdl2_gl_refresh,
+    .dpy_mouse_set           = sdl_mouse_warp,
+    .dpy_cursor_define       = sdl_mouse_define,
+};
+#endif
+
+void sdl_display_early_init(int opengl)
+{
+    switch (opengl) {
+    case -1: /* default */
+    case 0:  /* off */
+        break;
+    case 1: /* on */
+#ifdef CONFIG_OPENGL
+        display_opengl = 1;
+#endif
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+}
+
 void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
 {
     int flags;
@@ -761,10 +765,16 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
         if (!qemu_console_is_graphic(con)) {
             sdl2_console[i].hidden = true;
         }
+        sdl2_console[i].idx = i;
+#ifdef CONFIG_OPENGL
+        sdl2_console[i].opengl = display_opengl;
+        sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;
+#else
+        sdl2_console[i].opengl = 0;
         sdl2_console[i].dcl.ops = &dcl_2d_ops;
+#endif
         sdl2_console[i].dcl.con = con;
         register_displaychangelistener(&sdl2_console[i].dcl);
-        sdl2_console[i].idx = i;
     }
 
     /* Load a 32x32x4 image. White pixels are transparent. */
This page took 0.031242 seconds and 4 git commands to generate.