Add a target for the GLFW surface helper.

This CL moves the GLFWUtils.cpp into a dawn/glfw/utils.cpp and
GLFWUtils.h into include/webgpu/webgpu_glfw.h. A build target
(`webgpu_glfw` alias to `dawn_glfw`) is added in order to allow
using that target in downstream projects without having to re-implement.

Change-Id: I93e85d5af3f486b3c754f2f854aafbda51901d6d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/98700
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/include/webgpu/webgpu_glfw.h b/include/webgpu/webgpu_glfw.h
new file mode 100644
index 0000000..5d3f4e3
--- /dev/null
+++ b/include/webgpu/webgpu_glfw.h
@@ -0,0 +1,58 @@
+// Copyright 2022 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef INCLUDE_WEBGPU_WEBGPU_GLFW_H_
+#define INCLUDE_WEBGPU_WEBGPU_GLFW_H_
+
+#include <memory>
+
+#include "webgpu/webgpu_cpp.h"
+
+#if defined(WGPU_GLFW_SHARED_LIBRARY)
+#if defined(_WIN32)
+#if defined(WGPU_GLFW_IMPLEMENTATION)
+#define WGPU_GLFW_EXPORT __declspec(dllexport)
+#else
+#define WGPU_GLFW_EXPORT __declspec(dllimport)
+#endif
+#else  // defined(_WIN32)
+#if defined(WGPU_GLFW_IMPLEMENTATION)
+#define WGPU_GLFW_EXPORT __attribute__((visibility("default")))
+#else
+#define WGPU_GLFW_EXPORT
+#endif
+#endif  // defined(_WIN32)
+#else   // defined(WGPU_GLFW_SHARED_LIBRARY)
+#define WGPU_GLFW_EXPORT
+#endif  // defined(WGPU_GLFW_SHARED_LIBRARY)
+
+struct GLFWwindow;
+
+namespace wgpu::glfw {
+
+// Does the necessary setup on the GLFWwindow to allow creating a wgpu::Surface with it and
+// calls `instance.CreateSurface` with the correct descriptor for this window.
+// Returns a null wgpu::Surface on failure.
+WGPU_GLFW_EXPORT wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance,
+                                                      GLFWwindow* window);
+
+// 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);
+
+}  // namespace wgpu::glfw
+
+#endif  // INCLUDE_WEBGPU_WEBGPU_GLFW_H_
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 725a17a..73f465f 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -22,6 +22,7 @@
 add_subdirectory(wire)
 # TODO(dawn:269): Remove once the implementation-based swapchains are removed.
 add_subdirectory(utils)
+add_subdirectory(glfw)
 
 if (DAWN_BUILD_SAMPLES)
     #TODO(dawn:269): Add this once implementation-based swapchains are removed.
