mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-24 14:05:53 +00:00
This is needed so that: 1. We can support multiple devices in the wire. The device will need to know how to destroy its child objects. 2. The wire needs to be aware of all objects and their in-flight callbacks so that it can reject them if the wire is disconnnected. A future change will handle this. 3. Fix leaks of objects on page teardown. When the page is torn down, the wire client is destroyed, and we skip calling release() for all objects since the object holding the proc table was also destroyed. Bug: dawn:384, dawn:556 Change-Id: Ie23afe4e515b02e924fcfc2db92b749fd2257c9c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/31160 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
146 lines
5.3 KiB
C++
146 lines
5.3 KiB
C++
//* Copyright 2017 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_WIRECMD_AUTOGEN_H_
|
|
#define DAWNWIRE_WIRECMD_AUTOGEN_H_
|
|
|
|
#include <dawn/webgpu.h>
|
|
|
|
#include "dawn_wire/ObjectType_autogen.h"
|
|
|
|
namespace dawn_wire {
|
|
|
|
using ObjectId = uint32_t;
|
|
using ObjectGeneration = uint32_t;
|
|
struct ObjectHandle {
|
|
ObjectId id;
|
|
ObjectGeneration generation;
|
|
|
|
ObjectHandle();
|
|
ObjectHandle(ObjectId id, ObjectGeneration generation);
|
|
|
|
ObjectHandle(const volatile ObjectHandle& rhs);
|
|
ObjectHandle& operator=(const volatile ObjectHandle& rhs);
|
|
|
|
// MSVC has a bug where it thinks the volatile copy assignment is a duplicate.
|
|
// Workaround this by forwarding to a different function AssignFrom.
|
|
template <typename T>
|
|
ObjectHandle& operator=(const T& rhs) {
|
|
return AssignFrom(rhs);
|
|
}
|
|
ObjectHandle& AssignFrom(const ObjectHandle& rhs);
|
|
ObjectHandle& AssignFrom(const volatile ObjectHandle& rhs);
|
|
};
|
|
|
|
enum class DeserializeResult {
|
|
Success,
|
|
FatalError,
|
|
};
|
|
|
|
// Interface to allocate more space to deserialize pointed-to data.
|
|
// nullptr is treated as an error.
|
|
class DeserializeAllocator {
|
|
public:
|
|
virtual void* GetSpace(size_t size) = 0;
|
|
};
|
|
|
|
// Interface to convert an ID to a server object, if possible.
|
|
// Methods return FatalError if the ID is for a non-existent object and Success otherwise.
|
|
class ObjectIdResolver {
|
|
public:
|
|
{% for type in by_category["object"] %}
|
|
virtual DeserializeResult GetFromId(ObjectId id, {{as_cType(type.name)}}* out) const = 0;
|
|
virtual DeserializeResult GetOptionalFromId(ObjectId id, {{as_cType(type.name)}}* out) const = 0;
|
|
{% endfor %}
|
|
};
|
|
|
|
// Interface to convert a client object to its ID for the wiring.
|
|
class ObjectIdProvider {
|
|
public:
|
|
{% for type in by_category["object"] %}
|
|
virtual ObjectId GetId({{as_cType(type.name)}} object) const = 0;
|
|
virtual ObjectId GetOptionalId({{as_cType(type.name)}} object) const = 0;
|
|
{% endfor %}
|
|
};
|
|
|
|
//* Enum used as a prefix to each command on the wire format.
|
|
enum class WireCmd : uint32_t {
|
|
{% for command in cmd_records["command"] %}
|
|
{{command.name.CamelCase()}},
|
|
{% endfor %}
|
|
};
|
|
|
|
//* Enum used as a prefix to each command on the return wire format.
|
|
enum class ReturnWireCmd : uint32_t {
|
|
{% for command in cmd_records["return command"] %}
|
|
{{command.name.CamelCase()}},
|
|
{% endfor %}
|
|
};
|
|
|
|
struct CmdHeader {
|
|
uint64_t commandSize;
|
|
};
|
|
|
|
{% macro write_command_struct(command, is_return_command) %}
|
|
{% set Return = "Return" if is_return_command else "" %}
|
|
{% set Cmd = command.name.CamelCase() + "Cmd" %}
|
|
struct {{Return}}{{Cmd}} {
|
|
//* From a filled structure, compute how much size will be used in the serialization buffer.
|
|
size_t GetRequiredSize() const;
|
|
|
|
//* Serialize the structure and everything it points to into serializeBuffer which must be
|
|
//* big enough to contain all the data (as queried from GetRequiredSize).
|
|
void Serialize(size_t commandSize, char* serializeBuffer
|
|
{%- if not is_return_command -%}
|
|
, const ObjectIdProvider& objectIdProvider
|
|
{%- endif -%}
|
|
) const;
|
|
|
|
//* Deserializes the structure from a buffer, consuming a maximum of *size bytes. When this
|
|
//* function returns, buffer and size will be updated by the number of bytes consumed to
|
|
//* deserialize the structure. Structures containing pointers will use allocator to get
|
|
//* scratch space to deserialize the pointed-to data.
|
|
//* Deserialize returns:
|
|
//* - Success if everything went well (yay!)
|
|
//* - FatalError is something bad happened (buffer too small for example)
|
|
DeserializeResult Deserialize(const volatile char** buffer, size_t* size, DeserializeAllocator* allocator
|
|
{%- if command.may_have_dawn_object -%}
|
|
, const ObjectIdResolver& resolver
|
|
{%- endif -%}
|
|
);
|
|
|
|
{% if command.derived_method %}
|
|
//* Command handlers want to know the object ID in addition to the backing object.
|
|
//* Doesn't need to be filled before Serialize, or GetRequiredSize.
|
|
ObjectId selfId;
|
|
{% endif %}
|
|
|
|
{% for member in command.members %}
|
|
{{as_annotated_cType(member)}};
|
|
{% endfor %}
|
|
};
|
|
{% endmacro %}
|
|
|
|
{% for command in cmd_records["command"] %}
|
|
{{write_command_struct(command, False)}}
|
|
{% endfor %}
|
|
|
|
{% for command in cmd_records["return command"] %}
|
|
{{write_command_struct(command, True)}}
|
|
{% endfor %}
|
|
|
|
} // namespace dawn_wire
|
|
|
|
#endif // DAWNWIRE_WIRECMD_AUTOGEN_H_
|