2019-01-15 18:18:06 -08:00
|
|
|
// 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.
|
|
|
|
|
2022-02-04 04:51:25 -08:00
|
|
|
#include "dawn/wire/client/Client.h"
|
2020-04-14 19:00:14 -07:00
|
|
|
|
2022-02-04 04:51:25 -08:00
|
|
|
#include "dawn/common/Compiler.h"
|
2022-02-04 04:51:25 -08:00
|
|
|
#include "dawn/wire/client/Device.h"
|
2019-01-15 18:18:06 -08:00
|
|
|
|
2022-01-11 01:57:33 -08:00
|
|
|
namespace dawn::wire::client {
|
2019-01-15 18:18:06 -08:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
namespace {
|
2021-01-13 12:58:18 -08:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
class NoopCommandSerializer final : public CommandSerializer {
|
|
|
|
public:
|
|
|
|
static NoopCommandSerializer* GetInstance() {
|
|
|
|
static NoopCommandSerializer gNoopCommandSerializer;
|
|
|
|
return &gNoopCommandSerializer;
|
2020-04-23 14:21:52 -07:00
|
|
|
}
|
|
|
|
|
2022-05-09 09:26:44 -07:00
|
|
|
~NoopCommandSerializer() override = default;
|
2019-03-28 05:57:11 -07:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
size_t GetMaximumAllocationSize() const final { return 0; }
|
|
|
|
void* GetCmdSpace(size_t size) final { return nullptr; }
|
|
|
|
bool Flush() final { return false; }
|
|
|
|
};
|
2019-03-28 05:57:11 -07:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
} // anonymous namespace
|
2021-04-12 18:26:04 -07:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
Client::Client(CommandSerializer* serializer, MemoryTransferService* memoryTransferService)
|
|
|
|
: ClientBase(), mSerializer(serializer), mMemoryTransferService(memoryTransferService) {
|
|
|
|
if (mMemoryTransferService == nullptr) {
|
|
|
|
// If a MemoryTransferService is not provided, fall back to inline memory.
|
|
|
|
mOwnedMemoryTransferService = CreateInlineMemoryTransferService();
|
|
|
|
mMemoryTransferService = mOwnedMemoryTransferService.get();
|
2021-04-12 18:26:04 -07:00
|
|
|
}
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
2021-04-12 18:26:04 -07:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
Client::~Client() {
|
|
|
|
DestroyAllObjects();
|
|
|
|
}
|
2021-01-19 11:27:52 -08:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
void Client::DestroyAllObjects() {
|
2022-06-07 08:25:34 -07:00
|
|
|
// Free all devices first since they may hold references to other objects
|
|
|
|
// like the default queue. The Device destructor releases the default queue,
|
|
|
|
// which would be invalid if the queue was already freed.
|
|
|
|
while (!mObjects[ObjectType::Device].empty()) {
|
|
|
|
ObjectBase* object = mObjects[ObjectType::Device].head()->value();
|
|
|
|
|
|
|
|
DestroyObjectCmd cmd;
|
|
|
|
cmd.objectType = ObjectType::Device;
|
2022-06-14 07:55:46 -07:00
|
|
|
cmd.objectId = object->GetWireId();
|
2022-06-07 08:25:34 -07:00
|
|
|
SerializeCommand(cmd);
|
2022-06-17 14:21:39 -07:00
|
|
|
mObjectStores[ObjectType::Device].Free(object);
|
2022-06-07 08:25:34 -07:00
|
|
|
}
|
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
for (auto& objectList : mObjects) {
|
|
|
|
ObjectType objectType = static_cast<ObjectType>(&objectList - mObjects.data());
|
|
|
|
if (objectType == ObjectType::Device) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
while (!objectList.empty()) {
|
|
|
|
ObjectBase* object = objectList.head()->value();
|
2021-04-12 18:26:04 -07:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
DestroyObjectCmd cmd;
|
|
|
|
cmd.objectType = objectType;
|
2022-06-14 07:55:46 -07:00
|
|
|
cmd.objectId = object->GetWireId();
|
2022-05-01 07:40:55 -07:00
|
|
|
SerializeCommand(cmd);
|
2022-06-17 14:21:39 -07:00
|
|
|
mObjectStores[objectType].Free(object);
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
2021-01-21 16:25:05 -08:00
|
|
|
}
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
|
2022-06-19 13:13:01 -07:00
|
|
|
ReservedTexture Client::ReserveTexture(WGPUDevice device, const WGPUTextureDescriptor* descriptor) {
|
|
|
|
Texture* texture = Make<Texture>(descriptor);
|
2022-05-01 07:40:55 -07:00
|
|
|
|
|
|
|
ReservedTexture result;
|
2022-06-14 07:55:46 -07:00
|
|
|
result.texture = ToAPI(texture);
|
|
|
|
result.id = texture->GetWireId();
|
|
|
|
result.generation = texture->GetWireGeneration();
|
|
|
|
result.deviceId = FromAPI(device)->GetWireId();
|
|
|
|
result.deviceGeneration = FromAPI(device)->GetWireGeneration();
|
2022-05-01 07:40:55 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-05-26 03:32:17 -07:00
|
|
|
ReservedSwapChain Client::ReserveSwapChain(WGPUDevice device,
|
|
|
|
const WGPUSwapChainDescriptor* descriptor) {
|
|
|
|
SwapChain* swapChain = Make<SwapChain>(nullptr, descriptor);
|
2022-05-01 07:40:55 -07:00
|
|
|
|
|
|
|
ReservedSwapChain result;
|
2022-06-14 07:55:46 -07:00
|
|
|
result.swapchain = ToAPI(swapChain);
|
|
|
|
result.id = swapChain->GetWireId();
|
|
|
|
result.generation = swapChain->GetWireGeneration();
|
|
|
|
result.deviceId = FromAPI(device)->GetWireId();
|
|
|
|
result.deviceGeneration = FromAPI(device)->GetWireGeneration();
|
2022-05-01 07:40:55 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReservedDevice Client::ReserveDevice() {
|
2023-05-16 18:52:30 -07:00
|
|
|
Device* device = Make<Device>(nullptr);
|
2022-05-01 07:40:55 -07:00
|
|
|
|
|
|
|
ReservedDevice result;
|
2022-06-14 07:55:46 -07:00
|
|
|
result.device = ToAPI(device);
|
|
|
|
result.id = device->GetWireId();
|
|
|
|
result.generation = device->GetWireGeneration();
|
2022-05-01 07:40:55 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReservedInstance Client::ReserveInstance() {
|
2022-06-17 14:21:39 -07:00
|
|
|
Instance* instance = Make<Instance>();
|
2022-05-01 07:40:55 -07:00
|
|
|
|
|
|
|
ReservedInstance result;
|
2022-06-14 07:55:46 -07:00
|
|
|
result.instance = ToAPI(instance);
|
|
|
|
result.id = instance->GetWireId();
|
|
|
|
result.generation = instance->GetWireGeneration();
|
2022-05-01 07:40:55 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::ReclaimTextureReservation(const ReservedTexture& reservation) {
|
2022-06-17 14:21:39 -07:00
|
|
|
Free(FromAPI(reservation.texture));
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Client::ReclaimSwapChainReservation(const ReservedSwapChain& reservation) {
|
2022-06-17 14:21:39 -07:00
|
|
|
Free(FromAPI(reservation.swapchain));
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Client::ReclaimDeviceReservation(const ReservedDevice& reservation) {
|
2022-06-17 14:21:39 -07:00
|
|
|
Free(FromAPI(reservation.device));
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Client::ReclaimInstanceReservation(const ReservedInstance& reservation) {
|
2022-06-17 14:21:39 -07:00
|
|
|
Free(FromAPI(reservation.instance));
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Client::Disconnect() {
|
|
|
|
mDisconnected = true;
|
|
|
|
mSerializer = ChunkedCommandSerializer(NoopCommandSerializer::GetInstance());
|
|
|
|
|
|
|
|
auto& deviceList = mObjects[ObjectType::Device];
|
|
|
|
{
|
|
|
|
for (LinkNode<ObjectBase>* device = deviceList.head(); device != deviceList.end();
|
|
|
|
device = device->next()) {
|
|
|
|
static_cast<Device*>(device->value())
|
|
|
|
->HandleDeviceLost(WGPUDeviceLostReason_Undefined, "GPU connection lost");
|
2020-04-14 19:00:14 -07:00
|
|
|
}
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
|
|
|
for (auto& objectList : mObjects) {
|
|
|
|
for (LinkNode<ObjectBase>* object = objectList.head(); object != objectList.end();
|
|
|
|
object = object->next()) {
|
|
|
|
object->value()->CancelCallbacksForDisconnect();
|
2021-01-13 10:31:47 -08:00
|
|
|
}
|
2020-11-11 11:46:18 -08:00
|
|
|
}
|
2022-05-01 07:40:55 -07:00
|
|
|
}
|
2020-11-11 11:46:18 -08:00
|
|
|
|
2022-05-01 07:40:55 -07:00
|
|
|
bool Client::IsDisconnected() const {
|
|
|
|
return mDisconnected;
|
|
|
|
}
|
2020-11-12 10:03:42 -08:00
|
|
|
|
2022-06-17 14:21:39 -07:00
|
|
|
void Client::Free(ObjectBase* obj, ObjectType type) {
|
|
|
|
mObjectStores[type].Free(obj);
|
|
|
|
}
|
|
|
|
|
2022-01-11 01:57:33 -08:00
|
|
|
} // namespace dawn::wire::client
|