diff --git a/src/dawn/glfw/BUILD.gn b/src/dawn/glfw/BUILD.gn
new file mode 100644
index 0000000..4c7c825
--- /dev/null
+++ b/src/dawn/glfw/BUILD.gn
@@ -0,0 +1,51 @@
+# Copyright 2022 The Dawn Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../scripts/dawn_overrides_with_defaults.gni")
+
+import("${dawn_root}/scripts/dawn_component.gni")
+import("${dawn_root}/scripts/dawn_features.gni")
+
+###############################################################################
+# GLFW utils
+###############################################################################
+
+if (dawn_supports_glfw_for_windowing) {
+  static_library("glfw") {
+    defines = [ "WGPU_GLFW_IMPLEMENTATION" ]
+
+    sources = [ "utils.cpp" ]
+    deps = [
+      "${dawn_root}/src/dawn:cpp",
+      "${dawn_root}/src/dawn:proc",
+      "${dawn_root}/src/dawn/common",
+    ]
+
+    if (dawn_enable_metal) {
+      sources += [ "utils_metal.mm" ]
+      frameworks = [
+        "Metal.framework",
+        "QuartzCore.framework",
+      ]
+    }
+
+    public_deps = [
+      "${dawn_root}/include/dawn:cpp_headers",
+      "${dawn_root}/third_party/gn/glfw",
+    ]
+  }
+} else {
+  group("glfw") {
+  }
+}
diff --git a/src/dawn/glfw/CMakeLists.txt b/src/dawn/glfw/CMakeLists.txt
new file mode 100644
index 0000000..74062a3
--- /dev/null
+++ b/src/dawn/glfw/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright 2022 The Dawn Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if(DAWN_SUPPORTS_GLFW_FOR_WINDOWING)
+
+add_library(dawn_glfw STATIC ${DAWN_PLACEHOLDER_FILE})
+common_compile_options(dawn_glfw)
+target_sources(dawn_glfw PRIVATE
+    "utils.cpp"
+)
+target_link_libraries(dawn_glfw
+  PUBLIC
+    glfw
+    dawncpp_headers
+    dawn_common
+  PRIVATE
+    dawn_internal_config
+)
+
+target_compile_definitions(dawn_glfw PRIVATE "WGPU_IMPLEMENTATION")
+if(BUILD_SHARED_LIBS)
+    target_compile_definitions(dawn_glfw PRIVATE "WGPU_SHARED_LIBRARY")
+endif()
+
+if (DAWN_ENABLE_METAL)
+    target_link_libraries(dawn_glfw PRIVATE "-framework Metal")
+    target_sources(dawn_glfw PRIVATE
+        "utils_metal.mm"
+    )
+endif()
+
+add_library(webgpu_glfw ALIAS dawn_glfw)
+
+endif()
diff --git a/src/dawn/glfw/README.md b/src/dawn/glfw/README.md
new file mode 100644
index 0000000..f38624c
--- /dev/null
+++ b/src/dawn/glfw/README.md
@@ -0,0 +1,5 @@
+In order to use Dawn WebGPU implementation with GLFW there is some
+boilerplate code needed in order to create the WebGPU surface. This repo
+contains an implementation of that boilerplate which can be used by
+downstream applications. It can also serve as an example of how to
+integrate Dawn and GLFW if there is desire to not use this helper.
diff --git a/src/dawn/utils/GLFWUtils.cpp b/src/dawn/glfw/utils.cpp
similarity index 96%
rename from src/dawn/utils/GLFWUtils.cpp
rename to src/dawn/glfw/utils.cpp
index c18ca52..0ae95ff 100644
--- a/src/dawn/utils/GLFWUtils.cpp
+++ b/src/dawn/glfw/utils.cpp
@@ -13,11 +13,12 @@
 // limitations under the License.
 
 #include <cstdlib>
+#include <memory>
 #include <utility>
 
 #include "GLFW/glfw3.h"
 #include "dawn/common/Platform.h"
-#include "dawn/utils/GLFWUtils.h"
+#include "webgpu/webgpu_glfw.h"
 
 #if DAWN_PLATFORM_IS(WINDOWS)
 #define GLFW_EXPOSE_NATIVE_WIN32
@@ -30,7 +31,7 @@
 #endif
 #include "GLFW/glfw3native.h"
 
-namespace utils {
+namespace wgpu::glfw {
 
 wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow* window) {
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
@@ -81,4 +82,4 @@
 #endif
 }
 
-}  // namespace utils
+}  // namespace wgpu::glfw
diff --git a/src/dawn/utils/GLFWUtils_metal.mm b/src/dawn/glfw/utils_metal.mm
similarity index 90%
rename from src/dawn/utils/GLFWUtils_metal.mm
rename to src/dawn/glfw/utils_metal.mm
index 3bb39e0..d5576f9 100644
--- a/src/dawn/utils/GLFWUtils_metal.mm
+++ b/src/dawn/glfw/utils_metal.mm
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #if !defined(DAWN_ENABLE_BACKEND_METAL)
-#error "GLFWUtils_metal.mm requires the Metal backend to be enabled."
+#error "utils_metal.mm requires the Metal backend to be enabled."
 #endif  // !defined(DAWN_ENABLE_BACKEND_METAL)
 
-#include "dawn/utils/GLFWUtils.h"
+#include "webgpu/webgpu_glfw.h"
 
 #import <QuartzCore/CAMetalLayer.h>
 #include "GLFW/glfw3.h"
@@ -26,7 +26,7 @@
 #define GLFW_EXPOSE_NATIVE_COCOA
 #include "GLFW/glfw3native.h"
 
