• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "dawn_wire/server/Server.h"
16 
17 namespace dawn_wire { namespace server {
18 
19     namespace {
20 
21         template <ObjectType objectType, typename Pipeline>
HandleCreateRenderPipelineAsyncCallbackResult(KnownObjects<Pipeline> * knownObjects,WGPUCreatePipelineAsyncStatus status,Pipeline pipeline,CreatePipelineAsyncUserData * data)22         void HandleCreateRenderPipelineAsyncCallbackResult(KnownObjects<Pipeline>* knownObjects,
23                                                            WGPUCreatePipelineAsyncStatus status,
24                                                            Pipeline pipeline,
25                                                            CreatePipelineAsyncUserData* data) {
26             // May be null if the device was destroyed. Device destruction destroys child
27             // objects on the wire.
28             auto* pipelineObject =
29                 knownObjects->Get(data->pipelineObjectID, AllocationState::Reserved);
30             // Should be impossible to fail. ObjectIds can't be freed by a destroy command until
31             // they move from Reserved to Allocated, or if they are destroyed here.
32             ASSERT(pipelineObject != nullptr);
33 
34             if (status == WGPUCreatePipelineAsyncStatus_Success) {
35                 // Assign the handle and allocated status if the pipeline is created successfully.
36                 pipelineObject->state = AllocationState::Allocated;
37                 pipelineObject->handle = pipeline;
38 
39                 // This should be impossible to fail. It would require a command to be sent that
40                 // creates a duplicate ObjectId, which would fail validation.
41                 bool success = TrackDeviceChild(pipelineObject->deviceInfo, objectType,
42                                                 data->pipelineObjectID);
43                 ASSERT(success);
44             } else {
45                 // Otherwise, free the ObjectId which will make it unusable.
46                 knownObjects->Free(data->pipelineObjectID);
47                 ASSERT(pipeline == nullptr);
48             }
49         }
50 
51     }  // anonymous namespace
52 
OnUncapturedError(ObjectHandle device,WGPUErrorType type,const char * message)53     void Server::OnUncapturedError(ObjectHandle device, WGPUErrorType type, const char* message) {
54         ReturnDeviceUncapturedErrorCallbackCmd cmd;
55         cmd.device = device;
56         cmd.type = type;
57         cmd.message = message;
58 
59         SerializeCommand(cmd);
60     }
61 
OnDeviceLost(ObjectHandle device,WGPUDeviceLostReason reason,const char * message)62     void Server::OnDeviceLost(ObjectHandle device,
63                               WGPUDeviceLostReason reason,
64                               const char* message) {
65         ReturnDeviceLostCallbackCmd cmd;
66         cmd.device = device;
67         cmd.reason = reason;
68         cmd.message = message;
69 
70         SerializeCommand(cmd);
71     }
72 
OnLogging(ObjectHandle device,WGPULoggingType type,const char * message)73     void Server::OnLogging(ObjectHandle device, WGPULoggingType type, const char* message) {
74         ReturnDeviceLoggingCallbackCmd cmd;
75         cmd.device = device;
76         cmd.type = type;
77         cmd.message = message;
78 
79         SerializeCommand(cmd);
80     }
81 
DoDevicePopErrorScope(ObjectId deviceId,uint64_t requestSerial)82     bool Server::DoDevicePopErrorScope(ObjectId deviceId, uint64_t requestSerial) {
83         auto* device = DeviceObjects().Get(deviceId);
84         if (device == nullptr) {
85             return false;
86         }
87 
88         auto userdata = MakeUserdata<ErrorScopeUserdata>();
89         userdata->requestSerial = requestSerial;
90         userdata->device = ObjectHandle{deviceId, device->generation};
91 
92         ErrorScopeUserdata* unownedUserdata = userdata.release();
93         bool success = mProcs.devicePopErrorScope(
94             device->handle,
95             ForwardToServer<decltype(
96                 &Server::OnDevicePopErrorScope)>::Func<&Server::OnDevicePopErrorScope>(),
97             unownedUserdata);
98         if (!success) {
99             delete unownedUserdata;
100         }
101         return success;
102     }
103 
OnDevicePopErrorScope(WGPUErrorType type,const char * message,ErrorScopeUserdata * userdata)104     void Server::OnDevicePopErrorScope(WGPUErrorType type,
105                                        const char* message,
106                                        ErrorScopeUserdata* userdata) {
107         ReturnDevicePopErrorScopeCallbackCmd cmd;
108         cmd.device = userdata->device;
109         cmd.requestSerial = userdata->requestSerial;
110         cmd.type = type;
111         cmd.message = message;
112 
113         SerializeCommand(cmd);
114     }
115 
DoDeviceCreateComputePipelineAsync(ObjectId deviceId,uint64_t requestSerial,ObjectHandle pipelineObjectHandle,const WGPUComputePipelineDescriptor * descriptor)116     bool Server::DoDeviceCreateComputePipelineAsync(
117         ObjectId deviceId,
118         uint64_t requestSerial,
119         ObjectHandle pipelineObjectHandle,
120         const WGPUComputePipelineDescriptor* descriptor) {
121         auto* device = DeviceObjects().Get(deviceId);
122         if (device == nullptr) {
123             return false;
124         }
125 
126         auto* resultData =
127             ComputePipelineObjects().Allocate(pipelineObjectHandle.id, AllocationState::Reserved);
128         if (resultData == nullptr) {
129             return false;
130         }
131 
132         resultData->generation = pipelineObjectHandle.generation;
133         resultData->deviceInfo = device->info.get();
134 
135         auto userdata = MakeUserdata<CreatePipelineAsyncUserData>();
136         userdata->device = ObjectHandle{deviceId, device->generation};
137         userdata->requestSerial = requestSerial;
138         userdata->pipelineObjectID = pipelineObjectHandle.id;
139 
140         mProcs.deviceCreateComputePipelineAsync(
141             device->handle, descriptor,
142             ForwardToServer<decltype(&Server::OnCreateComputePipelineAsyncCallback)>::Func<
143                 &Server::OnCreateComputePipelineAsyncCallback>(),
144             userdata.release());
145         return true;
146     }
147 
OnCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus status,WGPUComputePipeline pipeline,const char * message,CreatePipelineAsyncUserData * data)148     void Server::OnCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus status,
149                                                       WGPUComputePipeline pipeline,
150                                                       const char* message,
151                                                       CreatePipelineAsyncUserData* data) {
152         HandleCreateRenderPipelineAsyncCallbackResult<ObjectType::ComputePipeline>(
153             &ComputePipelineObjects(), status, pipeline, data);
154 
155         ReturnDeviceCreateComputePipelineAsyncCallbackCmd cmd;
156         cmd.device = data->device;
157         cmd.status = status;
158         cmd.requestSerial = data->requestSerial;
159         cmd.message = message;
160 
161         SerializeCommand(cmd);
162     }
163 
DoDeviceCreateRenderPipelineAsync(ObjectId deviceId,uint64_t requestSerial,ObjectHandle pipelineObjectHandle,const WGPURenderPipelineDescriptor * descriptor)164     bool Server::DoDeviceCreateRenderPipelineAsync(ObjectId deviceId,
165                                                    uint64_t requestSerial,
166                                                    ObjectHandle pipelineObjectHandle,
167                                                    const WGPURenderPipelineDescriptor* descriptor) {
168         auto* device = DeviceObjects().Get(deviceId);
169         if (device == nullptr) {
170             return false;
171         }
172 
173         auto* resultData =
174             RenderPipelineObjects().Allocate(pipelineObjectHandle.id, AllocationState::Reserved);
175         if (resultData == nullptr) {
176             return false;
177         }
178 
179         resultData->generation = pipelineObjectHandle.generation;
180         resultData->deviceInfo = device->info.get();
181 
182         auto userdata = MakeUserdata<CreatePipelineAsyncUserData>();
183         userdata->device = ObjectHandle{deviceId, device->generation};
184         userdata->requestSerial = requestSerial;
185         userdata->pipelineObjectID = pipelineObjectHandle.id;
186 
187         mProcs.deviceCreateRenderPipelineAsync(
188             device->handle, descriptor,
189             ForwardToServer<decltype(&Server::OnCreateRenderPipelineAsyncCallback)>::Func<
190                 &Server::OnCreateRenderPipelineAsyncCallback>(),
191             userdata.release());
192         return true;
193     }
194 
OnCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus status,WGPURenderPipeline pipeline,const char * message,CreatePipelineAsyncUserData * data)195     void Server::OnCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus status,
196                                                      WGPURenderPipeline pipeline,
197                                                      const char* message,
198                                                      CreatePipelineAsyncUserData* data) {
199         HandleCreateRenderPipelineAsyncCallbackResult<ObjectType::RenderPipeline>(
200             &RenderPipelineObjects(), status, pipeline, data);
201 
202         ReturnDeviceCreateRenderPipelineAsyncCallbackCmd cmd;
203         cmd.device = data->device;
204         cmd.status = status;
205         cmd.requestSerial = data->requestSerial;
206         cmd.message = message;
207 
208         SerializeCommand(cmd);
209     }
210 
211 }}  // namespace dawn_wire::server
212