[dawn][wire] Introduce server/client MemoryHandle.

This single handle class (one for each side of the wire) will replace
the Read/WriteHandles. First introduce the new interfaces unimplemented
to allow for a multi-sided patch to update Chromium as well.

Bug: 524776858
Change-Id: I78697c51dd2a0248578b5f957fbc5ed78757f029
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/317535
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Shao, Jiawei <jiawei.shao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/include/dawn/wire/WireClient.h b/include/dawn/wire/WireClient.h
index 43c572a..5169119 100644
--- a/include/dawn/wire/WireClient.h
+++ b/include/dawn/wire/WireClient.h
@@ -109,17 +109,25 @@
     MemoryTransferService();
     virtual ~MemoryTransferService();
 
-    class ReadHandle;
-    class WriteHandle;
 
     // Create a handle for reading server data.
     // This may fail and return nullptr.
+    class ReadHandle;
     virtual ReadHandle* CreateReadHandle(size_t) = 0;
 
     // Create a handle for writing server data.
     // This may fail and return nullptr.
+    class WriteHandle;
     virtual WriteHandle* CreateWriteHandle(size_t) = 0;
 
+    // Create a handle for sharing memory with the server.
+    // This may fail and return nullptr.
+    class MemoryHandle;
+    virtual std::unique_ptr<MemoryHandle> CreateMemoryHandle(size_t size) {
+        // TODO(https://crbug.com/524776858): Make pure virtual once Chromium implements it.
+        return nullptr;
+    }
+
     class DAWN_WIRE_EXPORT ReadHandle {
       public:
         ReadHandle();
@@ -185,6 +193,55 @@
         WriteHandle& operator=(const WriteHandle&) = delete;
     };
 
+    class DAWN_WIRE_EXPORT MemoryHandle {
+      public:
+        MemoryHandle();
+        virtual ~MemoryHandle();
+
+        // Get the required serialization size for SerializeCreate
+        virtual size_t GetSerializeCreateSize() const = 0;
+
+        // Serialize the handle into |serializeSpace| so it can be received by the server.
+        virtual void SerializeCreate(std::span<std::byte> serializeSpace) const = 0;
+
+        // Returns a const view of the memory.
+        virtual std::span<const std::byte> GetConstData() const { return GetData(); }
+
+        // Returns a mutable view of the memory.
+        virtual std::span<std::byte> GetData() const = 0;
+
+        // Get the required serialization size for SerializeDataUpdate for the range [offset, offset
+        // + size)
+        virtual size_t GetSerializeDataUpdateSize(size_t offset, size_t size) const = 0;
+
+        // Serializes into |serializeData| the modification of the contents in the range [offset,
+        // offset + size).
+        virtual void SerializeDataUpdate(std::span<std::byte> serializeData,
+                                         size_t offset,
+                                         size_t size) const = 0;
+
+        // Applies a data update for the range [offset, offset + size) that was produced by
+        // `server::MemoryTransferService::MemoryHandle::SerializeDataUpdate`.
+        //
+        // For hardening, the implementation must return false if offset + size overflows the size
+        // of the memory (or if offset + size overflows a size_t).
+        //
+        // Parameters:
+        //  - `deserializeData`: The serialized payload from the server specifying the updated
+        //    buffer contents.
+        //  - `offset`: The byte offset of the range to update within the whole allocation.
+        //  - `size`: The size of the range to update.
+        //
+        // Returns true on success, or false if the deserialization is invalid (e.g. OOB access).
+        virtual bool DeserializeDataUpdate(std::span<const std::byte> deserializeData,
+                                           size_t offset,
+                                           size_t size) = 0;
+
+      private:
+        MemoryHandle(const MemoryHandle&) = delete;
+        MemoryHandle& operator=(const MemoryHandle&) = delete;
+    };
+
   private:
     MemoryTransferService(const MemoryTransferService&) = delete;
     MemoryTransferService& operator=(const MemoryTransferService&) = delete;
diff --git a/include/dawn/wire/WireServer.h b/include/dawn/wire/WireServer.h
index 654b39f..b21beba 100644
--- a/include/dawn/wire/WireServer.h
+++ b/include/dawn/wire/WireServer.h
@@ -89,18 +89,24 @@
     MemoryTransferService();
     virtual ~MemoryTransferService();
 
-    class ReadHandle;
-    class WriteHandle;
-
     // Deserialize data to create Read/Write handles. These handles are for the client
     // to Read/Write data.
     // TODO(https://issues.chromium.org/492456046): Pass as a `span<uint8_t> deseriazlizeData`.
