-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[WebGPU] Non-owning getters have the wrong lifetime #8936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebGPU] Non-owning getters have the wrong lifetime #8936
Conversation
|
EWS run on previous version of this PR (hash e582ec9)
|
e582ec9 to
d609891
Compare
|
EWS run on previous version of this PR (hash d609891)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an alternative way of doing this: instead of retaining the +0 bind group, we can retain the wrapper of the pipeline object which owns the +0 bind group. Maybe that's better than this approach? It would allow us to not expose more WebGPU.framework API additions, which is always good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mike and I both agree that this approach is better, but requires more thought about how to make this work with the C++ type system. Marking as draft for now.
|
Thinking about this more, this is exactly the reason I created
I think DeviceHolder is an antipattern; instead, I've seen another pattern in WebCore to provide custom implementations of ref() and deref() methods. Maybe we could do something like: |
|
Oh, that's not going to work, because Do we want to make |
d609891 to
88f7797
Compare
|
EWS run on previous version of this PR (hash 88f7797)
|
Maybe not.... maybe it's smart? 🤔 |
88f7797 to
6a2f82a
Compare
|
EWS run on previous version of this PR (hash 6a2f82a)
|
6a2f82a to
1ab5f46
Compare
|
EWS run on previous version of this PR (hash 1ab5f46)
|
1ab5f46 to
5088ac2
Compare
|
EWS run on previous version of this PR (hash 5088ac2)
|
5088ac2 to
c274f96
Compare
|
EWS run on previous version of this PR (hash c274f96)
|
c274f96 to
1ea320e
Compare
|
EWS run on current version of this PR (hash 1ea320e)
|
https://bugs.webkit.org/show_bug.cgi?id=250958 rdar://104518638 Reviewed by Dean Jackson. There are 2 places in WebGPU where objects have getter methods that return internally-retained objects: 1. Device::getQueue() is supposed to return the same queue object every time you call it, and 2. PresentationContext::getCurrentTexture() is supposed to return the same texture object every time you call it within the same frame. Let's call this pattern "Owner" and "Owned." The Owner is supposed to retain its Owned. Easy peasy, right? Well, it gets trickier because: 1. We have a corresponding set of Impl objects in PAL, each of which is supposed to maintain a strong reference to its corresponding object in WebGPU.framework. 2. Objects exposed by WebGPU.framework are not reference counted. So, naively, we would have: +-----------+ | OwnerImpl | +-----------+ | \ | \ | \ | V | +-----------+ | | OwnedImpl | | +-----------+ | | ~~~~~~~~|~~~~~~~~~~~~~|~~~~~~~~~~ WebGPU.framework boundary V | +-------+ | | Owner | | +-------+ | \ | \ | \ | V V BANG!!! EXPLOSION!!! +-------+ | Owned | +-------+ The above design can't actually work, because Owned isn't reference counted. So, instead, we can introduce a reference- counted facade on top of Owner, to look like this: +-----------+ | OwnerImpl | +-----------+ | \ | \ | \ | V | +-----------+ | | OwnedImpl | | +-----------+ | | | | V V +--------------+ | OwnerWrapper | +--------------+ | | ~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~ WebGPU.framework boundary V +-------+ | Owner | +-------+ \ \ \ V +-------+ | Owned | +-------+ This design has all the properties we want: 1. All WebGPU.framework objects have a single owner 2. Any strong reference to the OwnerImpl keeps the Owner alive 3. Any strong reference to the OwnedImpl keeps the Owned alive 4. There are no reference cycles The OwnedImpl doesn't actually call any functions on the OwnerWrapper; the only reason it refs it is to make the above requirements hold. There are 2 other possible designs which satisfy the requirements: 1. Have OwnedImpl delegate its ref() and deref() calls to the OwnerImpl, and 2. Make WebGPU.framework objects reference counted. I chose this patch's design over (1) because (1) is significantly more complicated and I'm more likely to make a mistake with that design. I chose this patch's design over (2) because I didn't want to change the semantic behavior of the WebGPU.h objects. * Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj: * Source/WebCore/PAL/pal/CMakeLists.txt: * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceImpl.cpp: (PAL::WebGPU::DeviceImpl::DeviceImpl): (PAL::WebGPU::DeviceImpl::destroy): (PAL::WebGPU::DeviceImpl::createBuffer): (PAL::WebGPU::DeviceImpl::createTexture): (PAL::WebGPU::DeviceImpl::createSurfaceTexture): (PAL::WebGPU::DeviceImpl::createSampler): (PAL::WebGPU::DeviceImpl::createBindGroupLayout): (PAL::WebGPU::DeviceImpl::createPipelineLayout): (PAL::WebGPU::DeviceImpl::createBindGroup): (PAL::WebGPU::DeviceImpl::createShaderModule): (PAL::WebGPU::DeviceImpl::createComputePipeline): (PAL::WebGPU::DeviceImpl::createRenderPipeline): (PAL::WebGPU::DeviceImpl::createComputePipelineAsync): (PAL::WebGPU::DeviceImpl::createRenderPipelineAsync): (PAL::WebGPU::DeviceImpl::createCommandEncoder): (PAL::WebGPU::DeviceImpl::createRenderBundleEncoder): (PAL::WebGPU::DeviceImpl::createQuerySet): (PAL::WebGPU::DeviceImpl::pushErrorScope): (PAL::WebGPU::DeviceImpl::popErrorScope): (PAL::WebGPU::DeviceImpl::setLabelInternal): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceImpl.h: * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceWrapper.cpp: Copied from Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceHolderImpl.cpp. (PAL::WebGPU::DeviceWrapper::DeviceWrapper): (PAL::WebGPU::DeviceWrapper::~DeviceWrapper): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceWrapper.h: Copied from Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceHolderImpl.h. * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUPresentationContextImpl.cpp: (PAL::WebGPU::PresentationContextImpl::~PresentationContextImpl): (PAL::WebGPU::PresentationContextImpl::configure): (PAL::WebGPU::PresentationContextImpl::unconfigure): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUPresentationContextImpl.h: * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUQueueImpl.cpp: (PAL::WebGPU::QueueImpl::QueueImpl): (PAL::WebGPU::QueueImpl::~QueueImpl): (PAL::WebGPU::QueueImpl::submit): (PAL::WebGPU::QueueImpl::onSubmittedWorkDone): (PAL::WebGPU::QueueImpl::writeBuffer): (PAL::WebGPU::QueueImpl::writeTexture): (PAL::WebGPU::QueueImpl::setLabelInternal): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUQueueImpl.h: * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUSwapChainWrapper.cpp: Renamed from Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceHolderImpl.cpp. (PAL::WebGPU::SwapChainWrapper::SwapChainWrapper): (PAL::WebGPU::SwapChainWrapper::~SwapChainWrapper): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUSwapChainWrapper.h: Renamed from Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUDeviceHolderImpl.h. * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUTextureImpl.cpp: (PAL::WebGPU::TextureImpl::TextureImpl): (PAL::WebGPU::TextureImpl::~TextureImpl): * Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUTextureImpl.h: Canonical link: https://commits.webkit.org/259867@main
|
Committed 259867@main (6c4c981): https://commits.webkit.org/259867@main Reviewed commits have been landed. Closing PR #8936 and removing active labels. |
1ea320e to
6c4c981
Compare
6c4c981
1ea320e