diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 4a9feafd..23805b21 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -12,6 +12,8 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-07-05: Metal: Add dispatch synchronization. +// 2022-06-30: Metal: Use __bridge for ARC based systems. // 2022-06-01: Metal: Fixed null dereference on exit inside command buffer completion handler. // 2022-04-27: Misc: Store backend data in a per-context struct, allowing to use this backend with multiple contexts. // 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code). @@ -296,8 +298,11 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id c ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); if (bd != NULL) { - [bd->SharedMetalContext.bufferCache addObject:vertexBuffer]; - [bd->SharedMetalContext.bufferCache addObject:indexBuffer]; + @synchronized(bd->SharedMetalContext.bufferCache) + { + [bd->SharedMetalContext.bufferCache addObject:vertexBuffer]; + [bd->SharedMetalContext.bufferCache addObject:indexBuffer]; + } } }); }]; @@ -440,28 +445,31 @@ void ImGui_ImplMetal_DestroyDeviceObjects() { uint64_t now = GetMachAbsoluteTimeInSeconds(); - // Purge old buffers that haven't been useful for a while - if (now - self.lastBufferCachePurge > 1.0) + @synchronized(self.bufferCache) { - NSMutableArray* survivors = [NSMutableArray array]; + // Purge old buffers that haven't been useful for a while + if (now - self.lastBufferCachePurge > 1.0) + { + NSMutableArray* survivors = [NSMutableArray array]; + for (MetalBuffer* candidate in self.bufferCache) + if (candidate.lastReuseTime > self.lastBufferCachePurge) + [survivors addObject:candidate]; + self.bufferCache = [survivors mutableCopy]; + self.lastBufferCachePurge = now; + } + + // See if we have a buffer we can reuse + MetalBuffer* bestCandidate = nil; for (MetalBuffer* candidate in self.bufferCache) - if (candidate.lastReuseTime > self.lastBufferCachePurge) - [survivors addObject:candidate]; - self.bufferCache = [survivors mutableCopy]; - self.lastBufferCachePurge = now; - } + if (candidate.buffer.length >= length && (bestCandidate == nil || bestCandidate.lastReuseTime > candidate.lastReuseTime)) + bestCandidate = candidate; - // See if we have a buffer we can reuse - MetalBuffer* bestCandidate = nil; - for (MetalBuffer* candidate in self.bufferCache) - if (candidate.buffer.length >= length && (bestCandidate == nil || bestCandidate.lastReuseTime > candidate.lastReuseTime)) - bestCandidate = candidate; - - if (bestCandidate != nil) - { - [self.bufferCache removeObject:bestCandidate]; - bestCandidate.lastReuseTime = now; - return bestCandidate; + if (bestCandidate != nil) + { + [self.bufferCache removeObject:bestCandidate]; + bestCandidate.lastReuseTime = now; + return bestCandidate; + } } // No luck; make a new buffer diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ad3b5abd..0708d8ef 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,7 @@ Other Changes: Enter keep the input active and select all text. - Misc: io.Framerate moving average now converge in 60 frames instead of 120. (#5236, #4138) - Backends: Metal: Use __bridge for ARC based systems. (#5403) [@stack] +- Backends: Metal: Add dispatch synchronization. (#5447) [@luigifcruz] - Backends: OSX: Fixes to support full app creation in C++. (#5403) [@stack]