From c72ddfcf7add3042ccfe7d919f4513db02acbf84 Mon Sep 17 00:00:00 2001 From: Yrom Date: Thu, 21 Aug 2025 11:56:47 +0800 Subject: [PATCH] backend: use VirtualAlloc for creating soft CircularBuffer on Windows --- filament/backend/src/CircularBuffer.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/filament/backend/src/CircularBuffer.cpp b/filament/backend/src/CircularBuffer.cpp index 1329ab9944..0791451e92 100644 --- a/filament/backend/src/CircularBuffer.cpp +++ b/filament/backend/src/CircularBuffer.cpp @@ -38,6 +38,11 @@ #include #include +#if defined(WIN32) +# include // for VirtualAlloc, VirtualProtect, VirtualFree +# include +#endif + using namespace utils; namespace filament::backend { @@ -134,6 +139,21 @@ void* CircularBuffer::alloc(size_t size) { mprotect(guard, BLOCK_SIZE, PROT_NONE); } return data; +#elif defined(WIN32) + size_t const BLOCK_SIZE = getBlockSize(); + // On Windows, use VirtualAlloc instead of malloc to allocate virtual memory. + // This allows us to set page protection by VirtualProtect. + void* data = VirtualAlloc(nullptr, size * 2 + BLOCK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + FILAMENT_CHECK_POSTCONDITION(data != nullptr) + << "couldn't allocate " << (size * 2 / 1024) + << " KiB of virtual address space for the command buffer"; + + // guard page at the end + void* guard = (void*)(uintptr_t(data) + size * 2); + DWORD oldProtect = 0; + BOOL ok = VirtualProtect(guard, BLOCK_SIZE, PAGE_NOACCESS, &oldProtect); + FILAMENT_CHECK_POSTCONDITION(ok) << "VirtualProtect failed to set guard page"; + return data; #else return ::malloc(2 * size); #endif @@ -150,6 +170,10 @@ void CircularBuffer::dealloc() noexcept { mAshmemFd = -1; } } +#elif defined(WIN32) + if (mData) { + VirtualFree(mData, 0, MEM_RELEASE); + } #else ::free(mData); #endif