dawn_wire/client: Encapsulate all queue/fence-related logic

This CL only moves code, renames client::Fence members, and introduces
client::Queue. Additional fence methods are added for the interaction
with the queue. There are no functional changes.

With this ApiProcs.cpp is almost passthrough and will be removed in a
follow-up CL.

Bug: dawn:445
Change-Id: I65544ef76b54614452cf7c74a948a96cb35a4cfe
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24061
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn_wire.json b/dawn_wire.json
index f3c1c8c..54d8c94 100644
--- a/dawn_wire.json
+++ b/dawn_wire.json
@@ -119,7 +119,8 @@
         "client_special_objects": [
             "Buffer",
             "Device",
-            "Fence"
+            "Fence",
+            "Queue"
         ],
         "server_custom_pre_handler_commands": [
             "BufferDestroy",
diff --git a/src/dawn_wire/BUILD.gn b/src/dawn_wire/BUILD.gn
index 5d1b2d7..aa8b0c0 100644
--- a/src/dawn_wire/BUILD.gn
+++ b/src/dawn_wire/BUILD.gn
@@ -20,9 +20,7 @@
 # Public dawn_wire headers so they can be publically visible for
 # dependencies of dawn_wire
 source_set("dawn_wire_headers") {
-  public_deps = [
-    "${dawn_root}/src/dawn:dawn_headers",
-  ]
+  public_deps = [ "${dawn_root}/src/dawn:dawn_headers" ]
   all_dependent_configs = [ "${dawn_root}/src/common:dawn_public_include_dirs" ]
   sources = [
     "${dawn_root}/src/include/dawn_wire/Wire.h",
@@ -78,6 +76,8 @@
     "client/Fence.cpp",
     "client/Fence.h",
     "client/ObjectAllocator.h",
+    "client/Queue.cpp",
+    "client/Queue.h",
     "server/ObjectStorage.h",
     "server/Server.cpp",
     "server/Server.h",
@@ -89,7 +89,5 @@
   ]
 
   # Make headers publicly visible
-  public_deps = [
-    ":dawn_wire_headers",
-  ]
+  public_deps = [ ":dawn_wire_headers" ]
 }
diff --git a/src/dawn_wire/CMakeLists.txt b/src/dawn_wire/CMakeLists.txt
index 8ec7bff..579d46a 100644
--- a/src/dawn_wire/CMakeLists.txt
+++ b/src/dawn_wire/CMakeLists.txt
@@ -42,6 +42,8 @@
     "client/Fence.cpp"
     "client/Fence.h"
     "client/ObjectAllocator.h"
+    "client/Queue.cpp"
+    "client/Queue.h"
     "server/ObjectStorage.h"
     "server/Server.cpp"
     "server/Server.h"
diff --git a/src/dawn_wire/client/ApiObjects.h b/src/dawn_wire/client/ApiObjects.h
index b74eefe..f842d53 100644
--- a/src/dawn_wire/client/ApiObjects.h
+++ b/src/dawn_wire/client/ApiObjects.h
@@ -20,6 +20,7 @@
 #include "dawn_wire/client/Buffer.h"
 #include "dawn_wire/client/Device.h"
 #include "dawn_wire/client/Fence.h"
+#include "dawn_wire/client/Queue.h"
 
 #include "dawn_wire/client/ApiObjects_autogen.h"
 
diff --git a/src/dawn_wire/client/ApiProcs.cpp b/src/dawn_wire/client/ApiProcs.cpp
index 0475284..db4365b 100644
--- a/src/dawn_wire/client/ApiProcs.cpp
+++ b/src/dawn_wire/client/ApiProcs.cpp
@@ -86,8 +86,8 @@
     }
 
     uint64_t ClientHandwrittenFenceGetCompletedValue(WGPUFence cSelf) {
-        auto fence = reinterpret_cast<Fence*>(cSelf);
-        return fence->completedValue;
+        Fence* fence = reinterpret_cast<Fence*>(cSelf);
+        return fence->GetCompletedValue();
     }
 
     void ClientHandwrittenFenceOnCompletion(WGPUFence cFence,
@@ -95,72 +95,18 @@
                                             WGPUFenceOnCompletionCallback callback,
                                             void* userdata) {
         Fence* fence = reinterpret_cast<Fence*>(cFence);
-        if (value > fence->signaledValue) {
-            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
-                                    WGPUErrorType_Validation,
-                                    "Value greater than fence signaled value");
-            callback(WGPUFenceCompletionStatus_Error, userdata);
-            return;
-        }
-
-        if (value <= fence->completedValue) {
-            callback(WGPUFenceCompletionStatus_Success, userdata);
-            return;
-        }
-
-        Fence::OnCompletionData request;
-        request.completionCallback = callback;
-        request.userdata = userdata;
-        fence->requests.Enqueue(std::move(request), value);
+        fence->OnCompletion(value, callback, userdata);
     }
 
     WGPUFence ClientHandwrittenQueueCreateFence(WGPUQueue cSelf,
                                                 WGPUFenceDescriptor const* descriptor) {
         Queue* queue = reinterpret_cast<Queue*>(cSelf);
-        Device* device = queue->device;
-
-        QueueCreateFenceCmd cmd;
-        cmd.self = cSelf;
-        auto* allocation = device->GetClient()->FenceAllocator().New(device);
-        cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
-        cmd.descriptor = descriptor;
-
-        device->GetClient()->SerializeCommand(cmd);
-
-        WGPUFence cFence = reinterpret_cast<WGPUFence>(allocation->object.get());
-
-        Fence* fence = reinterpret_cast<Fence*>(cFence);
-        fence->queue = queue;
-
-        uint64_t initialValue = descriptor != nullptr ? descriptor->initialValue : 0u;
-        fence->signaledValue = initialValue;
-        fence->completedValue = initialValue;
-        return cFence;
+        return queue->CreateFence(descriptor);
     }
 
     void ClientHandwrittenQueueSignal(WGPUQueue cQueue, WGPUFence cFence, uint64_t signalValue) {
-        Fence* fence = reinterpret_cast<Fence*>(cFence);
         Queue* queue = reinterpret_cast<Queue*>(cQueue);
-        if (fence->queue != queue) {
-            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
-                                    WGPUErrorType_Validation,
-                                    "Fence must be signaled on the queue on which it was created.");
-            return;
-        }
-        if (signalValue <= fence->signaledValue) {
-            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
-                                    WGPUErrorType_Validation,
-                                    "Fence value less than or equal to signaled value");
-            return;
-        }
-        fence->signaledValue = signalValue;
-
-        QueueSignalCmd cmd;
-        cmd.self = cQueue;
-        cmd.fence = cFence;
-        cmd.signalValue = signalValue;
-
-        queue->device->GetClient()->SerializeCommand(cmd);
+        queue->Signal(cFence, signalValue);
     }
 
     void ClientHandwrittenQueueWriteBuffer(WGPUQueue cQueue,
@@ -169,16 +115,7 @@
                                            const void* data,
                                            size_t size) {
         Queue* queue = reinterpret_cast<Queue*>(cQueue);
-        Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
-
-        QueueWriteBufferInternalCmd cmd;
-        cmd.queueId = queue->id;
-        cmd.bufferId = buffer->id;
-        cmd.bufferOffset = bufferOffset;
-        cmd.data = static_cast<const uint8_t*>(data);
-        cmd.size = size;
-
-        queue->device->GetClient()->SerializeCommand(cmd);
+        queue->WriteBuffer(cBuffer, bufferOffset, data, size);
     }
 
     void ClientDeviceReference(WGPUDevice) {
diff --git a/src/dawn_wire/client/ClientDoers.cpp b/src/dawn_wire/client/ClientDoers.cpp
index ffc5198..55818ba 100644
--- a/src/dawn_wire/client/ClientDoers.cpp
+++ b/src/dawn_wire/client/ClientDoers.cpp
@@ -77,8 +77,7 @@
             return true;
         }
 
