Add DeviceLostCallback to dawn.json and dawn_wire

Bug: dawn:68
Change-Id: I6d8dd071be4ec612c67245bfde218e31e7a998b8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14660
Commit-Queue: Natasha Lee <natlee@microsoft.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_wire/client/ApiProcs.cpp b/src/dawn_wire/client/ApiProcs.cpp
index 14f25e4..128bde7 100644
--- a/src/dawn_wire/client/ApiProcs.cpp
+++ b/src/dawn_wire/client/ApiProcs.cpp
@@ -431,5 +431,11 @@
         Device* device = reinterpret_cast<Device*>(cSelf);
         device->SetUncapturedErrorCallback(callback, userdata);
     }
+    void ClientDeviceSetDeviceLostCallback(WGPUDevice cSelf,
+                                           WGPUDeviceLostCallback callback,
+                                           void* userdata) {
+        Device* device = reinterpret_cast<Device*>(cSelf);
+        device->SetDeviceLostCallback(callback, userdata);
+    }
 
 }}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/ClientDoers.cpp b/src/dawn_wire/client/ClientDoers.cpp
index 1be0f1d..dd90406 100644
--- a/src/dawn_wire/client/ClientDoers.cpp
+++ b/src/dawn_wire/client/ClientDoers.cpp
@@ -35,6 +35,11 @@
         return true;
     }
 
+    bool Client::DoDeviceLostCallback(char const* message) {
+        mDevice->HandleDeviceLost(message);
+        return true;
+    }
+
     bool Client::DoDevicePopErrorScopeCallback(uint64_t requestSerial,
                                                WGPUErrorType errorType,
                                                const char* message) {
diff --git a/src/dawn_wire/client/Device.cpp b/src/dawn_wire/client/Device.cpp
index 8577a4f..175617f 100644
--- a/src/dawn_wire/client/Device.cpp
+++ b/src/dawn_wire/client/Device.cpp
@@ -42,11 +42,22 @@
         }
     }
 
+    void Device::HandleDeviceLost(const char* message) {
+        if (mDeviceLostCallback) {
+            mDeviceLostCallback(message, mDeviceLostUserdata);
+        }
+    }
+
     void Device::SetUncapturedErrorCallback(WGPUErrorCallback errorCallback, void* errorUserdata) {
         mErrorCallback = errorCallback;
         mErrorUserdata = errorUserdata;
     }
 
+    void Device::SetDeviceLostCallback(WGPUDeviceLostCallback callback, void* userdata) {
+        mDeviceLostCallback = callback;
+        mDeviceLostUserdata = userdata;
+    }
+
     void Device::PushErrorScope(WGPUErrorFilter filter) {
         mErrorScopeStackSize++;
 
diff --git a/src/dawn_wire/client/Device.h b/src/dawn_wire/client/Device.h
index 9c1bb2f..af5934e 100644
--- a/src/dawn_wire/client/Device.h
+++ b/src/dawn_wire/client/Device.h
@@ -32,7 +32,9 @@
 
         Client* GetClient();
         void HandleError(WGPUErrorType errorType, const char* message);
+        void HandleDeviceLost(const char* message);
         void SetUncapturedErrorCallback(WGPUErrorCallback errorCallback, void* errorUserdata);
+        void SetDeviceLostCallback(WGPUDeviceLostCallback errorCallback, void* errorUserdata);
 
         void PushErrorScope(WGPUErrorFilter filter);
         bool RequestPopErrorScope(WGPUErrorCallback callback, void* userdata);
@@ -49,7 +51,9 @@
 
         Client* mClient = nullptr;
         WGPUErrorCallback mErrorCallback = nullptr;
+        WGPUDeviceLostCallback mDeviceLostCallback = nullptr;
         void* mErrorUserdata;
+        void* mDeviceLostUserdata;
     };
 
 }}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/server/Server.cpp b/src/dawn_wire/server/Server.cpp
index d03980a..d05285d 100644
--- a/src/dawn_wire/server/Server.cpp
+++ b/src/dawn_wire/server/Server.cpp
@@ -32,6 +32,7 @@
         deviceData->handle = device;
 
         mProcs.deviceSetUncapturedErrorCallback(device, ForwardUncapturedError, this);
+        mProcs.deviceSetDeviceLostCallback(device, ForwardDeviceLost, this);
     }
 
     Server::~Server() {
diff --git a/src/dawn_wire/server/Server.h b/src/dawn_wire/server/Server.h
index 28f4c81..effe69e 100644
--- a/src/dawn_wire/server/Server.h
+++ b/src/dawn_wire/server/Server.h
@@ -62,6 +62,7 @@
 
         // Forwarding callbacks
         static void ForwardUncapturedError(WGPUErrorType type, const char* message, void* userdata);
+        static void ForwardDeviceLost(const char* message, void* userdata);
         static void ForwardPopErrorScope(WGPUErrorType type, const char* message, void* userdata);
         static void ForwardBufferMapReadAsync(WGPUBufferMapAsyncStatus status,
                                               const void* ptr,
@@ -75,6 +76,7 @@
 
         // Error callbacks
         void OnUncapturedError(WGPUErrorType type, const char* message);
+        void OnDeviceLost(const char* message);
         void OnDevicePopErrorScope(WGPUErrorType type,
                                    const char* message,
                                    ErrorScopeUserdata* userdata);
diff --git a/src/dawn_wire/server/ServerDevice.cpp b/src/dawn_wire/server/ServerDevice.cpp
index 6f27867..66c0d70 100644
--- a/src/dawn_wire/server/ServerDevice.cpp
+++ b/src/dawn_wire/server/ServerDevice.cpp
@@ -21,6 +21,11 @@
         server->OnUncapturedError(type, message);
     }
 
+    void Server::ForwardDeviceLost(const char* message, void* userdata) {
+        auto server = static_cast<Server*>(userdata);
+        server->OnDeviceLost(message);
+    }
+
     void Server::OnUncapturedError(WGPUErrorType type, const char* message) {
         ReturnDeviceUncapturedErrorCallbackCmd cmd;
         cmd.type = type;
@@ -31,6 +36,15 @@
         cmd.Serialize(allocatedBuffer);
     }
 
+    void Server::OnDeviceLost(const char* message) {
+        ReturnDeviceLostCallbackCmd cmd;
+        cmd.message = message;
+
+        size_t requiredSize = cmd.GetRequiredSize();
+        char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+        cmd.Serialize(allocatedBuffer);
+    }
+
     bool Server::DoDevicePopErrorScope(WGPUDevice cDevice, uint64_t requestSerial) {
         ErrorScopeUserdata* userdata = new ErrorScopeUserdata;
         userdata->server = this;