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