[wgpu-headers] Introduce 2nd userdata to get compilation info callback.

- Updates the wire to use the new APIs
- Updates relevant usages to use new C++ helpers

Bug: 42241461
Change-Id: Iaa0011d3ce5028e79590822a5cd4eeb4e51bb6be
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/189683
Auto-Submit: Loko Kung <lokokung@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index bdd4d56..551eac1 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -959,6 +959,13 @@
             {"name": "userdata", "type": "void *"}
         ]
     },
+    "compilation info callback 2": {
+        "category": "callback function",
+        "args": [
+            {"name": "status", "type": "compilation info request status"},
+            {"name": "compilation info", "type": "compilation info", "annotation": "const*"}
+        ]
+    },
     "compilation info callback info": {
         "category": "structure",
         "extensible": "in",
@@ -968,6 +975,12 @@
             {"name": "userdata", "type": "void *", "default": "nullptr"}
         ]
     },
+    "compilation info callback info 2": {
+        "category": "callback info",
+        "members": [
+            {"name": "callback", "type": "compilation info callback 2"}
+        ]
+    },
     "compilation info request status": {
         "category": "enum",
         "values": [
@@ -3598,6 +3611,15 @@
                 ]
             },
             {
+                "name": "get compilation info 2",
+                "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.",
+                "tags": ["dawn", "emscripten"],
+                "returns": "future",
+                "args": [
+                    {"name": "callback info", "type": "compilation info callback info 2"}
+                ]
+            },
+            {
                 "name": "set label",
                 "returns": "void",
                 "args": [
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index e797463..88ffb7e 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -247,6 +247,7 @@
             "InstanceRequestAdapter2",
             "ShaderModuleGetCompilationInfo",
             "ShaderModuleGetCompilationInfoF",
+            "ShaderModuleGetCompilationInfo2",
             "QuerySetGetType",
             "QuerySetGetCount",
             "QueueOnSubmittedWorkDone",
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 2848ab2..b3e66bd 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -1420,29 +1420,64 @@
     return mTintData.Use([&](auto tintData) { return tintData->tintProgramRecreateCount; });
 }
 
+namespace {
+
+void DefaultGetCompilationInfoCallback(WGPUCompilationInfoRequestStatus status,
+                                       const WGPUCompilationInfo* compilationInfo,
+                                       void* callback,
+                                       void* userdata) {
+    if (callback == nullptr) {
+        DAWN_ASSERT(userdata == nullptr);
+        return;
+    }
+    auto cb = reinterpret_cast<WGPUCompilationInfoCallback>(callback);
+    cb(status, compilationInfo, userdata);
+}
+
+}  // anonymous namespace
+
 void ShaderModuleBase::APIGetCompilationInfo(wgpu::CompilationInfoCallback callback,
                                              void* userdata) {
+    GetInstance()->EmitDeprecationWarning(
+        "Old GetCompilationInfo APIs are deprecated. If using C please pass a CallbackInfo struct "
+        "that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
     if (callback == nullptr) {
         return;
     }
-    CompilationInfoCallbackInfo callbackInfo = {nullptr, wgpu::CallbackMode::AllowSpontaneous,
-                                                callback, userdata};
-    APIGetCompilationInfoF(callbackInfo);
+    APIGetCompilationInfo2({nullptr, WGPUCallbackMode_AllowSpontaneous,
+                            &DefaultGetCompilationInfoCallback, reinterpret_cast<void*>(callback),
+                            userdata});
 }
 
 Future ShaderModuleBase::APIGetCompilationInfoF(const CompilationInfoCallbackInfo& callbackInfo) {
+    GetInstance()->EmitDeprecationWarning(
+        "Old GetCompilationInfo APIs are deprecated. If using C please pass a CallbackInfo struct "
+        "that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
+    return APIGetCompilationInfo2({ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode),
+                                   &DefaultGetCompilationInfoCallback,
+                                   reinterpret_cast<void*>(callbackInfo.callback),
+                                   callbackInfo.userdata});
+}
+
+Future ShaderModuleBase::APIGetCompilationInfo2(
+    const WGPUCompilationInfoCallbackInfo2& callbackInfo) {
     struct CompilationInfoEvent final : public EventManager::TrackedEvent {
-        WGPUCompilationInfoCallback mCallback;
-        raw_ptr<void> mUserdata;
+        WGPUCompilationInfoCallback2 mCallback;
+        raw_ptr<void> mUserdata1;
+        raw_ptr<void> mUserdata2;
         // Need to keep a Ref of the compilation messages in case the ShaderModule goes away before
         // the callback happens.
         Ref<ShaderModuleBase> mShaderModule;
 
-        CompilationInfoEvent(const CompilationInfoCallbackInfo& callbackInfo,
+        CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo2& callbackInfo,
                              Ref<ShaderModuleBase> shaderModule)
-            : TrackedEvent(callbackInfo.mode, TrackedEvent::Completed{}),
+            : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode),
+                           TrackedEvent::Completed{}),
               mCallback(callbackInfo.callback),
-              mUserdata(callbackInfo.userdata),
+              mUserdata1(callbackInfo.userdata1),
+              mUserdata2(callbackInfo.userdata2),
               mShaderModule(std::move(shaderModule)) {}
 
         ~CompilationInfoEvent() override { EnsureComplete(EventCompletionType::Shutdown); }
@@ -1455,11 +1490,9 @@
                 status = WGPUCompilationInfoRequestStatus_Success;
                 compilationInfo = mShaderModule->mCompilationMessages->GetCompilationInfo();
             }
-            if (mCallback) {
-                mCallback(status, compilationInfo, mUserdata.ExtractAsDangling());
-            } else {
-                DAWN_ASSERT(mUserdata == nullptr);
-            }
+
+            mCallback(status, compilationInfo, mUserdata1.ExtractAsDangling(),
+                      mUserdata2.ExtractAsDangling());
         }
     };
     FutureID futureID = GetDevice()->GetInstance()->GetEventManager()->TrackEvent(
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index ad309a5..41cdeb8 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -323,6 +323,7 @@
 
     void APIGetCompilationInfo(wgpu::CompilationInfoCallback callback, void* userdata);
     Future APIGetCompilationInfoF(const CompilationInfoCallbackInfo& callbackInfo);
+    Future APIGetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo);
 
     void InjectCompilationMessages(std::unique_ptr<OwnedCompilationMessages> compilationMessages);
     OwnedCompilationMessages* GetCompilationMessages() const;
