Changeset - r25364:8533eacddd57
[Not reviewed]
master
0 3 0
Michael Lutz - 3 years ago 2021-05-01 17:55:46
michi@icosahedron.de
Fix #9147: Delay making screenshots until the next draw tick as we may not access the video buffer from the game thread.
3 files changed with 32 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/console_cmds.cpp
Show inline comments
 
@@ -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) {
src/screenshot.cpp
Show inline comments
 
@@ -864,7 +864,7 @@ static ScreenshotType _confirmed_screens
 
 */
 
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(Screensho
 
		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, co
 
	}
 

	
 
	_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, co
 
	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".
src/screenshot.h
Show inline comments
 
@@ -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];
0 comments (0 inline, 0 general)