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 void {{Cmd}}::Serialize(char* buffer
{%- if command.may_have_dawn_object -%} {%- if not is_return -%}
, const ObjectIdProvider& objectIdProvider , const ObjectIdProvider& objectIdProvider
{%- endif -%} {%- endif -%}
) const { ) const {

View File

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

View File

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

View File

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

View File

@ -54,14 +54,14 @@ namespace dawn_wire { namespace client {
return result; return result;
} }
void* Client::GetCmdSpace(size_t size) { char* Client::GetCmdSpace(size_t size) {
if (DAWN_UNLIKELY(mIsDisconnected)) { if (DAWN_UNLIKELY(mIsDisconnected)) {
if (size > mDummyCmdSpace.size()) { if (size > mDummyCmdSpace.size()) {
mDummyCmdSpace.resize(size); mDummyCmdSpace.resize(size);
} }
return mDummyCmdSpace.data(); return mDummyCmdSpace.data();
} }
return mSerializer->GetCmdSpace(size); return static_cast<char*>(mSerializer->GetCmdSpace(size));
} }
void Client::Disconnect() { 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); const volatile char* HandleCommands(const volatile char* commands, size_t size);
ReservedTexture ReserveTexture(WGPUDevice device); 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(); void Disconnect();
private: private:
#include "dawn_wire/client/ClientPrototypes_autogen.inc" #include "dawn_wire/client/ClientPrototypes_autogen.inc"
char* GetCmdSpace(size_t size);
Device* mDevice = nullptr; Device* mDevice = nullptr;
CommandSerializer* mSerializer = nullptr; CommandSerializer* mSerializer = nullptr;
WireDeserializeAllocator mAllocator; WireDeserializeAllocator mAllocator;

View File

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

View File

@ -39,8 +39,8 @@ namespace dawn_wire { namespace server {
DestroyAllObjects(mProcs); DestroyAllObjects(mProcs);
} }
void* Server::GetCmdSpace(size_t size) { char* Server::GetCmdSpace(size_t size) {
return mSerializer->GetCmdSpace(size); return static_cast<char*>(mSerializer->GetCmdSpace(size));
} }
bool Server::InjectTexture(WGPUTexture texture, uint32_t id, uint32_t generation) { 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); bool InjectTexture(WGPUTexture texture, uint32_t id, uint32_t generation);
private: 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 // Forwarding callbacks
static void ForwardUncapturedError(WGPUErrorType type, const char* message, void* userdata); 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.initialDataInfoLength = initialDataInfoLength;
cmd.initialDataInfo = nullptr; cmd.initialDataInfo = nullptr;
size_t commandSize = cmd.GetRequiredSize(); char* readHandleSpace = SerializeCommand(cmd, initialDataInfoLength);
size_t requiredSize = commandSize + initialDataInfoLength;
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
if (status == WGPUBufferMapAsyncStatus_Success) { if (status == WGPUBufferMapAsyncStatus_Success) {
// Serialize the initialization message into the space after the command. // 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. // The in-flight map request returned successfully.
// Move the ReadHandle so it is owned by the buffer. // Move the ReadHandle so it is owned by the buffer.
@ -284,9 +281,7 @@ namespace dawn_wire { namespace server {
cmd.requestSerial = data->requestSerial; cmd.requestSerial = data->requestSerial;
cmd.status = status; cmd.status = status;
size_t requiredSize = cmd.GetRequiredSize(); SerializeCommand(cmd);
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
if (status == WGPUBufferMapAsyncStatus_Success) { if (status == WGPUBufferMapAsyncStatus_Success) {
// The in-flight map request returned successfully. // The in-flight map request returned successfully.

View File

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

View File

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