Remove CreateBufferMappedAsync

The upstream WebGPU spec decided to not pursue CreateBufferMappedAsync,
and it adds some complexity to Dawn, so we remove it.

Bug: dawn:22
Change-Id: I4182a90c4a1aa0bfbaecd7d8f67d7049cf5df5d6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/17321
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez
2020-04-15 13:53:15 +00:00
committed by Commit Bot service account
parent e3f44e3cd6
commit 0ff7ed41ec
12 changed files with 0 additions and 803 deletions

View File

@@ -410,50 +410,6 @@ class CreateBufferMappedTests : public DawnTest {
return result;
}
template <WGPUBufferMapAsyncStatus expectedStatus = WGPUBufferMapAsyncStatus_Success>
wgpu::CreateBufferMappedResult CreateBufferMappedAsyncAndWait(wgpu::BufferUsage usage,
uint64_t size) {
wgpu::BufferDescriptor descriptor = {};
descriptor.size = size;
descriptor.usage = usage;
struct ResultInfo {
wgpu::CreateBufferMappedResult result;
bool done = false;
} resultInfo;
device.CreateBufferMappedAsync(
&descriptor,
[](WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result,
void* userdata) {
ASSERT_EQ(status, expectedStatus);
auto* resultInfo = reinterpret_cast<ResultInfo*>(userdata);
resultInfo->result.buffer = wgpu::Buffer::Acquire(result.buffer);
resultInfo->result.data = result.data;
resultInfo->result.dataLength = result.dataLength;
resultInfo->done = true;
},
&resultInfo);
while (!resultInfo.done) {
WaitABit();
}
CheckResultStartsZeroed(resultInfo.result, size);
return resultInfo.result;
}
wgpu::CreateBufferMappedResult CreateBufferMappedAsyncWithDataAndWait(
wgpu::BufferUsage usage,
const std::vector<uint32_t>& data) {
size_t byteLength = data.size() * sizeof(uint32_t);
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncAndWait(usage, byteLength);
memcpy(result.data, data.data(), byteLength);
return result;
}
private:
const void* mappedData = nullptr;
};
@@ -592,140 +548,6 @@ TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailure) {
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
}
// Test that the simplest CreateBufferMappedAsync works for MapWrite buffers.
TEST_P(CreateBufferMappedTests, MapWriteUsageSmallAsync) {
uint32_t myData = 230502;
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
}
// Test that the simplest CreateBufferMappedAsync works for MapRead buffers.
TEST_P(CreateBufferMappedTests, MapReadUsageSmallAsync) {
uint32_t myData = 230502;
wgpu::CreateBufferMappedResult result =
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::MapRead, {myData});
UnmapBuffer(result.buffer);
const void* mappedData = MapReadAsyncAndWait(result.buffer);
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
UnmapBuffer(result.buffer);
}
// Test that the simplest CreateBufferMappedAsync works for non-mappable buffers.
TEST_P(CreateBufferMappedTests, NonMappableUsageSmallAsync) {
uint32_t myData = 4239;
wgpu::CreateBufferMappedResult result =
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
}
// Test CreateBufferMappedAsync for a large MapWrite buffer
TEST_P(CreateBufferMappedTests, MapWriteUsageLargeAsync) {
constexpr uint64_t kDataSize = 1000 * 1000;
std::vector<uint32_t> myData;
for (uint32_t i = 0; i < kDataSize; ++i) {
myData.push_back(i);
}
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
}
// Test CreateBufferMappedAsync for a large MapRead buffer
TEST_P(CreateBufferMappedTests, MapReadUsageLargeAsync) {
constexpr uint64_t kDataSize = 1000 * 1000;
std::vector<uint32_t> myData;
for (uint32_t i = 0; i < kDataSize; ++i) {
myData.push_back(i);
}
wgpu::CreateBufferMappedResult result =
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::MapRead, {myData});
UnmapBuffer(result.buffer);
const void* mappedData = MapReadAsyncAndWait(result.buffer);
ASSERT_EQ(0, memcmp(mappedData, myData.data(), kDataSize * sizeof(uint32_t)));
UnmapBuffer(result.buffer);
}
// Test CreateBufferMappedAsync for a large non-mappable buffer
TEST_P(CreateBufferMappedTests, NonMappableUsageLargeAsync) {
constexpr uint64_t kDataSize = 1000 * 1000;
std::vector<uint32_t> myData;
for (uint32_t i = 0; i < kDataSize; ++i) {
myData.push_back(i);
}
wgpu::CreateBufferMappedResult result =
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
}
// Test that mapping a buffer is valid after CreateBufferMappedAsync and Unmap
TEST_P(CreateBufferMappedTests, CreateThenMapSuccessAsync) {
static uint32_t myData = 230502;
static uint32_t myData2 = 1337;
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
bool done = false;
result.buffer.MapWriteAsync(
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
ASSERT_NE(nullptr, data);
*static_cast<uint32_t*>(data) = myData2;
*static_cast<bool*>(userdata) = true;
},
&done);
while (!done) {
WaitABit();
}
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_EQ(myData2, result.buffer, 0);
}
// Test that is is invalid to map a buffer twice when using CreateBufferMappedAsync
TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailureAsync) {
uint32_t myData = 230502;
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
ASSERT_DEVICE_ERROR([&]() {
bool done = false;
result.buffer.MapWriteAsync(
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Error, status);
ASSERT_EQ(nullptr, data);
*static_cast<bool*>(userdata) = true;
},
&done);
while (!done) {
WaitABit();
}
}());
// CreateBufferMappedAsync is unaffected by the MapWrite error.
UnmapBuffer(result.buffer);
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
}
// Test that creating a very large buffers fails gracefully.
TEST_P(CreateBufferMappedTests, LargeBufferFails) {
// TODO(http://crbug.com/dawn/27): Missing support.

View File

@@ -296,38 +296,6 @@ TEST_P(DeviceLostTest, CreateBufferMappedFails) {
ASSERT_DEVICE_ERROR(device.CreateBufferMapped(&bufferDescriptor));
}
// Test that CreateBufferMappedAsync fails after device is lost
TEST_P(DeviceLostTest, CreateBufferMappedAsyncFails) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
SetCallbackAndLoseForTesting();
struct ResultInfo {
wgpu::CreateBufferMappedResult result;
bool done = false;
} resultInfo;
ASSERT_DEVICE_ERROR(device.CreateBufferMappedAsync(
&bufferDescriptor,
[](WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result, void* userdata) {
auto* resultInfo = static_cast<ResultInfo*>(userdata);
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
EXPECT_NE(nullptr, result.data);
resultInfo->result.buffer = wgpu::Buffer::Acquire(result.buffer);
resultInfo->result.data = result.data;
resultInfo->result.dataLength = result.dataLength;
resultInfo->done = true;
},
&resultInfo));
while (!resultInfo.done) {
ASSERT_DEVICE_ERROR(WaitABit());
}
ASSERT_DEVICE_ERROR(resultInfo.result.buffer.Unmap());
}
// Test that BufferMapReadAsync fails after device is lost
TEST_P(DeviceLostTest, BufferMapReadAsyncFails) {
wgpu::BufferDescriptor bufferDescriptor;

View File

@@ -69,18 +69,6 @@ namespace {
void* userdata));
};
std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
uint32_t* lastCreateMappedPointer = nullptr;
void ToMockCreateBufferMappedCallback(WGPUBufferMapAsyncStatus status,
WGPUCreateBufferMappedResult result,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
lastCreateMappedPointer = static_cast<uint32_t*>(result.data);
// Unpack WGPUCreateBufferMappedResult to make writing matchers easier
mockCreateBufferMappedCallback->Call(status, result.buffer, lastCreateMappedPointer,
result.dataLength, userdata);
}
} // anonymous namespace
class WireBufferMappingTests : public WireTest {
@@ -94,8 +82,6 @@ class WireBufferMappingTests : public WireTest {
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
mockCreateBufferMappedCallback =
std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
@@ -115,7 +101,6 @@ class WireBufferMappingTests : public WireTest {
// Delete mocks so that expectations are checked
mockBufferMapReadCallback = nullptr;
mockBufferMapWriteCallback = nullptr;
mockCreateBufferMappedCallback = nullptr;
}
void FlushServer() {
@@ -123,7 +108,6 @@ class WireBufferMappingTests : public WireTest {
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
}
protected:
@@ -629,187 +613,3 @@ TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapFailure) {
FlushClient();
}
// Test successful CreateBufferMappedAsync
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncSuccess) {
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
WGPUCreateBufferMappedResult apiResult;
uint32_t serverBufferContent = 31337;
apiResult.buffer = apiBuffer;
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
apiResult.dataLength = kBufferSize;
uint32_t updatedContent = 4242;
uint32_t zero = 0;
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
FlushClient();
WGPUBuffer buffer;
// The callback always gets a buffer full of zeroes.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
.WillOnce(::testing::SaveArg<1>(&buffer));
FlushServer();
// Write something to the mapped pointer
*lastCreateMappedPointer = updatedContent;
wgpuBufferUnmap(buffer);
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
FlushClient();
// After the buffer is unmapped, the content of the buffer is updated on the server
ASSERT_EQ(serverBufferContent, updatedContent);
}
// Test CreateBufferMappedAsync with map error
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncMapError) {
WGPUBufferDescriptor descriptor = {};
WGPUCreateBufferMappedResult apiResult;
apiResult.buffer = apiBuffer;
apiResult.data = nullptr; // error mapping
apiResult.dataLength = kBufferSize;
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
FlushClient();
WGPUBuffer buffer;
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Error, _, nullptr, 0, _))
.WillOnce(::testing::SaveArg<1>(&buffer));
FlushServer();
wgpuBufferUnmap(buffer);
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
FlushClient();
}
// Test that the CreateBufferMappedCallback isn't fired twice when unmap() is called inside the
// callback
TEST_F(WireBufferMappingTests, UnmapInsideCreateBufferMappedAsyncCallback) {
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
WGPUCreateBufferMappedResult apiResult;
uint32_t serverBufferContent = 31337;
apiResult.buffer = apiBuffer;
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
apiResult.dataLength = kBufferSize;
uint32_t zero = 0;
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
FlushClient();
WGPUBuffer buffer;
// The callback always gets a buffer full of zeroes.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); })));
FlushServer();
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
FlushClient();
}
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is deleted inside
// the callback
TEST_F(WireBufferMappingTests, ReleaseInsideCreateBufferMappedAsyncCallback) {
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
WGPUCreateBufferMappedResult apiResult;
uint32_t serverBufferContent = 31337;
apiResult.buffer = apiBuffer;
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
apiResult.dataLength = kBufferSize;
uint32_t zero = 0;
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
FlushClient();
WGPUBuffer buffer;
// The callback always gets a buffer full of zeroes.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); })));
FlushServer();
EXPECT_CALL(api, BufferRelease(apiBuffer));
FlushClient();
}
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is destroyed inside
// the callback
TEST_F(WireBufferMappingTests, DestroyInsideCreateBufferMappedAsyncCallback) {
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
WGPUCreateBufferMappedResult apiResult;
uint32_t serverBufferContent = 31337;
apiResult.buffer = apiBuffer;
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
apiResult.dataLength = kBufferSize;
uint32_t zero = 0;
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
FlushClient();
WGPUBuffer buffer;
// The callback always gets a buffer full of zeroes.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
InvokeWithoutArgs([&]() { wgpuBufferDestroy(buffer); })));
FlushServer();
EXPECT_CALL(api, BufferDestroy(apiBuffer));
FlushClient();
}