-namespace utils {
+namespace wgpu::glfw {
 
 std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window) {
     NSWindow* nsWindow = glfwGetCocoaWindow(window);
@@ -46,4 +46,4 @@
     return std::move(desc);
 }
 
-}  // namespace utils
+}  // namespace wgpu::glfw
diff --git a/src/dawn/samples/BUILD.gn b/src/dawn/samples/BUILD.gn
index 58874cf..f78498e 100644
--- a/src/dawn/samples/BUILD.gn
+++ b/src/dawn/samples/BUILD.gn
@@ -36,10 +36,10 @@
     "${dawn_root}/src/dawn:cpp",
     "${dawn_root}/src/dawn:proc_shared",
     "${dawn_root}/src/dawn/common",
+    "${dawn_root}/src/dawn/glfw",
     "${dawn_root}/src/dawn/native",
     "${dawn_root}/src/dawn/utils",
     "${dawn_root}/src/dawn/utils:bindings",
-    "${dawn_root}/src/dawn/utils:glfw",
     "${dawn_root}/src/dawn/wire",
   ]
   public_configs = [ "${dawn_root}/src/dawn/common:internal_config" ]
diff --git a/src/dawn/samples/CMakeLists.txt b/src/dawn/samples/CMakeLists.txt
index 1a8e007..9f35868 100644
--- a/src/dawn/samples/CMakeLists.txt
+++ b/src/dawn/samples/CMakeLists.txt
@@ -23,6 +23,7 @@
     dawncpp
     dawn_proc
     dawn_common
+    dawn_glfw
     dawn_native
     dawn_wire
     dawn_utils
diff --git a/src/dawn/samples/ManualSwapChainTest.cpp b/src/dawn/samples/ManualSwapChainTest.cpp
index c6e61cc..bed9f12 100644
--- a/src/dawn/samples/ManualSwapChainTest.cpp
+++ b/src/dawn/samples/ManualSwapChainTest.cpp
@@ -63,10 +63,10 @@
 #include "dawn/dawn_proc.h"
 #include "dawn/native/DawnNative.h"
 #include "dawn/utils/ComboRenderPipelineDescriptor.h"
-#include "dawn/utils/GLFWUtils.h"
 #include "dawn/utils/ScopedAutoreleasePool.h"
 #include "dawn/utils/WGPUHelpers.h"
 #include "dawn/webgpu_cpp.h"
