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 #ifndef DAWNWIRE_CLIENT_BUFFER_H_ 16 #define DAWNWIRE_CLIENT_BUFFER_H_ 17 18 #include <dawn/webgpu.h> 19 20 #include "dawn_wire/WireClient.h" 21 #include "dawn_wire/client/ObjectBase.h" 22 23 #include <map> 24 25 namespace dawn_wire { namespace client { 26 27 class Buffer final : public ObjectBase { 28 public: 29 using ObjectBase::ObjectBase; 30 31 static WGPUBuffer Create(Device* device, const WGPUBufferDescriptor* descriptor); 32 static WGPUBuffer CreateError(Device* device); 33 34 ~Buffer(); 35 36 bool OnMapAsyncCallback(uint32_t requestSerial, 37 uint32_t status, 38 uint64_t readInitialDataInfoLength, 39 const uint8_t* readInitialDataInfo); 40 void MapAsync(WGPUMapModeFlags mode, 41 size_t offset, 42 size_t size, 43 WGPUBufferMapCallback callback, 44 void* userdata); 45 void* GetMappedRange(size_t offset, size_t size); 46 const void* GetConstMappedRange(size_t offset, size_t size); 47 void Unmap(); 48 49 void Destroy(); 50 51 private: 52 void CancelCallbacksForDisconnect() override; 53 54 bool IsMappedForReading() const; 55 bool IsMappedForWriting() const; 56 bool CheckGetMappedRangeOffsetSize(size_t offset, size_t size) const; 57 58 // We want to defer all the validation to the server, which means we could have multiple 59 // map request in flight at a single time and need to track them separately. 60 // On well-behaved applications, only one request should exist at a single time. 61 struct MapRequestData { 62 WGPUBufferMapCallback callback = nullptr; 63 void* userdata = nullptr; 64 size_t offset = 0; 65 size_t size = 0; 66 67 // When the buffer is destroyed or unmapped too early, the unmappedBeforeX status takes 68 // precedence over the success value returned from the server. However Error statuses 69 // from the server take precedence over the client-side status. 70 WGPUBufferMapAsyncStatus clientStatus = WGPUBufferMapAsyncStatus_Success; 71 72 // TODO(enga): Use a tagged pointer to save space. 73 std::unique_ptr<MemoryTransferService::ReadHandle> readHandle = nullptr; 74 std::unique_ptr<MemoryTransferService::WriteHandle> writeHandle = nullptr; 75 }; 76 std::map<uint32_t, MapRequestData> mRequests; 77 uint32_t mRequestSerial = 0; 78 uint64_t mSize = 0; 79 80 // Only one mapped pointer can be active at a time because Unmap clears all the in-flight 81 // requests. 82 // TODO(enga): Use a tagged pointer to save space. 83 std::unique_ptr<MemoryTransferService::ReadHandle> mReadHandle = nullptr; 84 std::unique_ptr<MemoryTransferService::WriteHandle> mWriteHandle = nullptr; 85 void* mMappedData = nullptr; 86 size_t mMapOffset = 0; 87 size_t mMapSize = 0; 88 }; 89 90 }} // namespace dawn_wire::client 91 92 #endif // DAWNWIRE_CLIENT_BUFFER_H_ 93