View File

@@ -70,16 +70,6 @@ namespace {
void* userdata));
};
std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
void ToMockCreateBufferMappedCallback(WGPUBufferMapAsyncStatus status,
WGPUCreateBufferMappedResult result,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
mockCreateBufferMappedCallback->Call(status, result.buffer,
static_cast<uint32_t*>(result.data), result.dataLength,
userdata);
}
} // anonymous namespace
// WireMemoryTransferServiceTests test the MemoryTransferService with buffer mapping.
@@ -113,8 +103,6 @@ class WireMemoryTransferServiceTests : public WireTest {
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
mockCreateBufferMappedCallback =
std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();
// TODO(enga): Make this thread-safe.
mBufferContent++;
@@ -131,7 +119,6 @@ class WireMemoryTransferServiceTests : public WireTest {
// Delete mocks so that expectations are checked
mockBufferMapReadCallback = nullptr;
mockBufferMapWriteCallback = nullptr;
mockCreateBufferMappedCallback = nullptr;
}
void FlushClient(bool success = true) {
@@ -144,7 +131,6 @@ class WireMemoryTransferServiceTests : public WireTest {
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
Mock::VerifyAndClearExpectations(&clientMemoryTransferService);
}
@@ -188,27 +174,6 @@ class WireMemoryTransferServiceTests : public WireTest {
return std::make_pair(apiResult, result);
}
WGPUCreateBufferMappedResult CreateBufferMappedAsync() {
WGPUBufferDescriptor descriptor = {};
descriptor.size = sizeof(mBufferContent);
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
WGPUBuffer apiBuffer = api.GetNewBuffer();
WGPUCreateBufferMappedResult apiResult;
apiResult.buffer = apiBuffer;
apiResult.data = reinterpret_cast<uint8_t*>(&mMappedBufferContent);
apiResult.dataLength = sizeof(mMappedBufferContent);
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
.WillOnce(Return(apiResult))
.RetiresOnSaturation();
return apiResult;
}
ClientReadHandle* ExpectReadHandleCreation() {
// Create the handle first so we can use it in later expectations.
ClientReadHandle* handle = clientMemoryTransferService.NewReadHandle();
@@ -934,168 +899,6 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDestroyBeforeUnmap) {
}
}
// Test successful CreateBufferMappedAsync.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncSuccess) {
// The client should create and serialize a WriteHandle on createBufferMappedAsync
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
FlushClient();
// The client receives a success callback. Save the buffer argument so we can call Unmap.
WGPUBuffer buffer;
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, &mMappedBufferContent,
sizeof(mMappedBufferContent), _))
.WillOnce(SaveArg<1>(&buffer));
// Since the mapping succeeds, the client opens the WriteHandle.
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
FlushServer();
// The client writes to the handle contents.
mMappedBufferContent = mUpdatedBufferContent;
// The client will then flush and destroy the handle on Unmap()
ExpectClientWriteHandleSerializeFlush(clientHandle);
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
wgpuBufferUnmap(buffer);
// The server deserializes the Flush message.
ExpectServerWriteHandleDeserializeFlush(serverHandle, mUpdatedBufferContent);
// After the handle is updated it can be destroyed.
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
EXPECT_CALL(api, BufferUnmap(apiResult.buffer)).Times(1);
FlushClient();
}
// Test CreateBufferMappedAsync WriteHandle creation failure.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncWriteHandleCreationFailure) {
// Mock a WriteHandle creation failure
MockWriteHandleCreationFailure();
WGPUBufferDescriptor descriptor = {};
descriptor.size = sizeof(mBufferContent);
// Failed creation of a WriteHandle is a fatal failure. The client synchronously receives
// a DEVICE_LOST callback.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_DeviceLost, _, nullptr, 0, _))
.Times(1);
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
nullptr);
}
// Test CreateBufferMappedAsync DeserializeWriteHandle failure.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncDeserializeWriteHandleFailure) {
// The client should create and serialize a WriteHandle on createBufferMappedAsync
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
DAWN_UNUSED(apiResult);
// The server should then deserialize the WriteHandle from the client.
// Mock a deserialization failure.
MockServerWriteHandleDeserializeFailure();
FlushClient(false);
// The server hit a fatal failure and never returned the callback. It is called when the
// wire is destructed.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Unknown, _, nullptr, 0, _))
.Times(1);
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
}
// Test CreateBufferMappedAsync handle Open failure.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncHandleOpenFailure) {
// The client should create and serialize a WriteHandle on createBufferMappedAsync
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
DAWN_UNUSED(apiResult);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
FlushClient();
// Since the mapping succeeds, the client opens the WriteHandle.
MockClientWriteHandleOpenFailure(clientHandle);
// Failing to open a handle is a fatal failure. The client receives a DEVICE_LOST callback.
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_DeviceLost, _, nullptr, 0, _))
.Times(1);
// Since opening the handle fails, it is destroyed immediately.
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
FlushServer(false);
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
}
// Test CreateBufferMappedAsync DeserializeFlush failure.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncDeserializeFlushFailure) {
// The client should create and serialize a WriteHandle on createBufferMappedAsync
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
DAWN_UNUSED(apiResult);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
FlushClient();
// The client receives a success callback. Save the buffer argument so we can call Unmap.
WGPUBuffer buffer;
EXPECT_CALL(*mockCreateBufferMappedCallback,
Call(WGPUBufferMapAsyncStatus_Success, _, &mMappedBufferContent,
sizeof(mMappedBufferContent), _))
.WillOnce(SaveArg<1>(&buffer));
// Since the mapping succeeds, the client opens the WriteHandle.
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
FlushServer();
// The client writes to the handle contents.
mMappedBufferContent = mUpdatedBufferContent;
// The client will then flush and destroy the handle on Unmap()
ExpectClientWriteHandleSerializeFlush(clientHandle);
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
wgpuBufferUnmap(buffer);
// The server deserializes the Flush message.
// Mock a deserialization failure.
MockServerWriteHandleDeserializeFlushFailure(serverHandle);
FlushClient(false);
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
}
// Test successful CreateBufferMapped.
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedSuccess) {
// The client should create and serialize a WriteHandle on createBufferMapped.