+#include "webgpu/webgpu_glfw.h"
 
 struct WindowData {
     GLFWwindow* window = nullptr;
@@ -123,7 +123,7 @@
     std::unique_ptr<WindowData> data = std::make_unique<WindowData>();
     data->window = window;
     data->serial = windowSerial++;
-    data->surface = utils::CreateSurfaceForWindow(instance->Get(), window);
+    data->surface = wgpu::glfw::CreateSurfaceForWindow(instance->Get(), window);
     data->currentDesc = descriptor;
     data->targetDesc = descriptor;
     SyncFromWindow(data.get());
diff --git a/src/dawn/samples/SampleUtils.cpp b/src/dawn/samples/SampleUtils.cpp
index c6036c7..1aab249 100644
--- a/src/dawn/samples/SampleUtils.cpp
+++ b/src/dawn/samples/SampleUtils.cpp
@@ -28,10 +28,10 @@
 #include "dawn/dawn_proc.h"
 #include "dawn/dawn_wsi.h"
 #include "dawn/native/DawnNative.h"
-#include "dawn/utils/GLFWUtils.h"
 #include "dawn/utils/TerribleCommandBuffer.h"
 #include "dawn/wire/WireClient.h"
 #include "dawn/wire/WireServer.h"
+#include "webgpu/webgpu_glfw.h"
 
 void PrintDeviceError(WGPUErrorType errorType, const char* message, void*) {
     const char* errorTypeName = "";
@@ -132,7 +132,7 @@
     DawnProcTable backendProcs = dawn::native::GetProcs();
 
     // Create the swapchain
-    auto surfaceChainedDesc = utils::SetupWindowAndGetSurfaceDescriptor(window);
+    auto surfaceChainedDesc = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
     WGPUSurfaceDescriptor surfaceDesc;
     surfaceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(surfaceChainedDesc.get());
     WGPUSurface surface = backendProcs.instanceCreateSurface(instance->Get(), &surfaceDesc);
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index 2d2205d..410745d 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -371,7 +371,7 @@
 
   if (dawn_supports_glfw_for_windowing || dawn_enable_opengl) {
     assert(dawn_supports_glfw_for_windowing)
-    public_deps += [ "${dawn_root}/src/dawn/utils:glfw" ]
+    public_deps += [ "${dawn_root}/src/dawn/glfw" ]
   }
 
   sources = [
diff --git a/src/dawn/tests/end2end/SwapChainTests.cpp b/src/dawn/tests/end2end/SwapChainTests.cpp
index a7c50e7..b5dab31 100644
--- a/src/dawn/tests/end2end/SwapChainTests.cpp
+++ b/src/dawn/tests/end2end/SwapChainTests.cpp
@@ -16,8 +16,8 @@
 
 #include "dawn/common/Constants.h"
 #include "dawn/common/Log.h"
-#include "dawn/utils/GLFWUtils.h"
 #include "dawn/utils/WGPUHelpers.h"
+#include "webgpu/webgpu_glfw.h"
 
 #include "GLFW/glfw3.h"
 
@@ -45,7 +45,7 @@
         int height;
         glfwGetFramebufferSize(window, &width, &height);
 
-        surface = utils::CreateSurfaceForWindow(GetInstance(), window);
+        surface = wgpu::glfw::CreateSurfaceForWindow(GetInstance(), window);
         ASSERT_NE(surface, nullptr);
 
         baseDescriptor.width = width;
diff --git a/src/dawn/tests/end2end/SwapChainValidationTests.cpp b/src/dawn/tests/end2end/SwapChainValidationTests.cpp
index f0a2ff7..b02d760 100644
--- a/src/dawn/tests/end2end/SwapChainValidationTests.cpp
+++ b/src/dawn/tests/end2end/SwapChainValidationTests.cpp
@@ -17,8 +17,8 @@
 #include "dawn/common/Constants.h"
 #include "dawn/common/Log.h"
 #include "dawn/utils/ComboRenderPipelineDescriptor.h"
-#include "dawn/utils/GLFWUtils.h"
 #include "dawn/utils/WGPUHelpers.h"
+#include "webgpu/webgpu_glfw.h"
 
 #include "GLFW/glfw3.h"
 
@@ -38,7 +38,7 @@
         glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
         window = glfwCreateWindow(400, 400, "SwapChainValidationTests window", nullptr, nullptr);
 
-        surface = utils::CreateSurfaceForWindow(GetInstance(), window);
+        surface = wgpu::glfw::CreateSurfaceForWindow(GetInstance(), window);
         ASSERT_NE(surface, nullptr);
 
         goodDescriptor.width = 1;
diff --git a/src/dawn/tests/end2end/WindowSurfaceTests.cpp b/src/dawn/tests/end2end/WindowSurfaceTests.cpp
index 763f19f..31ec57a 100644
--- a/src/dawn/tests/end2end/WindowSurfaceTests.cpp
+++ b/src/dawn/tests/end2end/WindowSurfaceTests.cpp
@@ -20,8 +20,8 @@
 #include "dawn/dawn_proc.h"
 #include "dawn/native/DawnNative.h"
 #include "dawn/tests/DawnTest.h"
-#include "dawn/utils/GLFWUtils.h"
 #include "gtest/gtest.h"
+#include "webgpu/webgpu_glfw.h"
 
 // Include windows.h before GLFW so GLFW's APIENTRY macro doesn't conflict with windows.h's.
 #if DAWN_PLATFORM_IS(WINDOWS)
@@ -84,7 +84,7 @@
 TEST_F(WindowSurfaceInstanceTests, ControlCase) {
     GLFWwindow* window = CreateWindow();
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
 
     wgpu::SurfaceDescriptor descriptor;
     descriptor.nextInChain = chainedDescriptor.get();
@@ -126,9 +126,9 @@
 TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) {
     GLFWwindow* window = CreateWindow();
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor1 =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor2 =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
 
     wgpu::SurfaceDescriptor descriptor;
     descriptor.nextInChain = chainedDescriptor1.get();
@@ -143,7 +143,7 @@
 TEST_F(WindowSurfaceInstanceTests, CorrectSTypeHWND) {
     GLFWwindow* window = CreateWindow();
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
     ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromWindowsHWND);
 }
 
@@ -179,7 +179,7 @@
 TEST_F(WindowSurfaceInstanceTests, CorrectSTypeXlib) {
     GLFWwindow* window = CreateWindow();
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
     ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromXlibWindow);
 }
 
@@ -219,7 +219,7 @@
 TEST_F(WindowSurfaceInstanceTests, CorrectSTypeMetal) {
     GLFWwindow* window = CreateWindow();
     std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
-        utils::SetupWindowAndGetSurfaceDescriptor(window);
+        wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
     ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromMetalLayer);
 }
 
diff --git a/src/dawn/utils/BUILD.gn b/src/dawn/utils/BUILD.gn
index e281b41..e74473d 100644
--- a/src/dawn/utils/BUILD.gn
+++ b/src/dawn/utils/BUILD.gn
@@ -17,48 +17,6 @@
 import("${dawn_root}/scripts/dawn_features.gni")
 
 ###############################################################################
-# GLFW wrapping target
-###############################################################################
-
-# GLFW does not support ChromeOS, Android or Fuchsia, so provide a small mock
-# library that can be linked into the Dawn tests on these platforms. Otherwise,
-# use the real library from third_party/.
-if (dawn_supports_glfw_for_windowing) {
-  group("glfw") {
-    public_deps = [ "${dawn_root}/third_party/gn/glfw" ]
-  }
-} else if (is_fuchsia) {
-  # The mock implementation of GLFW on Fuchsia
-  config("glfw_public_config") {
-    # Allow inclusion of <GLFW/glfw3.h>
-    include_dirs = [ "${dawn_glfw_dir}/include" ]
-
-    # The GLFW/glfw3.h header includes <GL/gl.h> by default, but the latter
-    # does not exist on Fuchsia. Defining GLFW_INCLUDE_NONE helps work around
-    # the issue, but it needs to be defined for any file that includes the
-    # header.
-    defines = [
-      "GLFW_INCLUDE_NONE",
-      "GLFW_INCLUDE_VULKAN",
-    ]
-  }
-
-  static_library("glfw") {
-    sources = [
-      # NOTE: The header below is required to pass "gn check".
-      "${dawn_glfw_dir}/include/GLFW/glfw3.h",
-      "Glfw3Fuchsia.cpp",
-    ]
-    public_configs = [ ":glfw_public_config" ]
-    deps = [ "${dawn_root}/src/dawn/common" ]
-  }
-} else {
-  # Just skip GLFW on other systems
-  group("glfw") {
-  }
-}
-
-###############################################################################
 # Utils for tests and samples
 ###############################################################################
 
@@ -121,19 +79,6 @@
     sources += [ "ScopedAutoreleasePool.cpp" ]
   }
 
