diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-05-01 19:55:46 +0200 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2021-05-02 17:57:24 +0200 |
commit | 1f159f79de7428cbaa6133ec9cf06ce559980ea6 (patch) | |
tree | ebdfebfbca17f8ab485198b48c473a1138f3be8f | |
parent | 91b8ce073f54dff48cd61186c32d0a720a2abb4d (diff) | |
download | openttd-1f159f79de7428cbaa6133ec9cf06ce559980ea6.tar.xz |
Fix #9147: Delay making screenshots until the next draw tick as we may not access the video buffer from the game thread.
-rw-r--r-- | src/console_cmds.cpp | 2 | ||||
-rw-r--r-- | src/screenshot.cpp | 38 | ||||
-rw-r--r-- | src/screenshot.h | 2 |
3 files changed, 32 insertions, 10 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 69a44e63d..99b3b5458 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1416,7 +1416,7 @@ DEF_CONSOLE_CMD(ConScreenShot) ScreenshotType type = SC_VIEWPORT; uint32 width = 0; uint32 height = 0; - const char *name = nullptr; + std::string name{}; uint32 arg_index = 1; if (argc > arg_index) { diff --git a/src/screenshot.cpp b/src/screenshot.cpp index dc76996fb..0e3bf3d8e 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -864,7 +864,7 @@ static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the curre */ static void ScreenshotConfirmationCallback(Window *w, bool confirmed) { - if (confirmed) MakeScreenshot(_confirmed_screenshot_type, nullptr); + if (confirmed) MakeScreenshot(_confirmed_screenshot_type, {}); } /** @@ -890,24 +890,20 @@ void MakeScreenshotWithConfirm(ScreenshotType t) ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmationCallback); } else { /* Less than 64M pixels, just do it */ - MakeScreenshot(t, nullptr); + MakeScreenshot(t, {}); } } /** * Make a screenshot. - * Unconditionally take a screenshot of the requested type. * @param t the type of screenshot to make. * @param name the name to give to the screenshot. * @param width the width of the screenshot of, or 0 for current viewport width (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM). * @param height the height of the screenshot of, or 0 for current viewport height (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM). * @return true iff the screenshot was made successfully - * @see MakeScreenshotWithConfirm */ -bool MakeScreenshot(ScreenshotType t, const char *name, uint32 width, uint32 height) +static bool RealMakeScreenshot(ScreenshotType t, std::string name, uint32 width, uint32 height) { - VideoDriver::VideoBufferLocker lock; - if (t == SC_VIEWPORT) { /* First draw the dirty parts of the screen and only then change the name * of the screenshot. This way the screenshot will always show the name @@ -918,7 +914,7 @@ bool MakeScreenshot(ScreenshotType t, const char *name, uint32 width, uint32 hei } _screenshot_name[0] = '\0'; - if (name != nullptr) strecpy(_screenshot_name, name, lastof(_screenshot_name)); + if (!name.empty()) strecpy(_screenshot_name, name.c_str(), lastof(_screenshot_name)); bool ret; switch (t) { @@ -969,6 +965,32 @@ bool MakeScreenshot(ScreenshotType t, const char *name, uint32 width, uint32 hei return ret; } +/** + * Schedule making a screenshot. + * Unconditionally take a screenshot of the requested type. + * @param t the type of screenshot to make. + * @param name the name to give to the screenshot. + * @param width the width of the screenshot of, or 0 for current viewport width (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM). + * @param height the height of the screenshot of, or 0 for current viewport height (only works for SC_ZOOMEDIN and SC_DEFAULTZOOM). + * @return true iff the screenshot was successfully made. + * @see MakeScreenshotWithConfirm + */ +bool MakeScreenshot(ScreenshotType t, std::string name, uint32 width, uint32 height) +{ + if (t == SC_CRASHLOG) { + /* Video buffer might or might not be locked. */ + VideoDriver::VideoBufferLocker lock; + + return RealMakeScreenshot(t, name, width, height); + } + + VideoDriver::GetInstance()->QueueOnMainThread([=] { // Capture by value to not break scope. + RealMakeScreenshot(t, name, width, height); + }); + + return true; +} + /** * Return the owner of a tile to display it with in the small map in mode "Owner". diff --git a/src/screenshot.h b/src/screenshot.h index 148c018e1..e65813573 100644 --- a/src/screenshot.h +++ b/src/screenshot.h @@ -28,7 +28,7 @@ enum ScreenshotType { void SetupScreenshotViewport(ScreenshotType t, struct Viewport *vp, uint32 width = 0, uint32 height = 0); bool MakeHeightmapScreenshot(const char *filename); void MakeScreenshotWithConfirm(ScreenshotType t); -bool MakeScreenshot(ScreenshotType t, const char *name, uint32 width = 0, uint32 height = 0); +bool MakeScreenshot(ScreenshotType t, std::string name, uint32 width = 0, uint32 height = 0); bool MakeMinimapWorldScreenshot(); extern char _screenshot_format_name[8]; |