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) %}
|
{% macro serialize_member(member, in, out) %}
|
||||||
{%- if member.type.category == "object" -%}
|
{%- if member.type.category == "object" -%}
|
||||||
{%- set Optional = "Optional" if member.optional else "" -%}
|
{%- 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"%}
|
{% elif member.type.category == "structure"%}
|
||||||
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
|
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
|
||||||
{% if member.annotation == "const*const*" %}
|
{% if member.annotation == "const*const*" %}
|
||||||
|
@ -416,8 +416,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
WireResult {{Cmd}}::Serialize(size_t commandSize, SerializeBuffer* buffer
|
WireResult {{Cmd}}::Serialize(size_t commandSize, SerializeBuffer* buffer
|
||||||
{%- if not is_return -%}
|
{%- if command.may_have_dawn_object -%}
|
||||||
, const ObjectIdProvider& objectIdProvider
|
, const ObjectIdProvider& provider
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
) const {
|
) const {
|
||||||
{{Name}}Transfer* transfer;
|
{{Name}}Transfer* transfer;
|
||||||
|
@ -426,7 +426,7 @@ namespace {
|
||||||
|
|
||||||
WIRE_TRY({{Name}}Serialize(*this, transfer, buffer
|
WIRE_TRY({{Name}}Serialize(*this, transfer, buffer
|
||||||
{%- if command.may_have_dawn_object -%}
|
{%- if command.may_have_dawn_object -%}
|
||||||
, objectIdProvider
|
, provider
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
));
|
));
|
||||||
return WireResult::Success;
|
return WireResult::Success;
|
||||||
|
@ -666,6 +666,36 @@ namespace dawn_wire {
|
||||||
{{ write_command_serialization_methods(command, True) }}
|
{{ write_command_serialization_methods(command, True) }}
|
||||||
{% endfor %}
|
{% 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.
|
// Implementations of serialization/deserialization of WPGUDeviceProperties.
|
||||||
size_t SerializedWGPUDevicePropertiesSize(const WGPUDeviceProperties* deviceProperties) {
|
size_t SerializedWGPUDevicePropertiesSize(const WGPUDeviceProperties* deviceProperties) {
|
||||||
return sizeof(WGPUDeviceProperties) +
|
return sizeof(WGPUDeviceProperties) +
|
||||||
|
|
|
@ -66,8 +66,8 @@ namespace dawn_wire {
|
||||||
class ObjectIdProvider {
|
class ObjectIdProvider {
|
||||||
public:
|
public:
|
||||||
{% for type in by_category["object"] %}
|
{% for type in by_category["object"] %}
|
||||||
virtual ObjectId GetId({{as_cType(type.name)}} object) const = 0;
|
virtual WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const = 0;
|
||||||
virtual ObjectId GetOptionalId({{as_cType(type.name)}} object) const = 0;
|
virtual WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const = 0;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,11 +98,17 @@ namespace dawn_wire {
|
||||||
|
|
||||||
//* Serialize the structure and everything it points to into serializeBuffer which must be
|
//* Serialize the structure and everything it points to into serializeBuffer which must be
|
||||||
//* big enough to contain all the data (as queried from GetRequiredSize).
|
//* big enough to contain all the data (as queried from GetRequiredSize).
|
||||||
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer
|
{% if command.may_have_dawn_object %}
|
||||||
{%- if not is_return_command -%}
|
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer, const ObjectIdProvider& objectIdProvider) const;
|
||||||
, const ObjectIdProvider& objectIdProvider
|
{% else %}
|
||||||
{%- endif -%}
|
WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer) const;
|
||||||
) 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
|
//* 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
|
//* 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:
|
private:
|
||||||
// Implementation of the ObjectIdProvider interface
|
// Implementation of the ObjectIdProvider interface
|
||||||
{% for type in by_category["object"] %}
|
{% for type in by_category["object"] %}
|
||||||
ObjectId GetId({{as_cType(type.name)}} object) const final {
|
WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||||
return object == nullptr ? 0 : reinterpret_cast<{{as_wireType(type)}}>(object)->id;
|
ASSERT(out != nullptr);
|
||||||
}
|
|
||||||
ObjectId GetOptionalId({{as_cType(type.name)}} object) const final {
|
|
||||||
if (object == 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 %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ class WireWGPUDevicePropertiesTests : public testing::Test {};
|
||||||
|
|
||||||
// Test that the serialization and deserialization of WGPUDeviceProperties can work correctly.
|
// Test that the serialization and deserialization of WGPUDeviceProperties can work correctly.
|
||||||
TEST_F(WireWGPUDevicePropertiesTests, SerializeWGPUDeviceProperties) {
|
TEST_F(WireWGPUDevicePropertiesTests, SerializeWGPUDeviceProperties) {
|
||||||
WGPUDeviceProperties sentWGPUDeviceProperties;
|
WGPUDeviceProperties sentWGPUDeviceProperties = {};
|
||||||
sentWGPUDeviceProperties.textureCompressionBC = true;
|
sentWGPUDeviceProperties.textureCompressionBC = true;
|
||||||
// Set false to test that the serialization can handle both true and false correctly.
|
// Set false to test that the serialization can handle both true and false correctly.
|
||||||
sentWGPUDeviceProperties.pipelineStatisticsQuery = false;
|
sentWGPUDeviceProperties.pipelineStatisticsQuery = false;
|
||||||
|
|
Loading…
Reference in New Issue