-        fence->completedValue = value;
-        fence->CheckPassedFences();
+        fence->OnUpdateCompletedValueCallback(value);
         return true;
     }
 
diff --git a/src/dawn_wire/client/Device.h b/src/dawn_wire/client/Device.h
index f32259a..42dff18 100644
--- a/src/dawn_wire/client/Device.h
+++ b/src/dawn_wire/client/Device.h
@@ -24,7 +24,7 @@
 namespace dawn_wire { namespace client {
 
     class Client;
-    struct Queue;
+    class Queue;
 
     class Device : public ObjectBase {
       public:
diff --git a/src/dawn_wire/client/Fence.cpp b/src/dawn_wire/client/Fence.cpp
index 607483e..aa0407c 100644
--- a/src/dawn_wire/client/Fence.cpp
+++ b/src/dawn_wire/client/Fence.cpp
@@ -14,22 +14,74 @@
 
 #include "dawn_wire/client/Fence.h"
 
+#include "dawn_wire/client/ApiProcs_autogen.h"
+
 namespace dawn_wire { namespace client {
 
     Fence::~Fence() {
         // Callbacks need to be fired in all cases, as they can handle freeing resources
         // so we call them with "Unknown" status.
-        for (auto& request : requests.IterateAll()) {
+        for (auto& request : mRequests.IterateAll()) {
             request.completionCallback(WGPUFenceCompletionStatus_Unknown, request.userdata);
         }
-        requests.Clear();
+        mRequests.Clear();
+    }
+
+    void Fence::Initialize(Queue* queue, const WGPUFenceDescriptor* descriptor) {
+        mQueue = queue;
+
+        uint64_t initialValue = descriptor != nullptr ? descriptor->initialValue : 0u;
+        mSignaledValue = initialValue;
+        mCompletedValue = initialValue;
     }
 
     void Fence::CheckPassedFences() {
-        for (auto& request : requests.IterateUpTo(completedValue)) {
+        for (auto& request : mRequests.IterateUpTo(mCompletedValue)) {
             request.completionCallback(WGPUFenceCompletionStatus_Success, request.userdata);
         }
-        requests.ClearUpTo(completedValue);
+        mRequests.ClearUpTo(mCompletedValue);
+    }
+
+    void Fence::OnCompletion(uint64_t value,
+                             WGPUFenceOnCompletionCallback callback,
+                             void* userdata) {
+        if (value > mSignaledValue) {
+            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(device), WGPUErrorType_Validation,
+                                    "Value greater than fence signaled value");
+            callback(WGPUFenceCompletionStatus_Error, userdata);
+            return;
+        }
+
+        if (value <= mCompletedValue) {
+            callback(WGPUFenceCompletionStatus_Success, userdata);
+            return;
+        }
+
+        Fence::OnCompletionData request;
+        request.completionCallback = callback;
+        request.userdata = userdata;
+        mRequests.Enqueue(std::move(request), value);
+    }
+
+    void Fence::OnUpdateCompletedValueCallback(uint64_t value) {
+        mCompletedValue = value;
+        CheckPassedFences();
+    }
+
+    uint64_t Fence::GetCompletedValue() const {
+        return mCompletedValue;
+    }
+
+    uint64_t Fence::GetSignaledValue() const {
+        return mSignaledValue;
+    }
+
+    Queue* Fence::GetQueue() const {
+        return mQueue;
+    }
+
+    void Fence::SetSignaledValue(uint64_t value) {
+        mSignaledValue = value;
     }
 
 }}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Fence.h b/src/dawn_wire/client/Fence.h
index 4acde6d..107b4e7 100644
--- a/src/dawn_wire/client/Fence.h
+++ b/src/dawn_wire/client/Fence.h
@@ -22,21 +22,33 @@
 
 namespace dawn_wire { namespace client {
 
-    struct Queue;
-    struct Fence : ObjectBase {
+    class Queue;
+    class Fence : public ObjectBase {
+      public:
         using ObjectBase::ObjectBase;
 
         ~Fence();
-        void CheckPassedFences();
+        void Initialize(Queue* queue, const WGPUFenceDescriptor* descriptor);
 
+        void CheckPassedFences();
+        void OnCompletion(uint64_t value, WGPUFenceOnCompletionCallback callback, void* userdata);
+        void OnUpdateCompletedValueCallback(uint64_t value);
+
+        uint64_t GetCompletedValue() const;
+        uint64_t GetSignaledValue() const;
+        Queue* GetQueue() const;
+
+        void SetSignaledValue(uint64_t value);
+
+      private:
         struct OnCompletionData {
             WGPUFenceOnCompletionCallback completionCallback = nullptr;
             void* userdata = nullptr;
         };
-        Queue* queue = nullptr;
-        uint64_t signaledValue = 0;
-        uint64_t completedValue = 0;
-        SerialMap<OnCompletionData> requests;
+        Queue* mQueue = nullptr;
+        uint64_t mSignaledValue = 0;
+        uint64_t mCompletedValue = 0;
+        SerialMap<OnCompletionData> mRequests;
     };
 
 }}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Queue.cpp b/src/dawn_wire/client/Queue.cpp
new file mode 100644
index 0000000..fa338f3
--- /dev/null
+++ b/src/dawn_wire/client/Queue.cpp
@@ -0,0 +1,78 @@
+// Copyright 2020 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_wire/client/Queue.h"
+
+#include "dawn_wire/client/ApiProcs_autogen.h"
+#include "dawn_wire/client/Client.h"
+#include "dawn_wire/client/Device.h"
+
+namespace dawn_wire { namespace client {
+
+    WGPUFence Queue::CreateFence(WGPUFenceDescriptor const* descriptor) {
+        auto* allocation = device->GetClient()->FenceAllocator().New(device);
+
+        QueueCreateFenceCmd cmd;
+        cmd.self = reinterpret_cast<WGPUQueue>(this);
+        cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
+        cmd.descriptor = descriptor;
+        device->GetClient()->SerializeCommand(cmd);
+
+        Fence* fence = allocation->object.get();
+        fence->Initialize(this, descriptor);
+        return reinterpret_cast<WGPUFence>(fence);
+    }
+
+    void Queue::Signal(WGPUFence cFence, uint64_t signalValue) {
+        Fence* fence = reinterpret_cast<Fence*>(cFence);
+        if (fence->GetQueue() != this) {
+            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
+                                    WGPUErrorType_Validation,
+                                    "Fence must be signaled on the queue on which it was created.");
+            return;
+        }
+        if (signalValue <= fence->GetSignaledValue()) {
+            ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
+                                    WGPUErrorType_Validation,
+                                    "Fence value less than or equal to signaled value");
+            return;
+        }
+
+        fence->SetSignaledValue(signalValue);
+
+        QueueSignalCmd cmd;
+        cmd.self = reinterpret_cast<WGPUQueue>(this);
+        cmd.fence = cFence;
+        cmd.signalValue = signalValue;
+
+        device->GetClient()->SerializeCommand(cmd);
+    }
+
+    void Queue::WriteBuffer(WGPUBuffer cBuffer,
+                            uint64_t bufferOffset,
+                            const void* data,
+                            size_t size) {
+        Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
+
+        QueueWriteBufferInternalCmd cmd;
+        cmd.queueId = id;
+        cmd.bufferId = buffer->id;
+        cmd.bufferOffset = bufferOffset;
+        cmd.data = static_cast<const uint8_t*>(data);
+        cmd.size = size;
+
+        device->GetClient()->SerializeCommand(cmd);
+    }
+
+}}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Queue.h b/src/dawn_wire/client/Queue.h
new file mode 100644
index 0000000..9e51618
--- /dev/null
+++ b/src/dawn_wire/client/Queue.h
@@ -0,0 +1,38 @@
+// Copyright 2020 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNWIRE_CLIENT_QUEUE_H_
+#define DAWNWIRE_CLIENT_QUEUE_H_
+
+#include <dawn/webgpu.h>
+
+#include "dawn_wire/WireClient.h"
+#include "dawn_wire/client/ObjectBase.h"
+
+#include <map>
+
+namespace dawn_wire { namespace client {
+
+    class Queue : public ObjectBase {
+      public:
+        using ObjectBase::ObjectBase;
+
+        WGPUFence CreateFence(const WGPUFenceDescriptor* descriptor);
+        void Signal(WGPUFence fence, uint64_t signalValue);
+        void WriteBuffer(WGPUBuffer cBuffer, uint64_t bufferOffset, const void* data, size_t size);
+    };
+
+}}  // namespace dawn_wire::client
+
+#endif  // DAWNWIRE_CLIENT_QUEUE_H_