[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