System: Render save state screenshots at fixed resolution

Fixes delays when saving state at high internal resolution.
This commit is contained in:
Connor McLaughlin
2021-04-28 02:37:52 +10:00
parent 67adc986ab
commit c2916e0719
5 changed files with 80 additions and 34 deletions

View File

@ -1224,7 +1224,7 @@ bool DoLoadState(ByteStream* state, bool force_software_renderer, bool update_di
return true;
}
bool SaveState(ByteStream* state, u32 screenshot_size /* = 128 */)
bool SaveState(ByteStream* state, u32 screenshot_size /* = 256 */)
{
if (IsShutdown())
return false;
@ -1254,17 +1254,45 @@ bool SaveState(ByteStream* state, u32 screenshot_size /* = 128 */)
// save screenshot
if (screenshot_size > 0)
{
// assume this size is the width
HostDisplay* display = g_host_interface->GetDisplay();
const float display_aspect_ratio = display->GetDisplayAspectRatio();
const u32 screenshot_width = screenshot_size;
const u32 screenshot_height =
std::max(1u, static_cast<u32>(static_cast<float>(screenshot_width) /
((display_aspect_ratio > 0.0f) ? display_aspect_ratio : 1.0f)));
Log_VerbosePrintf("Saving %ux%u screenshot for state", screenshot_width, screenshot_height);
std::vector<u32> screenshot_buffer;
if (g_host_interface->GetDisplay()->WriteDisplayTextureToBuffer(&screenshot_buffer, screenshot_size,
screenshot_size) &&
!screenshot_buffer.empty())
u32 screenshot_stride;
HostDisplayPixelFormat screenshot_format;
if (display->RenderScreenshot(screenshot_width, screenshot_height, &screenshot_buffer, &screenshot_stride,
&screenshot_format) ||
!display->ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
HostDisplayPixelFormat::RGBA8))
{
header.offset_to_screenshot = static_cast<u32>(state->GetPosition());
header.screenshot_width = screenshot_size;
header.screenshot_height = screenshot_size;
header.screenshot_size = static_cast<u32>(screenshot_buffer.size() * sizeof(u32));
if (!state->Write2(screenshot_buffer.data(), header.screenshot_size))
return false;
if (screenshot_stride != (screenshot_width * sizeof(u32)))
{
Log_WarningPrintf("Failed to save %ux%u screenshot for save state due to incorrect stride(%u)",
screenshot_width, screenshot_height, screenshot_stride);
}
else
{
if (display->UsesLowerLeftOrigin())
display->FlipTextureDataRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride);
header.offset_to_screenshot = static_cast<u32>(state->GetPosition());
header.screenshot_width = screenshot_width;
header.screenshot_height = screenshot_height;
header.screenshot_size = static_cast<u32>(screenshot_buffer.size() * sizeof(u32));
if (!state->Write2(screenshot_buffer.data(), header.screenshot_size))
return false;
}
}
else
{
Log_WarningPrintf("Failed to save %ux%u screenshot for save state due to render/conversion failure",
screenshot_width, screenshot_height);
}
}