Title: [292747] trunk/Source/WebGPU
Revision
292747
Author
mmaxfi...@apple.com
Date
2022-04-11 17:30:21 -0700 (Mon, 11 Apr 2022)

Log Message

[WebGPU] Make sure asynchronous things are asynchronous
https://bugs.webkit.org/show_bug.cgi?id=239056

Reviewed by Kimmo Kinnunen.

This isn't strictly necessary, because these asynchronous callbacks get hooked up
to promises in the browser which only call their callbacks at microtask boundaries.
However, for native code that uses WebGPU.framework, it's probably better to make
sure the asynchronous callbacks are actually asynchronous.

* WebGPU/Adapter.mm:
(WebGPU::Adapter::requestDevice):
* WebGPU/Buffer.mm:
(WebGPU::Buffer::mapAsync):
* WebGPU/ComputePipeline.mm:
(WebGPU::Device::createComputePipelineAsync):
* WebGPU/Device.mm:
(WebGPU::Device::loseTheDevice):
(WebGPU::Device::popErrorScope):
* WebGPU/Instance.mm:
(WebGPU::Instance::requestAdapter):
* WebGPU/RenderPipeline.mm:
(WebGPU::Device::createRenderPipelineAsync):
* WebGPU/ShaderModule.mm:
(WebGPU::ShaderModule::getCompilationInfo):

Modified Paths

Diff

Modified: trunk/Source/WebGPU/ChangeLog (292746 => 292747)


--- trunk/Source/WebGPU/ChangeLog	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/ChangeLog	2022-04-12 00:30:21 UTC (rev 292747)
@@ -1,5 +1,33 @@
 2022-04-11  Myles C. Maxfield  <mmaxfi...@apple.com>
 
+        [WebGPU] Make sure asynchronous things are asynchronous
+        https://bugs.webkit.org/show_bug.cgi?id=239056
+
+        Reviewed by Kimmo Kinnunen.
+
+        This isn't strictly necessary, because these asynchronous callbacks get hooked up
+        to promises in the browser which only call their callbacks at microtask boundaries.
+        However, for native code that uses WebGPU.framework, it's probably better to make
+        sure the asynchronous callbacks are actually asynchronous.
+
+        * WebGPU/Adapter.mm:
+        (WebGPU::Adapter::requestDevice):
+        * WebGPU/Buffer.mm:
+        (WebGPU::Buffer::mapAsync):
+        * WebGPU/ComputePipeline.mm:
+        (WebGPU::Device::createComputePipelineAsync):
+        * WebGPU/Device.mm:
+        (WebGPU::Device::loseTheDevice):
+        (WebGPU::Device::popErrorScope):
+        * WebGPU/Instance.mm:
+        (WebGPU::Instance::requestAdapter):
+        * WebGPU/RenderPipeline.mm:
+        (WebGPU::Device::createRenderPipelineAsync):
+        * WebGPU/ShaderModule.mm:
+        (WebGPU::ShaderModule::getCompilationInfo):
+
+2022-04-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
         [WebGPU] Implement missing validity checks
         https://bugs.webkit.org/show_bug.cgi?id=238722
 

Modified: trunk/Source/WebGPU/WebGPU/Adapter.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/Adapter.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/Adapter.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -114,21 +114,30 @@
 void Adapter::requestDevice(const WGPUDeviceDescriptor& descriptor, CompletionHandler<void(WGPURequestDeviceStatus, Ref<Device>&&, String&&)>&& callback)
 {
     if (descriptor.nextInChain) {
-        callback(WGPURequestDeviceStatus_Error, Device::createInvalid(*this), "Unknown descriptor type"_s);
+        instance().scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestDeviceStatus_Error, Device::createInvalid(strongThis), "Unknown descriptor type"_s);
+        });
         return;
     }
 
     if (descriptor.requiredFeaturesCount) {
-        callback(WGPURequestDeviceStatus_Error, Device::createInvalid(*this), "Device does not support requested features"_s);
+        instance().scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestDeviceStatus_Error, Device::createInvalid(strongThis), "Device does not support requested features"_s);
+        });
         return;
     }
 
     if (descriptor.requiredLimits && !deviceMeetsRequiredLimits(m_device, *descriptor.requiredLimits)) {
-        callback(WGPURequestDeviceStatus_Error, Device::createInvalid(*this), "Device does not support requested limits"_s);
+        instance().scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestDeviceStatus_Error, Device::createInvalid(strongThis), "Device does not support requested limits"_s);
+        });
         return;
     }
 
-    callback(WGPURequestDeviceStatus_Success, Device::create(m_device, String::fromLatin1(descriptor.label), *this), { });
+    auto label = String::fromLatin1(descriptor.label);
+    instance().scheduleWork([strongThis = Ref { *this }, label = WTFMove(label), callback = WTFMove(callback)]() mutable {
+        callback(WGPURequestDeviceStatus_Success, Device::create(strongThis->m_device, WTFMove(label), strongThis), { });
+    });
 }
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/Buffer.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/Buffer.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/Buffer.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -252,7 +252,9 @@
     if (!validateMapAsync(mode, offset, rangeSize)) {
         m_device->generateAValidationError("Validation failure."_s);
 
-        callback(WGPUBufferMapAsyncStatus_Error);
+        m_device->instance().scheduleWork([callback = WTFMove(callback)]() mutable {
+            callback(WGPUBufferMapAsyncStatus_Error);
+        });
         return;
     }
 

