dawn_wire: Factor the common command serialization pattern.

Bug: dawn:445

Change-Id: I15a99a126c0494fd06dd727ff5c9008cde675d76
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23560
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-06-19 16:49:43 +00:00 committed by Commit Bot service account
parent 8f9523eb38
commit 90abd47a28
12 changed files with 57 additions and 92 deletions

View File

@ -380,7 +380,7 @@ namespace {
}
void {{Cmd}}::Serialize(char* buffer
{%- if command.may_have_dawn_object -%}
{%- if not is_return -%}
, const ObjectIdProvider& objectIdProvider
{%- endif -%}
) const {

View File

@ -102,7 +102,7 @@ namespace dawn_wire {
//* Serialize the structure and everything it points to into serializeBuffer which must be
//* big enough to contain all the data (as queried from GetRequiredSize).
void Serialize(char* serializeBuffer
{%- if command.may_have_dawn_object -%}
{%- if not is_return_command -%}
, const ObjectIdProvider& objectIdProvider
{%- endif -%}
) const;

View File

@ -196,9 +196,7 @@ namespace dawn_wire { namespace client {
{% endfor %}
//* Allocate space to send the command and copy the value args over.
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *device->GetClient());
device->GetClient()->SerializeCommand(cmd);
{% if method.return_type.category == "object" %}
return reinterpret_cast<{{as_cType(method.return_type.name)}}>(allocation->object.get());
@ -226,10 +224,7 @@ namespace dawn_wire { namespace client {
cmd.objectType = ObjectType::{{type.name.CamelCase()}};
cmd.objectId = obj->id;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(obj->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
obj->device->GetClient()->SerializeCommand(cmd);
obj->device->GetClient()->{{type.name.CamelCase()}}Allocator().Free(obj);
}

View File

@ -36,13 +36,11 @@ namespace dawn_wire { namespace client {
cmd.handleCreateInfoLength = handleCreateInfoLength;
cmd.handleCreateInfo = nullptr;
size_t commandSize = cmd.GetRequiredSize();
size_t requiredSize = commandSize + handleCreateInfoLength;
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
char* writeHandleSpace =
buffer->device->GetClient()->SerializeCommand(cmd, handleCreateInfoLength);
// Serialize the handle into the space after the command.
handle->SerializeCreate(allocatedBuffer + commandSize);
handle->SerializeCreate(writeHandleSpace);
}
} // namespace
@ -155,9 +153,7 @@ namespace dawn_wire { namespace client {
cmd.descriptor = descriptor;
cmd.result = ObjectHandle{buffer->id, bufferObjectAndSerial->generation};
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *wireClient);
wireClient->SerializeCommand(cmd);
return reinterpret_cast<WGPUBuffer>(buffer);
}
@ -223,12 +219,11 @@ namespace dawn_wire { namespace client {
cmd.handleCreateInfoLength = handleCreateInfoLength;
cmd.handleCreateInfo = nullptr;
size_t commandSize = cmd.GetRequiredSize();
size_t requiredSize = commandSize + handleCreateInfoLength;
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *wireClient);
char* writeHandleSpace =
buffer->device->GetClient()->SerializeCommand(cmd, handleCreateInfoLength);
// Serialize the WriteHandle into the space after the command.
buffer->writeHandle->SerializeCreate(allocatedBuffer + commandSize);
buffer->writeHandle->SerializeCreate(writeHandleSpace);
return result;
}
@ -286,10 +281,7 @@ namespace dawn_wire { namespace client {
cmd.count = count;
cmd.data = static_cast<const uint8_t*>(data);
Client* wireClient = buffer->device->GetClient();
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
buffer->device->GetClient()->SerializeCommand(cmd);
}
void ClientHandwrittenBufferUnmap(WGPUBuffer cBuffer) {
@ -316,14 +308,12 @@ namespace dawn_wire { namespace client {
cmd.writeFlushInfoLength = writeFlushInfoLength;
cmd.writeFlushInfo = nullptr;
size_t commandSize = cmd.GetRequiredSize();
size_t requiredSize = commandSize + writeFlushInfoLength;
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
char* writeHandleSpace =
buffer->device->GetClient()->SerializeCommand(cmd, writeFlushInfoLength);
// Serialize flush metadata into the space after the command.
// This closes the handle for writing.
buffer->writeHandle->SerializeFlush(allocatedBuffer + commandSize);
buffer->writeHandle->SerializeFlush(writeHandleSpace);
buffer->writeHandle = nullptr;
} else if (buffer->readHandle) {
@ -333,10 +323,7 @@ namespace dawn_wire { namespace client {
BufferUnmapCmd cmd;
cmd.self = cBuffer;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *buffer->device->GetClient());
buffer->device->GetClient()->SerializeCommand(cmd);
}
void ClientHandwrittenBufferDestroy(WGPUBuffer cBuffer) {
@ -349,10 +336,7 @@ namespace dawn_wire { namespace client {
BufferDestroyCmd cmd;
cmd.self = cBuffer;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *buffer->device->GetClient());
buffer->device->GetClient()->SerializeCommand(cmd);
}
WGPUFence ClientHandwrittenQueueCreateFence(WGPUQueue cSelf,
@ -366,9 +350,7 @@ namespace dawn_wire { namespace client {
cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
cmd.descriptor = descriptor;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *device->GetClient());
device->GetClient()->SerializeCommand(cmd);
WGPUFence cFence = reinterpret_cast<WGPUFence>(allocation->object.get());
@ -403,10 +385,7 @@ namespace dawn_wire { namespace client {
cmd.fence = cFence;
cmd.signalValue = signalValue;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(fence->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *fence->device->GetClient());
queue->device->GetClient()->SerializeCommand(cmd);
}
void ClientHandwrittenQueueWriteBuffer(WGPUQueue cQueue,
@ -424,10 +403,7 @@ namespace dawn_wire { namespace client {
cmd.data = static_cast<const uint8_t*>(data);
cmd.size = size;
Client* wireClient = buffer->device->GetClient();
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
queue->device->GetClient()->SerializeCommand(cmd);
}
void ClientDeviceReference(WGPUDevice) {

View File

@ -54,14 +54,14 @@ namespace dawn_wire { namespace client {
return result;
}
void* Client::GetCmdSpace(size_t size) {
char* Client::GetCmdSpace(size_t size) {
if (DAWN_UNLIKELY(mIsDisconnected)) {
if (size > mDummyCmdSpace.size()) {
mDummyCmdSpace.resize(size);
}
return mDummyCmdSpace.data();
}
return mSerializer->GetCmdSpace(size);
return static_cast<char*>(mSerializer->GetCmdSpace(size));
}
void Client::Disconnect() {

View File

@ -42,13 +42,22 @@ namespace dawn_wire { namespace client {
const volatile char* HandleCommands(const volatile char* commands, size_t size);
ReservedTexture ReserveTexture(WGPUDevice device);
void* GetCmdSpace(size_t size);
template <typename Cmd>
char* SerializeCommand(const Cmd& cmd, size_t extraSize = 0) {
size_t requiredSize = cmd.GetRequiredSize();
// TODO(cwallez@chromium.org): Check for overflows and allocation success?
char* allocatedBuffer = GetCmdSpace(requiredSize + extraSize);
cmd.Serialize(allocatedBuffer, *this);
return allocatedBuffer + requiredSize;
}
void Disconnect();
private:
#include "dawn_wire/client/ClientPrototypes_autogen.inc"
char* GetCmdSpace(size_t size);
Device* mDevice = nullptr;
CommandSerializer* mSerializer = nullptr;
WireDeserializeAllocator mAllocator;

View File

@ -34,9 +34,7 @@ namespace dawn_wire { namespace client {
cmd.self = reinterpret_cast<WGPUDevice>(this);
cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(mClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *mClient);
mClient->SerializeCommand(cmd);
}
Device::~Device() {
@ -51,9 +49,7 @@ namespace dawn_wire { namespace client {
cmd.objectType = ObjectType::Queue;
cmd.objectId = mDefaultQueue->id;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(mClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
mClient->SerializeCommand(cmd);
mClient->QueueAllocator().Free(mDefaultQueue);
}
@ -92,10 +88,7 @@ namespace dawn_wire { namespace client {
cmd.self = reinterpret_cast<WGPUDevice>(this);
cmd.filter = filter;
Client* wireClient = GetClient();
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *wireClient);
mClient->SerializeCommand(cmd);
}
bool Device::RequestPopErrorScope(WGPUErrorCallback callback, void* userdata) {
@ -113,10 +106,7 @@ namespace dawn_wire { namespace client {
cmd.device = reinterpret_cast<WGPUDevice>(this);
cmd.requestSerial = serial;
Client* wireClient = GetClient();
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *wireClient);
mClient->SerializeCommand(cmd);
return true;
}

View File

@ -39,8 +39,8 @@ namespace dawn_wire { namespace server {
DestroyAllObjects(mProcs);
}
void* Server::GetCmdSpace(size_t size) {
return mSerializer->GetCmdSpace(size);
char* Server::GetCmdSpace(size_t size) {
return static_cast<char*>(mSerializer->GetCmdSpace(size));
}
bool Server::InjectTexture(WGPUTexture texture, uint32_t id, uint32_t generation) {

View File

@ -58,7 +58,15 @@ namespace dawn_wire { namespace server {
bool InjectTexture(WGPUTexture texture, uint32_t id, uint32_t generation);
private:
void* GetCmdSpace(size_t size);
template <typename Cmd>
char* SerializeCommand(const Cmd& cmd, size_t extraSize = 0) {
size_t requiredSize = cmd.GetRequiredSize();
// TODO(cwallez@chromium.org): Check for overflows and allocation success?
char* allocatedBuffer = GetCmdSpace(requiredSize + extraSize);
cmd.Serialize(allocatedBuffer);
return allocatedBuffer + requiredSize;
}
char* GetCmdSpace(size_t size);
// Forwarding callbacks
static void ForwardUncapturedError(WGPUErrorType type, const char* message, void* userdata);

View File

@ -252,14 +252,11 @@ namespace dawn_wire { namespace server {
cmd.initialDataInfoLength = initialDataInfoLength;
cmd.initialDataInfo = nullptr;
size_t commandSize = cmd.GetRequiredSize();
size_t requiredSize = commandSize + initialDataInfoLength;
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
char* readHandleSpace = SerializeCommand(cmd, initialDataInfoLength);
if (status == WGPUBufferMapAsyncStatus_Success) {
// Serialize the initialization message into the space after the command.
data->readHandle->SerializeInitialData(ptr, dataLength, allocatedBuffer + commandSize);
data->readHandle->SerializeInitialData(ptr, dataLength, readHandleSpace);
// The in-flight map request returned successfully.
// Move the ReadHandle so it is owned by the buffer.
@ -284,9 +281,7 @@ namespace dawn_wire { namespace server {
cmd.requestSerial = data->requestSerial;
cmd.status = status;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
SerializeCommand(cmd);
if (status == WGPUBufferMapAsyncStatus_Success) {
// The in-flight map request returned successfully.

View File

@ -31,18 +31,14 @@ namespace dawn_wire { namespace server {
cmd.type = type;
cmd.message = message;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
SerializeCommand(cmd);
}
void Server::OnDeviceLost(const char* message) {
ReturnDeviceLostCallbackCmd cmd;
cmd.message = message;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
SerializeCommand(cmd);
}
bool Server::DoDevicePopErrorScope(WGPUDevice cDevice, uint64_t requestSerial) {
@ -73,9 +69,7 @@ namespace dawn_wire { namespace server {
cmd.type = type;
cmd.message = message;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
SerializeCommand(cmd);
}
}} // namespace dawn_wire::server

View File

@ -35,9 +35,7 @@ namespace dawn_wire { namespace server {
cmd.fence = data->fence;
cmd.value = data->value;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
SerializeCommand(cmd);
}
}} // namespace dawn_wire::server