Bug 1780792 - Move the buffer creation code in Buffer.cpp. r=jimb

No funcitonal change here, I like to have the code maintaining and depending on the same invariants to be in the same place.

Depends on D151616

Differential Revision: https://phabricator.services.mozilla.com/D151617
This commit is contained in:
Nicolas Silva 2022-08-10 15:55:05 +00:00
parent 6c728ff882
commit 8829006db0
4 changed files with 60 additions and 42 deletions

View File

@ -53,6 +53,53 @@ Buffer::~Buffer() {
mozilla::DropJSObjects(this);
}
already_AddRefed<Buffer> Buffer::Create(Device* aDevice, RawId aDeviceId,
const dom::GPUBufferDescriptor& aDesc,
ErrorResult& aRv) {
if (aDevice->IsLost()) {
RefPtr<Buffer> buffer =
new Buffer(aDevice, 0, aDesc.mSize, 0, ipc::Shmem());
return buffer.forget();
}
RefPtr<WebGPUChild> actor = aDevice->GetBridge();
ipc::Shmem shmem;
bool hasMapFlags = aDesc.mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
dom::GPUBufferUsage_Binding::MAP_READ);
if (hasMapFlags || aDesc.mMappedAtCreation) {
const auto checked = CheckedInt<size_t>(aDesc.mSize);
if (!checked.isValid()) {
aRv.ThrowRangeError("Mappable size is too large");
return nullptr;
}
const auto& size = checked.value();
if (!actor->AllocUnsafeShmem(size, &shmem)) {
aRv.ThrowAbortError(
nsPrintfCString("Unable to allocate shmem of size %" PRIuPTR, size));
return nullptr;
}
// zero out memory
memset(shmem.get<uint8_t>(), 0, size);
}
MaybeShmem maybeShmem = mozilla::null_t();
if (shmem.IsReadable()) {
maybeShmem = shmem;
}
RawId id = actor->DeviceCreateBuffer(aDeviceId, aDesc, std::move(maybeShmem));
RefPtr<Buffer> buffer =
new Buffer(aDevice, id, aDesc.mSize, aDesc.mUsage, std::move(shmem));
if (aDesc.mMappedAtCreation) {
buffer->SetMapped(!(aDesc.mUsage & dom::GPUBufferUsage_Binding::MAP_READ));
}
return buffer.forget();
}
bool Buffer::Mappable() const {
return (mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
dom::GPUBufferUsage_Binding::MAP_READ)) != 0;

View File

@ -17,9 +17,10 @@ namespace mozilla {
class ErrorResult;
namespace dom {
struct GPUBufferDescriptor;
template <typename T>
class Optional;
}
} // namespace dom
namespace ipc {
class Shmem;
@ -43,13 +44,17 @@ class Buffer final : public ObjectBase, public ChildOf<Device> {
GPU_DECL_CYCLE_COLLECTION(Buffer)
GPU_DECL_JS_WRAP(Buffer)
Buffer(Device* const aParent, RawId aId, BufferAddress aSize, uint32_t aUsage,
ipc::Shmem&& aShmem);
static already_AddRefed<Buffer> Create(Device* aDevice, RawId aDeviceId,
const dom::GPUBufferDescriptor& aDesc,
ErrorResult& aRv);
void SetMapped(bool aWritable);
const RawId mId;
private:
Buffer(Device* const aParent, RawId aId, BufferAddress aSize, uint32_t aUsage,
ipc::Shmem&& aShmem);
virtual ~Buffer();
void Cleanup();
void UnmapArrayBuffers(JSContext* aCx, ErrorResult& aRv);

View File

@ -95,6 +95,8 @@ void Device::CleanupUnregisteredInParent() {
mValid = false;
}
bool Device::IsLost() const { return !mBridge || !mBridge->CanSend(); }
// Generate an error on the Device timeline for this device.
//
// aMessage is interpreted as UTF-8.
@ -121,45 +123,7 @@ dom::Promise* Device::GetLost(ErrorResult& aRv) {
already_AddRefed<Buffer> Device::CreateBuffer(
const dom::GPUBufferDescriptor& aDesc, ErrorResult& aRv) {
if (!mBridge->CanSend()) {
RefPtr<Buffer> buffer = new Buffer(this, 0, aDesc.mSize, 0, ipc::Shmem());
return buffer.forget();
}
ipc::Shmem shmem;
bool hasMapFlags = aDesc.mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
dom::GPUBufferUsage_Binding::MAP_READ);
if (hasMapFlags || aDesc.mMappedAtCreation) {
const auto checked = CheckedInt<size_t>(aDesc.mSize);
if (!checked.isValid()) {
aRv.ThrowRangeError("Mappable size is too large");
return nullptr;
}
const auto& size = checked.value();
if (!mBridge->AllocUnsafeShmem(size, &shmem)) {
aRv.ThrowAbortError(
nsPrintfCString("Unable to allocate shmem of size %" PRIuPTR, size));
return nullptr;
}
// zero out memory
memset(shmem.get<uint8_t>(), 0, size);
}
MaybeShmem maybeShmem = mozilla::null_t();
if (shmem.IsReadable()) {
maybeShmem = shmem;
}
RawId id = mBridge->DeviceCreateBuffer(mId, aDesc, std::move(maybeShmem));
RefPtr<Buffer> buffer =
new Buffer(this, id, aDesc.mSize, aDesc.mUsage, std::move(shmem));
if (aDesc.mMappedAtCreation) {
buffer->SetMapped(!(aDesc.mUsage & dom::GPUBufferUsage_Binding::MAP_READ));
}
return buffer.forget();
return Buffer::Create(this, mId, aDesc, aRv);
}
RefPtr<MappingPromise> Device::MapBufferAsync(RawId aId, uint32_t aMode,

View File

@ -114,6 +114,8 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
void GenerateError(const nsCString& aMessage);
bool IsLost() const;
private:
~Device();
void Cleanup();