diff --git a/src/dawn/tests/end2end/MultithreadTests.cpp b/src/dawn/tests/end2end/MultithreadTests.cpp
index 48455da..008e0fe 100644
--- a/src/dawn/tests/end2end/MultithreadTests.cpp
+++ b/src/dawn/tests/end2end/MultithreadTests.cpp
@@ -260,13 +260,15 @@
     for (uint32_t index = 0; index < shaderModules.size(); ++index) {
         uint32_t sourceIndex = index / kCacheHitFactor;
         shaderModules[index].GetCompilationInfo(
-            [](WGPUCompilationInfoRequestStatus, const WGPUCompilationInfo* info, void* userdata) {
+            wgpu::CallbackMode::AllowProcessEvents,
+            [sourceIndex](wgpu::CompilationInfoRequestStatus status,
+                          const wgpu::CompilationInfo* info) {
+                ASSERT_EQ(wgpu::CompilationInfoRequestStatus::Success, status);
                 for (size_t i = 0; i < info->messageCount; ++i) {
                     EXPECT_THAT(info->messages[i].message, testing::HasSubstr("unreachable"));
-                    EXPECT_EQ(info->messages[i].lineNum, 5u + *static_cast<uint32_t*>(userdata));
+                    EXPECT_EQ(info->messages[i].lineNum, 5u + sourceIndex);
                 }
-            },
-            &sourceIndex);
+            });
     }
 }
 
diff --git a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
index 1e363f5..fce0dc9 100644
--- a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
@@ -282,40 +282,39 @@
     messages->AddMessageForTesting("Complete Message", wgpu::CompilationMessageType::Info, 3, 4, 5,
                                    6);
 