Modified: trunk/Source/WebGPU/WebGPU/ComputePipeline.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/ComputePipeline.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/ComputePipeline.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -172,7 +172,9 @@
 {
     // FIXME: Implement this
     UNUSED_PARAM(descriptor);
-    callback(WGPUCreatePipelineAsyncStatus_Error, ComputePipeline::createInvalid(*this), { });
+    instance().scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+        callback(WGPUCreatePipelineAsyncStatus_Error, ComputePipeline::createInvalid(strongThis), { });
+    });
 }
 
 ComputePipeline::ComputePipeline(id<MTLComputePipelineState> computePipelineState, Device& device)

Modified: trunk/Source/WebGPU/WebGPU/Device.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/Device.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/Device.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -115,8 +115,11 @@
 
     makeInvalid();
 
-    if (m_deviceLostCallback)
-        m_deviceLostCallback(reason, "Device lost."_s);
+    if (m_deviceLostCallback) {
+        instance().scheduleWork([deviceLostCallback = WTFMove(m_deviceLostCallback), reason]() {
+            deviceLostCallback(reason, "Device lost."_s);
+        });
+    }
 
     // FIXME: The spec doesn't actually say to do this, but it's pretty important because
     // the total number of command queues alive at a time is limited to a pretty low limit.
@@ -206,7 +209,9 @@
     // https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope
 
     if (!validatePopErrorScope()) {
-        callback(WGPUErrorType_Unknown, "popErrorScope() failed validation."_s);
+        instance().scheduleWork([callback = WTFMove(callback)]() mutable {
+            callback(WGPUErrorType_Unknown, "popErrorScope() failed validation."_s);
+        });
         return false;
     }
 

Modified: trunk/Source/WebGPU/WebGPU/Instance.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/Instance.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/Instance.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -149,31 +149,43 @@
     auto sortedDevices = WebGPU::sortedDevices(devices, options.powerPreference);
 
     if (options.nextInChain) {
-        callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(*this), "Unknown descriptor type"_s);
+        scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(strongThis), "Unknown descriptor type"_s);
+        });
         return;
     }
 
     if (options.forceFallbackAdapter) {
-        callback(WGPURequestAdapterStatus_Unavailable, Adapter::createInvalid(*this), "No adapters present"_s);
+        scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestAdapterStatus_Unavailable, Adapter::createInvalid(strongThis), "No adapters present"_s);
+        });
         return;
     }
 
     if (!sortedDevices) {
-        callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(*this), "Unknown power preference"_s);
+        scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(strongThis), "Unknown power preference"_s);
+        });
         return;
     }
 
     if (!sortedDevices.count) {
-        callback(WGPURequestAdapterStatus_Unavailable, Adapter::createInvalid(*this), "No adapters present"_s);
+        scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestAdapterStatus_Unavailable, Adapter::createInvalid(strongThis), "No adapters present"_s);
+        });
         return;
     }
 
     if (!sortedDevices[0]) {
-        callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(*this), "Adapter is internally null"_s);
+        scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+            callback(WGPURequestAdapterStatus_Error, Adapter::createInvalid(strongThis), "Adapter is internally null"_s);
+        });
         return;
     }
 
-    callback(WGPURequestAdapterStatus_Success, Adapter::create(sortedDevices[0], *this), { });
+    scheduleWork([strongThis = Ref { *this }, device = sortedDevices[0], callback = WTFMove(callback)]() mutable {
+        callback(WGPURequestAdapterStatus_Success, Adapter::create(device, strongThis), { });
+    });
 }
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/RenderPipeline.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/RenderPipeline.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/RenderPipeline.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -42,7 +42,9 @@
 {
     // FIXME: Implement this.
     UNUSED_PARAM(descriptor);
-    callback(WGPUCreatePipelineAsyncStatus_Error, RenderPipeline::createInvalid(*this), { });
+    instance().scheduleWork([strongThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
+        callback(WGPUCreatePipelineAsyncStatus_Error, RenderPipeline::createInvalid(strongThis), { });
+    });
 }
 
 RenderPipeline::RenderPipeline(id<MTLRenderPipelineState> renderPipelineState, Device& device)

Modified: trunk/Source/WebGPU/WebGPU/ShaderModule.mm (292746 => 292747)


--- trunk/Source/WebGPU/WebGPU/ShaderModule.mm	2022-04-12 00:23:05 UTC (rev 292746)
+++ trunk/Source/WebGPU/WebGPU/ShaderModule.mm	2022-04-12 00:30:21 UTC (rev 292747)
@@ -207,7 +207,9 @@
             static_cast<uint32_t>(compilationMessageData.compilationMessages.size()),
             compilationMessageData.compilationMessages.data(),
         };
-        callback(WGPUCompilationInfoRequestStatus_Success, compilationInfo);
+        m_device->instance().scheduleWork([compilationInfo = WTFMove(compilationInfo), callback = WTFMove(callback)]() mutable {
+            callback(WGPUCompilationInfoRequestStatus_Success, compilationInfo);
+        });
     }, [&](const WGSL::FailedCheck& failedCheck) {
         auto compilationMessageData(convertMessages(
             { failedCheck.errors, WGPUCompilationMessageType_Error },
@@ -217,7 +219,9 @@
             static_cast<uint32_t>(compilationMessageData.compilationMessages.size()),
             compilationMessageData.compilationMessages.data(),
         };
-        callback(WGPUCompilationInfoRequestStatus_Error, compilationInfo);
+        m_device->instance().scheduleWork([compilationInfo = WTFMove(compilationInfo), callback = WTFMove(callback)]() mutable {
+            callback(WGPUCompilationInfoRequestStatus_Error, compilationInfo);
+        });
     }, [](std::monostate) {
         ASSERT_NOT_REACHED();
     });
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to