diff --git a/generator/templates/dawn/wire/client/ApiProcs.cpp b/generator/templates/dawn/wire/client/ApiProcs.cpp index ef46293def..85fe15d421 100644 --- a/generator/templates/dawn/wire/client/ApiProcs.cpp +++ b/generator/templates/dawn/wire/client/ApiProcs.cpp @@ -58,7 +58,7 @@ namespace dawn::wire::client { //* For object creation, store the object ID the client will use for the result. {% if method.return_type.category == "object" %} - auto* returnObject = self->GetClient()->{{method.return_type.name.CamelCase()}}Allocator().New(self->GetClient()); + auto* returnObject = self->GetClient()->Make<{{method.return_type.name.CamelCase()}}>(); cmd.result = returnObject->GetWireHandle(); {% endif %} @@ -97,7 +97,7 @@ namespace dawn::wire::client { Client* client = obj->GetClient(); client->SerializeCommand(cmd); - client->{{type.name.CamelCase()}}Allocator().Free(obj); + client->Free(obj); } void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{cType}} cObj) { diff --git a/generator/templates/dawn/wire/client/ClientBase.h b/generator/templates/dawn/wire/client/ClientBase.h index 2fb1e5d94d..03d08e9b30 100644 --- a/generator/templates/dawn/wire/client/ClientBase.h +++ b/generator/templates/dawn/wire/client/ClientBase.h @@ -18,7 +18,6 @@ #include "dawn/wire/ChunkedCommandHandler.h" #include "dawn/wire/WireCmd_autogen.h" #include "dawn/wire/client/ApiObjects.h" -#include "dawn/wire/client/ObjectAllocator.h" namespace dawn::wire::client { @@ -27,25 +26,6 @@ namespace dawn::wire::client { ClientBase() = default; ~ClientBase() override = default; - {% for type in by_category["object"] %} - const ObjectAllocator<{{type.name.CamelCase()}}>& {{type.name.CamelCase()}}Allocator() const { - return m{{type.name.CamelCase()}}Allocator; - } - ObjectAllocator<{{type.name.CamelCase()}}>& {{type.name.CamelCase()}}Allocator() { - return m{{type.name.CamelCase()}}Allocator; - } - {% endfor %} - - void FreeObject(ObjectType objectType, ObjectBase* obj) { - switch (objectType) { - {% for type in by_category["object"] %} - case ObjectType::{{type.name.CamelCase()}}: - m{{type.name.CamelCase()}}Allocator.Free(static_cast<{{type.name.CamelCase()}}*>(obj)); - break; - {% endfor %} - } - } - private: // Implementation of the ObjectIdProvider interface {% for type in by_category["object"] %} @@ -63,10 +43,6 @@ namespace dawn::wire::client { return WireResult::Success; } {% endfor %} - - {% for type in by_category["object"] %} - ObjectAllocator<{{type.name.CamelCase()}}> m{{type.name.CamelCase()}}Allocator; - {% endfor %} }; } // namespace dawn::wire::client diff --git a/generator/templates/dawn/wire/client/ClientHandlers.cpp b/generator/templates/dawn/wire/client/ClientHandlers.cpp index f682c34e8c..d09c0f54b1 100644 --- a/generator/templates/dawn/wire/client/ClientHandlers.cpp +++ b/generator/templates/dawn/wire/client/ClientHandlers.cpp @@ -21,7 +21,7 @@ namespace dawn::wire::client { {% for command in cmd_records["return command"] %} bool Client::Handle{{command.name.CamelCase()}}(DeserializeBuffer* deserializeBuffer) { Return{{command.name.CamelCase()}}Cmd cmd; - WireResult deserializeResult = cmd.Deserialize(deserializeBuffer, &mAllocator); + WireResult deserializeResult = cmd.Deserialize(deserializeBuffer, &mWireCommandAllocator); if (deserializeResult == WireResult::FatalError) { return false; @@ -32,7 +32,7 @@ namespace dawn::wire::client { {% set name = as_varName(member.name) %} {% if member.type.dict_name == "ObjectHandle" %} - {{Type}}* {{name}} = {{Type}}Allocator().GetObject(cmd.{{name}}.id); + {{Type}}* {{name}} = Get<{{Type}}>(cmd.{{name}}.id); if ({{name}} != nullptr && {{name}}->GetWireGeneration() != cmd.{{name}}.generation) { {{name}} = nullptr; } @@ -84,7 +84,7 @@ namespace dawn::wire::client { if (!success) { return nullptr; } - mAllocator.Reset(); + mWireCommandAllocator.Reset(); } if (deserializeBuffer.AvailableSize() != 0) { diff --git a/src/dawn/wire/BUILD.gn b/src/dawn/wire/BUILD.gn index 5b2662649b..56aa038879 100644 --- a/src/dawn/wire/BUILD.gn +++ b/src/dawn/wire/BUILD.gn @@ -90,9 +90,10 @@ dawn_component("wire") { "client/Instance.h", "client/LimitsAndFeatures.cpp", "client/LimitsAndFeatures.h", - "client/ObjectAllocator.h", "client/ObjectBase.cpp", "client/ObjectBase.h", + "client/ObjectStore.cpp", + "client/ObjectStore.h", "client/QuerySet.cpp", "client/QuerySet.h", "client/Queue.cpp", diff --git a/src/dawn/wire/CMakeLists.txt b/src/dawn/wire/CMakeLists.txt index 9a79484878..c470cea071 100644 --- a/src/dawn/wire/CMakeLists.txt +++ b/src/dawn/wire/CMakeLists.txt @@ -63,7 +63,8 @@ target_sources(dawn_wire PRIVATE "client/Instance.h" "client/LimitsAndFeatures.cpp" "client/LimitsAndFeatures.h" - "client/ObjectAllocator.h" + "client/ObjectStore.cpp" + "client/ObjectStore.h" "client/ObjectBase.cpp" "client/ObjectBase.h" "client/QuerySet.cpp" diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp index ceab7b07e3..6edf63c813 100644 --- a/src/dawn/wire/client/Adapter.cpp +++ b/src/dawn/wire/client/Adapter.cpp @@ -71,7 +71,7 @@ void Adapter::RequestDevice(const WGPUDeviceDescriptor* descriptor, return; } - Device* device = client->DeviceAllocator().New(client); + Device* device = client->Make(); uint64_t serial = mRequestDeviceRequests.Add({callback, device->GetWireId(), userdata}); AdapterRequestDeviceCmd cmd; @@ -110,12 +110,12 @@ bool Adapter::OnRequestDeviceCallback(uint64_t requestSerial, } Client* client = GetClient(); - Device* device = client->DeviceAllocator().GetObject(request.deviceObjectId); + Device* device = client->Get(request.deviceObjectId); // If the return status is a failure we should give a null device to the callback and // free the allocation. if (status != WGPURequestDeviceStatus_Success) { - client->DeviceAllocator().Free(device); + client->Free(device); request.callback(status, nullptr, message, request.userdata); return true; } diff --git a/src/dawn/wire/client/Buffer.cpp b/src/dawn/wire/client/Buffer.cpp index b66e49b113..aaf6282727 100644 --- a/src/dawn/wire/client/Buffer.cpp +++ b/src/dawn/wire/client/Buffer.cpp @@ -74,7 +74,7 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor // Create the buffer and send the creation command. // This must happen after any potential device->CreateErrorBuffer() // as server expects allocating ids to be monotonically increasing - Buffer* buffer = wireClient->BufferAllocator().New(wireClient); + Buffer* buffer = wireClient->Make(); buffer->mDevice = device; buffer->mDeviceIsAlive = device->GetAliveWeakPtr(); buffer->mSize = descriptor->size; @@ -127,7 +127,7 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor WGPUBuffer Buffer::CreateError(Device* device, const WGPUBufferDescriptor* descriptor) { Client* client = device->GetClient(); - Buffer* buffer = client->BufferAllocator().New(client); + Buffer* buffer = client->Make(); buffer->mDevice = device; buffer->mDeviceIsAlive = device->GetAliveWeakPtr(); buffer->mSize = descriptor->size; diff --git a/src/dawn/wire/client/Client.cpp b/src/dawn/wire/client/Client.cpp index a41c020ab6..6c5e6312fc 100644 --- a/src/dawn/wire/client/Client.cpp +++ b/src/dawn/wire/client/Client.cpp @@ -61,7 +61,7 @@ void Client::DestroyAllObjects() { cmd.objectType = ObjectType::Device; cmd.objectId = object->GetWireId(); SerializeCommand(cmd); - FreeObject(ObjectType::Device, object); + mObjectStores[ObjectType::Device].Free(object); } for (auto& objectList : mObjects) { @@ -76,13 +76,13 @@ void Client::DestroyAllObjects() { cmd.objectType = objectType; cmd.objectId = object->GetWireId(); SerializeCommand(cmd); - FreeObject(objectType, object); + mObjectStores[objectType].Free(object); } } } ReservedTexture Client::ReserveTexture(WGPUDevice device) { - Texture* texture = TextureAllocator().New(this); + Texture* texture = Make(); ReservedTexture result; result.texture = ToAPI(texture); @@ -94,7 +94,7 @@ ReservedTexture Client::ReserveTexture(WGPUDevice device) { } ReservedSwapChain Client::ReserveSwapChain(WGPUDevice device) { - SwapChain* swapChain = SwapChainAllocator().New(this); + SwapChain* swapChain = Make(); ReservedSwapChain result; result.swapchain = ToAPI(swapChain); @@ -106,7 +106,7 @@ ReservedSwapChain Client::ReserveSwapChain(WGPUDevice device) { } ReservedDevice Client::ReserveDevice() { - Device* device = DeviceAllocator().New(this); + Device* device = Make(); ReservedDevice result; result.device = ToAPI(device); @@ -116,7 +116,7 @@ ReservedDevice Client::ReserveDevice() { } ReservedInstance Client::ReserveInstance() { - Instance* instance = InstanceAllocator().New(this); + Instance* instance = Make(); ReservedInstance result; result.instance = ToAPI(instance); @@ -126,19 +126,19 @@ ReservedInstance Client::ReserveInstance() { } void Client::ReclaimTextureReservation(const ReservedTexture& reservation) { - TextureAllocator().Free(FromAPI(reservation.texture)); + Free(FromAPI(reservation.texture)); } void Client::ReclaimSwapChainReservation(const ReservedSwapChain& reservation) { - SwapChainAllocator().Free(FromAPI(reservation.swapchain)); + Free(FromAPI(reservation.swapchain)); } void Client::ReclaimDeviceReservation(const ReservedDevice& reservation) { - DeviceAllocator().Free(FromAPI(reservation.device)); + Free(FromAPI(reservation.device)); } void Client::ReclaimInstanceReservation(const ReservedInstance& reservation) { - InstanceAllocator().Free(FromAPI(reservation.instance)); + Free(FromAPI(reservation.instance)); } void Client::Disconnect() { @@ -165,4 +165,8 @@ bool Client::IsDisconnected() const { return mDisconnected; } +void Client::Free(ObjectBase* obj, ObjectType type) { + mObjectStores[type].Free(obj); +} + } // namespace dawn::wire::client diff --git a/src/dawn/wire/client/Client.h b/src/dawn/wire/client/Client.h index d045f0c06e..ad5769a468 100644 --- a/src/dawn/wire/client/Client.h +++ b/src/dawn/wire/client/Client.h @@ -16,6 +16,7 @@ #define SRC_DAWN_WIRE_CLIENT_CLIENT_H_ #include +#include #include "dawn/common/LinkedList.h" #include "dawn/common/NonCopyable.h" @@ -26,6 +27,7 @@ #include "dawn/wire/WireCmd_autogen.h" #include "dawn/wire/WireDeserializeAllocator.h" #include "dawn/wire/client/ClientBase_autogen.h" +#include "dawn/wire/client/ObjectStore.h" namespace dawn::wire::client { @@ -37,6 +39,32 @@ class Client : public ClientBase { Client(CommandSerializer* serializer, MemoryTransferService* memoryTransferService); ~Client() override; + // Make(arg1, arg2, arg3) creates a new T, calling a constructor of the form: + // + // T::T(ObjectBaseParams, arg1, arg2, arg3) + template + T* Make(Args&&... args) { + constexpr ObjectType type = ObjectTypeToTypeEnum::value; + + ObjectBaseParams params = {this, mObjectStores[type].ReserveHandle()}; + T* object = new T(params, std::forward(args)...); + + mObjects[type].Append(object); + mObjectStores[type].Insert(std::unique_ptr(object)); + return object; + } + + template + void Free(T* obj) { + Free(obj, ObjectTypeToTypeEnum::value); + } + void Free(ObjectBase* obj, ObjectType type); + + template + T* Get(ObjectId id) { + return static_cast(mObjectStores[ObjectTypeToTypeEnum::value].Get(id)); + } + // ChunkedCommandHandler implementation const volatile char* HandleCommandsImpl(const volatile char* commands, size_t size) override; @@ -67,21 +95,16 @@ class Client : public ClientBase { void Disconnect(); bool IsDisconnected() const; - template - void TrackObject(T* object) { - mObjects[ObjectTypeToTypeEnum::value].Append(object); - } - private: void DestroyAllObjects(); #include "dawn/wire/client/ClientPrototypes_autogen.inc" ChunkedCommandSerializer mSerializer; - WireDeserializeAllocator mAllocator; + WireDeserializeAllocator mWireCommandAllocator; + PerObjectType mObjectStores; MemoryTransferService* mMemoryTransferService = nullptr; std::unique_ptr mOwnedMemoryTransferService = nullptr; - PerObjectType> mObjects; bool mDisconnected = false; }; diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp index c09cb3b670..d945694c69 100644 --- a/src/dawn/wire/client/Device.cpp +++ b/src/dawn/wire/client/Device.cpp @@ -20,7 +20,6 @@ #include "dawn/common/Log.h" #include "dawn/wire/client/ApiObjects_autogen.h" #include "dawn/wire/client/Client.h" -#include "dawn/wire/client/ObjectAllocator.h" namespace dawn::wire::client { @@ -221,7 +220,7 @@ WGPUQueue Device::GetQueue() { if (mQueue == nullptr) { // Get the primary queue for this device. Client* client = GetClient(); - mQueue = client->QueueAllocator().New(client); + mQueue = client->Make(); DeviceGetQueueCmd cmd; cmd.self = ToAPI(this); @@ -243,7 +242,7 @@ void Device::CreateComputePipelineAsync(WGPUComputePipelineDescriptor const* des "GPU device disconnected", userdata); } - ComputePipeline* pipeline = client->ComputePipelineAllocator().New(client); + ComputePipeline* pipeline = client->Make(); CreatePipelineAsyncRequest request = {}; request.createComputePipelineAsyncCallback = callback; @@ -270,20 +269,17 @@ bool Device::OnCreateComputePipelineAsyncCallback(uint64_t requestSerial, } Client* client = GetClient(); - auto* pipelineAllocation = - client->ComputePipelineAllocator().GetObject(request.pipelineObjectID); + ComputePipeline* pipeline = client->Get(request.pipelineObjectID); // If the return status is a failure we should give a null pipeline to the callback and // free the allocation. if (status != WGPUCreatePipelineAsyncStatus_Success) { - client->ComputePipelineAllocator().Free(pipelineAllocation); + client->Free(pipeline); request.createComputePipelineAsyncCallback(status, nullptr, message, request.userdata); return true; } - WGPUComputePipeline pipeline = reinterpret_cast(pipelineAllocation); - request.createComputePipelineAsyncCallback(status, pipeline, message, request.userdata); - + request.createComputePipelineAsyncCallback(status, ToAPI(pipeline), message, request.userdata); return true; } @@ -296,7 +292,7 @@ void Device::CreateRenderPipelineAsync(WGPURenderPipelineDescriptor const* descr "GPU device disconnected", userdata); } - RenderPipeline* pipeline = client->RenderPipelineAllocator().New(client); + RenderPipeline* pipeline = client->Make(); CreatePipelineAsyncRequest request = {}; request.createRenderPipelineAsyncCallback = callback; @@ -323,20 +319,17 @@ bool Device::OnCreateRenderPipelineAsyncCallback(uint64_t requestSerial, } Client* client = GetClient(); - auto* pipelineAllocation = - client->RenderPipelineAllocator().GetObject(request.pipelineObjectID); + RenderPipeline* pipeline = client->Get(request.pipelineObjectID); // If the return status is a failure we should give a null pipeline to the callback and // free the allocation. if (status != WGPUCreatePipelineAsyncStatus_Success) { - client->RenderPipelineAllocator().Free(pipelineAllocation); + client->Free(pipeline); request.createRenderPipelineAsyncCallback(status, nullptr, message, request.userdata); return true; } - WGPURenderPipeline pipeline = reinterpret_cast(pipelineAllocation); - request.createRenderPipelineAsyncCallback(status, pipeline, message, request.userdata); - + request.createRenderPipelineAsyncCallback(status, ToAPI(pipeline), message, request.userdata); return true; } diff --git a/src/dawn/wire/client/Instance.cpp b/src/dawn/wire/client/Instance.cpp index 9812f2ef89..efd9b74103 100644 --- a/src/dawn/wire/client/Instance.cpp +++ b/src/dawn/wire/client/Instance.cpp @@ -41,7 +41,7 @@ void Instance::RequestAdapter(const WGPURequestAdapterOptions* options, return; } - Adapter* adapter = client->AdapterAllocator().New(client); + Adapter* adapter = client->Make(); uint64_t serial = mRequestAdapterRequests.Add({callback, adapter->GetWireId(), userdata}); InstanceRequestAdapterCmd cmd; @@ -82,12 +82,12 @@ bool Instance::OnRequestAdapterCallback(uint64_t requestSerial, } Client* client = GetClient(); - Adapter* adapter = client->AdapterAllocator().GetObject(request.adapterObjectId); + Adapter* adapter = client->Get(request.adapterObjectId); // If the return status is a failure we should give a null adapter to the callback and // free the allocation. if (status != WGPURequestAdapterStatus_Success) { - client->AdapterAllocator().Free(adapter); + client->Free(adapter); request.callback(status, nullptr, message, request.userdata); return true; } diff --git a/src/dawn/wire/client/ObjectAllocator.h b/src/dawn/wire/client/ObjectAllocator.h deleted file mode 100644 index f369a70b30..0000000000 --- a/src/dawn/wire/client/ObjectAllocator.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2019 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 SRC_DAWN_WIRE_CLIENT_OBJECTALLOCATOR_H_ -#define SRC_DAWN_WIRE_CLIENT_OBJECTALLOCATOR_H_ - -#include -#include -#include -#include - -#include "dawn/common/Assert.h" -#include "dawn/common/Compiler.h" -#include "dawn/wire/WireCmd_autogen.h" -#include "dawn/wire/client/ObjectBase.h" - -namespace dawn::wire::client { - -template -class ObjectAllocator { - public: - ObjectAllocator() { - // ID 0 is nullptr - mObjects.emplace_back(nullptr); - } - - template - T* New(Client* client) { - ObjectHandle handle = GetFreeHandle(); - ObjectBaseParams params = {client, handle}; - auto object = std::make_unique(params); - client->TrackObject(object.get()); - - if (handle.id >= mObjects.size()) { - ASSERT(handle.id == mObjects.size()); - mObjects.emplace_back(std::move(object)); - } else { - // The generation should never overflow. We don't recycle ObjectIds that would - // overflow their next generation. - ASSERT(handle.generation != 0); - ASSERT(mObjects[handle.id] == nullptr); - mObjects[handle.id] = std::move(object); - } - - return mObjects[handle.id].get(); - } - void Free(T* obj) { - ASSERT(obj->IsInList()); - // The wire reuses ID for objects to keep them in a packed array starting from 0. - // To avoid issues with asynchronous server->client communication referring to an ID that's - // already reused, each handle also has a generation that's increment by one on each reuse. - // Avoid overflows by only reusing the ID if the increment of the generation won't overflow. - ObjectHandle currentHandle = obj->GetWireHandle(); - if (DAWN_LIKELY(currentHandle.generation != std::numeric_limits::max())) { - mFreeHandles.push_back({currentHandle.id, currentHandle.generation + 1}); - } - mObjects[currentHandle.id] = nullptr; - } - - T* GetObject(uint32_t id) { - if (id >= mObjects.size()) { - return nullptr; - } - return mObjects[id].get(); - } - - private: - ObjectHandle GetFreeHandle() { - if (mFreeHandles.empty()) { - return {mCurrentId++, 0}; - } - ObjectHandle handle = mFreeHandles.back(); - mFreeHandles.pop_back(); - return handle; - } - - // 0 is an ID reserved to represent nullptr - uint32_t mCurrentId = 1; - std::vector mFreeHandles; - std::vector> mObjects; -}; -} // namespace dawn::wire::client - -#endif // SRC_DAWN_WIRE_CLIENT_OBJECTALLOCATOR_H_ diff --git a/src/dawn/wire/client/ObjectStore.cpp b/src/dawn/wire/client/ObjectStore.cpp new file mode 100644 index 0000000000..299a67802f --- /dev/null +++ b/src/dawn/wire/client/ObjectStore.cpp @@ -0,0 +1,72 @@ +// Copyright 2022 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/ObjectStore.h" + +#include +#include + +namespace dawn::wire::client { + +ObjectStore::ObjectStore() { + // ID 0 is nullptr + mObjects.emplace_back(nullptr); + mCurrentId = 1; +} + +ObjectHandle ObjectStore::ReserveHandle() { + if (mFreeHandles.empty()) { + return {mCurrentId++, 0}; + } + ObjectHandle handle = mFreeHandles.back(); + mFreeHandles.pop_back(); + return handle; +} + +void ObjectStore::Insert(std::unique_ptr obj) { + ObjectId id = obj->GetWireId(); + + if (id >= mObjects.size()) { + ASSERT(id == mObjects.size()); + mObjects.emplace_back(std::move(obj)); + } else { + // The generation should never overflow. We don't recycle ObjectIds that would + // overflow their next generation. + ASSERT(obj->GetWireGeneration() != 0); + ASSERT(mObjects[id] == nullptr); + mObjects[id] = std::move(obj); + } +} + +void ObjectStore::Free(ObjectBase* obj) { + ASSERT(obj->IsInList()); + // The wire reuses ID for objects to keep them in a packed array starting from 0. + // To avoid issues with asynchronous server->client communication referring to an ID that's + // already reused, each handle also has a generation that's increment by one on each reuse. + // Avoid overflows by only reusing the ID if the increment of the generation won't overflow. + const ObjectHandle& currentHandle = obj->GetWireHandle(); + if (DAWN_LIKELY(currentHandle.generation != std::numeric_limits::max())) { + mFreeHandles.push_back({currentHandle.id, currentHandle.generation + 1}); + } + mObjects[currentHandle.id] = nullptr; +} + +ObjectBase* ObjectStore::Get(ObjectId id) const { + if (id >= mObjects.size()) { + return nullptr; + } + return mObjects[id].get(); +} + +} // namespace dawn::wire::client diff --git a/src/dawn/wire/client/ObjectStore.h b/src/dawn/wire/client/ObjectStore.h new file mode 100644 index 0000000000..5d9b7415d0 --- /dev/null +++ b/src/dawn/wire/client/ObjectStore.h @@ -0,0 +1,51 @@ +// Copyright 2019 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 SRC_DAWN_WIRE_CLIENT_OBJECTSTORE_H_ +#define SRC_DAWN_WIRE_CLIENT_OBJECTSTORE_H_ + +#include +#include + +#include "dawn/wire/client/ObjectBase.h" + +namespace dawn::wire::client { + +class Client; + +// A helper class used in Client, ObjectStore owns the association of some ObjectBase and +// ObjectHandles. The lifetime of the ObjectBase is then owned by the ObjectStore, destruction +// happening when Free is called. +// +// Since the wire has one "ID" namespace per type of object, each ObjectStore should contain a +// single type of objects. However no templates are used because Client wraps ObjectStore and is +// type-generic, so ObjectStore is type-erased to only work on ObjectBase. +class ObjectStore { + public: + ObjectStore(); + + ObjectHandle ReserveHandle(); + void Insert(std::unique_ptr obj); + void Free(ObjectBase* obj); + ObjectBase* Get(ObjectId id) const; + + private: + uint32_t mCurrentId; + std::vector mFreeHandles; + std::vector> mObjects; +}; + +} // namespace dawn::wire::client + +#endif // SRC_DAWN_WIRE_CLIENT_OBJECTSTORE_H_ diff --git a/src/dawn/wire/client/QuerySet.cpp b/src/dawn/wire/client/QuerySet.cpp index 903c65ddca..4a22a0c500 100644 --- a/src/dawn/wire/client/QuerySet.cpp +++ b/src/dawn/wire/client/QuerySet.cpp @@ -22,7 +22,7 @@ namespace dawn::wire::client { // static WGPUQuerySet QuerySet::Create(Device* device, const WGPUQuerySetDescriptor* descriptor) { Client* wireClient = device->GetClient(); - QuerySet* querySet = wireClient->QuerySetAllocator().New(wireClient); + QuerySet* querySet = wireClient->Make(); // Copy over descriptor data for reflection. querySet->mType = descriptor->type; diff --git a/src/dawn/wire/client/Texture.cpp b/src/dawn/wire/client/Texture.cpp index 99ea97fb7f..1fffde22e2 100644 --- a/src/dawn/wire/client/Texture.cpp +++ b/src/dawn/wire/client/Texture.cpp @@ -22,7 +22,7 @@ namespace dawn::wire::client { // static WGPUTexture Texture::Create(Device* device, const WGPUTextureDescriptor* descriptor) { Client* wireClient = device->GetClient(); - Texture* texture = wireClient->TextureAllocator().New(wireClient); + Texture* texture = wireClient->Make(); // Copy over descriptor data for reflection. texture->mSize = descriptor->size;