-    auto callback = [](WGPUCompilationInfoRequestStatus status, const WGPUCompilationInfo* info,
-                       void* userdata) {
-        ASSERT_EQ(WGPUCompilationInfoRequestStatus_Success, status);
-        ASSERT_NE(nullptr, info);
-        ASSERT_EQ(4u, info->messageCount);
+    shaderModule.GetCompilationInfo(
+        wgpu::CallbackMode::AllowSpontaneous,
+        [](wgpu::CompilationInfoRequestStatus status, const wgpu::CompilationInfo* info) {
+            ASSERT_EQ(wgpu::CompilationInfoRequestStatus::Success, status);
+            ASSERT_NE(nullptr, info);
+            ASSERT_EQ(4u, info->messageCount);
 
-        const WGPUCompilationMessage* message = &info->messages[0];
-        ASSERT_STREQ("Info Message", message->message);
-        ASSERT_EQ(WGPUCompilationMessageType_Info, message->type);
-        ASSERT_EQ(0u, message->lineNum);
-        ASSERT_EQ(0u, message->linePos);
+            const wgpu::CompilationMessage* message = &info->messages[0];
+            ASSERT_STREQ("Info Message", message->message);
+            ASSERT_EQ(wgpu::CompilationMessageType::Info, message->type);
+            ASSERT_EQ(0u, message->lineNum);
+            ASSERT_EQ(0u, message->linePos);
 
-        message = &info->messages[1];
-        ASSERT_STREQ("Warning Message", message->message);
-        ASSERT_EQ(WGPUCompilationMessageType_Warning, message->type);
-        ASSERT_EQ(0u, message->lineNum);
-        ASSERT_EQ(0u, message->linePos);
+            message = &info->messages[1];
+            ASSERT_STREQ("Warning Message", message->message);
+            ASSERT_EQ(wgpu::CompilationMessageType::Warning, message->type);
+            ASSERT_EQ(0u, message->lineNum);
+            ASSERT_EQ(0u, message->linePos);
 
-        message = &info->messages[2];
-        ASSERT_STREQ("Error Message", message->message);
-        ASSERT_EQ(WGPUCompilationMessageType_Error, message->type);
-        ASSERT_EQ(3u, message->lineNum);
-        ASSERT_EQ(4u, message->linePos);
+            message = &info->messages[2];
+            ASSERT_STREQ("Error Message", message->message);
+            ASSERT_EQ(wgpu::CompilationMessageType::Error, message->type);
+            ASSERT_EQ(3u, message->lineNum);
+            ASSERT_EQ(4u, message->linePos);
 
-        message = &info->messages[3];
-        ASSERT_STREQ("Complete Message", message->message);
-        ASSERT_EQ(WGPUCompilationMessageType_Info, message->type);
-        ASSERT_EQ(3u, message->lineNum);
-        ASSERT_EQ(4u, message->linePos);
-        ASSERT_EQ(5u, message->offset);
-        ASSERT_EQ(6u, message->length);
-    };
-
-    shaderModule.GetCompilationInfo(callback, nullptr);
+            message = &info->messages[3];
+            ASSERT_STREQ("Complete Message", message->message);
+            ASSERT_EQ(wgpu::CompilationMessageType::Info, message->type);
+            ASSERT_EQ(3u, message->lineNum);
+            ASSERT_EQ(4u, message->linePos);
+            ASSERT_EQ(5u, message->offset);
+            ASSERT_EQ(6u, message->length);
+        });
 }
 
 // Validate the maximum location of effective inter-stage variables cannot be greater than 16
@@ -737,20 +736,19 @@
     ASSERT_DEVICE_ERROR(errorShaderModule = device.CreateErrorShaderModule(
                             &descriptor, "Shader compilation error"));
 
