mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 03:57:17 +01:00
Outputs: Defensive checks, and don't wait for a Metal drawable twice in a frame
- Metal: when a layer has no drawable to give (it can take a second to say so), don't ask again in the same frame for every pass to it. - Swapchains other than the primary are created, resized and destroyed between frames (Metal asserts it), and destroyed with the last reference to them (ReleaseAssertLast, Metal and Vulkan). - BindFramebufferSamplesAsTexture asserts it isn't given a swapchain, like BindFramebufferAsTexture. - An offscreen Metal swapchain can't be resized, asserted. - VulkanRenderManager asserts that no additional swapchain outlives it. - Native_RemoveOutputAndWait asserts it isn't called on the thread that handles the requests, where it would always time out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ba55ee7e5f
commit
da33eab776
6 files changed
+26
-3
No files matched your search
@@ -217,6 +217,8 @@ static uint64_t g_outputRequestsQueued = 0;
|
||||
static uint64_t g_outputRequestsDone = 0;
|
||||
// Whether the outputs have swapchains, between NativeInitGraphics and NativeShutdownGraphics.
|
||||
static bool g_outputsLive = false;
|
||||
// The thread that handles the requests, which mustn't wait for them.
|
||||
static std::thread::id g_outputRequestThread;
|
||||
static std::atomic<int> g_nextOutputId{1};
|
||||
|
||||
static void ProcessOutputRequests() {
|
||||
@@ -236,6 +238,7 @@ static void ProcessOutputRequests() {
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(g_outputRequestLock);
|
||||
g_outputRequestsDone = queued;
|
||||
g_outputRequestThread = std::this_thread::get_id();
|
||||
g_outputRequestsDoneCond.notify_all();
|
||||
}
|
||||
|
||||
@@ -2098,6 +2101,7 @@ void Native_RemoveOutput(int id) {
|
||||
bool Native_RemoveOutputAndWait(int id) {
|
||||
Native_RemoveOutput(id);
|
||||
std::unique_lock<std::mutex> lock(g_outputRequestLock);
|
||||
_dbg_assert_msg_(std::this_thread::get_id() != g_outputRequestThread, "Waiting for output requests on the thread that handles them");
|
||||
const uint64_t queued = g_outputRequestsQueued;
|
||||
// Without a device, the outputs have no swapchains to let go of.
|
||||
const bool done = g_outputRequestsDoneCond.wait_for(lock, std::chrono::seconds(3), [=] {
|
||||
|
||||
Reference in new issue
Block a user