-  if (dawn_supports_glfw_for_windowing) {
-    sources += [
-      "GLFWUtils.cpp",
-      "GLFWUtils.h",
-    ]
-    deps += [ ":glfw" ]
-
-    if (dawn_enable_metal) {
-      sources += [ "GLFWUtils_metal.mm" ]
-      frameworks += [ "Metal.framework" ]
-    }
-  }
-
   public_deps = [ "${dawn_root}/include/dawn:cpp_headers" ]
 }
 
@@ -154,8 +99,8 @@
     public_deps = [ "${dawn_root}/include/dawn:headers" ]
 
     deps = [
-      ":glfw",
       "${dawn_root}/src/dawn/common",
+      "${dawn_root}/src/dawn/glfw",
       "${dawn_root}/src/dawn/native",
     ]
     libs = []
diff --git a/src/dawn/utils/CMakeLists.txt b/src/dawn/utils/CMakeLists.txt
index a05bcba..eddbbbe 100644
--- a/src/dawn/utils/CMakeLists.txt
+++ b/src/dawn/utils/CMakeLists.txt
@@ -73,8 +73,6 @@
     target_sources(dawn_utils PRIVATE
         "BackendBinding.cpp"
         "BackendBinding.h"
-        "GLFWUtils.cpp"
-        "GLFWUtils.h"
     )
     target_link_libraries(dawn_utils PRIVATE glfw)
 
@@ -84,7 +82,6 @@
 
     if (DAWN_ENABLE_METAL)
         target_sources(dawn_utils PRIVATE
-            "GLFWUtils_metal.mm"
             "MetalBinding.mm"
         )
     endif()
