sdl: handle activate events
authornotaz <notasas@gmail.com>
Sat, 22 Dec 2012 19:14:50 +0000 (21:14 +0200)
committernotaz <notasas@gmail.com>
Sun, 23 Dec 2012 00:14:35 +0000 (02:14 +0200)
gl.c
plat_sdl.c
plat_sdl.h

diff --git a/gl.c b/gl.c
index 2360a0c..92b39f7 100644 (file)
--- a/gl.c
+++ b/gl.c
@@ -136,22 +136,24 @@ int gl_flip(const void *fb, int w, int h)
 {
        static int old_w, old_h;
 
-       if (w != old_w || h != old_h) {
-               float f_w = (float)w / 1024.0f;
-               float f_h = (float)h / 512.0f;
-               texture[1*2 + 0] = f_w;
-               texture[2*2 + 1] = f_h;
-               texture[3*2 + 0] = f_w;
-               texture[3*2 + 1] = f_h;
-               old_w = w;
-               old_h = h;
+       if (fb != NULL) {
+               if (w != old_w || h != old_h) {
+                       float f_w = (float)w / 1024.0f;
+                       float f_h = (float)h / 512.0f;
+                       texture[1*2 + 0] = f_w;
+                       texture[2*2 + 1] = f_h;
+                       texture[3*2 + 0] = f_w;
+                       texture[3*2 + 1] = f_h;
+                       old_w = w;
+                       old_h = h;
+               }
+
+               glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
+                       GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
+               if (gl_have_error("glTexSubImage2D"))
+                       return -1;
        }
 
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
-               GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
-       if (gl_have_error("glTexSubImage2D"))
-               return -1;
-
        glVertexPointer(3, GL_FLOAT, 0, vertices);
        glTexCoordPointer(2, GL_FLOAT, 0, texture);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
index c5cf64c..609d267 100644 (file)
@@ -31,7 +31,8 @@ static int old_fullscreen;
 static int vout_mode_overlay = -1, vout_mode_gl = -1;
 static void *display, *window;
 
-int plat_sdl_change_video_mode(int w, int h)
+/* w, h is layer resolution */
+int plat_sdl_change_video_mode(int w, int h, int force)
 {
   static int prev_w, prev_h;
 
@@ -44,6 +45,13 @@ int plat_sdl_change_video_mode(int w, int h)
   else
     prev_h = h;
 
+  // skip GL recreation if window doesn't change - avoids flicker
+  if (plat_target.vout_method == vout_mode_gl && plat_sdl_gl_active
+      && plat_target.vout_fullscreen == old_fullscreen && !force)
+  {
+    return 0;
+  }
+
   if (plat_sdl_overlay != NULL) {
     SDL_FreeYUVOverlay(plat_sdl_overlay);
     plat_sdl_overlay = NULL;
@@ -111,6 +119,7 @@ int plat_sdl_change_video_mode(int w, int h)
 
 void plat_sdl_event_handler(void *event_)
 {
+  static int was_active;
   SDL_Event *event = event_;
 
   if (event->type == SDL_VIDEORESIZE) {
@@ -120,8 +129,21 @@ void plat_sdl_event_handler(void *event_)
     {
       window_w = event->resize.w;
       window_h = event->resize.h;
-      plat_sdl_change_video_mode(0, 0);
+      plat_sdl_change_video_mode(0, 0, 1);
+    }
+  }
+  else if (event->type == SDL_ACTIVEEVENT) {
+    if (event->active.gain && !was_active) {
+      if (plat_sdl_overlay != NULL) {
+        SDL_Rect dstrect = { 0, 0, plat_sdl_screen->w, plat_sdl_screen->h };
+        SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect);
+      }
+      else if (plat_sdl_gl_active) {
+        gl_flip(NULL, 0, 0);
+      }
+      // else SDL takes care of it
     }
+    was_active = event->active.gain;
   }
 }
 
@@ -158,7 +180,7 @@ int plat_sdl_init(void)
       g_menuscreen_h = h;
   }
 
-  ret = plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h);
+  ret = plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 1);
   if (ret != 0) {
     plat_sdl_screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE);
     if (plat_sdl_screen == NULL) {
index c22561d..15eeed9 100644 (file)
@@ -5,7 +5,7 @@ extern SDL_Overlay *plat_sdl_overlay;
 extern int plat_sdl_gl_active;
 
 int plat_sdl_init(void);
-int plat_sdl_change_video_mode(int w, int h);
+int plat_sdl_change_video_mode(int w, int h, int force);
 void plat_sdl_overlay_clear(void);
 void plat_sdl_event_handler(void *event_);
 void plat_sdl_finish(void);