[dawn] Make the Instance simply RefCounted.

- Before, the Instance needed to be externally refcounted because
  there wasn't a way to get the Instance once the last external
  reference was dropped, hence it could cause any WaitAnyOnly or
  AllowProcessEvent events to be leaked. Since then, we have
  added a `GetInstance()` API on the Adapter which means that as
  long as we have a Device (which has `GetAdapter()`) on it, the
  instance can be reached. As a result, we only need to clear all
  events when the last device reference is dropped. This means
  that the Instance can just be a simple refcounted object now.
- This is also necessary because the `WaitAny()` and
  `ProcessEvents()` APIs implicitly assume that if they are called,
  that the Instance is externally alive. However, because users
  can drop the last external reference, then get a new one when
  they need it via the Device/Adapter, some teardown code in
  Chromium could cause a crash by calling those APIs on an
  Instance retrieved via the getter APIs after the original
  external reference was dropped.

Bug: 467732049, 474662276
Change-Id: Ib04c6243538983c2ba4c3060beb23487da66a499
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/283515
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Auto-Submit: Loko Kung <lokokung@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp
index 045b3d9..35e9354 100644
--- a/src/dawn/native/Instance.cpp
+++ b/src/dawn/native/Instance.cpp
@@ -224,6 +224,10 @@
 InstanceBase::~InstanceBase() = default;
 
 void InstanceBase::DeleteThis() {
+    // Stop tracking events. See comment on ShutDown.
+    mEventManager.ShutDown();
+    mLoggingCallbackInfo = kEmptyLoggingCallbackInfo;
+
     // Flush all remaining callback tasks on all devices and on the instance.
     absl::flat_hash_set<DeviceBase*> devices;
     do {
@@ -242,19 +246,13 @@
         mCallbackTaskManager->Flush();
     } while (!mCallbackTaskManager->IsEmpty());
 
-    RefCountedWithExternalCount::DeleteThis();
+    RefCounted::DeleteThis();
 }
 
 void InstanceBase::DisconnectDawnPlatform() {
     SetPlatform(nullptr);
 }
 
-void InstanceBase::WillDropLastExternalRef() {
-    // Stop tracking events. See comment on ShutDown.
-    mEventManager.ShutDown();
-    mLoggingCallbackInfo = kEmptyLoggingCallbackInfo;
-}
-
 // TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
 MaybeError InstanceBase::Initialize(const UnpackedPtr<InstanceDescriptor>& descriptor) {
     // Initialize the platform to the default for now.
diff --git a/src/dawn/native/Instance.h b/src/dawn/native/Instance.h
index f1ee301..7a26657 100644
--- a/src/dawn/native/Instance.h
+++ b/src/dawn/native/Instance.h
@@ -38,7 +38,7 @@
 #include "absl/container/flat_hash_set.h"
 #include "dawn/common/MutexProtected.h"
 #include "dawn/common/Ref.h"
-#include "dawn/common/RefCountedWithExternalCount.h"
+#include "dawn/common/RefCounted.h"
 #include "dawn/common/ityp_array.h"
 #include "dawn/common/ityp_bitset.h"
 #include "dawn/native/Adapter.h"
@@ -74,7 +74,7 @@
 
 // This is called InstanceBase for consistency across the frontend, even if the backends don't
 // specialize this class.
-class InstanceBase final : public ErrorSink, public RefCountedWithExternalCount<RefCounted> {
+class InstanceBase final : public ErrorSink, public RefCounted {
   public:
     static ResultOrError<Ref<InstanceBase>> Create(const InstanceDescriptor* descriptor = nullptr);
 
@@ -162,7 +162,6 @@
     ~InstanceBase() override;
 
     void DeleteThis() override;
-    void WillDropLastExternalRef() override;
 
     InstanceBase(const InstanceBase& other) = delete;
     InstanceBase& operator=(const InstanceBase& other) = delete;
diff --git a/src/dawn/tests/end2end/EventTests.cpp b/src/dawn/tests/end2end/EventTests.cpp
index c2d60bf..efd6c19 100644
--- a/src/dawn/tests/end2end/EventTests.cpp
+++ b/src/dawn/tests/end2end/EventTests.cpp
@@ -451,43 +451,6 @@
     TestWaitAll(/*loopOnlyOnce=*/true);
 }
 
-TEST_P(EventCompletionTests, WorkDoneDropInstanceBeforeEvent) {
-    // TODO(crbug.com/dawn/1987): Wire does not implement instance destruction correctly yet.
-    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-    // Spontaneous events only make sense with WaitType::Spin since we are dropping the instance.
-    DAWN_TEST_UNSUPPORTED_IF(IsSpontaneous() && GetWaitType() != WaitType::Spin);
-
-    UseSecondInstance();
-    testInstance = nullptr;  // Drop the last external ref to the instance.
-
-    if (IsSpontaneous()) {
-        TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
-        TestWaitAll();
-    } else {
-        TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::CallbackCancelled));
-        EXPECT_EQ(mCallbacksCompletedCount, 1u);
-    }
-}
-
-TEST_P(EventCompletionTests, WorkDoneDropInstanceAfterEvent) {
-    // TODO(crbug.com/dawn/1987): Wire does not implement instance destruction correctly yet.
-    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-    // Spontaneous events only make sense with WaitType::Spin since we are dropping the instance.
-    DAWN_TEST_UNSUPPORTED_IF(IsSpontaneous() && GetWaitType() != WaitType::Spin);
-
-    UseSecondInstance();
-
-    if (IsSpontaneous()) {
-        TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
-        testInstance = nullptr;  // Drop the last external ref to the instance.
-        TestWaitAll();
-    } else {
-        TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::CallbackCancelled));
-        testInstance = nullptr;  // Drop the last external ref to the instance.
-        EXPECT_EQ(mCallbacksCompletedCount, 1u);
-    }
-}
-
 // TODO(crbug.com/dawn/1987):
 // - Test any reentrancy guarantees (for ProcessEvents or WaitAny inside a callback),
 //   to make sure things don't blow up and we don't attempt to hold locks recursively.