Diff
Modified: trunk/Source/WebCore/ChangeLog (247396 => 247397)
--- trunk/Source/WebCore/ChangeLog 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/ChangeLog 2019-07-12 21:07:49 UTC (rev 247397)
@@ -1,3 +1,50 @@
+2019-07-12 Justin Fan <justin_...@apple.com>
+
+ [WebGPU] Move error scopes out of GPUDevice for more portable error generation
+ https://bugs.webkit.org/show_bug.cgi?id=199740
+
+ Reviewed by Myles C. Maxfield.
+
+ Move error generation into a separate RefCounted class to allow GPU objects to generate
+ errors independent of any GPUDevice.
+ Create GPUObjectBase to delegate error generation and refactor GPUBuffer to inherit from GPUObjectBase.
+
+ No behavior change or new tests. Error scopes covered by error-scopes-test.html.
+
+ * Modules/webgpu/WebGPUDevice.cpp:
+ (WebCore::WebGPUDevice::WebGPUDevice): Now creates a GPUErrorGenerator.
+ (WebCore::WebGPUDevice::createBuffer const): Pass the GPUErrorGenerator to any created GPUBuffer.
+ (WebCore::WebGPUDevice::createBufferMapped const): Ditto.
+ (WebCore::WebGPUDevice::popErrorScope): Shouldn't be const. Can just ask for the GPUError rather than passing a lambda.
+ (WebCore::WebGPUDevice::pushErrorScope const): Deleted.
+ (WebCore::WebGPUDevice::popErrorScope const): Deleted.
+ * Modules/webgpu/WebGPUDevice.h:
+ (WebCore::WebGPUDevice::pushErrorScope):
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/gpu/GPUBuffer.h: Now inherits from GPUObjectBase for error generation ease.
+ * platform/graphics/gpu/GPUDevice.cpp:
+ (WebCore::GPUDevice::tryCreateBuffer): Ensure GPUBuffers reference the GPUErrorGenerator.
+ (WebCore::GPUDevice::pushErrorScope): Deleted. No longer needed here.
+ (WebCore::GPUDevice::popErrorScope): Deleted.
+ (WebCore::GPUDevice::registerError): Deleted.
+ * platform/graphics/gpu/GPUDevice.h: Move error scope logic out.
+ * platform/graphics/gpu/GPUErrorGenerator.cpp: Added.
+ (WebCore::GPUErrorGenerator::pushErrorScope):
+ (WebCore::GPUErrorGenerator::popErrorScope):
+ (WebCore::GPUErrorGenerator::generateError):
+ * platform/graphics/gpu/GPUErrorGenerator.h: Added.
+ (WebCore::GPUErrorGenerator::create):
+ * platform/graphics/gpu/GPUObjectBase.h: Added.
+ (WebCore::GPUObjectBase::generateError):
+ (WebCore::GPUObjectBase::GPUObjectBase):
+ * platform/graphics/gpu/cocoa/GPUBufferMetal.mm: Use the GPUErrorGenerator directly during buffer creation.
+ (WebCore::GPUBuffer::validateBufferUsage):
+ (WebCore::GPUBuffer::tryCreate):
+ (WebCore::GPUBuffer::GPUBuffer):
+ * platform/graphics/gpu/cocoa/GPUQueueMetal.mm:
+ (WebCore::GPUQueue::submit): Prevent possible null dereference.
+
2019-07-12 Youenn Fablet <you...@apple.com>
Add release logging for quota checks
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp (247396 => 247397)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp 2019-07-12 21:07:49 UTC (rev 247397)
@@ -67,6 +67,7 @@
#include "WebGPUSwapChain.h"
#include "WebGPUTexture.h"
#include <wtf/Optional.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -80,12 +81,13 @@
WebGPUDevice::WebGPUDevice(Ref<const WebGPUAdapter>&& adapter, Ref<GPUDevice>&& device)
: m_adapter(WTFMove(adapter))
, m_device(WTFMove(device))
+ , m_errorScopes(GPUErrorScopes::create())
{
}
Ref<WebGPUBuffer> WebGPUDevice::createBuffer(const GPUBufferDescriptor& descriptor) const
{
- auto buffer = m_device->tryCreateBuffer(descriptor);
+ auto buffer = m_device->tryCreateBuffer(descriptor, GPUBufferMappedOption::NotMapped, m_errorScopes.copyRef());
return WebGPUBuffer::create(WTFMove(buffer));
}
@@ -93,7 +95,7 @@
{
JSC::JSValue wrappedArrayBuffer = JSC::jsNull();
- auto buffer = m_device->tryCreateBuffer(descriptor, true);
+ auto buffer = m_device->tryCreateBuffer(descriptor, GPUBufferMappedOption::IsMapped, m_errorScopes.copyRef());
if (buffer) {
auto arrayBuffer = buffer->mapOnCreation();
wrappedArrayBuffer = toJS(&state, JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), arrayBuffer);
@@ -184,21 +186,16 @@
return makeRef(*m_queue.get());
}
-void WebGPUDevice::pushErrorScope(GPUErrorFilter filter) const
+void WebGPUDevice::popErrorScope(ErrorPromise&& promise)
{
- m_device->pushErrorScope(filter);
+ String failMessage;
+ Optional<GPUError> error = m_errorScopes->popErrorScope(failMessage);
+ if (failMessage.isEmpty())
+ promise.resolve(error);
+ else
+ promise.reject(Exception { OperationError, "GPUDevice::popErrorScope(): " + failMessage });
}
-void WebGPUDevice::popErrorScope(ErrorPromise&& promise) const
-{
- m_device->popErrorScope([promise = WTFMove(promise)] (Optional<GPUError>&& error, const String& failMessage) mutable {
- if (failMessage.isEmpty())
- promise.resolve(error);
- else
- promise.reject(Exception { OperationError, failMessage });
- });
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGPU)
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.h (247396 => 247397)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.h 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -28,6 +28,7 @@
#if ENABLE(WEBGPU)
#include "GPUDevice.h"
+#include "GPUErrorScopes.h"
#include "JSDOMPromiseDeferred.h"
#include "WebGPUAdapter.h"
#include "WebGPUQueue.h"
@@ -99,8 +100,8 @@
Ref<WebGPUQueue> getQueue() const;
- void pushErrorScope(GPUErrorFilter) const;
- void popErrorScope(ErrorPromise&&) const;
+ void pushErrorScope(GPUErrorFilter filter) { m_errorScopes->pushErrorScope(filter); }
+ void popErrorScope(ErrorPromise&&);
private:
WebGPUDevice(Ref<const WebGPUAdapter>&&, Ref<GPUDevice>&&);
@@ -108,6 +109,8 @@
Ref<const WebGPUAdapter> m_adapter;
Ref<GPUDevice> m_device;
mutable RefPtr<WebGPUQueue> m_queue;
+
+ Ref<GPUErrorScopes> m_errorScopes;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Sources.txt (247396 => 247397)
--- trunk/Source/WebCore/Sources.txt 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/Sources.txt 2019-07-12 21:07:49 UTC (rev 247397)
@@ -1829,6 +1829,7 @@
platform/graphics/gpu/GPUDevice.cpp
platform/graphics/gpu/GPUError.cpp
+platform/graphics/gpu/GPUErrorScopes.cpp
platform/graphics/gpu/GPUValidationError.cpp
platform/graphics/gpu/GPUPipelineLayout.cpp
platform/graphics/gpu/GPUProgrammablePassEncoder.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (247396 => 247397)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-07-12 21:07:49 UTC (rev 247397)
@@ -13954,6 +13954,8 @@
D03211CE21AC954E00763CF2 /* GPURenderPassEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPURenderPassEncoder.h; sourceTree = "<group>"; };
D03211CF21AC954E00763CF2 /* GPUProgrammablePassEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUProgrammablePassEncoder.h; sourceTree = "<group>"; };
D03211D021AC954F00763CF2 /* GPURenderPassDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPURenderPassDescriptor.h; sourceTree = "<group>"; };
+ D03586B122D7F2EA00DA0284 /* GPUErrorScopes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUErrorScopes.h; sourceTree = "<group>"; };
+ D03586B222D7F2EA00DA0284 /* GPUErrorScopes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUErrorScopes.cpp; sourceTree = "<group>"; };
D036DD8D208FFC0C00F9F4B2 /* WebGLCompressedTextureASTC.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGLCompressedTextureASTC.idl; sourceTree = "<group>"; };
D03C849A21FFC6670002227F /* GPUDepthStencilStateDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUDepthStencilStateDescriptor.h; sourceTree = "<group>"; };
D03C849C21FFC7FC0002227F /* GPUCompareFunction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUCompareFunction.h; sourceTree = "<group>"; };
@@ -14031,6 +14033,7 @@
D09AFB1722D6694E00C4538C /* GPUOutOfMemoryError.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUOutOfMemoryError.idl; sourceTree = "<group>"; };
D09AFB1922D6698A00C4538C /* GPUOutOfMemoryError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUOutOfMemoryError.h; sourceTree = "<group>"; };
D09AFB2D22D6C01400C4538C /* GPUError.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUError.cpp; sourceTree = "<group>"; };
+ D09AFB3722D7D5C600C4538C /* GPUObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUObjectBase.h; sourceTree = "<group>"; };
D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLCompressedTextureASTC.h; sourceTree = "<group>"; };
D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLCompressedTextureASTC.cpp; sourceTree = "<group>"; };
D0A3A7301405A39800FB8ED3 /* ResourceLoaderOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoaderOptions.h; sourceTree = "<group>"; };
@@ -18337,9 +18340,12 @@
D09AFB2D22D6C01400C4538C /* GPUError.cpp */,
D09AFB0722D5391B00C4538C /* GPUError.h */,
D09AFB0222D0471900C4538C /* GPUErrorFilter.h */,
+ D03586B222D7F2EA00DA0284 /* GPUErrorScopes.cpp */,
+ D03586B122D7F2EA00DA0284 /* GPUErrorScopes.h */,
D026F47D220A2AC600AC5F49 /* GPUExtent3D.h */,
D0F7559F2203BA1400118058 /* GPULimits.h */,
D08AA02F220D0BD50058C502 /* GPULoadOp.h */,
+ D09AFB3722D7D5C600C4538C /* GPUObjectBase.h */,
D09AFB1922D6698A00C4538C /* GPUOutOfMemoryError.h */,
312FF8C421A4C2F400EB199D /* GPUPipelineDescriptorBase.h */,
D003288721C9A4E500622AA6 /* GPUPipelineLayout.cpp */,
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -29,6 +29,7 @@
#include "DeferrableTask.h"
#include "GPUBufferUsage.h"
+#include "GPUObjectBase.h"
#include <wtf/Function.h>
#include <wtf/OptionSet.h>
#include <wtf/Ref.h>
@@ -51,6 +52,8 @@
struct GPUBufferDescriptor;
+enum class GPUBufferMappedOption;
+
#if USE(METAL)
using PlatformBuffer = MTLBuffer;
#else
@@ -58,7 +61,7 @@
#endif
using PlatformBufferSmartPtr = RetainPtr<PlatformBuffer>;
-class GPUBuffer : public RefCounted<GPUBuffer> {
+class GPUBuffer : public GPUObjectBase {
public:
enum class State {
Mapped,
@@ -68,7 +71,7 @@
~GPUBuffer();
- static RefPtr<GPUBuffer> tryCreate(Ref<GPUDevice>&&, const GPUBufferDescriptor&, bool isMappedOnCreation);
+ static RefPtr<GPUBuffer> tryCreate(Ref<GPUDevice>&&, const GPUBufferDescriptor&, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
PlatformBuffer *platformBuffer() const { return m_platformBuffer.get(); }
size_t byteLength() const { return m_byteLength; }
@@ -107,8 +110,8 @@
PendingMappingCallback(MappingCallback&&);
};
- GPUBuffer(PlatformBufferSmartPtr&&, Ref<GPUDevice>&&, size_t, OptionSet<GPUBufferUsage::Flags>, bool);
- static bool validateBufferUsage(GPUDevice&, OptionSet<GPUBufferUsage::Flags>);
+ GPUBuffer(PlatformBufferSmartPtr&&, Ref<GPUDevice>&&, size_t, OptionSet<GPUBufferUsage::Flags>, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
+ static bool validateBufferUsage(GPUDevice&, OptionSet<GPUBufferUsage::Flags>, GPUErrorScopes&);
JSC::ArrayBuffer* stagingBufferForRead();
JSC::ArrayBuffer* stagingBufferForWrite();
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -36,6 +36,11 @@
GPUBufferUsageFlags usage;
};
+enum class GPUBufferMappedOption {
+ IsMapped,
+ NotMapped
+};
+
} // namespace WebCore
#endif // ENABLE(WEBGPU)
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp 2019-07-12 21:07:49 UTC (rev 247397)
@@ -35,6 +35,7 @@
#include "GPUCommandBuffer.h"
#include "GPUComputePipeline.h"
#include "GPUComputePipelineDescriptor.h"
+#include "GPUErrorScopes.h"
#include "GPUPipelineLayout.h"
#include "GPUPipelineLayoutDescriptor.h"
#include "GPURenderPipeline.h"
@@ -51,9 +52,9 @@
namespace WebCore {
-RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(const GPUBufferDescriptor& descriptor, bool isMappedOnCreation)
+RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(const GPUBufferDescriptor& descriptor, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
{
- return GPUBuffer::tryCreate(makeRef(*this), descriptor, isMappedOnCreation);
+ return GPUBuffer::tryCreate(makeRef(*this), descriptor, isMapped, WTFMove(errorScopes));
}
RefPtr<GPUTexture> GPUDevice::tryCreateTexture(const GPUTextureDescriptor& descriptor) const
@@ -109,40 +110,6 @@
m_swapChain = WTFMove(swapChain);
}
-void GPUDevice::pushErrorScope(GPUErrorFilter filter)
-{
- m_errorScopes.append(ErrorScope { filter, WTF::nullopt });
-}
-
-void GPUDevice::popErrorScope(ErrorCallback&& callback)
-{
- if (!m_platformDevice)
- callback(WTF::nullopt, "GPUDevice::popErrorScope(): Invalid GPUDevice!");
- else if (m_errorScopes.isEmpty())
- callback(WTF::nullopt, "GPUDevice::popErrorScope(): No error scope exists!");
- else {
- auto scope = m_errorScopes.takeLast();
- callback(scope.filter == GPUErrorFilter::None ? WTF::nullopt : WTFMove(scope.error), { });
- }
-}
-
-void GPUDevice::registerError(const String& message, GPUErrorFilter filter)
-{
- auto iterator = std::find_if(m_errorScopes.rbegin(), m_errorScopes.rend(), [filter](const ErrorScope& scope) {
- 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())
- return;
-
- // If the scope has already captured an error, ignore this new one.
- if (iterator->error)
- return;
-
- iterator->error = createError(filter, message);
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGPU)
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.h (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.h 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -27,8 +27,6 @@
#if ENABLE(WEBGPU)
-#include "GPUError.h"
-#include "GPUErrorFilter.h"
#include "GPUQueue.h"
#include "GPUSwapChain.h"
#include <wtf/Function.h>
@@ -35,9 +33,7 @@
#include <wtf/Optional.h>
#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
-#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
-#include <wtf/text/WTFString.h>
OBJC_PROTOCOL(MTLDevice);
@@ -47,6 +43,7 @@
class GPUBuffer;
class GPUCommandBuffer;
class GPUComputePipeline;
+class GPUErrorScopes;
class GPUPipelineLayout;
class GPURenderPipeline;
class GPUSampler;
@@ -64,6 +61,8 @@
struct GPUSwapChainDescriptor;
struct GPUTextureDescriptor;
+enum class GPUBufferMappedOption;
+
using PlatformDevice = MTLDevice;
using PlatformDeviceSmartPtr = RetainPtr<MTLDevice>;
@@ -71,7 +70,7 @@
public:
static RefPtr<GPUDevice> tryCreate(const Optional<GPURequestAdapterOptions>&);
- RefPtr<GPUBuffer> tryCreateBuffer(const GPUBufferDescriptor&, bool isMappedOnCreation = false);
+ RefPtr<GPUBuffer> tryCreateBuffer(const GPUBufferDescriptor&, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
RefPtr<GPUTexture> tryCreateTexture(const GPUTextureDescriptor&) const;
RefPtr<GPUSampler> tryCreateSampler(const GPUSamplerDescriptor&) const;
@@ -90,25 +89,12 @@
GPUSwapChain* swapChain() const { return m_swapChain.get(); }
void setSwapChain(RefPtr<GPUSwapChain>&&);
- void pushErrorScope(GPUErrorFilter);
-
- using ErrorCallback = WTF::Function<void(Optional<GPUError>&&, const String&)>;
- void popErrorScope(ErrorCallback&&);
- void registerError(const String&, GPUErrorFilter = GPUErrorFilter::Validation);
-
private:
- struct ErrorScope {
- const GPUErrorFilter filter;
- Optional<GPUError> error;
- };
-
explicit GPUDevice(PlatformDeviceSmartPtr&&);
PlatformDeviceSmartPtr m_platformDevice;
mutable RefPtr<GPUQueue> m_queue;
RefPtr<GPUSwapChain> m_swapChain;
-
- Vector<ErrorScope> m_errorScopes;
};
} // namespace WebCore
Copied: trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.cpp (from rev 247396, trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h) (0 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.cpp 2019-07-12 21:07:49 UTC (rev 247397)
@@ -0,0 +1,68 @@
+/*
+ * 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 "GPUErrorScopes.h"
+
+#if ENABLE(WEBGPU)
+
+namespace WebCore {
+
+void GPUErrorScopes::pushErrorScope(GPUErrorFilter filter)
+{
+ m_errorScopes.append(ErrorScope { filter, WTF::nullopt });
+}
+
+Optional<GPUError> GPUErrorScopes::popErrorScope(String& failMessage)
+{
+ if (m_errorScopes.isEmpty()) {
+ failMessage = "No error scope exists!";
+ return WTF::nullopt;
+ }
+
+ auto scope = m_errorScopes.takeLast();
+ return scope.filter == GPUErrorFilter::None ? WTF::nullopt : scope.error;
+}
+
+void GPUErrorScopes::generateError(const String& message, GPUErrorFilter filter)
+{
+ auto iterator = std::find_if(m_errorScopes.rbegin(), m_errorScopes.rend(), [filter](const ErrorScope& scope) {
+ 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())
+ return;
+
+ // If the scope has already captured an error, ignore this new one.
+ if (iterator->error)
+ return;
+
+ iterator->error = createError(filter, message);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
Copied: trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.h (from rev 247396, trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h) (0 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -0,0 +1,61 @@
+/*
+ * 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 "GPUError.h"
+#include "GPUErrorFilter.h"
+#include <wtf/Optional.h>
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class GPUErrorScopes : public RefCounted<GPUErrorScopes> {
+public:
+ static Ref<GPUErrorScopes> create() { return adoptRef(*new GPUErrorScopes); }
+
+ void pushErrorScope(GPUErrorFilter);
+ Optional<GPUError> popErrorScope(String& failMessage);
+ void generateError(const String&, GPUErrorFilter = GPUErrorFilter::Validation);
+
+private:
+ struct ErrorScope {
+ const GPUErrorFilter filter;
+ Optional<GPUError> error;
+ };
+
+ GPUErrorScopes() = default;
+
+ Vector<ErrorScope> m_errorScopes;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
Copied: trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h (from rev 247396, trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h) (0 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h 2019-07-12 21:07:49 UTC (rev 247397)
@@ -0,0 +1,52 @@
+/*
+ * 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 "GPUErrorScopes.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class GPUObjectBase : public RefCounted<GPUObjectBase> {
+public:
+ void generateError(const String& message, GPUErrorFilter filter = GPUErrorFilter::Validation)
+ {
+ m_errorScopes->generateError(message, filter);
+ }
+
+protected:
+ GPUObjectBase(Ref<GPUErrorScopes>&& reporter)
+ : m_errorScopes(WTFMove(reporter)) { }
+
+private:
+ Ref<GPUErrorScopes> m_errorScopes;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm 2019-07-12 21:07:49 UTC (rev 247397)
@@ -42,7 +42,7 @@
static constexpr auto readOnlyFlags = OptionSet<GPUBufferUsage::Flags> { GPUBufferUsage::Flags::Index, GPUBufferUsage::Flags::Vertex, GPUBufferUsage::Flags::Uniform, GPUBufferUsage::Flags::TransferSource };
-bool GPUBuffer::validateBufferUsage(GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage)
+bool GPUBuffer::validateBufferUsage(GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage, GPUErrorScopes& errorScopes)
{
if (!device.platformDevice()) {
LOG(WebGPU, "GPUBuffer::tryCreate(): Invalid GPUDevice!");
@@ -50,7 +50,7 @@
}
if (usage.containsAll({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })) {
- device.registerError("GPUBuffer::tryCreate(): Buffer cannot have both MAP_READ and MAP_WRITE usage!");
+ errorScopes.generateError("GPUBuffer::tryCreate(): Buffer cannot have both MAP_READ and MAP_WRITE usage!");
return false;
}
@@ -62,23 +62,23 @@
return true;
}
-RefPtr<GPUBuffer> GPUBuffer::tryCreate(Ref<GPUDevice>&& device, const GPUBufferDescriptor& descriptor, bool isMappedOnCreation)
+RefPtr<GPUBuffer> GPUBuffer::tryCreate(Ref<GPUDevice>&& device, const GPUBufferDescriptor& descriptor, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
{
// MTLBuffer size (NSUInteger) is 32 bits on some platforms.
NSUInteger size = 0;
if (!WTF::convertSafely(descriptor.size, size)) {
- device->registerError("", GPUErrorFilter::OutOfMemory);
+ errorScopes->generateError("", GPUErrorFilter::OutOfMemory);
return nullptr;
}
auto usage = OptionSet<GPUBufferUsage::Flags>::fromRaw(descriptor.usage);
- if (!validateBufferUsage(device.get(), usage))
+ if (!validateBufferUsage(device.get(), usage, errorScopes))
return nullptr;
#if PLATFORM(MAC)
// copyBufferToBuffer calls require 4-byte alignment. "Unmapping" a mapped-on-creation GPUBuffer
// that is otherwise unmappable requires such a copy to upload data.
- if (isMappedOnCreation
+ if (isMapped == GPUBufferMappedOption::IsMapped
&& !usage.containsAny({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })
&& descriptor.size % 4) {
LOG(WebGPU, "GPUBuffer::tryCreate(): Data must be aligned to a multiple of 4 bytes!");
@@ -102,19 +102,20 @@
END_BLOCK_OBJC_EXCEPTIONS;
if (!mtlBuffer) {
- device->registerError("", GPUErrorFilter::OutOfMemory);
+ errorScopes->generateError("", GPUErrorFilter::OutOfMemory);
return nullptr;
}
- return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(device), size, usage, isMappedOnCreation));
+ return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(device), size, usage, isMapped, WTFMove(errorScopes)));
}
-GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, Ref<GPUDevice>&& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, bool isMapped)
- : m_platformBuffer(WTFMove(buffer))
+GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, Ref<GPUDevice>&& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
+ : GPUObjectBase(WTFMove(errorScopes))
+ , m_platformBuffer(WTFMove(buffer))
, m_device(WTFMove(device))
, m_byteLength(size)
, m_usage(usage)
- , m_isMappedFromCreation(isMapped)
+ , m_isMappedFromCreation(isMapped == GPUBufferMappedOption::IsMapped)
{
}
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm (247396 => 247397)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm 2019-07-12 20:58:43 UTC (rev 247396)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm 2019-07-12 21:07:49 UTC (rev 247397)
@@ -96,7 +96,7 @@
END_BLOCK_OBJC_EXCEPTIONS;
}
- if (m_presentTask.hasPendingTask() || !m_device->swapChain())
+ if (m_presentTask.hasPendingTask() || !m_device || !m_device->swapChain())
return;
// If a GPUSwapChain exists, ensure that a present is scheduled after all command buffers.