[WebGPU] Implement GPUUncapturedErrorEvent
authorjustin_fan@apple.com <justin_fan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Sep 2019 19:21:58 +0000 (19:21 +0000)
committerjustin_fan@apple.com <justin_fan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Sep 2019 19:21:58 +0000 (19:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199676

Reviewed by Dean Jackson.

Source/WebCore:

Implement GPUUncapturedErrorEvent and "uncapturederror" event name.
Add the onuncapturederror EventHandler attribute to GPUDevice.

Test: webgpu/uncaptured-errors.html

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Modules/webgpu/GPUUncapturedErrorEvent.cpp:
(WebCore::GPUUncapturedErrorEvent::create):
(WebCore::GPUUncapturedErrorEvent::GPUUncapturedErrorEvent):
(WebCore::GPUUncapturedErrorEvent::eventInterface const):
* Modules/webgpu/GPUUncapturedErrorEvent.h:
* Modules/webgpu/GPUUncapturedErrorEvent.idl:
* Modules/webgpu/WebGPUAdapter.cpp: Must now provide ScriptExecutionContext to any created GPUDevice.
(WebCore::WebGPUAdapter::requestDevice const):
* Modules/webgpu/WebGPUAdapter.h:
* Modules/webgpu/WebGPUAdapter.idl:
* Modules/webgpu/WebGPUDevice.cpp: Is now an EventTarget.
(WebCore::WebGPUDevice::tryCreate):
(WebCore::WebGPUDevice::WebGPUDevice):
(WebCore::printValidationErrorToConsole):
(WebCore::WebGPUDevice::dispatchUncapturedError): Events should only be fired from the main thread.
* Modules/webgpu/WebGPUDevice.h:
* Modules/webgpu/WebGPUDevice.idl:
* Modules/webgpu/WebGPUDeviceEventHandler.idl:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/WebCoreBuiltinNames.h:
* dom/EventNames.h:
* dom/EventNames.in:
* dom/EventTargetFactory.in:
* platform/graphics/gpu/GPUError.cpp: GPUErrors can only be created internally; creation should never fail.
(WebCore::createError):
* platform/graphics/gpu/GPUError.h:
* platform/graphics/gpu/GPUErrorScopes.cpp:
(WebCore::GPUErrorScopes::create):
(WebCore::GPUErrorScopes::GPUErrorScopes):
(WebCore::GPUErrorScopes::generateError): Use a callback for now, since GPUErrorScopes is still under platform.
* platform/graphics/gpu/GPUErrorScopes.h:
(WebCore::GPUErrorScopes::create): Deleted.

LayoutTests:

Add a test to ensure GPUUncapturedErrorEvents work.

* webgpu/uncaptured-errors.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249539 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/uncaptured-errors.html [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources-input.xcfilelist
Source/WebCore/DerivedSources-output.xcfilelist
Source/WebCore/DerivedSources.make
Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.cpp [new file with mode: 0644]
Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.idl [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WebGPUAdapter.cpp
Source/WebCore/Modules/webgpu/WebGPUAdapter.h
Source/WebCore/Modules/webgpu/WebGPUAdapter.idl
Source/WebCore/Modules/webgpu/WebGPUDevice.cpp
Source/WebCore/Modules/webgpu/WebGPUDevice.h
Source/WebCore/Modules/webgpu/WebGPUDevice.idl
Source/WebCore/Modules/webgpu/WebGPUDeviceEventHandler.idl [new file with mode: 0644]
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/WebCoreBuiltinNames.h
Source/WebCore/dom/EventNames.h
Source/WebCore/dom/EventNames.in
Source/WebCore/dom/EventTargetFactory.in
Source/WebCore/platform/graphics/gpu/GPUError.cpp
Source/WebCore/platform/graphics/gpu/GPUError.h
Source/WebCore/platform/graphics/gpu/GPUErrorScopes.cpp
Source/WebCore/platform/graphics/gpu/GPUErrorScopes.h

index 71b9505..548ad60 100644 (file)
@@ -1,3 +1,14 @@
+2019-09-05  Justin Fan  <justin_fan@apple.com>
+
+        [WebGPU] Implement GPUUncapturedErrorEvent
+        https://bugs.webkit.org/show_bug.cgi?id=199676
+
+        Reviewed by Dean Jackson.
+
+        Add a test to ensure GPUUncapturedErrorEvents work.
+
+        * webgpu/uncaptured-errors.html: Added.
+
 2019-09-05  Ryan Haddad  <ryanhaddad@apple.com>
 
         [iOS] Layout Test imported/w3c/web-platform-tests/html/semantics/embedded-content/the-video-element/video_timeupdate_on_seek.html is failing
diff --git a/LayoutTests/webgpu/uncaptured-errors.html b/LayoutTests/webgpu/uncaptured-errors.html
new file mode 100644 (file)
index 0000000..9e2ec42
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test Error Scopes.</title>
+<body>
+<script src="js/webgpu-functions.js"></script>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+let tests = {};
+let eventWatcher;
+
+const causeUncapturedErrorEvent = device => {
+    device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.MAP_WRITE });
+};
+
+tests["Fire an uncaptured GPUDevice error event at 'device'."] = async device => {
+    const asyncTest = async_test("GPUUncapturedErrorEvent async test.");
+    const eventWatcher = new EventWatcher(asyncTest, device, "uncapturederror");
+    const eventFired = eventWatcher.wait_for("uncapturederror").then(event => {
+        assert_true(event.error instanceof GPUValidationError, "Successfully fired GPUUncapturedErrorEvent.");
+        asyncTest.done();
+    });
+
+    const timeout = new Promise((_, reject) => {
+        setTimeout(() => { reject("Timed out waiting for error event!") }, 3000);
+    });
+
+    causeUncapturedErrorEvent(device);
+
+    return Promise.race([eventFired, timeout]);
+};
+
+tests["Intercept an uncaptured error with GPUDevice.onuncapturederror EventHandler."] = async device => {
+    const capturedErrorPromise = new Promise(resolve => {
+        device.onuncapturederror = event => {
+            assert_true(event.error instanceof GPUValidationError, "Successfully fired GPUUncapturedErrorEvent.");
+            resolve();
+        };
+
+        causeUncapturedErrorEvent(device);
+    });
+
+    const timeout = new Promise((_, reject) => {
+        setTimeout(() => { reject("Timed out waiting for error event!") }, 3000);
+    });
+
+    return Promise.race([capturedErrorPromise, timeout]);
+};
+
+runTestsWithDevice(tests);
+</script>
+</body>
\ No newline at end of file
index 39c0ddc..9fb4e0b 100644 (file)
@@ -492,6 +492,7 @@ set(WebCore_NON_SVG_IDL_FILES
     Modules/webgpu/GPUTextureDescriptor.idl
     Modules/webgpu/GPUTextureFormat.idl
     Modules/webgpu/GPUTextureUsage.idl
+    Modules/webgpu/GPUUncapturedErrorEvent.idl
     Modules/webgpu/GPUValidationError.idl
     Modules/webgpu/GPUVertexAttributeDescriptor.idl
     Modules/webgpu/GPUVertexBufferDescriptor.idl
@@ -512,6 +513,7 @@ set(WebCore_NON_SVG_IDL_FILES
     Modules/webgpu/WebGPUComputePipelineDescriptor.idl
     Modules/webgpu/WebGPUDevice.idl
     Modules/webgpu/WebGPUDeviceErrorScopes.idl
+    Modules/webgpu/WebGPUDeviceEventHandler.idl
     Modules/webgpu/WebGPUPipelineDescriptorBase.idl
     Modules/webgpu/WebGPUPipelineLayout.idl
     Modules/webgpu/WebGPUPipelineLayoutDescriptor.idl
index 6fe1a27..d0c4c06 100644 (file)
@@ -1,3 +1,53 @@
+2019-09-05  Justin Fan  <justin_fan@apple.com>
+
+        [WebGPU] Implement GPUUncapturedErrorEvent
+        https://bugs.webkit.org/show_bug.cgi?id=199676
+
+        Reviewed by Dean Jackson.
+
+        Implement GPUUncapturedErrorEvent and "uncapturederror" event name.
+        Add the onuncapturederror EventHandler attribute to GPUDevice.
+
+        Test: webgpu/uncaptured-errors.html
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Modules/webgpu/GPUUncapturedErrorEvent.cpp:
+        (WebCore::GPUUncapturedErrorEvent::create):
+        (WebCore::GPUUncapturedErrorEvent::GPUUncapturedErrorEvent):
+        (WebCore::GPUUncapturedErrorEvent::eventInterface const):
+        * Modules/webgpu/GPUUncapturedErrorEvent.h:
+        * Modules/webgpu/GPUUncapturedErrorEvent.idl:
+        * Modules/webgpu/WebGPUAdapter.cpp: Must now provide ScriptExecutionContext to any created GPUDevice.
+        (WebCore::WebGPUAdapter::requestDevice const):
+        * Modules/webgpu/WebGPUAdapter.h:
+        * Modules/webgpu/WebGPUAdapter.idl:
+        * Modules/webgpu/WebGPUDevice.cpp: Is now an EventTarget.
+        (WebCore::WebGPUDevice::tryCreate):
+        (WebCore::WebGPUDevice::WebGPUDevice):
+        (WebCore::printValidationErrorToConsole):
+        (WebCore::WebGPUDevice::dispatchUncapturedError): Events should only be fired from the main thread.
+        * Modules/webgpu/WebGPUDevice.h:
+        * Modules/webgpu/WebGPUDevice.idl:
+        * Modules/webgpu/WebGPUDeviceEventHandler.idl:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/WebCoreBuiltinNames.h:
+        * dom/EventNames.h:
+        * dom/EventNames.in:
+        * dom/EventTargetFactory.in:
+        * platform/graphics/gpu/GPUError.cpp: GPUErrors can only be created internally; creation should never fail.
+        (WebCore::createError):
+        * platform/graphics/gpu/GPUError.h:
+        * platform/graphics/gpu/GPUErrorScopes.cpp:
+        (WebCore::GPUErrorScopes::create):
+        (WebCore::GPUErrorScopes::GPUErrorScopes):
+        (WebCore::GPUErrorScopes::generateError): Use a callback for now, since GPUErrorScopes is still under platform.
+        * platform/graphics/gpu/GPUErrorScopes.h:
+        (WebCore::GPUErrorScopes::create): Deleted.
+
 2019-09-05  Antti Koivisto  <antti@apple.com>
 
         Generate event region for both the main graphics layer and the scrolled contents layer
index f401f74..728d586 100644 (file)
@@ -346,6 +346,7 @@ $(PROJECT_DIR)/Modules/webgpu/GPUStoreOp.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUTextureDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUTextureFormat.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUTextureUsage.idl
+$(PROJECT_DIR)/Modules/webgpu/GPUUncapturedErrorEvent.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUValidationError.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUVertexAttributeDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUVertexBufferDescriptor.idl
@@ -368,6 +369,7 @@ $(PROJECT_DIR)/Modules/webgpu/WebGPUComputePipeline.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUComputePipelineDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUDevice.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUDeviceErrorScopes.idl
+$(PROJECT_DIR)/Modules/webgpu/WebGPUDeviceEventHandler.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUPipelineDescriptorBase.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUPipelineLayout.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUPipelineLayoutDescriptor.idl
index 014b15a..ecf2732 100644 (file)
@@ -635,6 +635,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUTextureFormat.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUTextureFormat.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUTextureUsage.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUTextureUsage.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUUncapturedErrorEvent.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUUncapturedErrorEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUValidationError.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUValidationError.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexAttributeDescriptor.cpp
@@ -775,8 +777,6 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLMeterElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLMeterElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLModElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLModElement.h
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOrForeignElement.cpp
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOrForeignElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOListElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOListElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLObjectElement.cpp
@@ -787,6 +787,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOptionElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOptionElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOptionsCollection.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOptionsCollection.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOrForeignElement.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOrForeignElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOutputElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLOutputElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLParagraphElement.cpp
@@ -1961,6 +1963,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDevice.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDevice.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDeviceErrorScopes.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDeviceErrorScopes.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDeviceEventHandler.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUDeviceEventHandler.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUPipelineDescriptorBase.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUPipelineDescriptorBase.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSWebGPUPipelineLayout.cpp
index eb6d827..0d3c69a 100644 (file)
@@ -398,6 +398,7 @@ JS_BINDING_IDLS = \
     $(WebCore)/Modules/webgpu/GPUTextureDescriptor.idl \
     $(WebCore)/Modules/webgpu/GPUTextureFormat.idl \
     $(WebCore)/Modules/webgpu/GPUTextureUsage.idl \
+    $(WebCore)/Modules/webgpu/GPUUncapturedErrorEvent.idl \
     $(WebCore)/Modules/webgpu/GPUValidationError.idl \
     $(WebCore)/Modules/webgpu/GPUVertexAttributeDescriptor.idl \
     $(WebCore)/Modules/webgpu/GPUVertexBufferDescriptor.idl \
@@ -418,6 +419,7 @@ JS_BINDING_IDLS = \
     $(WebCore)/Modules/webgpu/WebGPUComputePipelineDescriptor.idl \
     $(WebCore)/Modules/webgpu/WebGPUDevice.idl \
        $(WebCore)/Modules/webgpu/WebGPUDeviceErrorScopes.idl \
+    $(WebCore)/Modules/webgpu/WebGPUDeviceEventHandler.idl \
     $(WebCore)/Modules/webgpu/WebGPUQueue.idl \
     $(WebCore)/Modules/webgpu/WebGPUPipelineDescriptorBase.idl \
     $(WebCore)/Modules/webgpu/WebGPUPipelineLayout.idl \
diff --git a/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.cpp b/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.cpp
new file mode 100644 (file)
index 0000000..4e0150a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GPUUncapturedErrorEvent.h"
+
+#if ENABLE(WEBGPU)
+
+namespace WebCore {
+
+Ref<GPUUncapturedErrorEvent> GPUUncapturedErrorEvent::create(const AtomString& type, const Init& initializer, IsTrusted isTrusted)
+{
+    return adoptRef(*new GPUUncapturedErrorEvent(type, initializer, isTrusted));
+}
+
+Ref<GPUUncapturedErrorEvent> GPUUncapturedErrorEvent::create(const AtomString& type, GPUError&& error)
+{
+    return adoptRef(*new GPUUncapturedErrorEvent(type, WTFMove(error)));
+}
+
+GPUUncapturedErrorEvent::GPUUncapturedErrorEvent(const AtomString& type, const Init& initializer, IsTrusted isTrusted)
+    : Event(type, initializer, isTrusted)
+    , m_error(initializer.error)
+{
+}
+
+GPUUncapturedErrorEvent::GPUUncapturedErrorEvent(const AtomString& type, GPUError&& error)
+    : Event(type, CanBubble::No, IsCancelable::No)
+    , m_error(WTFMove(error))
+{
+}
+
+EventInterface GPUUncapturedErrorEvent::eventInterface() const
+{
+    return GPUUncapturedErrorEventInterfaceType;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
diff --git a/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.h b/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.h
new file mode 100644 (file)
index 0000000..1d9d41b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGPU)
+
+#include "Event.h"
+#include "GPUError.h"
+#include <wtf/Ref.h>
+
+namespace WebCore {
+
+class GPUUncapturedErrorEvent final : public Event {
+public:
+    struct Init: EventInit {
+        GPUError error;
+    };
+
+    static Ref<GPUUncapturedErrorEvent> create(const AtomString&, const Init&, IsTrusted = IsTrusted::No);
+    static Ref<GPUUncapturedErrorEvent> create(const AtomString&, GPUError&&);
+
+    const GPUError error() const { return m_error; }
+
+private:
+    GPUUncapturedErrorEvent(const AtomString&, const Init&, IsTrusted);
+    GPUUncapturedErrorEvent(const AtomString&, GPUError&&);
+
+    // Event
+    EventInterface eventInterface() const override;
+
+    GPUError m_error;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
diff --git a/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.idl b/Source/WebCore/Modules/webgpu/GPUUncapturedErrorEvent.idl
new file mode 100644 (file)
index 0000000..2d3c6a1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+// https://gpuweb.github.io/gpuweb
+
+typedef (GPUOutOfMemoryError or GPUValidationError) GPUError;
+
+[
+    Conditional=WEBGPU,
+    EnabledAtRuntime=WebGPU
+] dictionary GPUUncapturedErrorEventInit : EventInit {
+    required GPUError error;
+};
+
+[
+    Conditional=WEBGPU,
+    Constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict),
+    EnabledAtRuntime=WebGPU,
+    Exposed=Window
+] interface GPUUncapturedErrorEvent : Event {
+    readonly attribute GPUError error;
+};
index 618fa6f..52714fb 100644 (file)
@@ -28,8 +28,8 @@
 
 #if ENABLE(WEBGPU)
 
+#include "Document.h"
 #include "JSWebGPUDevice.h"
-#include "ScriptExecutionContext.h"
 
 namespace WebCore {
 
@@ -43,12 +43,14 @@ WebGPUAdapter::WebGPUAdapter(Optional<GPURequestAdapterOptions>&& options)
 {
 }
 
-void WebGPUAdapter::requestDevice(DeviceRequestPromise&& promise) const
+void WebGPUAdapter::requestDevice(Document& document, DeviceRequestPromise&& promise) const
 {
-    if (auto device = WebGPUDevice::tryCreate(*this))
-        promise.resolve(device.releaseNonNull());
-    else
-        promise.reject();
+    document.postTask([protectedThis = makeRef(*this), promise = WTFMove(promise)] (ScriptExecutionContext& context) mutable {
+        if (auto device = WebGPUDevice::tryCreate(context, protectedThis.get()))
+            promise.resolve(device.releaseNonNull());
+        else
+            promise.reject();
+    });
 }
 
 } // namespace WebCore
index 39ba3db..1849519 100644 (file)
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-class ScriptExecutionContext;
+class Document;
 class WebGPUDevice;
 
 class WebGPUAdapter : public RefCounted<WebGPUAdapter> {
@@ -43,7 +43,7 @@ public:
     static Ref<WebGPUAdapter> create(Optional<GPURequestAdapterOptions>&&);
 
     using DeviceRequestPromise = DOMPromiseDeferred<IDLInterface<WebGPUDevice>>;
-    void requestDevice(DeviceRequestPromise&&) const;
+    void requestDevice(Document&, DeviceRequestPromise&&) const;
     
     const Optional<GPURequestAdapterOptions>& options() const { return m_options; }
 
index d831903..7db95a6 100644 (file)
@@ -35,5 +35,5 @@
     // readonly attribute WebGPULimits limits; Don't expose higher limits for now.
 
     // May reject with DOMException  // TODO: DOMException("OperationError")?
-    Promise<WebGPUDevice> requestDevice(/*GPUDeviceDescriptor descriptor*/);
+    [CallWith=Document] Promise<WebGPUDevice> requestDevice(/*GPUDeviceDescriptor descriptor*/);
 };
index f404b80..c0f05fd 100644 (file)
@@ -28,6 +28,9 @@
 
 #if ENABLE(WEBGPU)
 
+#include "DOMWindow.h"
+#include "Document.h"
+#include "EventNames.h"
 #include "Exception.h"
 #include "GPUBindGroup.h"
 #include "GPUBindGroupBinding.h"
@@ -43,6 +46,7 @@
 #include "GPUSamplerDescriptor.h"
 #include "GPUShaderModuleDescriptor.h"
 #include "GPUTextureDescriptor.h"
+#include "GPUUncapturedErrorEvent.h"
 #include "JSDOMConvertBufferSource.h"
 #include "JSGPUOutOfMemoryError.h"
 #include "JSGPUValidationError.h"
 #include "WebGPUShaderModuleDescriptor.h"
 #include "WebGPUSwapChain.h"
 #include "WebGPUTexture.h"
+#include <JavaScriptCore/ConsoleMessage.h>
+#include <memory>
+#include <wtf/IsoMallocInlines.h>
+#include <wtf/MainThread.h>
 #include <wtf/Optional.h>
+#include <wtf/Variant.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-RefPtr<WebGPUDevice> WebGPUDevice::tryCreate(Ref<const WebGPUAdapter>&& adapter)
+WTF_MAKE_ISO_ALLOCATED_IMPL(WebGPUDevice);
+
+RefPtr<WebGPUDevice> WebGPUDevice::tryCreate(ScriptExecutionContext& context, Ref<const WebGPUAdapter>&& adapter)
 {
     if (auto device = GPUDevice::tryCreate(adapter->options()))
-        return adoptRef(new WebGPUDevice(WTFMove(adapter), device.releaseNonNull()));
+        return adoptRef(new WebGPUDevice(context, WTFMove(adapter), device.releaseNonNull()));
     return nullptr;
 }
 
-WebGPUDevice::WebGPUDevice(Ref<const WebGPUAdapter>&& adapter, Ref<GPUDevice>&& device)
-    : m_adapter(WTFMove(adapter))
+WebGPUDevice::WebGPUDevice(ScriptExecutionContext& context, Ref<const WebGPUAdapter>&& adapter, Ref<GPUDevice>&& device)
+    : m_scriptExecutionContext(context)
+    , m_adapter(WTFMove(adapter))
     , m_device(WTFMove(device))
-    , m_errorScopes(GPUErrorScopes::create())
+    , m_errorScopes(GPUErrorScopes::create([this, weakThis = makeWeakPtr(this)] (GPUError&& error) {
+        if (weakThis)
+            dispatchUncapturedError(WTFMove(error));
+    }))
 {
+    ASSERT(m_scriptExecutionContext.isDocument());
 }
 
 Ref<WebGPUBuffer> WebGPUDevice::createBuffer(const GPUBufferDescriptor& descriptor) const
@@ -205,6 +221,31 @@ void WebGPUDevice::popErrorScope(ErrorPromise&& promise)
         promise.reject(Exception { OperationError, "GPUDevice::popErrorScope(): " + failMessage });
 }
 
+// Errors reported via the validation error event should also appear in the console as warnings.
+static void printValidationErrorToConsole(GPUError& error, ScriptExecutionContext& context)
+{
+    if (!WTF::holds_alternative<RefPtr<GPUValidationError>>(error))
+        return;
+
+    auto validationError = WTF::get<RefPtr<GPUValidationError>>(error);
+    if (!validationError)
+        return;
+
+    auto message = validationError->message();
+    auto consoleMessage = makeUnique<Inspector::ConsoleMessage>(MessageSource::Rendering, MessageType::Log, MessageLevel::Warning, message);
+
+    downcast<Document>(context).addConsoleMessage(WTFMove(consoleMessage));
+}
+
+void WebGPUDevice::dispatchUncapturedError(GPUError&& error)
+{
+    printValidationErrorToConsole(error, m_scriptExecutionContext);
+
+    callOnMainThread([error = WTFMove(error), this, protectedThis = makeRef(*this)] () mutable {
+        dispatchEvent(GPUUncapturedErrorEvent::create(eventNames().uncapturederrorEvent, WTFMove(error)));
+    });
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBGPU)
index f4e43f2..ce454a9 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "EventTarget.h"
 #include "GPUDevice.h"
 #include "GPUErrorScopes.h"
 #include "JSDOMPromiseDeferred.h"
@@ -37,6 +38,7 @@
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
 
 namespace JSC {
 class ArrayBuffer;
@@ -75,9 +77,10 @@ enum class GPUErrorFilter;
 using ErrorIDLUnion = IDLUnion<IDLInterface<GPUOutOfMemoryError>, IDLInterface<GPUValidationError>>;
 using ErrorPromise = DOMPromiseDeferred<IDLNullable<ErrorIDLUnion>>;
 
-class WebGPUDevice : public RefCounted<WebGPUDevice> {
+class WebGPUDevice : public RefCounted<WebGPUDevice>, public EventTargetWithInlineData, public CanMakeWeakPtr<WebGPUDevice> {
+    WTF_MAKE_ISO_ALLOCATED(WebGPUDevice);
 public:
-    static RefPtr<WebGPUDevice> tryCreate(Ref<const WebGPUAdapter>&&);
+    static RefPtr<WebGPUDevice> tryCreate(ScriptExecutionContext&, Ref<const WebGPUAdapter>&&);
 
     const WebGPUAdapter& adapter() const { return m_adapter.get(); }
     GPUDevice& device() { return m_device.get(); }
@@ -103,8 +106,21 @@ public:
     void pushErrorScope(GPUErrorFilter filter) { m_errorScopes->pushErrorScope(filter); }
     void popErrorScope(ErrorPromise&&);
 
+    using RefCounted::ref;
+    using RefCounted::deref;
+
 private:
-    WebGPUDevice(Ref<const WebGPUAdapter>&&, Ref<GPUDevice>&&);
+    WebGPUDevice(ScriptExecutionContext&, Ref<const WebGPUAdapter>&&, Ref<GPUDevice>&&);
+
+    // EventTarget
+    EventTargetInterface eventTargetInterface() const final { return WebGPUDeviceEventTargetInterfaceType; }
+    ScriptExecutionContext* scriptExecutionContext() const final { return &m_scriptExecutionContext; }
+    void refEventTarget() final { ref(); }
+    void derefEventTarget() final { deref(); }
+
+    void dispatchUncapturedError(GPUError&&);
+
+    ScriptExecutionContext& m_scriptExecutionContext;
 
     Ref<const WebGPUAdapter> m_adapter;
     Ref<GPUDevice> m_device;
index f5ff008..cff4a98 100644 (file)
@@ -29,9 +29,8 @@ typedef sequence<any> GPUMappedBuffer;  // [GPUBuffer, ArrayBuffer]
 [
     Conditional=WEBGPU,
     EnabledAtRuntime=WebGPU,
-    ImplementationLacksVTable,
     InterfaceName=GPUDevice
-] interface WebGPUDevice {
+] interface WebGPUDevice : EventTarget {
     readonly attribute WebGPUAdapter adapter;
 
     WebGPUBuffer createBuffer(GPUBufferDescriptor descriptor);
diff --git a/Source/WebCore/Modules/webgpu/WebGPUDeviceEventHandler.idl b/Source/WebCore/Modules/webgpu/WebGPUDeviceEventHandler.idl
new file mode 100644 (file)
index 0000000..f545331
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+// https://gpuweb.github.io/gpuweb
+
+[
+    Conditional=WEBGPU,
+    EnabledAtRuntime=WebGPU
+] partial interface WebGPUDevice {
+    [Exposed=Window]
+    attribute EventHandler onuncapturederror;
+};
index 36dc770..fec1ca4 100644 (file)
@@ -303,6 +303,7 @@ Modules/websockets/WebSocketHandshake.cpp
 Modules/websockets/WorkerThreadableWebSocketChannel.cpp
 
 Modules/webgpu/GPUCanvasContext.cpp
+Modules/webgpu/GPUUncapturedErrorEvent.cpp
 Modules/webgpu/NavigatorGPU.cpp
 Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp
 Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp
@@ -2831,6 +2832,7 @@ JSGPUStoreOp.cpp
 JSGPUTextureDescriptor.cpp
 JSGPUTextureFormat.cpp
 JSGPUTextureUsage.cpp
+JSGPUUncapturedErrorEvent.cpp
 JSGPUValidationError.cpp
 JSGPUVertexAttributeDescriptor.cpp
 JSGPUVertexBufferDescriptor.cpp
@@ -3388,6 +3390,7 @@ JSWebGPUComputePipeline.cpp
 JSWebGPUComputePipelineDescriptor.cpp
 JSWebGPUDevice.cpp
 JSWebGPUDeviceErrorScopes.cpp
+JSWebGPUDeviceEventHandler.cpp
 JSWebGPUQueue.cpp
 JSWebGPUPipelineDescriptorBase.cpp
 JSWebGPUPipelineLayout.cpp
index 8196430..41d329e 100644 (file)
                D093D225217951D400329217 /* GPUCanvasContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUCanvasContext.h; sourceTree = "<group>"; };
                D093D227217951D400329217 /* GPUCanvasContext.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUCanvasContext.idl; sourceTree = "<group>"; };
                D093D2292179541600329217 /* GPUCanvasContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUCanvasContext.cpp; sourceTree = "<group>"; };
+               D09AC00523171F5200187762 /* GPUUncapturedErrorEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUUncapturedErrorEvent.h; sourceTree = "<group>"; };
+               D09AC00623171F5200187762 /* GPUUncapturedErrorEvent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUUncapturedErrorEvent.cpp; sourceTree = "<group>"; };
+               D09AC00723171F5200187762 /* GPUUncapturedErrorEvent.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUUncapturedErrorEvent.idl; sourceTree = "<group>"; };
+               D09AC00A231735BE00187762 /* WebGPUDeviceEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUDeviceEventHandler.h; sourceTree = "<group>"; };
+               D09AC00B231735BE00187762 /* WebGPUDeviceEventHandler.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGPUDeviceEventHandler.idl; sourceTree = "<group>"; };
                D09AFAFF22D02E5300C4538C /* WebGPUDeviceErrorScopes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUDeviceErrorScopes.h; sourceTree = "<group>"; };
                D09AFB0122D02E5300C4538C /* WebGPUDeviceErrorScopes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUDeviceErrorScopes.cpp; sourceTree = "<group>"; };
                D09AFB0222D0471900C4538C /* GPUErrorFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPUErrorFilter.h; sourceTree = "<group>"; };
                                D026F48B220A5B0B00AC5F49 /* GPUTextureDescriptor.idl */,
                                D0EACFAE219E30FD000FA75C /* GPUTextureFormat.idl */,
                                D026F483220A472F00AC5F49 /* GPUTextureUsage.idl */,
+                               D09AC00623171F5200187762 /* GPUUncapturedErrorEvent.cpp */,
+                               D09AC00523171F5200187762 /* GPUUncapturedErrorEvent.h */,
+                               D09AC00723171F5200187762 /* GPUUncapturedErrorEvent.idl */,
                                D09AFB0C22D55E9000C4538C /* GPUValidationError.idl */,
                                D0D8649621BA18F4003C983C /* GPUVertexAttributeDescriptor.idl */,
                                D0D8649821BA19A7003C983C /* GPUVertexBufferDescriptor.idl */,
                                D09AFB0122D02E5300C4538C /* WebGPUDeviceErrorScopes.cpp */,
                                D09AFAFF22D02E5300C4538C /* WebGPUDeviceErrorScopes.h */,
                                D09AFB0322D40CC500C4538C /* WebGPUDeviceErrorScopes.idl */,
+                               D09AC00A231735BE00187762 /* WebGPUDeviceEventHandler.h */,
+                               D09AC00B231735BE00187762 /* WebGPUDeviceEventHandler.idl */,
                                D0C419F02183EB31009EC1DE /* WebGPUPipelineDescriptorBase.h */,
                                D0C419F12183EB31009EC1DE /* WebGPUPipelineDescriptorBase.idl */,
                                D05A99E521C9BF2C00032B75 /* WebGPUPipelineLayout.cpp */,
index d884c66..1f08dc8 100644 (file)
@@ -107,6 +107,7 @@ namespace WebCore {
     macro(GPUTexture) \
     macro(GPUTextureUsage) \
     macro(GPUTextureView) \
+    macro(GPUUncapturedErrorEvent) \
     macro(GPUValidationError) \
     macro(HTMLAttachmentElement) \
     macro(HTMLAudioElement) \
@@ -285,6 +286,7 @@ namespace WebCore {
     macro(ontouchmove) \
     macro(ontouchstart) \
     macro(ontouchforcechange) \
+    macro(onuncapturederror) \
     macro(onvrdisplayactivate) \
     macro(onvrdisplayblur) \
     macro(onvrdisplayconnect) \
index 5b6ab68..fc4fd5c 100644 (file)
@@ -267,6 +267,7 @@ namespace WebCore {
     macro(transitionend) \
     macro(transitionrun) \
     macro(transitionstart) \
+    macro(uncapturederror) \
     macro(unhandledrejection) \
     macro(unload) \
     macro(unmute) \
index 8fda06d..ebc2425 100644 (file)
@@ -82,3 +82,4 @@ MediaEncryptedEvent conditional=ENCRYPTED_MEDIA
 MediaKeyMessageEvent conditional=ENCRYPTED_MEDIA
 VRDisplayEvent
 PointerEvent conditional=POINTER_EVENTS
+GPUUncapturedErrorEvent conditional=WEBGPU
index 8ca38a3..9b9bf93 100644 (file)
@@ -49,6 +49,7 @@ VRDisplay
 VideoTrackList conditional=VIDEO_TRACK
 VisualViewport
 WebAnimation
+WebGPUDevice conditional=WEBGPU
 WebKitMediaKeySession conditional=LEGACY_ENCRYPTED_MEDIA
 WebSocket
 Worker
index e864a3d..bb28d4f 100644 (file)
 
 namespace WebCore {
 
-Optional<GPUError> createError(GPUErrorFilter filter, const String& message)
+GPUError createError(GPUErrorFilter filter, const String& message)
 {
     switch (filter) {
     case GPUErrorFilter::OutOfMemory:
         return GPUError(RefPtr<GPUOutOfMemoryError>(GPUOutOfMemoryError::create()));
     case GPUErrorFilter::Validation:
         return GPUError(RefPtr<GPUValidationError>(GPUValidationError::create(message)));
-    default:
+    case GPUErrorFilter::None:
         ASSERT_NOT_REACHED();
-        return WTF::nullopt;
+        return GPUError(RefPtr<GPUValidationError>(GPUValidationError::create("Bad error!")));
     }
 }
 
index e67c35a..69fc8fa 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "GPUOutOfMemoryError.h"
 #include "GPUValidationError.h"
-#include <wtf/Optional.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Variant.h>
 #include <wtf/text/WTFString.h>
@@ -40,7 +39,7 @@ enum class GPUErrorFilter;
 
 using GPUError = Variant<RefPtr<GPUOutOfMemoryError>, RefPtr<GPUValidationError>>;
 
-Optional<GPUError> createError(GPUErrorFilter, const String&);
+GPUError createError(GPUErrorFilter, const String&);
 
 } // namespace WebCore
 
index ff93855..04e5734 100644 (file)
 
 namespace WebCore {
 
+const unsigned maxUncapturedErrorEventsAllowed = 256;
+
+Ref<GPUErrorScopes> GPUErrorScopes::create(UncapturedErrorCallback&& callback)
+{
+    return adoptRef(*new GPUErrorScopes(WTFMove(callback)));
+}
+
+GPUErrorScopes::GPUErrorScopes(UncapturedErrorCallback&& callback)
+    : m_uncapturedErrorCallback(WTFMove(callback))
+    , m_numUncapturedErrorEventsAllowed(maxUncapturedErrorEventsAllowed)
+{
+}
+
 void GPUErrorScopes::pushErrorScope(GPUErrorFilter filter)
 {
     m_errorScopes.append(ErrorScope { filter, WTF::nullopt });
@@ -52,9 +65,16 @@ void GPUErrorScopes::generateError(const String& message, GPUErrorFilter filter)
         return scope.filter == GPUErrorFilter::None || scope.filter == filter;
     });
 
-    // FIXME: https://webkit.org/b/199676 Uncaptured errors need to be fired as GPUUncapturedErrorEvents.
-    if (iterator == m_errorScopes.rend())
+    if (iterator == m_errorScopes.rend()) {
+        if (!m_numUncapturedErrorEventsAllowed)
+            return;
+
+        m_uncapturedErrorCallback(createError(filter, message));
+        if (!(--m_numUncapturedErrorEventsAllowed))
+            m_uncapturedErrorCallback(createError(GPUErrorFilter::Validation, "WebGPU: Too many errors; no more error events will fire on this GPUDevice."));
+
         return;
+    }
 
     // If the scope has already captured an error, ignore this new one.
     if (iterator->error)
index af88588..4d4fd5a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "GPUError.h"
 #include "GPUErrorFilter.h"
+#include <wtf/Function.h>
 #include <wtf/Optional.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -39,7 +40,8 @@ namespace WebCore {
 
 class GPUErrorScopes : public RefCounted<GPUErrorScopes> {
 public:
-    static Ref<GPUErrorScopes> create() { return adoptRef(*new GPUErrorScopes); }
+    using UncapturedErrorCallback = Function<void(GPUError&&)>;
+    static Ref<GPUErrorScopes> create(UncapturedErrorCallback&&);
 
     void pushErrorScope(GPUErrorFilter);
     Optional<GPUError> popErrorScope(String& failMessage);
@@ -54,10 +56,13 @@ private:
         Optional<GPUError> error;
     };
 
-    GPUErrorScopes() = default;
+    GPUErrorScopes(UncapturedErrorCallback&&);
+
+    UncapturedErrorCallback m_uncapturedErrorCallback;
 
     Vector<ErrorScope> m_errorScopes;
     String m_prefix;
+    unsigned m_numUncapturedErrorEventsAllowed;
 };
 
 } // namespace WebCore