[dawn] Add custom deleters for surface descriptor glfw_utils.
- Because wgpu::ChainedStruct doesn't have a virtual dtor, naively
using std::unique_ptr doesn't clean up the allocated descriptors
properly. I tried adding virtual dtor for wgpu::ChainedStruct,
but as a result of adding that, some of the static_asserts we
use to verify struct layouts started failing. Since this is just
a helper util, I just added custom deleters where applicable
which just casts the wgpu::ChainedStruct into the backing
implementation before deleting.
Change-Id: Ib37d4430b394f8e6da754033533ca36b30f14754
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/204415
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/include/webgpu/webgpu_glfw.h b/include/webgpu/webgpu_glfw.h
index c35252c..a319ffc 100644
--- a/include/webgpu/webgpu_glfw.h
+++ b/include/webgpu/webgpu_glfw.h
@@ -63,8 +63,8 @@
// Use for testing only. Does everything that CreateSurfaceForWindow does except the call to
// CreateSurface. Useful to be able to modify the descriptor for testing, or when trying to
// avoid using the global proc table.
-WGPU_GLFW_EXPORT std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(
- GLFWwindow* window);
+WGPU_GLFW_EXPORT std::unique_ptr<wgpu::ChainedStruct, void (*)(wgpu::ChainedStruct*)>
+SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window);
} // namespace wgpu::glfw
diff --git a/src/dawn/glfw/utils.cpp b/src/dawn/glfw/utils.cpp
index 2723374..4003931 100644
--- a/src/dawn/glfw/utils.cpp
+++ b/src/dawn/glfw/utils.cpp
@@ -48,8 +48,7 @@
namespace wgpu::glfw {
wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow* window) {
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
- SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor = SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor.get();
@@ -59,47 +58,53 @@
}
// SetupWindowAndGetSurfaceDescriptorCocoa defined in GLFWUtils_metal.mm
-std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window);
+std::unique_ptr<wgpu::ChainedStruct, void (*)(wgpu::ChainedStruct*)>
+SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window);
-std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
+std::unique_ptr<wgpu::ChainedStruct, void (*)(wgpu::ChainedStruct*)>
+SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
if (glfwGetWindowAttrib(window, GLFW_CLIENT_API) != GLFW_NO_API) {
dawn::ErrorLog() << "GL context was created on the window. Disable context creation by "
"setting the GLFW_CLIENT_API hint to GLFW_NO_API.";
- return nullptr;
+ return {nullptr, [](wgpu::ChainedStruct*) {}};
}
#if DAWN_PLATFORM_IS(WINDOWS)
- std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc =
- std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>();
+ wgpu::SurfaceDescriptorFromWindowsHWND* desc = new wgpu::SurfaceDescriptorFromWindowsHWND();
desc->hwnd = glfwGetWin32Window(window);
desc->hinstance = GetModuleHandle(nullptr);
- return std::move(desc);
+ return {desc, [](wgpu::ChainedStruct* desc) {
+ delete reinterpret_cast<wgpu::SurfaceDescriptorFromWindowsHWND*>(desc);
+ }};
#elif defined(DAWN_ENABLE_BACKEND_METAL)
return SetupWindowAndGetSurfaceDescriptorCocoa(window);
#elif defined(DAWN_USE_WAYLAND) || defined(DAWN_USE_X11)
#if defined(GLFW_PLATFORM_WAYLAND) && defined(DAWN_USE_WAYLAND)
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) {
- std::unique_ptr<wgpu::SurfaceDescriptorFromWaylandSurface> desc =
- std::make_unique<wgpu::SurfaceDescriptorFromWaylandSurface>();
+ wgpu::SurfaceDescriptorFromWaylandSurface* desc =
+ new wgpu::SurfaceDescriptorFromWaylandSurface();
desc->display = glfwGetWaylandDisplay();
desc->surface = glfwGetWaylandWindow(window);
- return std::move(desc);
+ return {desc, [](wgpu::ChainedStruct* desc) {
+ delete reinterpret_cast<wgpu::SurfaceDescriptorFromWaylandSurface*>(desc);
+ }};
} else // NOLINT(readability/braces)
#endif
#if defined(DAWN_USE_X11)
{
- std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc =
- std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>();
+ wgpu::SurfaceDescriptorFromXlibWindow* desc = new wgpu::SurfaceDescriptorFromXlibWindow();
desc->display = glfwGetX11Display();
desc->window = glfwGetX11Window(window);
- return std::move(desc);
+ return {desc, [](wgpu::ChainedStruct* desc) {
+ delete reinterpret_cast<wgpu::SurfaceDescriptorFromXlibWindow*>(desc);
+ }};
}
#else
{
- return nullptr;
+ return {nullptr, [](wgpu::ChainedStruct*) {}};
}
#endif
#else
- return nullptr;
+ return {nullptr, [](wgpu::ChainedStruct*) {}};
#endif
}
diff --git a/src/dawn/glfw/utils_metal.mm b/src/dawn/glfw/utils_metal.mm
index 6131a46..be71ac7 100644
--- a/src/dawn/glfw/utils_metal.mm
+++ b/src/dawn/glfw/utils_metal.mm
@@ -41,7 +41,8 @@
namespace wgpu::glfw {
-std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window) {
+std::unique_ptr<wgpu::ChainedStruct, void (*)(wgpu::ChainedStruct*)>
+SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window) {
@autoreleasepool {
NSWindow* nsWindow = glfwGetCocoaWindow(window);
NSView* view = [nsWindow contentView];
@@ -54,10 +55,11 @@
// Use retina if the window was created with retina support.
[[view layer] setContentsScale:[nsWindow backingScaleFactor]];
- std::unique_ptr<wgpu::SurfaceDescriptorFromMetalLayer> desc =
- std::make_unique<wgpu::SurfaceDescriptorFromMetalLayer>();
+ wgpu::SurfaceDescriptorFromMetalLayer* desc = new wgpu::SurfaceDescriptorFromMetalLayer();
desc->layer = [view layer];
- return std::move(desc);
+ return {desc, [](wgpu::ChainedStruct* desc) {
+ delete reinterpret_cast<wgpu::SurfaceDescriptorFromMetalLayer*>(desc);
+ }};
}
}
diff --git a/src/dawn/tests/end2end/WindowSurfaceTests.cpp b/src/dawn/tests/end2end/WindowSurfaceTests.cpp
index 5c03f04..c1dd093 100644
--- a/src/dawn/tests/end2end/WindowSurfaceTests.cpp
+++ b/src/dawn/tests/end2end/WindowSurfaceTests.cpp
@@ -99,8 +99,7 @@
// descriptor).
TEST_F(WindowSurfaceInstanceTests, ControlCase) {
GLFWwindow* window = CreateWindow();
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor.get();
@@ -141,10 +140,8 @@
// Test that it is invalid to give two valid chained descriptors
TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) {
GLFWwindow* window = CreateWindow();
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor1 =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor2 =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor1 = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor2 = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor1.get();
@@ -158,8 +155,7 @@
// Tests that GLFWUtils returns a descriptor of HWND type
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeHWND) {
GLFWwindow* window = CreateWindow();
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromWindowsHWND);
}
@@ -194,8 +190,7 @@
// Tests that GLFWUtils returns a descriptor of Xlib type
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeXlib) {
GLFWwindow* window = CreateWindow();
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromXlibWindow);
}
@@ -234,8 +229,7 @@
// Tests that GLFWUtils returns a descriptor of Metal type
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeMetal) {
GLFWwindow* window = CreateWindow();
- std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
- wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
+ auto chainedDescriptor = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromMetalLayer);
}