dawn_wire: Support deserializing s->c chained structs
Chained structs *may* contain objects which means deserialization may need an ObjectIdResolver. However, in practice, we never need to send chained structs from the server to the client that contain objects for a valid command. The one upcoming need for chained server->client structs is to serialize limit structs. Because limit structs never need objects, we provide a dummy implementation of the ObjectIdResolver which always yields an error. An analogous change is done for ObjectIdProvider. These classes will be used in a follow-up CL. Bug: dawn:685 Change-Id: I1c0f3f2d080377f2e1a77bc6e896f24d3d9ab931 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63981 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
8ee643c9d0
commit
dc7971ce58
|
@ -57,7 +57,7 @@
|
|||
{% macro serialize_member(member, in, out) %}
|
||||
{%- if member.type.category == "object" -%}
|
||||
{%- set Optional = "Optional" if member.optional else "" -%}
|
||||
{{out}} = provider.Get{{Optional}}Id({{in}});
|
||||
WIRE_TRY(provider.Get{{Optional}}Id({{in}}, &{{out}}));
|
||||
{% elif member.type.category == "structure"%}
|
||||
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
|
||||
{% if member.annotation == "const*const*" %}
|
||||
|
@ -416,8 +416,8 @@ namespace {
|
|||
}
|
||||
|
||||
WireResult {{Cmd}}::Serialize(size_t commandSize, SerializeBuffer* buffer
|
||||
{%- if not is_return -%}
|
||||
, const ObjectIdProvider& objectIdProvider
|
||||
{%- if command.may_have_dawn_object -%}
|
||||
, const ObjectIdProvider& provider
|
||||
{%- endif -%}
|
||||
) const {
|
||||
{{Name}}Transfer* transfer;
|
||||
|
@ -426,7 +426,7 @@ namespace {
|
|||
|
||||
WIRE_TRY({{Name}}Serialize(*this, transfer, buffer
|
||||
{%- if command.may_have_dawn_object -%}
|
||||
, objectIdProvider
|
||||
, provider
|
||||
{%- endif -%}
|
||||
));
|
||||
return WireResult::Success;
|
||||
|
@ -666,6 +666,36 @@ namespace dawn_wire {
|
|||
{{ write_command_serialization_methods(command, True) }}
|
||||
{% endfor %}
|
||||
|
||||
// Implementation of ObjectIdResolver that always errors.
|
||||
// Used when the generator adds a provider argument because of a chained
|
||||
// struct, but in practice, a chained struct in that location is invalid.
|
||||
class ErrorObjectIdResolver final : public ObjectIdResolver {
|
||||
public:
|
||||
{% for type in by_category["object"] %}
|
||||
WireResult GetFromId(ObjectId id, {{as_cType(type.name)}}* out) const override {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
WireResult GetOptionalFromId(ObjectId id, {{as_cType(type.name)}}* out) const override {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
// Implementation of ObjectIdProvider that always errors.
|
||||
// Used when the generator adds a provider argument because of a chained
|
||||
// struct, but in practice, a chained struct in that location is invalid.
|
||||
class ErrorObjectIdProvider final : public ObjectIdProvider {
|
||||
public:
|
||||
{% for type in by_category["object"] %}
|
||||
WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const override {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const override {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
// Implementations of serialization/deserialization of WPGUDeviceProperties.
|
||||
size_t SerializedWGPUDevicePropertiesSize(const WGPUDeviceProperties* deviceProperties) {
|
||||
return sizeof(WGPUDeviceProperties) +
|
||||
|
|
|
@ -66,8 +66,8 @@ namespace dawn_wire {
|
|||
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;
|
||||
virtual WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const = 0;
|
||||
virtual WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const = 0;
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
|
@ -98,11 +98,17 @@ namespace dawn_wire {
|
|||
|
||||
//* Serialize the structure and everything it points to into serializeBuffer which must be
|
||||
//* big enough to contain all the data (as queried from GetRequiredSize).
|
||||
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer
|
||||
{%- if not is_return_command -%}
|
||||
, const ObjectIdProvider& objectIdProvider
|
||||
{%- endif -%}
|
||||
) const;
|
||||
{% if command.may_have_dawn_object %}
|
||||
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer, const ObjectIdProvider& objectIdProvider) const;
|
||||
{% else %}
|
||||
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer) const;
|
||||
// Override which drops the provider if it's not needed.
|
||||
WireResult Serialize(size_t commandSize,
|
||||
SerializeBuffer* serializeBuffer,
|
||||
const ObjectIdProvider&) const {
|
||||
return Serialize(commandSize, serializeBuffer);
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
//* 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
|
||||
|
|
|
@ -49,14 +49,18 @@ namespace dawn_wire { namespace client {
|
|||
private:
|
||||
// Implementation of the ObjectIdProvider interface
|
||||
{% for type in by_category["object"] %}
|
||||
ObjectId GetId({{as_cType(type.name)}} object) const final {
|
||||
return object == nullptr ? 0 : reinterpret_cast<{{as_wireType(type)}}>(object)->id;
|
||||
}
|
||||
ObjectId GetOptionalId({{as_cType(type.name)}} object) const final {
|
||||
WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
ASSERT(out != nullptr);
|
||||
if (object == nullptr) {
|
||||
return 0;
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
return GetId(object);
|
||||
*out = reinterpret_cast<{{as_wireType(type)}}>(object)->id;
|
||||
return WireResult::Success;
|
||||
}
|
||||
WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
ASSERT(out != nullptr);
|
||||
*out = (object == nullptr ? 0 : reinterpret_cast<{{as_wireType(type)}}>(object)->id);
|
||||
return WireResult::Success;
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class WireWGPUDevicePropertiesTests : public testing::Test {};
|
|||
|
||||
// Test that the serialization and deserialization of WGPUDeviceProperties can work correctly.
|
||||
TEST_F(WireWGPUDevicePropertiesTests, SerializeWGPUDeviceProperties) {
|
||||
WGPUDeviceProperties sentWGPUDeviceProperties;
|
||||
WGPUDeviceProperties sentWGPUDeviceProperties = {};
|
||||
sentWGPUDeviceProperties.textureCompressionBC = true;
|
||||
// Set false to test that the serialization can handle both true and false correctly.
|
||||
sentWGPUDeviceProperties.pipelineStatisticsQuery = false;
|
||||
|
|
Loading…
Reference in New Issue