+    class ReadHandle;
     virtual bool DeserializeReadHandle(const void* deserializePointer,
                                        size_t deserializeSize,
                                        ReadHandle** readHandle) = 0;
+    class WriteHandle;
     virtual bool DeserializeWriteHandle(const void* deserializePointer,
                                         size_t deserializeSize,
                                         WriteHandle** writeHandle) = 0;
+    // Returns a MemoryHandle from the parameters in creationData. May return nullptr on failure.
+    class MemoryHandle;
+    virtual std::unique_ptr<MemoryHandle> DeserializeMemoryHandle(
+        std::span<const std::byte> creationData) {
+        // TODO(https://crbug.com/524776858): Make pure virtual once Chromium implements it.
+        return nullptr;
+    }
 
     class DAWN_WIRE_EXPORT ReadHandle {
       public:
@@ -166,6 +172,56 @@
         virtual size_t GetSourceSize() const { return 0; }
     };
 
+    class DAWN_WIRE_EXPORT MemoryHandle {
+      public:
+        MemoryHandle();
+        virtual ~MemoryHandle();
+
+        // Return a direct view of the memory if this MemoryHandle supports it, nullptr when not
+        // supported.
+        virtual std::span<std::byte> GetSource() const { return {}; }
+
+        // Get the required serialization size for SerializeDataUpdate for the range [offset, offset
+        // + size)
+        virtual size_t GetSerializeDataUpdateSize(size_t offset, size_t size) const = 0;
+
+        // Serializes into |serializeData| the modification of the contents in the range [offset,
+        // offset + size). The modified contents is passed in |data|.
+        //
+        // Parameters:
+        //  - `serializeData`: The output buffer to write the serialized payload into.
+        //  - `offset`: The byte offset of data.data() within the whole allocation..
+        //  - `size`: The size of the range to update (must be <= data.size()).
+        //  - `data`: The new contents for the range [offset, offset + data.size()).
+        virtual void SerializeDataUpdate(std::span<std::byte> serializeData,
+                                         size_t offset,
+                                         size_t size,
+                                         std::span<const std::byte> data) const = 0;
+
+        // Applies a data update for the range [offset, offset + size) that was produced by
+        // `client::MemoryTransferService::MemoryHandle::SerializeDataUpdate`.
+        //
+        // For hardening, the implementation must return false if offset + size overflows the size
+        // of the memory (or if offset + size overflows a size_t), or if size > target.size().
+        //
+        // Parameters:
+        //  - `deserializeData`: The serialized payload from the client specifying the updated
+        //    buffer contents.
+        //  - `offset`: The byte offset for target.data() within the whole allocation.
+        //  - `size`: The size of the range to update.
+        //  - `target`: The range of data that is written by the update.
+        //
+        // Returns true on success, or false if the deserialization is invalid (e.g. OOB access).
+        virtual bool DeserializeDataUpdate(std::span<const std::byte> deserializeData,
+                                           size_t offset,
+                                           size_t size,
+                                           std::span<std::byte> target) = 0;
+
+      private:
+        MemoryHandle(const MemoryHandle&) = delete;
+        MemoryHandle& operator=(const MemoryHandle&) = delete;
+    };
+
   private:
     MemoryTransferService(const MemoryTransferService&) = delete;
     MemoryTransferService& operator=(const MemoryTransferService&) = delete;
diff --git a/src/dawn/wire/WireClient.cpp b/src/dawn/wire/WireClient.cpp
index 9ca5d2b..73451b1 100644
--- a/src/dawn/wire/WireClient.cpp
+++ b/src/dawn/wire/WireClient.cpp
@@ -107,6 +107,10 @@
 MemoryTransferService::WriteHandle::WriteHandle() = default;
 
 MemoryTransferService::WriteHandle::~WriteHandle() = default;
+
+MemoryTransferService::MemoryHandle::MemoryHandle() = default;
+
+MemoryTransferService::MemoryHandle::~MemoryHandle() = default;
 }  // namespace client
 
 }  // namespace dawn::wire
diff --git a/src/dawn/wire/WireServer.cpp b/src/dawn/wire/WireServer.cpp
index d68311a..1dd74eb 100644
--- a/src/dawn/wire/WireServer.cpp
+++ b/src/dawn/wire/WireServer.cpp
@@ -89,6 +89,10 @@
 MemoryTransferService::WriteHandle::WriteHandle() = default;
 
 MemoryTransferService::WriteHandle::~WriteHandle() = default;
+
+MemoryTransferService::MemoryHandle::MemoryHandle() = default;
+
+MemoryTransferService::MemoryHandle::~MemoryHandle() = default;
 }  // namespace server
 
 }  // namespace dawn::wire