mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-08-09 22:33:18 -05:00
Latte: Serialize screenshot requests
This commit is contained in:
parent
f613dc6b22
commit
78367c9aca
|
|
@ -413,6 +413,9 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
|||
}
|
||||
else
|
||||
m_screenshot_state = ScreenshotState::None;
|
||||
const auto screenshotRequestId = GetActiveScreenshotRequestId();
|
||||
if (screenshotRequestId == 0)
|
||||
return;
|
||||
|
||||
auto texMtl = static_cast<LatteTextureMtl*>(texView->baseTexture);
|
||||
|
||||
|
|
@ -460,7 +463,7 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
|||
}
|
||||
|
||||
if (formatValid)
|
||||
SaveScreenshot(rgb_data, width, height, !padView);
|
||||
SaveScreenshot(screenshotRequestId, rgb_data, width, height, !padView);
|
||||
}
|
||||
|
||||
void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
|
||||
|
|
|
|||
|
|
@ -536,6 +536,9 @@ void OpenGLRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool pad
|
|||
}
|
||||
else
|
||||
m_screenshot_state = ScreenshotState::None;
|
||||
const auto screenshotRequestId = GetActiveScreenshotRequestId();
|
||||
if (screenshotRequestId == 0)
|
||||
return;
|
||||
|
||||
int screenshotWidth, screenshotHeight;
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
|
@ -577,7 +580,7 @@ void OpenGLRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool pad
|
|||
}
|
||||
}
|
||||
|
||||
SaveScreenshot(rgb_data, screenshotWidth, screenshotHeight, !padView);
|
||||
SaveScreenshot(screenshotRequestId, rgb_data, screenshotWidth, screenshotHeight, !padView);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter, sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight, bool padView, bool clearBackground)
|
||||
|
|
|
|||
|
|
@ -109,24 +109,70 @@ uint8 Renderer::RGBComponentToSRGB(uint8 cli)
|
|||
return (uint8)(cs * 255.0f);
|
||||
}
|
||||
|
||||
void Renderer::RequestScreenshot(ScreenshotSaveFunction onSaveScreenshot)
|
||||
std::optional<Renderer::ScreenshotRequestId> Renderer::RequestScreenshot(
|
||||
ScreenshotSaveFunction onSaveScreenshot, std::optional<bool> mainWindow)
|
||||
{
|
||||
std::lock_guard lock(m_screenshot_mutex);
|
||||
if (!onSaveScreenshot || m_screenshot_active_request_id != 0 ||
|
||||
m_screenshot_requested.load(std::memory_order_acquire) ||
|
||||
m_screenshot_state.load(std::memory_order_acquire) != ScreenshotState::None)
|
||||
return std::nullopt;
|
||||
auto requestId = m_screenshot_next_request_id++;
|
||||
if (requestId == 0)
|
||||
requestId = m_screenshot_next_request_id++;
|
||||
m_screenshot_active_request_id = requestId;
|
||||
m_on_save_screenshot = std::move(onSaveScreenshot);
|
||||
m_screenshot_main_window = mainWindow;
|
||||
m_screenshot_requested = true;
|
||||
m_on_save_screenshot = onSaveScreenshot;
|
||||
return requestId;
|
||||
}
|
||||
|
||||
bool Renderer::CancelScreenshotRequest(ScreenshotRequestId requestId)
|
||||
{
|
||||
std::lock_guard lock(m_screenshot_mutex);
|
||||
if (requestId == 0 || m_screenshot_active_request_id != requestId)
|
||||
return false;
|
||||
m_screenshot_requested = false;
|
||||
m_on_save_screenshot = {};
|
||||
m_screenshot_main_window.reset();
|
||||
m_screenshot_active_request_id = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::CancelScreenshotRequest()
|
||||
{
|
||||
std::lock_guard lock(m_screenshot_mutex);
|
||||
m_screenshot_requested = false;
|
||||
m_on_save_screenshot = {};
|
||||
m_screenshot_main_window.reset();
|
||||
m_screenshot_active_request_id = 0;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow)
|
||||
Renderer::ScreenshotRequestId Renderer::GetActiveScreenshotRequestId()
|
||||
{
|
||||
std::lock_guard lock(m_screenshot_mutex);
|
||||
return m_screenshot_active_request_id;
|
||||
}
|
||||
|
||||
void Renderer::SaveScreenshot(ScreenshotRequestId requestId, const std::vector<uint8>& rgb_data,
|
||||
int width, int height, bool mainWindow)
|
||||
{
|
||||
ScreenshotSaveFunction onSaveScreenshot;
|
||||
{
|
||||
std::lock_guard lock(m_screenshot_mutex);
|
||||
if (requestId == 0 || requestId != m_screenshot_active_request_id)
|
||||
return;
|
||||
if (m_screenshot_main_window.has_value() && m_screenshot_main_window.value() != mainWindow)
|
||||
return;
|
||||
m_screenshot_main_window.reset();
|
||||
m_screenshot_requested = false;
|
||||
onSaveScreenshot = std::move(m_on_save_screenshot);
|
||||
m_screenshot_active_request_id = 0;
|
||||
}
|
||||
std::thread(
|
||||
[=, screenshotRequested = std::exchange(m_screenshot_requested, false), onSaveScreenshot = std::exchange(m_on_save_screenshot, {})]() {
|
||||
if (screenshotRequested && onSaveScreenshot)
|
||||
[=, onSaveScreenshot = std::move(onSaveScreenshot)]() {
|
||||
if (onSaveScreenshot)
|
||||
{
|
||||
auto notificationMessage = onSaveScreenshot(rgb_data, width, height, mainWindow);
|
||||
if (notificationMessage.has_value())
|
||||
|
|
|
|||
|
|
@ -68,7 +68,10 @@ public:
|
|||
virtual void SwapBuffers(bool swapTV, bool swapDRC) = 0;
|
||||
|
||||
using ScreenshotSaveFunction = std::function<std::optional<std::string>(const std::vector<uint8>&, int, int, bool)>;
|
||||
void RequestScreenshot(ScreenshotSaveFunction onSaveScreenshot);
|
||||
using ScreenshotRequestId = uint64;
|
||||
[[nodiscard]] std::optional<ScreenshotRequestId> RequestScreenshot(
|
||||
ScreenshotSaveFunction onSaveScreenshot, std::optional<bool> mainWindow = {});
|
||||
bool CancelScreenshotRequest(ScreenshotRequestId requestId);
|
||||
void CancelScreenshotRequest();
|
||||
|
||||
virtual void HandleScreenshotRequest(LatteTextureView* texView, bool padView){}
|
||||
|
|
@ -175,11 +178,17 @@ protected:
|
|||
Main,
|
||||
Pad,
|
||||
};
|
||||
ScreenshotState m_screenshot_state = ScreenshotState::None;
|
||||
bool m_screenshot_requested = false;
|
||||
std::atomic<ScreenshotState> m_screenshot_state{ScreenshotState::None};
|
||||
std::atomic_bool m_screenshot_requested{false};
|
||||
std::mutex m_screenshot_mutex;
|
||||
ScreenshotRequestId m_screenshot_next_request_id{1};
|
||||
ScreenshotRequestId m_screenshot_active_request_id{};
|
||||
ScreenshotSaveFunction m_on_save_screenshot;
|
||||
std::optional<bool> m_screenshot_main_window;
|
||||
|
||||
void SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow);
|
||||
[[nodiscard]] ScreenshotRequestId GetActiveScreenshotRequestId();
|
||||
void SaveScreenshot(ScreenshotRequestId requestId, const std::vector<uint8>& rgb_data,
|
||||
int width, int height, bool mainWindow);
|
||||
|
||||
|
||||
ImFontAtlas* imguiFontAtlas{};
|
||||
|
|
|
|||
|
|
@ -1022,6 +1022,9 @@ void VulkanRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool pad
|
|||
}
|
||||
else
|
||||
m_screenshot_state = ScreenshotState::None;
|
||||
const auto screenshotRequestId = GetActiveScreenshotRequestId();
|
||||
if (screenshotRequestId == 0)
|
||||
return;
|
||||
|
||||
auto texViewVk = (LatteTextureViewVk*)texView;
|
||||
auto baseImageTex = texViewVk->GetBaseImage();
|
||||
|
|
@ -1268,7 +1271,7 @@ void VulkanRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool pad
|
|||
vkFreeMemory(m_logicalDevice, imageMemory, nullptr);
|
||||
|
||||
if (formatValid)
|
||||
SaveScreenshot(rgb_data, width, height, !padView);
|
||||
SaveScreenshot(screenshotRequestId, rgb_data, width, height, !padView);
|
||||
}
|
||||
|
||||
static const float kQueuePriority = 1.0f;
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void HotkeySettings::Init(MainWindow* mainWindowFrame)
|
|||
}},
|
||||
{&s_cfgHotkeys.takeScreenshot, [](void) {
|
||||
if (g_renderer)
|
||||
g_renderer->RequestScreenshot(SaveScreenshot);
|
||||
(void)g_renderer->RequestScreenshot(SaveScreenshot);
|
||||
}},
|
||||
{&s_cfgHotkeys.toggleFastForward, [](void) {
|
||||
ActiveSettings::SetTimerShiftFactor((ActiveSettings::GetTimerShiftFactor() < 3) ? 3 : 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user