Implement Instance->DisconnectDawnPlatform()

This patch implements InstanceBase->DisconnectDawnPlatform() which
can force setting InstanceBase->mPlatform to a member of InstanceBase
instead of a value out of Dawn (e.g.  dawn_platform_ in
WebGPUDecoderImpl in Chromium). We need to explicitly clear
dawn_instance_->mPlatform in Chromium because InstanceBase is always
destroyed after WebGPUDecoderImpl as a shared image object will still
keep a reference of InstanceBase after WebGPUDecoderImpl is destroyed.

Bug: dawn:2349
Change-Id: I4548dae7e3a7b028e4b29b6a041ec6c6e24e0996
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/180260
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/include/dawn/native/DawnNative.h b/include/dawn/native/DawnNative.h
index b6f2d99..a11283d 100644
--- a/include/dawn/native/DawnNative.h
+++ b/include/dawn/native/DawnNative.h
@@ -188,6 +188,9 @@
     // Returns the underlying WGPUInstance object.
     WGPUInstance Get() const;
 
+    // Make mImpl->mPlatform point to an object inside Dawn in case it becomes a dangling pointer
+    void DisconnectDawnPlatform();
+
   private:
     InstanceBase* mImpl = nullptr;
 };
diff --git a/src/dawn/native/DawnNative.cpp b/src/dawn/native/DawnNative.cpp
index 0587429..4ea32c5 100644
--- a/src/dawn/native/DawnNative.cpp
+++ b/src/dawn/native/DawnNative.cpp
@@ -219,6 +219,10 @@
     return ToAPI(mImpl);
 }
 
+void Instance::DisconnectDawnPlatform() {
+    mImpl->DisconnectDawnPlatform();
+}
+
 size_t GetLazyClearCountForTesting(WGPUDevice device) {
     return FromAPI(device)->GetLazyClearCountForTesting();
 }
diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp
index e884c02..38d4e9d 100644
--- a/src/dawn/native/Instance.cpp
+++ b/src/dawn/native/Instance.cpp
@@ -186,11 +186,13 @@
         mCallbackTaskManager->Flush();
     } while (!mCallbackTaskManager->IsEmpty());
 
-    mPlatform = nullptr;
-
     RefCountedWithExternalCount::DeleteThis();
 }
 
+void InstanceBase::DisconnectDawnPlatform() {
+    SetPlatform(nullptr);
+}
+
 void InstanceBase::WillDropLastExternalRef() {
     // InstanceBase uses RefCountedWithExternalCount to break refcycles.
 
diff --git a/src/dawn/native/Instance.h b/src/dawn/native/Instance.h
index 3c3fa6f..8e0b01d 100644
--- a/src/dawn/native/Instance.h
+++ b/src/dawn/native/Instance.h
@@ -175,6 +175,8 @@
     // TODO(https://github.com/webgpu-native/webgpu-headers/issues/252): Add a count argument.
     size_t APIEnumerateWGSLLanguageFeatures(wgpu::WGSLFeatureName* features) const;
 
+    void DisconnectDawnPlatform();
+
   private:
     explicit InstanceBase(const TogglesState& instanceToggles);
     ~InstanceBase() override;
@@ -217,9 +219,9 @@
     wgpu::LoggingCallback mLoggingCallback = nullptr;
     raw_ptr<void> mLoggingCallbackUserdata = nullptr;
 
+    std::unique_ptr<dawn::platform::Platform> mDefaultPlatform;
     // TODO(https://crbug.com/dawn/2349): Investigate DanglingUntriaged in dawn/native.
     raw_ptr<dawn::platform::Platform, DanglingUntriaged> mPlatform = nullptr;
-    std::unique_ptr<dawn::platform::Platform> mDefaultPlatform;
 
     BackendsArray mBackends;
     BackendsBitset mBackendsTried;