[aseprite] 71/134: Fix crash when other app prevent us to recreate the primary DirectDraw surface (fix #542)

Tobias Hansen thansen at moszumanska.debian.org
Sat Mar 14 17:10:08 UTC 2015


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 2de3f7caff5422d5fe9f23a456cfc215d99555cf
Author: David Capello <davidcapello at gmail.com>
Date:   Mon Nov 24 20:24:28 2014 -0300

    Fix crash when other app prevent us to recreate the primary DirectDraw surface (fix #542)
---
 src/allegro/src/win/wddbmp.c | 53 +++++++++++++++++++++++++-------------------
 src/allegro/src/win/wddwin.c | 21 +++++++++++++-----
 src/allegro/src/win/wmouse.c |  8 +++++++
 3 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/src/allegro/src/win/wddbmp.c b/src/allegro/src/win/wddbmp.c
index 01f7a0a..3d55265 100644
--- a/src/allegro/src/win/wddbmp.c
+++ b/src/allegro/src/win/wddbmp.c
@@ -307,34 +307,41 @@ void gfx_directx_destroy_surface(DDRAW_SURFACE *surf)
 
 int gfx_directx_restore_surface(DDRAW_SURFACE *surf)
 {
+  LPDIRECTDRAWSURFACE2 new_id;
   int type = (surf->flags & DDRAW_SURFACE_TYPE_MASK);
   HRESULT hr;
 
-   hr = IDirectDrawSurface2_Restore(surf->id);
-   if (FAILED(hr)) {
-     LPDIRECTDRAWSURFACE2 new_id;
-
-     hr = IDirectDrawSurface2_Release(surf->id);
-     if (FAILED(hr))
-       return -1;
-
-     new_id = create_directdraw2_surface(
-       surf->w, surf->h, ddpixel_format, type, 0);
-     if (!new_id) {
-       surf->id = 0;
-       return -1;
-     }
+  if (surf->id != 0) {
+    hr = IDirectDrawSurface2_Restore(surf->id);
+    if (SUCCEEDED(hr))
+      return 0; /* We were able to restore the surface successfully */
 
-     surf->id = new_id;
-
-     if (type == DDRAW_SURFACE_PRIMARY) {
-       hr = IDirectDrawSurface_SetClipper(surf->id, ddclipper);
-       if (FAILED(hr))
-         return -1;
-     }
-   }
+    hr = IDirectDrawSurface2_Release(surf->id);
+    if (FAILED(hr))
+      return -1;
+  }
+
+  /* In this case, the surface must be recreated because:
+     1) We weren't able to restore it with IDirectDrawSurface2_Restore()
+     2) We weren't able to re-create it in a previous
+        gfx_directx_restore_surface() call
+   */
+  new_id = create_directdraw2_surface(
+    surf->w, surf->h, ddpixel_format, type, 0);
+  if (!new_id) {
+    surf->id = 0;
+    return -1;
+  }
+
+  surf->id = new_id;
+
+  if (type == DDRAW_SURFACE_PRIMARY) {
+    hr = IDirectDrawSurface_SetClipper(surf->id, ddclipper);
+    if (FAILED(hr))
+      return -1;
+  }
 
-   return 0;
+  return 0;
 }
 
 
diff --git a/src/allegro/src/win/wddwin.c b/src/allegro/src/win/wddwin.c
index 7045f11..3238242 100644
--- a/src/allegro/src/win/wddwin.c
+++ b/src/allegro/src/win/wddwin.c
@@ -207,8 +207,10 @@ static void paint_win(RECT *rect)
    /* we may have lost the DirectDraw surfaces
     * (e.g after the monitor has gone to low power)
     */
-   if (IDirectDrawSurface2_IsLost(gfx_directx_primary_surface->id) == DDERR_SURFACELOST)
+   if (gfx_directx_primary_surface->id == 0 ||
+       IDirectDrawSurface2_IsLost(gfx_directx_primary_surface->id) == DDERR_SURFACELOST) {
       switch_in_win();
+   }
 
    /* clip the rectangle */
    rect->right = MIN(rect->right, gfx_directx_win.w);
@@ -249,9 +251,14 @@ static void update_matching_window(RECT *rect)
    ClientToScreen(allegro_wnd, &dest_rect.p);
    ClientToScreen(allegro_wnd, &dest_rect.p + 1);
 
-   /* blit offscreen backbuffer to the window */
-   IDirectDrawSurface2_Blt(gfx_directx_primary_surface->id, &dest_rect.r,
-                           offscreen_surface->id, rect, 0, NULL);
+   /* Blit offscreen backbuffer to the window.
+      The ID can be 0 when the primary surface is lost and we weren't
+      able to restore & recreate it in gfx_directx_restore_surface().
+    */
+   if (gfx_directx_primary_surface->id != 0) {
+      IDirectDrawSurface2_Blt(gfx_directx_primary_surface->id, &dest_rect.r,
+                              offscreen_surface->id, rect, 0, NULL);
+   }
 
    _exit_gfx_critical();
 }
@@ -372,8 +379,10 @@ static void update_colorconv_window(RECT *rect)
 
    if (direct) {
       /* blit directly to the primary surface without clipping */
-      ddsurf_blit_ex(gfx_directx_primary_surface->id, &dest_rect.r,
-                     offscreen_surface->id, &src_rect);
+      if (gfx_directx_primary_surface->id != 0) {
+         ddsurf_blit_ex(gfx_directx_primary_surface->id, &dest_rect.r,
+            offscreen_surface->id, &src_rect);
+      }
    }
    else {
       /* blit to the window using GDI */
diff --git a/src/allegro/src/win/wmouse.c b/src/allegro/src/win/wmouse.c
index 2c0c1c7..db50c0c 100644
--- a/src/allegro/src/win/wmouse.c
+++ b/src/allegro/src/win/wmouse.c
@@ -10,6 +10,8 @@
 #include "allegro/internal/aintern.h"
 #include "allegro/platform/aintwin.h"
 
+#include "wddraw.h"
+
 #ifndef ALLEGRO_WINDOWS
    #error something is wrong with the makefile
 #endif
@@ -333,6 +335,12 @@ void _al_win_mouse_handle_move(HWND hwnd, int x, int y)
 {
    _enter_critical();
 
+   /* Try to restore the primary surface as soon as possible if we
+      have lost it and were not able to recreate it */
+   if (gfx_directx_primary_surface && gfx_directx_primary_surface->id == 0) {
+     restore_all_ddraw_surfaces();
+   }
+
    _mouse_x = CLAMP(mouse_minx, x, mouse_maxx);
    _mouse_y = CLAMP(mouse_miny, y, mouse_maxy);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list