-    auto callback = [](WGPUCompilationInfoRequestStatus status, const WGPUCompilationInfo* info,
-                       void* userdata) {
-        ASSERT_EQ(WGPUCompilationInfoRequestStatus_Success, status);
-        ASSERT_NE(nullptr, info);
-        ASSERT_EQ(1u, info->messageCount);
+    errorShaderModule.GetCompilationInfo(
+        wgpu::CallbackMode::AllowSpontaneous,
+        [](wgpu::CompilationInfoRequestStatus status, const wgpu::CompilationInfo* info) {
+            ASSERT_EQ(wgpu::CompilationInfoRequestStatus::Success, status);
+            ASSERT_NE(nullptr, info);
+            ASSERT_EQ(1u, info->messageCount);
 
-        const WGPUCompilationMessage* message = &info->messages[0];
-        ASSERT_STREQ("Shader compilation error", message->message);
-        ASSERT_EQ(WGPUCompilationMessageType_Error, message->type);
-        ASSERT_EQ(0u, message->lineNum);
-        ASSERT_EQ(0u, message->linePos);
-    };
-
-    errorShaderModule.GetCompilationInfo(callback, nullptr);
+            const wgpu::CompilationMessage* message = &info->messages[0];
+            ASSERT_STREQ("Shader compilation error", message->message);
+            ASSERT_EQ(wgpu::CompilationMessageType::Error, message->type);
+            ASSERT_EQ(0u, message->lineNum);
+            ASSERT_EQ(0u, message->linePos);
+        });
 
     FlushWire();
 }
diff --git a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
index 91cc44b..8c8d2a0 100644
--- a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
@@ -77,9 +77,9 @@
 TEST_P(WireShaderModuleTests, GetCompilationInfo) {
     ShaderModuleGetCompilationInfo(shaderModule);
 
-    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _))
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _))
         .WillOnce(InvokeWithoutArgs([&] {
-            api.CallShaderModuleGetCompilationInfoCallback(
+            api.CallShaderModuleGetCompilationInfo2Callback(
                 apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &mCompilationInfo);
         }));
     FlushClient();
@@ -112,9 +112,9 @@
 TEST_P(WireShaderModuleTests, GetCompilationInfoBeforeDisconnect) {
     ShaderModuleGetCompilationInfo(shaderModule);
 
-    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _))
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _))
         .WillOnce(InvokeWithoutArgs([&] {
-            api.CallShaderModuleGetCompilationInfoCallback(
+            api.CallShaderModuleGetCompilationInfo2Callback(
                 apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &mCompilationInfo);
         }));
     FlushClient();
@@ -149,9 +149,9 @@
 
     ShaderModuleGetCompilationInfo(shaderModule);
 
-    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _))
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _))
         .WillOnce(InvokeWithoutArgs([&] {
-            api.CallShaderModuleGetCompilationInfoCallback(
+            api.CallShaderModuleGetCompilationInfo2Callback(
                 apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &mCompilationInfo);
         }));
     FlushClient();
@@ -178,9 +178,9 @@
 
     ShaderModuleGetCompilationInfo(shaderModule);
 
-    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _))
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _))
         .WillOnce(InvokeWithoutArgs([&] {
-            api.CallShaderModuleGetCompilationInfoCallback(
+            api.CallShaderModuleGetCompilationInfo2Callback(
                 apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &mCompilationInfo);
         }));
     FlushClient();
diff --git a/src/dawn/wire/client/ShaderModule.cpp b/src/dawn/wire/client/ShaderModule.cpp
index cc84965..31c4244 100644
--- a/src/dawn/wire/client/ShaderModule.cpp
+++ b/src/dawn/wire/client/ShaderModule.cpp
@@ -38,10 +38,11 @@
   public:
     static constexpr EventType kType = EventType::CompilationInfo;
 
-    CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo& callbackInfo, ShaderModule* shader)
+    CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo2& callbackInfo, ShaderModule* shader)
         : TrackedEvent(callbackInfo.mode),
           mCallback(callbackInfo.callback),
-          mUserdata(callbackInfo.userdata),
+          mUserdata1(callbackInfo.userdata1),
+          mUserdata2(callbackInfo.userdata2),
           mShader(shader) {
         DAWN_ASSERT(mShader != nullptr);
         mShader->AddRef();
@@ -90,13 +91,17 @@
         } else {
             compilationInfo = &(*mShader->mCompilationInfo);
         }
