Add MemoryTransfer interfaces to the wire

This patch adds MemoryTransfer client/server interfaces and
uses it to implement data transfers for buffer mapping.

This patch also provides a default "inline" implementation of
the MemoryTransfer which is used if the embedder does not
provide one on initialization.

Because implementations of MemoryTransfer perform their own
serialization, a skip_serialize option is added to WireCmd records.

Bug: dawn:156
Change-Id: I2fa035517628a3ad465b0bc18a6ffc477e2bd67f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8642
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng
2019-07-19 16:01:48 +00:00
committed by Commit Bot service account
parent 49aae0f3bd
commit 6a5418a760
25 changed files with 874 additions and 211 deletions

View File

@@ -23,6 +23,7 @@ namespace dawn_wire {
namespace client {
class Client;
class MemoryTransferService;
}
struct ReservedTexture {
@@ -31,9 +32,14 @@ namespace dawn_wire {
uint32_t generation;
};
struct DAWN_WIRE_EXPORT WireClientDescriptor {
CommandSerializer* serializer;
client::MemoryTransferService* memoryTransferService = nullptr;
};
class DAWN_WIRE_EXPORT WireClient : public CommandHandler {
public:
WireClient(CommandSerializer* serializer);
WireClient(const WireClientDescriptor& descriptor);
~WireClient();
DawnDevice GetDevice() const;
@@ -46,6 +52,67 @@ namespace dawn_wire {
std::unique_ptr<client::Client> mImpl;
};
namespace client {
class DAWN_WIRE_EXPORT MemoryTransferService {
public:
class ReadHandle;
class WriteHandle;
virtual ~MemoryTransferService();
// Create a handle for reading server data.
// This may fail and return nullptr.
virtual ReadHandle* CreateReadHandle(size_t) = 0;
// Create a handle for writing server data.
// This may fail and return nullptr.
virtual WriteHandle* CreateWriteHandle(size_t) = 0;
// Imported memory implementation needs to override these to create Read/Write
// handles associated with a particular buffer. The client should receive a file
// descriptor for the buffer out-of-band.
virtual ReadHandle* CreateReadHandle(DawnBuffer, uint64_t offset, size_t size);
virtual WriteHandle* CreateWriteHandle(DawnBuffer, uint64_t offset, size_t size);
class ReadHandle {
public:
// Serialize the handle into |serializePointer| so it can be received by the server.
// If |serializePointer| is nullptr, this returns the required serialization space.
virtual size_t SerializeCreate(void* serializePointer = nullptr) = 0;
// Load initial data and open the handle for reading.
// This function takes in the serialized result of
// server::MemoryTransferService::ReadHandle::SerializeInitialData.
// This function should write to |data| and |dataLength| the pointer and size of the
// mapped data for reading. It must live at least until the ReadHandle is
// destructed.
virtual bool DeserializeInitialData(const void* deserializePointer,
size_t deserializeSize,
const void** data,
size_t* dataLength) = 0;
virtual ~ReadHandle();
};
class WriteHandle {
public:
// Serialize the handle into |serializePointer| so it can be received by the server.
// If |serializePointer| is nullptr, this returns the required serialization space.
virtual size_t SerializeCreate(void* serializePointer = nullptr) = 0;
// Open the handle for reading. The data returned should be zero-initialized.
// The data returned must live at least until the WriteHandle is destructed.
// On failure, the pointer returned should be null.
virtual std::pair<void*, size_t> Open() = 0;
// Flush writes to the handle. This should serialize info to send updates to the
// server.
// If |serializePointer| is nullptr, this returns the required serialization space.
virtual size_t SerializeFlush(void* serializePointer = nullptr) = 0;
virtual ~WriteHandle();
};
};
} // namespace client
} // namespace dawn_wire
#endif // DAWNWIRE_WIRECLIENT_H_

View File

@@ -23,11 +23,19 @@ namespace dawn_wire {
namespace server {
class Server;
class MemoryTransferService;
}
struct DAWN_WIRE_EXPORT WireServerDescriptor {
DawnDevice device;
const DawnProcTable* procs;
CommandSerializer* serializer;
server::MemoryTransferService* memoryTransferService = nullptr;
};
class DAWN_WIRE_EXPORT WireServer : public CommandHandler {
public:
WireServer(DawnDevice device, const DawnProcTable& procs, CommandSerializer* serializer);
WireServer(const WireServerDescriptor& descriptor);
~WireServer();
const char* HandleCommands(const char* commands, size_t size) override final;
@@ -38,6 +46,53 @@ namespace dawn_wire {
std::unique_ptr<server::Server> mImpl;
};
namespace server {
class DAWN_WIRE_EXPORT MemoryTransferService {
public:
class ReadHandle;
class WriteHandle;
virtual ~MemoryTransferService();
// Deserialize data to create Read/Write handles. These handles are for the client
// to Read/Write data.
virtual bool DeserializeReadHandle(const void* deserializePointer,
size_t deserializeSize,
ReadHandle** readHandle) = 0;
virtual bool DeserializeWriteHandle(const void* deserializePointer,
size_t deserializeSize,
WriteHandle** writeHandle) = 0;
class ReadHandle {
public:
// Initialize the handle data.
// Serialize into |serializePointer| so the client can update handle data.
// If |serializePointer| is nullptr, this returns the required serialization space.
virtual size_t SerializeInitialData(const void* data,
size_t dataLength,
void* serializePointer = nullptr) = 0;
virtual ~ReadHandle();
};
class WriteHandle {
public:
// Set the target for writes from the client. DeserializeFlush should copy data
// into the target.
void SetTarget(void* data, size_t dataLength);
// This function takes in the serialized result of
// client::MemoryTransferService::WriteHandle::SerializeFlush.
virtual bool DeserializeFlush(const void* deserializePointer,
size_t deserializeSize) = 0;
virtual ~WriteHandle();
protected:
void* mTargetData = nullptr;
size_t mDataLength = 0;
};
};
} // namespace server
} // namespace dawn_wire
#endif // DAWNWIRE_WIRESERVER_H_