Changeset 247397 in webkit


Ignore:
Timestamp:
Jul 12, 2019 2:07:49 PM (5 years ago)
Author:
Justin Fan
Message:

[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.

Location:
trunk/Source/WebCore
Files:
11 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r247395 r247397  
     12019-07-12  Justin Fan  <justin_fan@apple.com>
     2
     3        [WebGPU] Move error scopes out of GPUDevice for more portable error generation
     4        https://bugs.webkit.org/show_bug.cgi?id=199740
     5
     6        Reviewed by Myles C. Maxfield.
     7
     8        Move error generation into a separate RefCounted class to allow GPU objects to generate
     9        errors independent of any GPUDevice.
     10        Create GPUObjectBase to delegate error generation and refactor GPUBuffer to inherit from GPUObjectBase.
     11
     12        No behavior change or new tests. Error scopes covered by error-scopes-test.html.
     13
     14        * Modules/webgpu/WebGPUDevice.cpp:
     15        (WebCore::WebGPUDevice::WebGPUDevice): Now creates a GPUErrorGenerator.
     16        (WebCore::WebGPUDevice::createBuffer const): Pass the GPUErrorGenerator to any created GPUBuffer.
     17        (WebCore::WebGPUDevice::createBufferMapped const): Ditto.
     18        (WebCore::WebGPUDevice::popErrorScope): Shouldn't be const. Can just ask for the GPUError rather than passing a lambda.
     19        (WebCore::WebGPUDevice::pushErrorScope const): Deleted.
     20        (WebCore::WebGPUDevice::popErrorScope const): Deleted.
     21        * Modules/webgpu/WebGPUDevice.h:
     22        (WebCore::WebGPUDevice::pushErrorScope):
     23        * Sources.txt:
     24        * WebCore.xcodeproj/project.pbxproj:
     25        * platform/graphics/gpu/GPUBuffer.h: Now inherits from GPUObjectBase for error generation ease.
     26        * platform/graphics/gpu/GPUDevice.cpp:
     27        (WebCore::GPUDevice::tryCreateBuffer): Ensure GPUBuffers reference the GPUErrorGenerator.
     28        (WebCore::GPUDevice::pushErrorScope): Deleted. No longer needed here.
     29        (WebCore::GPUDevice::popErrorScope): Deleted.
     30        (WebCore::GPUDevice::registerError): Deleted.
     31        * platform/graphics/gpu/GPUDevice.h: Move error scope logic out.
     32        * platform/graphics/gpu/GPUErrorGenerator.cpp: Added.
     33        (WebCore::GPUErrorGenerator::pushErrorScope):
     34        (WebCore::GPUErrorGenerator::popErrorScope):
     35        (WebCore::GPUErrorGenerator::generateError):
     36        * platform/graphics/gpu/GPUErrorGenerator.h: Added.
     37        (WebCore::GPUErrorGenerator::create):
     38        * platform/graphics/gpu/GPUObjectBase.h: Added.
     39        (WebCore::GPUObjectBase::generateError):
     40        (WebCore::GPUObjectBase::GPUObjectBase):
     41        * platform/graphics/gpu/cocoa/GPUBufferMetal.mm: Use the GPUErrorGenerator directly during buffer creation.
     42        (WebCore::GPUBuffer::validateBufferUsage):
     43        (WebCore::GPUBuffer::tryCreate):
     44        (WebCore::GPUBuffer::GPUBuffer):
     45        * platform/graphics/gpu/cocoa/GPUQueueMetal.mm:
     46        (WebCore::GPUQueue::submit): Prevent possible null dereference.
     47
    1482019-07-12  Youenn Fablet  <youenn@apple.com>
    249
  • trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp

    r247366 r247397  
    6868#include "WebGPUTexture.h"
    6969#include <wtf/Optional.h>
     70#include <wtf/text/WTFString.h>
    7071
    7172namespace WebCore {
     
    8182    : m_adapter(WTFMove(adapter))
    8283    , m_device(WTFMove(device))
     84    , m_errorScopes(GPUErrorScopes::create())
    8385{
    8486}
     
    8688Ref<WebGPUBuffer> WebGPUDevice::createBuffer(const GPUBufferDescriptor& descriptor) const
    8789{
    88     auto buffer = m_device->tryCreateBuffer(descriptor);
     90    auto buffer = m_device->tryCreateBuffer(descriptor, GPUBufferMappedOption::NotMapped, m_errorScopes.copyRef());
    8991    return WebGPUBuffer::create(WTFMove(buffer));
    9092}
     
    9496    JSC::JSValue wrappedArrayBuffer = JSC::jsNull();
    9597
    96     auto buffer = m_device->tryCreateBuffer(descriptor, true);
     98    auto buffer = m_device->tryCreateBuffer(descriptor, GPUBufferMappedOption::IsMapped, m_errorScopes.copyRef());
    9799    if (buffer) {
    98100        auto arrayBuffer = buffer->mapOnCreation();
     
    185187}
    186188
    187 void WebGPUDevice::pushErrorScope(GPUErrorFilter filter) const
    188 {
    189     m_device->pushErrorScope(filter);
    190 }
    191 
    192 void WebGPUDevice::popErrorScope(ErrorPromise&& promise) const
    193 {
    194     m_device->popErrorScope([promise = WTFMove(promise)] (Optional<GPUError>&& error, const String& failMessage) mutable {
    195         if (failMessage.isEmpty())
    196             promise.resolve(error);
    197         else
    198             promise.reject(Exception { OperationError, failMessage });
    199     });
     189void WebGPUDevice::popErrorScope(ErrorPromise&& promise)
     190{
     191    String failMessage;
     192    Optional<GPUError> error = m_errorScopes->popErrorScope(failMessage);
     193    if (failMessage.isEmpty())
     194        promise.resolve(error);
     195    else
     196        promise.reject(Exception { OperationError, "GPUDevice::popErrorScope(): " + failMessage });
    200197}
    201198
  • trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.h

    r247366 r247397  
    2929
    3030#include "GPUDevice.h"
     31#include "GPUErrorScopes.h"
    3132#include "JSDOMPromiseDeferred.h"
    3233#include "WebGPUAdapter.h"
     
    100101    Ref<WebGPUQueue> getQueue() const;
    101102
    102     void pushErrorScope(GPUErrorFilter) const;
    103     void popErrorScope(ErrorPromise&&) const;
     103    void pushErrorScope(GPUErrorFilter filter) { m_errorScopes->pushErrorScope(filter); }
     104    void popErrorScope(ErrorPromise&&);
    104105
    105106private:
     
    109110    Ref<GPUDevice> m_device;
    110111    mutable RefPtr<WebGPUQueue> m_queue;
     112
     113    Ref<GPUErrorScopes> m_errorScopes;
    111114};
    112115
  • trunk/Source/WebCore/Sources.txt

    r247366 r247397  
    18301830platform/graphics/gpu/GPUDevice.cpp
    18311831platform/graphics/gpu/GPUError.cpp
     1832platform/graphics/gpu/GPUErrorScopes.cpp
    18321833platform/graphics/gpu/GPUValidationError.cpp
    18331834platform/graphics/gpu/GPUPipelineLayout.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r247366 r247397  
    1395513955                D03211CF21AC954E00763CF2 /* GPUProgrammablePassEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUProgrammablePassEncoder.h; sourceTree = "<group>"; };
    1395613956                D03211D021AC954F00763CF2 /* GPURenderPassDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPURenderPassDescriptor.h; sourceTree = "<group>"; };
     13957                D03586B122D7F2EA00DA0284 /* GPUErrorScopes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUErrorScopes.h; sourceTree = "<group>"; };
     13958                D03586B222D7F2EA00DA0284 /* GPUErrorScopes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUErrorScopes.cpp; sourceTree = "<group>"; };
    1395713959                D036DD8D208FFC0C00F9F4B2 /* WebGLCompressedTextureASTC.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGLCompressedTextureASTC.idl; sourceTree = "<group>"; };
    1395813960                D03C849A21FFC6670002227F /* GPUDepthStencilStateDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUDepthStencilStateDescriptor.h; sourceTree = "<group>"; };
     
    1403214034                D09AFB1922D6698A00C4538C /* GPUOutOfMemoryError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUOutOfMemoryError.h; sourceTree = "<group>"; };
    1403314035                D09AFB2D22D6C01400C4538C /* GPUError.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUError.cpp; sourceTree = "<group>"; };
     14036                D09AFB3722D7D5C600C4538C /* GPUObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUObjectBase.h; sourceTree = "<group>"; };
    1403414037                D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLCompressedTextureASTC.h; sourceTree = "<group>"; };
    1403514038                D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLCompressedTextureASTC.cpp; sourceTree = "<group>"; };
     
    1833818341                                D09AFB0722D5391B00C4538C /* GPUError.h */,
    1833918342                                D09AFB0222D0471900C4538C /* GPUErrorFilter.h */,
     18343                                D03586B222D7F2EA00DA0284 /* GPUErrorScopes.cpp */,
     18344                                D03586B122D7F2EA00DA0284 /* GPUErrorScopes.h */,
    1834018345                                D026F47D220A2AC600AC5F49 /* GPUExtent3D.h */,
    1834118346                                D0F7559F2203BA1400118058 /* GPULimits.h */,
    1834218347                                D08AA02F220D0BD50058C502 /* GPULoadOp.h */,
     18348                                D09AFB3722D7D5C600C4538C /* GPUObjectBase.h */,
    1834318349                                D09AFB1922D6698A00C4538C /* GPUOutOfMemoryError.h */,
    1834418350                                312FF8C421A4C2F400EB199D /* GPUPipelineDescriptorBase.h */,
  • trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h

    r247366 r247397  
    3030#include "DeferrableTask.h"
    3131#include "GPUBufferUsage.h"
     32#include "GPUObjectBase.h"
    3233#include <wtf/Function.h>
    3334#include <wtf/OptionSet.h>
     
    5253struct GPUBufferDescriptor;
    5354
     55enum class GPUBufferMappedOption;
     56
    5457#if USE(METAL)
    5558using PlatformBuffer = MTLBuffer;
     
    5962using PlatformBufferSmartPtr = RetainPtr<PlatformBuffer>;
    6063
    61 class GPUBuffer : public RefCounted<GPUBuffer> {
     64class GPUBuffer : public GPUObjectBase {
    6265public:
    6366    enum class State {
     
    6972    ~GPUBuffer();
    7073
    71     static RefPtr<GPUBuffer> tryCreate(Ref<GPUDevice>&&, const GPUBufferDescriptor&, bool isMappedOnCreation);
     74    static RefPtr<GPUBuffer> tryCreate(Ref<GPUDevice>&&, const GPUBufferDescriptor&, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
    7275
    7376    PlatformBuffer *platformBuffer() const { return m_platformBuffer.get(); }
     
    108111    };
    109112
    110     GPUBuffer(PlatformBufferSmartPtr&&, Ref<GPUDevice>&&, size_t, OptionSet<GPUBufferUsage::Flags>, bool);
    111     static bool validateBufferUsage(GPUDevice&, OptionSet<GPUBufferUsage::Flags>);
     113    GPUBuffer(PlatformBufferSmartPtr&&, Ref<GPUDevice>&&, size_t, OptionSet<GPUBufferUsage::Flags>, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
     114    static bool validateBufferUsage(GPUDevice&, OptionSet<GPUBufferUsage::Flags>, GPUErrorScopes&);
    112115
    113116    JSC::ArrayBuffer* stagingBufferForRead();
  • trunk/Source/WebCore/platform/graphics/gpu/GPUBufferDescriptor.h

    r243658 r247397  
    3737};
    3838
     39enum class GPUBufferMappedOption {
     40    IsMapped,
     41    NotMapped
     42};
     43
    3944} // namespace WebCore
    4045
  • trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp

    r247366 r247397  
    3636#include "GPUComputePipeline.h"
    3737#include "GPUComputePipelineDescriptor.h"
     38#include "GPUErrorScopes.h"
    3839#include "GPUPipelineLayout.h"
    3940#include "GPUPipelineLayoutDescriptor.h"
     
    5253namespace WebCore {
    5354
    54 RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(const GPUBufferDescriptor& descriptor, bool isMappedOnCreation)
     55RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(const GPUBufferDescriptor& descriptor, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
    5556{
    56     return GPUBuffer::tryCreate(makeRef(*this), descriptor, isMappedOnCreation);
     57    return GPUBuffer::tryCreate(makeRef(*this), descriptor, isMapped, WTFMove(errorScopes));
    5758}
    5859
     
    110111}
    111112
    112 void GPUDevice::pushErrorScope(GPUErrorFilter filter)
    113 {
    114     m_errorScopes.append(ErrorScope { filter, WTF::nullopt });
    115 }
    116 
    117 void GPUDevice::popErrorScope(ErrorCallback&& callback)
    118 {
    119     if (!m_platformDevice)
    120         callback(WTF::nullopt, "GPUDevice::popErrorScope(): Invalid GPUDevice!");
    121     else if (m_errorScopes.isEmpty())
    122         callback(WTF::nullopt, "GPUDevice::popErrorScope(): No error scope exists!");
    123     else {
    124         auto scope = m_errorScopes.takeLast();
    125         callback(scope.filter == GPUErrorFilter::None ? WTF::nullopt : WTFMove(scope.error), { });
    126     }
    127 }
    128 
    129 void GPUDevice::registerError(const String& message, GPUErrorFilter filter)
    130 {
    131     auto iterator = std::find_if(m_errorScopes.rbegin(), m_errorScopes.rend(), [filter](const ErrorScope& scope) {
    132         return scope.filter == GPUErrorFilter::None || scope.filter == filter;
    133     });
    134 
    135     // FIXME: https://webkit.org/b/199676 Uncaptured errors need to be fired as GPUUncapturedErrorEvents.
    136     if (iterator == m_errorScopes.rend())
    137         return;
    138 
    139     // If the scope has already captured an error, ignore this new one.
    140     if (iterator->error)
    141         return;
    142 
    143     iterator->error = createError(filter, message);
    144 }
    145 
    146113} // namespace WebCore
    147114
  • trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.h

    r247366 r247397  
    2828#if ENABLE(WEBGPU)
    2929
    30 #include "GPUError.h"
    31 #include "GPUErrorFilter.h"
    3230#include "GPUQueue.h"
    3331#include "GPUSwapChain.h"
     
    3634#include <wtf/RefCounted.h>
    3735#include <wtf/RetainPtr.h>
    38 #include <wtf/Vector.h>
    3936#include <wtf/WeakPtr.h>
    40 #include <wtf/text/WTFString.h>
    4137
    4238OBJC_PROTOCOL(MTLDevice);
     
    4844class GPUCommandBuffer;
    4945class GPUComputePipeline;
     46class GPUErrorScopes;
    5047class GPUPipelineLayout;
    5148class GPURenderPipeline;
     
    6562struct GPUTextureDescriptor;
    6663
     64enum class GPUBufferMappedOption;
     65
    6766using PlatformDevice = MTLDevice;
    6867using PlatformDeviceSmartPtr = RetainPtr<MTLDevice>;
     
    7271    static RefPtr<GPUDevice> tryCreate(const Optional<GPURequestAdapterOptions>&);
    7372
    74     RefPtr<GPUBuffer> tryCreateBuffer(const GPUBufferDescriptor&, bool isMappedOnCreation = false);
     73    RefPtr<GPUBuffer> tryCreateBuffer(const GPUBufferDescriptor&, GPUBufferMappedOption, Ref<GPUErrorScopes>&&);
    7574    RefPtr<GPUTexture> tryCreateTexture(const GPUTextureDescriptor&) const;
    7675    RefPtr<GPUSampler> tryCreateSampler(const GPUSamplerDescriptor&) const;
     
    9190    void setSwapChain(RefPtr<GPUSwapChain>&&);
    9291
    93     void pushErrorScope(GPUErrorFilter);
    94 
    95     using ErrorCallback = WTF::Function<void(Optional<GPUError>&&, const String&)>;
    96     void popErrorScope(ErrorCallback&&);
    97     void registerError(const String&, GPUErrorFilter = GPUErrorFilter::Validation);
    98 
    9992private:
    100     struct ErrorScope {
    101         const GPUErrorFilter filter;
    102         Optional<GPUError> error;
    103     };
    104 
    10593    explicit GPUDevice(PlatformDeviceSmartPtr&&);
    10694
     
    10896    mutable RefPtr<GPUQueue> m_queue;
    10997    RefPtr<GPUSwapChain> m_swapChain;
    110 
    111     Vector<ErrorScope> m_errorScopes;
    11298};
    11399
  • trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.cpp

    r247396 r247397  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "GPUErrorScopes.h"
    2728
    2829#if ENABLE(WEBGPU)
    2930
    30 #include "GPUBufferUsage.h"
    31 
    3231namespace WebCore {
    3332
    34 struct GPUBufferDescriptor {
    35     uint64_t size;
    36     GPUBufferUsageFlags usage;
    37 };
     33void GPUErrorScopes::pushErrorScope(GPUErrorFilter filter)
     34{
     35    m_errorScopes.append(ErrorScope { filter, WTF::nullopt });
     36}
     37
     38Optional<GPUError> GPUErrorScopes::popErrorScope(String& failMessage)
     39{
     40    if (m_errorScopes.isEmpty()) {
     41        failMessage = "No error scope exists!";
     42        return WTF::nullopt;
     43    }
     44
     45    auto scope = m_errorScopes.takeLast();
     46    return scope.filter == GPUErrorFilter::None ? WTF::nullopt : scope.error;
     47}
     48
     49void GPUErrorScopes::generateError(const String& message, GPUErrorFilter filter)
     50{
     51    auto iterator = std::find_if(m_errorScopes.rbegin(), m_errorScopes.rend(), [filter](const ErrorScope& scope) {
     52        return scope.filter == GPUErrorFilter::None || scope.filter == filter;
     53    });
     54
     55    // FIXME: https://webkit.org/b/199676 Uncaptured errors need to be fired as GPUUncapturedErrorEvents.
     56    if (iterator == m_errorScopes.rend())
     57        return;
     58
     59    // If the scope has already captured an error, ignore this new one.
     60    if (iterator->error)
     61        return;
     62
     63    iterator->error = createError(filter, message);
     64}
    3865
    3966} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/gpu/GPUErrorScopes.h

    r247396 r247397  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(WEBGPU)
    2929
    30 #include "GPUBufferUsage.h"
     30#include "GPUError.h"
     31#include "GPUErrorFilter.h"
     32#include <wtf/Optional.h>
     33#include <wtf/Ref.h>
     34#include <wtf/RefCounted.h>
     35#include <wtf/Vector.h>
     36#include <wtf/text/WTFString.h>
    3137
    3238namespace WebCore {
    3339
    34 struct GPUBufferDescriptor {
    35     uint64_t size;
    36     GPUBufferUsageFlags usage;
     40class GPUErrorScopes : public RefCounted<GPUErrorScopes> {
     41public:
     42    static Ref<GPUErrorScopes> create() { return adoptRef(*new GPUErrorScopes); }
     43
     44    void pushErrorScope(GPUErrorFilter);
     45    Optional<GPUError> popErrorScope(String& failMessage);
     46    void generateError(const String&, GPUErrorFilter = GPUErrorFilter::Validation);
     47
     48private:
     49    struct ErrorScope {
     50        const GPUErrorFilter filter;
     51        Optional<GPUError> error;
     52    };
     53
     54    GPUErrorScopes() = default;
     55
     56    Vector<ErrorScope> m_errorScopes;
    3757};
    3858
  • trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h

    r247396 r247397  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(WEBGPU)
    2929
    30 #include "GPUBufferUsage.h"
     30#include "GPUErrorScopes.h"
     31#include <wtf/RefCounted.h>
    3132
    3233namespace WebCore {
    3334
    34 struct GPUBufferDescriptor {
    35     uint64_t size;
    36     GPUBufferUsageFlags usage;
     35class GPUObjectBase : public RefCounted<GPUObjectBase> {
     36public:
     37    void generateError(const String& message, GPUErrorFilter filter = GPUErrorFilter::Validation)
     38    {
     39        m_errorScopes->generateError(message, filter);
     40    }
     41
     42protected:
     43    GPUObjectBase(Ref<GPUErrorScopes>&& reporter)
     44        : m_errorScopes(WTFMove(reporter)) { }
     45
     46private:
     47    Ref<GPUErrorScopes> m_errorScopes;
    3748};
    3849
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm

    r247366 r247397  
    4343
    4444
    45 bool GPUBuffer::validateBufferUsage(GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage)
     45bool GPUBuffer::validateBufferUsage(GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage, GPUErrorScopes& errorScopes)
    4646{
    4747    if (!device.platformDevice()) {
     
    5151
    5252    if (usage.containsAll({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })) {
    53         device.registerError("GPUBuffer::tryCreate(): Buffer cannot have both MAP_READ and MAP_WRITE usage!");
     53        errorScopes.generateError("GPUBuffer::tryCreate(): Buffer cannot have both MAP_READ and MAP_WRITE usage!");
    5454        return false;
    5555    }
     
    6363}
    6464
    65 RefPtr<GPUBuffer> GPUBuffer::tryCreate(Ref<GPUDevice>&& device, const GPUBufferDescriptor& descriptor, bool isMappedOnCreation)
     65RefPtr<GPUBuffer> GPUBuffer::tryCreate(Ref<GPUDevice>&& device, const GPUBufferDescriptor& descriptor, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
    6666{
    6767    // MTLBuffer size (NSUInteger) is 32 bits on some platforms.
    6868    NSUInteger size = 0;
    6969    if (!WTF::convertSafely(descriptor.size, size)) {
    70         device->registerError("", GPUErrorFilter::OutOfMemory);
     70        errorScopes->generateError("", GPUErrorFilter::OutOfMemory);
    7171        return nullptr;
    7272    }
    7373
    7474    auto usage = OptionSet<GPUBufferUsage::Flags>::fromRaw(descriptor.usage);
    75     if (!validateBufferUsage(device.get(), usage))
     75    if (!validateBufferUsage(device.get(), usage, errorScopes))
    7676        return nullptr;
    7777
     
    7979    // copyBufferToBuffer calls require 4-byte alignment. "Unmapping" a mapped-on-creation GPUBuffer
    8080    // that is otherwise unmappable requires such a copy to upload data.
    81     if (isMappedOnCreation
     81    if (isMapped == GPUBufferMappedOption::IsMapped
    8282        && !usage.containsAny({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })
    8383        && descriptor.size % 4) {
     
    103103
    104104    if (!mtlBuffer) {
    105         device->registerError("", GPUErrorFilter::OutOfMemory);
    106         return nullptr;
    107     }
    108 
    109     return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(device), size, usage, isMappedOnCreation));
    110 }
    111 
    112 GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, Ref<GPUDevice>&& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, bool isMapped)
    113     : m_platformBuffer(WTFMove(buffer))
     105        errorScopes->generateError("", GPUErrorFilter::OutOfMemory);
     106        return nullptr;
     107    }
     108
     109    return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(device), size, usage, isMapped, WTFMove(errorScopes)));
     110}
     111
     112GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, Ref<GPUDevice>&& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, GPUBufferMappedOption isMapped, Ref<GPUErrorScopes>&& errorScopes)
     113    : GPUObjectBase(WTFMove(errorScopes))
     114    , m_platformBuffer(WTFMove(buffer))
    114115    , m_device(WTFMove(device))
    115116    , m_byteLength(size)
    116117    , m_usage(usage)
    117     , m_isMappedFromCreation(isMapped)
     118    , m_isMappedFromCreation(isMapped == GPUBufferMappedOption::IsMapped)
    118119{
    119120}
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm

    r242759 r247397  
    9797    }
    9898
    99     if (m_presentTask.hasPendingTask() || !m_device->swapChain())
     99    if (m_presentTask.hasPendingTask() || !m_device || !m_device->swapChain())
    100100        return;
    101101
Note: See TracChangeset for help on using the changeset viewer.