+
+        void* userdata1 = mUserdata1.ExtractAsDangling();
+        void* userdata2 = mUserdata2.ExtractAsDangling();
         if (mCallback) {
-            mCallback(mStatus, compilationInfo, mUserdata.ExtractAsDangling());
+            mCallback(mStatus, compilationInfo, userdata1, userdata2);
         }
     }
 
-    WGPUCompilationInfoCallback mCallback;
-    raw_ptr<void> mUserdata;
+    WGPUCompilationInfoCallback2 mCallback;
+    raw_ptr<void> mUserdata1;
+    raw_ptr<void> mUserdata2;
 
     WGPUCompilationInfoRequestStatus mStatus;
 
@@ -109,15 +114,39 @@
     return ObjectType::ShaderModule;
 }
 
+namespace {
+
+void DefaultGetCompilationInfoCallback(WGPUCompilationInfoRequestStatus status,
+                                       const WGPUCompilationInfo* compilationInfo,
+                                       void* callback,
+                                       void* userdata) {
+    if (callback == nullptr) {
+        DAWN_ASSERT(userdata == nullptr);
+        return;
+    }
+    auto cb = reinterpret_cast<WGPUCompilationInfoCallback>(callback);
+    cb(status, compilationInfo, userdata);
+}
+
+}  // anonymous namespace
+
 void ShaderModule::GetCompilationInfo(WGPUCompilationInfoCallback callback, void* userdata) {
-    WGPUCompilationInfoCallbackInfo callbackInfo = {};
-    callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
-    callbackInfo.callback = callback;
-    callbackInfo.userdata = userdata;
-    GetCompilationInfoF(callbackInfo);
+    if (callback == nullptr) {
+        DAWN_ASSERT(userdata == nullptr);
+        return;
+    }
+    GetCompilationInfo2({nullptr, WGPUCallbackMode_AllowSpontaneous,
+                         &DefaultGetCompilationInfoCallback, reinterpret_cast<void*>(callback),
+                         userdata});
 }
 
 WGPUFuture ShaderModule::GetCompilationInfoF(const WGPUCompilationInfoCallbackInfo& callbackInfo) {
+    return GetCompilationInfo2(
+        {callbackInfo.nextInChain, callbackInfo.mode, &DefaultGetCompilationInfoCallback,
+         reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata});
+}
+
+WGPUFuture ShaderModule::GetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo) {
     auto [futureIDInternal, tracked] =
         GetEventManager().TrackEvent(std::make_unique<CompilationInfoEvent>(callbackInfo, this));
     if (!tracked) {
diff --git a/src/dawn/wire/client/ShaderModule.h b/src/dawn/wire/client/ShaderModule.h
index 9b6bb26..c1432fc 100644
--- a/src/dawn/wire/client/ShaderModule.h
+++ b/src/dawn/wire/client/ShaderModule.h
@@ -46,6 +46,7 @@
 
     void GetCompilationInfo(WGPUCompilationInfoCallback callback, void* userdata);
     WGPUFuture GetCompilationInfoF(const WGPUCompilationInfoCallbackInfo& callbackInfo);
+    WGPUFuture GetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo);
 
   private:
     friend class Client;
diff --git a/src/dawn/wire/server/ServerShaderModule.cpp b/src/dawn/wire/server/ServerShaderModule.cpp
index 21c28aa..effb4e0 100644
--- a/src/dawn/wire/server/ServerShaderModule.cpp
+++ b/src/dawn/wire/server/ServerShaderModule.cpp
@@ -38,9 +38,10 @@
     userdata->eventManager = eventManager;
     userdata->future = future;
 
-    mProcs.shaderModuleGetCompilationInfo(
-        shaderModule->handle, ForwardToServer<&Server::OnShaderModuleGetCompilationInfo>,
-        userdata.release());
+    mProcs.shaderModuleGetCompilationInfo2(
+        shaderModule->handle,
+        {nullptr, WGPUCallbackMode_AllowProcessEvents,
+         ForwardToServer2<&Server::OnShaderModuleGetCompilationInfo>, userdata.release(), nullptr});
     return WireResult::Success;
 }