HostDisplay: Add method to render screenshots at window size

This commit is contained in:
Connor McLaughlin
2021-03-06 02:11:17 +10:00
parent 757bef7b6d
commit 2aea58d056
8 changed files with 279 additions and 33 deletions

View File

@ -613,3 +613,40 @@ bool HostDisplay::WriteDisplayTextureToBuffer(std::vector<u32>* buffer, u32 resi
return true;
}
bool HostDisplay::WriteScreenshotToFile(std::string filename, bool compress_on_thread /*= false*/)
{
const u32 width = m_window_info.surface_width;
const u32 height = m_window_info.surface_height;
if (width == 0 || height == 0)
return false;
std::vector<u32> pixels;
u32 pixels_stride;
HostDisplayPixelFormat pixels_format;
if (!RenderScreenshot(width, height, &pixels, &pixels_stride, &pixels_format))
{
Log_ErrorPrintf("Failed to render %ux%u screenshot", width, height);
return false;
}
auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "wb");
if (!fp)
{
Log_ErrorPrintf("Can't open file '%s': errno %d", filename.c_str(), errno);
return false;
}
const RenderAPI api = GetRenderAPI();
const bool flip_y = (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES);
if (!compress_on_thread)
{
return CompressAndWriteTextureToFile(width, height, std::move(filename), std::move(fp), true, flip_y, width, height,
std::move(pixels), pixels_stride, pixels_format);
}
std::thread compress_thread(CompressAndWriteTextureToFile, width, height, std::move(filename), std::move(fp), true,
flip_y, width, height, std::move(pixels), pixels_stride, pixels_format);
compress_thread.detach();
return true;
}

View File

@ -115,6 +115,10 @@ public:
/// Returns false if the window was completely occluded.
virtual bool Render() = 0;
/// Renders the display with postprocessing to the specified image.
virtual bool RenderScreenshot(u32 width, u32 height, std::vector<u32>* out_pixels, u32* out_stride,
HostDisplayPixelFormat* out_format) = 0;
virtual void SetVSync(bool enabled) = 0;
#ifdef WITH_IMGUI
@ -232,6 +236,9 @@ public:
bool WriteDisplayTextureToBuffer(std::vector<u32>* buffer, u32 resize_width = 0, u32 resize_height = 0,
bool clear_alpha = true);
/// Helper function to save screenshot to PNG.
bool WriteScreenshotToFile(std::string filename, bool compress_on_thread = false);
protected:
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
ALWAYS_INLINE bool HasDisplayTexture() const { return (m_display_texture_handle != nullptr); }