From 1fa386cc87bc7460123ef27432b3d0d328037b1f Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Tue, 21 Dec 2021 04:04:51 +0000 Subject: [PATCH] dawn_wire: use memcpy on structures when possible This patch sets 'is_wire_transparent' on the structures whose members are all wire transparent and are not pointers, so that we can use memcpy when serializing and deserializing these structures: - GPUBlendComponent - GPUColor - GPUExtent3D - GPULimits - GPUOrigin3D - GPUStencilFaceState - GPUVertexAttribute - GPUBlendState In the next patch we will support memcpy on the qualified structures whose members contain pointers (e.g. GPUVertexBufferLayout). BUG=chromium:1266727 Change-Id: If46289f2d10cc7b17e6f5330cd2c2d4dc481f8b9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/73000 Reviewed-by: Corentin Wallez Reviewed-by: Austin Eng Commit-Queue: Jiawei Shao --- generator/dawn_json_generator.py | 15 +++++++++++++ generator/templates/dawn_wire/WireCmd.cpp | 26 ++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py index 60dfbe7f10..6a89240467 100644 --- a/generator/dawn_json_generator.py +++ b/generator/dawn_json_generator.py @@ -242,6 +242,21 @@ class StructureType(Record, Type): # two nextInChain members. assert not (self.extensible and self.chained) + def update_metadata(self): + Record.update_metadata(self) + + if self.may_have_dawn_object: + self.is_wire_transparent = False + return + + assert not (self.chained or self.extensible) + + def get_is_wire_transparent(member): + return member.type.is_wire_transparent and member.annotation == 'value' + + self.is_wire_transparent = all( + get_is_wire_transparent(m) for m in self.members) + @property def output(self): return self.chained == "out" or self.extensible == "out" diff --git a/generator/templates/dawn_wire/WireCmd.cpp b/generator/templates/dawn_wire/WireCmd.cpp index 0eb1bd1aa3..7bc148f6df 100644 --- a/generator/templates/dawn_wire/WireCmd.cpp +++ b/generator/templates/dawn_wire/WireCmd.cpp @@ -63,9 +63,14 @@ {%- if member.type.category == "object" -%} {%- set Optional = "Optional" if member.optional else "" -%} WIRE_TRY(provider.Get{{Optional}}Id({{in}}, &{{out}})); - {% elif member.type.category == "structure"%} - {%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%} - WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}})); + {%- elif member.type.category == "structure" -%} + {%- if member.type.is_wire_transparent -%} + static_assert(sizeof({{out}}) == sizeof({{in}}), "Serialize memcpy size must match."); + memcpy(&{{out}}, &{{in}}, {{member_transfer_sizeof(member)}}); + {%- else -%} + {%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%} + WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}})); + {%- endif -%} {%- else -%} {{out}} = {{in}}; {%- endif -%} @@ -77,11 +82,16 @@ {%- set Optional = "Optional" if member.optional else "" -%} WIRE_TRY(resolver.Get{{Optional}}FromId({{in}}, &{{out}})); {%- elif member.type.category == "structure" -%} - WIRE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, deserializeBuffer, allocator - {%- if member.type.may_have_dawn_object -%} - , resolver - {%- endif -%} - )); + {%- if member.type.is_wire_transparent -%} + static_assert(sizeof({{out}}) == sizeof({{in}}), "Deserialize memcpy size must match."); + memcpy(&{{out}}, const_cast(&{{in}}), {{member_transfer_sizeof(member)}}); + {%- else -%} + WIRE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, deserializeBuffer, allocator + {%- if member.type.may_have_dawn_object -%} + , resolver + {%- endif -%} + )); + {%- endif -%} {%- else -%} static_assert(sizeof({{out}}) >= sizeof({{in}}), "Deserialize assignment may not narrow."); {{out}} = {{in}};