mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
Fix crash when other app prevent us to recreate the primary DirectDraw surface (fix #542)
This commit is contained in:
parent
80501899ca
commit
2de3f7caff
@ -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;
|
||||
if (surf->id != 0) {
|
||||
hr = IDirectDrawSurface2_Restore(surf->id);
|
||||
if (SUCCEEDED(hr))
|
||||
return 0; /* We were able to restore the surface successfully */
|
||||
|
||||
hr = IDirectDrawSurface2_Release(surf->id);
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
surf->id = new_id;
|
||||
|
||||
if (type == DDRAW_SURFACE_PRIMARY) {
|
||||
hr = IDirectDrawSurface_SetClipper(surf->id, ddclipper);
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (type == DDRAW_SURFACE_PRIMARY) {
|
||||
hr = IDirectDrawSurface_SetClipper(surf->id, ddclipper);
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user