mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-10-11 20:39:02 +00:00
If the client drops the last reference to the device, it would dereference an invalid pointer upon calling InjectError. So, skip the call. We can't keep the device alive if the Buffer is still alive because we intend to make all objects internally null if you delete their device. It is ok to skip error injection because if the client deletes the device, it should not expect to receive any more error callbacks. Bug: dawn:384 Change-Id: I4c694310e4395b06cd49603fc5d4cd846799decb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/37580 Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
99 lines
3.7 KiB
C++
99 lines
3.7 KiB
C++
// 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 DAWNWIRE_CLIENT_BUFFER_H_
|
|
#define DAWNWIRE_CLIENT_BUFFER_H_
|
|
|
|
#include <dawn/webgpu.h>
|
|
|
|
#include "dawn_wire/WireClient.h"
|
|
#include "dawn_wire/client/ObjectBase.h"
|
|
|
|
#include <map>
|
|
|
|
namespace dawn_wire { namespace client {
|
|
|
|
class Device;
|
|
|
|
class Buffer final : public ObjectBase {
|
|
public:
|
|
using ObjectBase::ObjectBase;
|
|
|
|
static WGPUBuffer Create(Device* device, const WGPUBufferDescriptor* descriptor);
|
|
static WGPUBuffer CreateError(Device* device);
|
|
|
|
~Buffer();
|
|
|
|
bool OnMapAsyncCallback(uint32_t requestSerial,
|
|
uint32_t status,
|
|
uint64_t readInitialDataInfoLength,
|
|
const uint8_t* readInitialDataInfo);
|
|
void MapAsync(WGPUMapModeFlags mode,
|
|
size_t offset,
|
|
size_t size,
|
|
WGPUBufferMapCallback callback,
|
|
void* userdata);
|
|
void* GetMappedRange(size_t offset, size_t size);
|
|
const void* GetConstMappedRange(size_t offset, size_t size);
|
|
void Unmap();
|
|
|
|
void Destroy();
|
|
|
|
private:
|
|
void CancelCallbacksForDisconnect() override;
|
|
|
|
bool IsMappedForReading() const;
|
|
bool IsMappedForWriting() const;
|
|
bool CheckGetMappedRangeOffsetSize(size_t offset, size_t size) const;
|
|
|
|
Device* mDevice;
|
|
|
|
// We want to defer all the validation to the server, which means we could have multiple
|
|
// map request in flight at a single time and need to track them separately.
|
|
// On well-behaved applications, only one request should exist at a single time.
|
|
struct MapRequestData {
|
|
WGPUBufferMapCallback callback = nullptr;
|
|
void* userdata = nullptr;
|
|
size_t offset = 0;
|
|
size_t size = 0;
|
|
|
|
// When the buffer is destroyed or unmapped too early, the unmappedBeforeX status takes
|
|
// precedence over the success value returned from the server. However Error statuses
|
|
// from the server take precedence over the client-side status.
|
|
WGPUBufferMapAsyncStatus clientStatus = WGPUBufferMapAsyncStatus_Success;
|
|
|
|
// TODO(enga): Use a tagged pointer to save space.
|
|
std::unique_ptr<MemoryTransferService::ReadHandle> readHandle = nullptr;
|
|
std::unique_ptr<MemoryTransferService::WriteHandle> writeHandle = nullptr;
|
|
};
|
|
std::map<uint32_t, MapRequestData> mRequests;
|
|
uint32_t mRequestSerial = 0;
|
|
uint64_t mSize = 0;
|
|
|
|
// Only one mapped pointer can be active at a time because Unmap clears all the in-flight
|
|
// requests.
|
|
// TODO(enga): Use a tagged pointer to save space.
|
|
std::unique_ptr<MemoryTransferService::ReadHandle> mReadHandle = nullptr;
|
|
std::unique_ptr<MemoryTransferService::WriteHandle> mWriteHandle = nullptr;
|
|
void* mMappedData = nullptr;
|
|
size_t mMapOffset = 0;
|
|
size_t mMapSize = 0;
|
|
|
|
std::weak_ptr<bool> mDeviceIsAlive;
|
|
};
|
|
|
|
}} // namespace dawn_wire::client
|
|
|
|
#endif // DAWNWIRE_CLIENT_BUFFER_H_
|