Bug 1771254 - Add MaybeShmem. r=jimb,aosmond

Most operations maniplating shmems in WebGPU are fallible, we'll have to handle passing them conditionally in most messages.

This commit starts with BufferMap, to avoid crashing when map is called on an invalid buffer.

Differential Revision: https://phabricator.services.mozilla.com/D149892
This commit is contained in:
Nicolas Silva 2022-08-10 15:55:02 +00:00
parent 8a829cb5fa
commit 29159ae421
6 changed files with 52 additions and 9 deletions

View File

@ -151,9 +151,29 @@ must be either GPUMapMode.READ or GPUMapMode.WRITE");
mappingPromise->Then(
GetCurrentSerialEventTarget(), __func__,
[promise, self](ipc::Shmem&& aShmem) {
self->mMapped->mShmem = std::move(aShmem);
promise->MaybeResolve(0);
[promise, self](MaybeShmem&& aShmem) {
switch (aShmem.type()) {
case MaybeShmem::TShmem: {
// TODO: This isn't quite aligned with the spec but it prevents from
// crashing when unmapping before the promise is resolved.
if (self->mMapped.isSome()) {
self->mMapped->mShmem = std::move(aShmem);
promise->MaybeResolve(0);
} else {
promise->MaybeRejectWithOperationError(
"Unmapped or invalid buffer");
}
break;
}
default: {
if (self->mMapped.isSome()) {
self->mMapped->mShmem = ipc::Shmem();
}
promise->MaybeRejectWithOperationError(
"Attempted to map an invalid buffer");
}
}
},
[promise](const ipc::ResponseRejectReason&) {
promise->MaybeRejectWithAbortError("Internal communication error!");

View File

@ -12,6 +12,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/webgpu/WebGPUTypes.h"
#include "mozilla/webgpu/PWebGPUTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/DOMEventTargetHelper.h"
@ -79,7 +80,7 @@ class SupportedLimits;
class Texture;
class WebGPUChild;
using MappingPromise = MozPromise<ipc::Shmem, ipc::ResponseRejectReason, true>;
using MappingPromise = MozPromise<MaybeShmem, ipc::ResponseRejectReason, true>;
class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
public:

View File

@ -20,6 +20,7 @@ include "mozilla/layers/LayersMessageUtils.h";
include "mozilla/webgpu/WebGPUSerialize.h";
include "mozilla/layers/WebRenderMessageUtils.h";
include protocol PCanvasManager;
include PWebGPUTypes;
namespace mozilla {
namespace webgpu {
@ -48,7 +49,7 @@ parent:
// TODO: We want to return an array of compilation messages.
async DeviceCreateShaderModule(RawId selfId, RawId bufferId, nsString label, nsCString code) returns (WebGPUCompilationMessage[] messages);
async BufferReturnShmem(RawId selfId, Shmem shmem);
async BufferMap(RawId selfId, WGPUHostMap hostMap, uint64_t offset, uint64_t size) returns (Shmem sm);
async BufferMap(RawId selfId, WGPUHostMap hostMap, uint64_t offset, uint64_t size) returns (MaybeShmem sm);
async BufferUnmap(RawId selfId, Shmem shmem, bool flush, bool keepShmem);
async BufferDestroy(RawId selfId);
async TextureDestroy(RawId selfId);

View File

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using struct mozilla::null_t from "mozilla/ipc/IPCCore.h";
namespace mozilla {
namespace webgpu {
[Comparable] union MaybeShmem {
Shmem;
null_t;
};
} // namespace layers
} // namespace mozilla

View File

@ -378,15 +378,17 @@ struct MapRequest {
static void MapCallback(ffi::WGPUBufferMapAsyncStatus status,
uint8_t* userdata) {
auto* req = reinterpret_cast<MapRequest*>(userdata);
// TODO: better handle errors
MOZ_ASSERT(status == ffi::WGPUBufferMapAsyncStatus_Success);
if (req->mHostMap == ffi::WGPUHostMap_Read) {
if (status != ffi::WGPUBufferMapAsyncStatus_Success) {
req->mResolver(MaybeShmem(null_t()));
} else if (req->mHostMap == ffi::WGPUHostMap_Read) {
const uint8_t* ptr = ffi::wgpu_server_buffer_get_mapped_range(
req->mContext, req->mBufferId, req->mOffset,
req->mShmem.Size<uint8_t>());
memcpy(req->mShmem.get<uint8_t>(), ptr, req->mShmem.Size<uint8_t>());
req->mResolver(MaybeShmem(std::move(req->mShmem)));
}
req->mResolver(std::move(req->mShmem));
delete req;
}
@ -399,6 +401,7 @@ ipc::IPCResult WebGPUParent::RecvBufferMap(RawId aSelfId,
aSelfId, aOffset, aSize));
auto& shmem = mSharedMemoryMap[aSelfId];
if (!shmem.IsReadable()) {
aResolver(MaybeShmem(mozilla::null_t()));
MOZ_LOG(sLogger, LogLevel::Error, ("\tshmem is empty\n"));
return IPC_OK();
}
@ -409,6 +412,7 @@ ipc::IPCResult WebGPUParent::RecvBufferMap(RawId aSelfId,
reinterpret_cast<uint8_t*>(request)};
ffi::wgpu_server_buffer_map(mContext.get(), aSelfId, aOffset, aSize, aHostMap,
callback);
return IPC_OK();
}

View File

@ -51,6 +51,7 @@ UNIFIED_SOURCES += [x + ".cpp" for x in h_and_cpp]
IPDL_SOURCES += [
"ipc/PWebGPU.ipdl",
"ipc/PWebGPUTypes.ipdlh",
]
EXPORTS.mozilla.webgpu += [