From f133c6b094e0a663fe12a7d11a6ea2656813edf9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Nov 2021 17:35:22 +1100 Subject: Fix crash saving blend files in background mode Reading the windows pixels was attempted in background mode. --- source/blender/windowmanager/intern/wm_files.c | 98 ++++++++++++++------------ 1 file changed, 52 insertions(+), 46 deletions(-) (limited to 'source/blender') diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index b79a5176d4f..a301b17227d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1558,15 +1558,16 @@ static void wm_history_file_update(void) * Screen-shot the active window. * \{ */ -static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_thumb) { - if (*thumb_pt) { - /* We are given a valid thumbnail data, so just generate image from it. */ - return BKE_main_thumbnail_to_imbuf(NULL, *thumb_pt); + *r_thumb = NULL; + + wmWindow *win = CTX_wm_window(C); + if (G.background || (win == NULL)) { + return NULL; } /* The window to capture should be a main window (without parent). */ - wmWindow *win = CTX_wm_window(C); while (win && win->parent) { win = win->parent; } @@ -1595,7 +1596,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); IMB_freeImBuf(thumb_ibuf); - *thumb_pt = thumb; + *r_thumb = thumb; } /* Must be freed by caller. */ @@ -1614,8 +1615,15 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu static ImBuf *blend_file_thumb_from_camera(const bContext *C, Scene *scene, bScreen *screen, - BlendThumbnail **thumb_pt) + BlendThumbnail **r_thumb) { + *r_thumb = NULL; + + /* Scene can be NULL if running a script at startup and calling the save operator. */ + if (G.background || scene == NULL) { + return NULL; + } + /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; BlendThumbnail *thumb; @@ -1629,17 +1637,6 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, ARegion *region = NULL; View3D *v3d = NULL; - /* In case we are given a valid thumbnail data, just generate image from it. */ - if (*thumb_pt) { - thumb = *thumb_pt; - return BKE_main_thumbnail_to_imbuf(NULL, thumb); - } - - /* scene can be NULL if running a script at startup and calling the save operator */ - if (G.background || scene == NULL) { - return NULL; - } - if (screen != NULL) { area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); if (area) { @@ -1713,13 +1710,13 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, IMB_scaleImBuf(ibuf, PREVIEW_RENDER_LARGE_HEIGHT, PREVIEW_RENDER_LARGE_HEIGHT); } else { - /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ + /* '*r_thumb' needs to stay NULL to prevent a bad thumbnail from being handled. */ CLOG_WARN(&LOG, "failed to create thumbnail: %s", err_out); thumb = NULL; } /* must be freed by caller */ - *thumb_pt = thumb; + *r_thumb = thumb; return ibuf; } @@ -1752,7 +1749,7 @@ static bool wm_file_write(bContext *C, Main *bmain = CTX_data_main(C); int len; int ok = false; - BlendThumbnail *thumb, *main_thumb; + BlendThumbnail *thumb = NULL, *main_thumb = NULL; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); @@ -1802,33 +1799,42 @@ static bool wm_file_write(bContext *C, /* don't forget not to return without! */ WM_cursor_wait(true); - /* blend file thumbnail */ - /* Save before exit_editmode, otherwise derivedmeshes for shared data corrupt T27765. */ - /* Main now can store a '.blend' thumbnail, useful for background mode - * or thumbnail customization. */ - main_thumb = thumb = bmain->blen_thumb; - if (BLI_thread_is_main() && U.file_preview_type != USER_FILE_PREVIEW_NONE) { - - int file_preview_type = U.file_preview_type; - - if (file_preview_type == USER_FILE_PREVIEW_AUTO) { - Scene *scene = CTX_data_scene(C); - bool do_render = (scene != NULL && scene->camera != NULL && - (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL)); - file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT; - } - - switch (file_preview_type) { - case USER_FILE_PREVIEW_SCREENSHOT: { - ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb); - break; + if (U.file_preview_type != USER_FILE_PREVIEW_NONE) { + /* Blend file thumbnail. + * + * - Save before exiting edit-mode, otherwise evaluated-mesh for shared data gets corrupted. + * See T27765. + * - Main can store a '.blend' thumbnail, + * useful for background-mode or thumbnail customization. + */ + main_thumb = thumb = bmain->blen_thumb; + if (thumb != NULL) { + /* In case we are given a valid thumbnail data, just generate image from it. */ + ibuf_thumb = BKE_main_thumbnail_to_imbuf(NULL, thumb); + } + else if (BLI_thread_is_main()) { + int file_preview_type = U.file_preview_type; + + if (file_preview_type == USER_FILE_PREVIEW_AUTO) { + Scene *scene = CTX_data_scene(C); + bool do_render = (scene != NULL && scene->camera != NULL && + (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL)); + file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT; } - case USER_FILE_PREVIEW_CAMERA: { - ibuf_thumb = blend_file_thumb_from_camera(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); - break; + + switch (file_preview_type) { + case USER_FILE_PREVIEW_SCREENSHOT: { + ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb); + break; + } + case USER_FILE_PREVIEW_CAMERA: { + ibuf_thumb = blend_file_thumb_from_camera( + C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); + break; + } + default: + BLI_assert_unreachable(); } - default: - BLI_assert_unreachable(); } } -- cgit v1.2.3