diff --git a/src/dawn/utils/GLFWUtils.h b/src/dawn/utils/GLFWUtils.h
deleted file mode 100644
index f42446d..0000000
--- a/src/dawn/utils/GLFWUtils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2020 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_DAWN_UTILS_GLFWUTILS_H_
-#define SRC_DAWN_UTILS_GLFWUTILS_H_
-
-#include <memory>
-
-#include "dawn/webgpu_cpp.h"
-
-struct GLFWwindow;
-
-namespace utils {
-
-// Does the necessary setup on the GLFWwindow to allow creating a wgpu::Surface with it and
-// calls `instance.CreateSurface` with the correct descriptor for this window.
-// Returns a null wgpu::Surface on failure.
-wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow* window);
-
-// 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.
-std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window);
-
-}  // namespace utils
-
-#endif  // SRC_DAWN_UTILS_GLFWUTILS_H_
diff --git a/src/dawn/utils/Glfw3Fuchsia.cpp b/src/dawn/utils/Glfw3Fuchsia.cpp
deleted file mode 100644
index 198a5fd..0000000
--- a/src/dawn/utils/Glfw3Fuchsia.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2019 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// A mock GLFW implementation that supports Fuchsia, but only implements
-// the functions called from Dawn.
-
-#include <dlfcn.h>
-
-// NOTE: This must be included before GLFW/glfw3.h because the latter will
-// include <vulkan/vulkan.h> and "common/vulkan_platform.h" wants to be
-// the first header to do so for validity reasons (e.g. undefining weird
-// macros on Windows and Linux).
-// clang-format off
-#include "dawn/common/vulkan_platform.h"
-#include "dawn/common/Assert.h"
-#include "GLFW/glfw3.h"
-// clang-format on
-
-int glfwInit(void) {
-    return GLFW_TRUE;
-}
-
-void glfwDefaultWindowHints(void) {}
-
-void glfwWindowHint(int hint, int value) {
-    DAWN_UNUSED(hint);
-    DAWN_UNUSED(value);
-}
-
-struct GLFWwindow {
-    PFN_vkGetInstanceProcAddr GetInstanceProcAddress = nullptr;
-    void* vulkan_loader = nullptr;
-
-    GLFWwindow() {
-        vulkan_loader = ::dlopen("libvulkan.so", RTLD_NOW);
-        ASSERT(vulkan_loader != nullptr);
-        GetInstanceProcAddress = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
-            dlsym(vulkan_loader, "vkGetInstanceProcAddr"));
-        ASSERT(GetInstanceProcAddress != nullptr);
-    }
-
-    ~GLFWwindow() {
-        if (vulkan_loader) {
-            ::dlclose(vulkan_loader);
-        }
-        vulkan_loader = nullptr;
-    }
-};
-
-GLFWwindow* glfwCreateWindow(int width,
-                             int height,
-                             const char* title,
-                             GLFWmonitor* monitor,
-                             GLFWwindow* share) {
-    ASSERT(monitor == nullptr);
-    ASSERT(share == nullptr);
-    DAWN_UNUSED(width);
-    DAWN_UNUSED(height);
-    DAWN_UNUSED(title);
-    return new GLFWwindow();
-}
-
-VkResult glfwCreateWindowSurface(VkInstance instance,
-                                 GLFWwindow* window,
-                                 const VkAllocationCallbacks* allocator,
-                                 VkSurfaceKHR* surface) {
-    // IMPORTANT: This assumes that the VkInstance was created with a Fuchsia
-    // swapchain layer enabled, as well as the corresponding extension that
-    // is queried here to perform the surface creation. Dawn should do all
-    // required steps in VulkanInfo.cpp, VulkanFunctions.cpp and BackendVk.cpp.
-
-    auto vkCreateImagePipeSurfaceFUCHSIA = reinterpret_cast<PFN_vkCreateImagePipeSurfaceFUCHSIA>(
-        window->GetInstanceProcAddress(instance, "vkCreateImagePipeSurfaceFUCHSIA"));
-    ASSERT(vkCreateImagePipeSurfaceFUCHSIA != nullptr);
-    if (!vkCreateImagePipeSurfaceFUCHSIA) {
-        *surface = VK_NULL_HANDLE;
-        return VK_ERROR_FEATURE_NOT_PRESENT;
-    }
-
-    const struct VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
-        VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
-        nullptr,            // pNext
-        0,                  // flags, ignored for now
-        ZX_HANDLE_INVALID,  // imagePipeHandle, a null handle matches the framebuffer.
-    };
-
-    return vkCreateImagePipeSurfaceFUCHSIA(instance, &create_info, nullptr, surface);
-}