Use wgpu::StringView for input strings.

These are:

 - entryPoint names
 - overridable constant names
 - the cache isolation key
 - the HTML canvas selector.

Fixups to dawn::native's entry point name handling were necessary, as
well as a StreamIn<NullableStringView> implementation for serialization
of the cache isolation key.

Bug: 42241188
Change-Id: Ib245a957557dfe0d8829ecc48dbee53d04be1fad
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/207535
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/dawn/native/api_StreamImpl.cpp b/generator/templates/dawn/native/api_StreamImpl.cpp
index 960d29f..68b5e4e 100644
--- a/generator/templates/dawn/native/api_StreamImpl.cpp
+++ b/generator/templates/dawn/native/api_StreamImpl.cpp
@@ -32,6 +32,7 @@
 {% set prefix = metadata.proc_table_prefix.lower() %}
 #include "{{native_dir}}/CacheKey.h"
 #include "{{native_dir}}/{{prefix}}_platform.h"
+#include "{{native_dir}}/{{metadata.namespace}}_structs_autogen.h"
 
 #include <cstring>
 
@@ -96,13 +97,23 @@
     {% endif %}
 {% endmacro %}
 
-// Custom stream operator for special bool type.
+// Custom stream operator for special bool type that doesn't have the same size as C++'s bool.
 {% set BoolCppType = metadata.namespace + "::" + as_cppType(types["bool"].name) %}
 template <>
 void stream::Stream<{{BoolCppType}}>::Write(stream::Sink* sink, const {{BoolCppType}}& t) {
     StreamIn(sink, static_cast<bool>(t));
 }
 
+// Custom stream operator for StringView.
+{% set StringViewType = as_cppType(types["string view"].name) %}
+template <>
+void stream::Stream<{{StringViewType}}>::Write(stream::Sink* sink, const {{StringViewType}}& t) {
+    bool undefined = t.IsUndefined();
+    std::string_view sv = t;
+    StreamIn(sink, undefined, sv);
+}
+
+
 {% call render_streaming_impl("adapter info", true, false) %}
 {% endcall %}
 
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 7168d65..3858e16 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -300,7 +300,7 @@
         "chained": "in",
         "chain roots": ["device descriptor"],
         "members": [
-            {"name": "isolation key", "type": "char", "annotation": "const*", "length": "strlen", "default": "\"\""},
+            {"name": "isolation key", "type": "string view"},
             {"name": "load data function", "type": "dawn load cache data function", "default": "nullptr"},
             {"name": "store data function", "type": "dawn store cache data function", "default": "nullptr"},
             {"name": "function userdata", "type": "void *", "default": "nullptr"}
@@ -847,7 +847,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "key", "type": "char", "annotation": "const*", "length": "strlen"},
+            {"name": "key", "type": "string view"},
             {"name": "value", "type": "double"}
         ]
     },
@@ -3027,7 +3027,7 @@
         "extensible": "in",
         "members": [
             {"name": "module", "type": "shader module"},
-            {"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "entry point", "type": "string view", "optional": true},
             {"name": "constant count", "type": "size_t", "default": 0},
             {"name": "constants", "type": "constant entry", "annotation": "const*", "length": "constant count"}
         ]
@@ -3774,7 +3774,7 @@
         "extensible": "in",
         "members": [
             {"name": "module", "type": "shader module"},
-            {"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "entry point", "type": "string view", "optional": true},
             {"name": "constant count", "type": "size_t", "default": 0},
             {"name": "constants", "type": "constant entry", "annotation": "const*", "length": "constant count"},
             {"name": "buffer count", "type": "size_t", "default": 0},
@@ -3826,7 +3826,7 @@
         "extensible": "in",
         "members": [
             {"name": "module", "type": "shader module"},
-            {"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "entry point", "type": "string view", "optional": true},
             {"name": "constant count", "type": "size_t", "default": 0},
             {"name": "constants", "type": "constant entry", "annotation": "const*", "length": "constant count"},
             {"name": "target count", "type": "size_t"},
@@ -4128,7 +4128,7 @@
         "chain roots": ["surface descriptor"],
         "tags": ["emscripten"],
         "members": [
-            {"name": "selector", "type": "char", "annotation": "const*", "length": "strlen"}
+            {"name": "selector", "type": "string view"}
         ]
     },
     "surface descriptor from metal layer": {
diff --git a/src/dawn/native/Pipeline.cpp b/src/dawn/native/Pipeline.cpp
index 58d5d4e..3091266 100644
--- a/src/dawn/native/Pipeline.cpp
+++ b/src/dawn/native/Pipeline.cpp
@@ -50,14 +50,14 @@
 namespace dawn::native {
 ResultOrError<ShaderModuleEntryPoint> ValidateProgrammableStage(DeviceBase* device,
                                                                 const ShaderModuleBase* module,
-                                                                const char* entryPointName,
+                                                                StringView entryPointName,
                                                                 uint32_t constantCount,
                                                                 const ConstantEntry* constants,
                                                                 const PipelineLayoutBase* layout,
                                                                 SingleShaderStage stage) {
     DAWN_TRY(device->ValidateObject(module));
 
-    if (entryPointName) {
+    if (!entryPointName.IsUndefined()) {
         DAWN_INVALID_IF(!module->HasEntryPoint(entryPointName),
                         "Entry point \"%s\" doesn't exist in the shader module %s.", entryPointName,
                         module);
@@ -103,42 +103,45 @@
     // pipelineBase is not yet constructed at this moment so iterate constants from descriptor
     size_t numUninitializedConstants = metadata.uninitializedOverrides.size();
     // Keep an initialized constants sets to handle duplicate initialization cases
-    absl::flat_hash_set<std::string> stageInitializedConstantIdentifiers;
+    absl::flat_hash_set<std::string_view> stageInitializedConstantIdentifiers;
     for (uint32_t i = 0; i < constantCount; i++) {
-        DAWN_INVALID_IF(metadata.overrides.count(constants[i].key) == 0,
+        std::string_view key = constants[i].key;
+        double value = constants[i].value;
+
+        DAWN_INVALID_IF(metadata.overrides.count(key) == 0,
                         "Pipeline overridable constant \"%s\" not found in %s.", constants[i].key,
                         module);
-        DAWN_INVALID_IF(!std::isfinite(constants[i].value),
+        DAWN_INVALID_IF(!std::isfinite(value),
                         "Pipeline overridable constant \"%s\" with value (%f) is not finite in %s",
-                        constants[i].key, constants[i].value, module);
+                        key, value, module);
 
         // Validate if constant value can be represented by the given scalar type in shader
-        auto type = metadata.overrides.at(constants[i].key).type;
+        auto type = metadata.overrides.at(key).type;
         switch (type) {
             case EntryPointMetadata::Override::Type::Float32:
-                DAWN_INVALID_IF(!IsDoubleValueRepresentable<float>(constants[i].value),
+                DAWN_INVALID_IF(!IsDoubleValueRepresentable<float>(value),
                                 "Pipeline overridable constant \"%s\" with value (%f) is not "
                                 "representable in type (%s)",
-                                constants[i].key, constants[i].value, "f32");
+                                key, value, "f32");
                 break;
             case EntryPointMetadata::Override::Type::Float16:
-                DAWN_INVALID_IF(!IsDoubleValueRepresentableAsF16(constants[i].value),
+                DAWN_INVALID_IF(!IsDoubleValueRepresentableAsF16(value),
                                 "Pipeline overridable constant \"%s\" with value (%f) is not "
                                 "representable in type (%s)",
-                                constants[i].key, constants[i].value, "f16");
+                                key, value, "f16");
                 break;
             case EntryPointMetadata::Override::Type::Int32:
-                DAWN_INVALID_IF(!IsDoubleValueRepresentable<int32_t>(constants[i].value),
+                DAWN_INVALID_IF(!IsDoubleValueRepresentable<int32_t>(value),
                                 "Pipeline overridable constant \"%s\" with value (%f) is not "
                                 "representable in type (%s)",
-                                constants[i].key, constants[i].value,
+                                key, value,
                                 type == EntryPointMetadata::Override::Type::Int32 ? "i32" : "b");
                 break;
             case EntryPointMetadata::Override::Type::Uint32:
-                DAWN_INVALID_IF(!IsDoubleValueRepresentable<uint32_t>(constants[i].value),
+                DAWN_INVALID_IF(!IsDoubleValueRepresentable<uint32_t>(value),
                                 "Pipeline overridable constant \"%s\" with value (%f) is not "
                                 "representable in type (%s)",
-                                constants[i].key, constants[i].value, "u32");
+                                key, value, "u32");
                 break;
             case EntryPointMetadata::Override::Type::Boolean:
                 // Conversion to boolean can't fail
@@ -148,15 +151,15 @@
                 DAWN_UNREACHABLE();
         }
 
-        if (!stageInitializedConstantIdentifiers.contains(constants[i].key)) {
-            if (metadata.uninitializedOverrides.contains(constants[i].key)) {
+        if (!stageInitializedConstantIdentifiers.contains(key)) {
+            if (metadata.uninitializedOverrides.contains(key)) {
                 numUninitializedConstants--;
             }
-            stageInitializedConstantIdentifiers.insert(constants[i].key);
+            stageInitializedConstantIdentifiers.insert(key);
         } else {
             // There are duplicate initializations
             return DAWN_VALIDATION_ERROR(
-                "Pipeline overridable constants \"%s\" is set more than once", constants[i].key);
+                "Pipeline overridable constants \"%s\" is set more than once", key);
         }
     }
 
diff --git a/src/dawn/native/Pipeline.h b/src/dawn/native/Pipeline.h
index e1d7c8c..665667f 100644
--- a/src/dawn/native/Pipeline.h
+++ b/src/dawn/native/Pipeline.h
@@ -48,7 +48,7 @@
 
 ResultOrError<ShaderModuleEntryPoint> ValidateProgrammableStage(DeviceBase* device,
                                                                 const ShaderModuleBase* module,
-                                                                const char* entryPointName,
+                                                                StringView entryPointName,
                                                                 uint32_t constantCount,
                                                                 const ConstantEntry* constants,
                                                                 const PipelineLayoutBase* layout,
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index 5cef13c..a2723e6 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -116,7 +116,7 @@
 
 StageAndDescriptor::StageAndDescriptor(SingleShaderStage shaderStage,
                                        ShaderModuleBase* module,
-                                       const char* entryPoint,
+                                       StringView entryPoint,
                                        size_t constantCount,
                                        ConstantEntry const* constants)
     : shaderStage(shaderStage),
diff --git a/src/dawn/native/PipelineLayout.h b/src/dawn/native/PipelineLayout.h
index 6d2b4ef..308f7f7 100644
--- a/src/dawn/native/PipelineLayout.h
+++ b/src/dawn/native/PipelineLayout.h
@@ -56,7 +56,7 @@
 struct StageAndDescriptor {
     StageAndDescriptor(SingleShaderStage shaderStage,
                        ShaderModuleBase* module,
-                       const char* entryPoint,
+                       StringView entryPoint,
                        size_t constantCount,
                        ConstantEntry const* constants);
 
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 21ff164..2fb5c6b 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -1394,19 +1394,19 @@
     return ObjectType::ShaderModule;
 }
 
-bool ShaderModuleBase::HasEntryPoint(const std::string& entryPoint) const {
+bool ShaderModuleBase::HasEntryPoint(std::string_view entryPoint) const {
     return mEntryPoints.contains(entryPoint);
 }
 
-ShaderModuleEntryPoint ShaderModuleBase::ReifyEntryPointName(const char* entryPointName,
+ShaderModuleEntryPoint ShaderModuleBase::ReifyEntryPointName(StringView entryPointName,
                                                              SingleShaderStage stage) const {
     ShaderModuleEntryPoint entryPoint;
-    if (entryPointName) {
-        entryPoint.defaulted = false;
-        entryPoint.name = entryPointName;
-    } else {
+    if (entryPointName.IsUndefined()) {
         entryPoint.defaulted = true;
         entryPoint.name = mDefaultEntryPointNames[stage];
+    } else {
+        entryPoint.defaulted = false;
+        entryPoint.name = entryPointName;
     }
     return entryPoint;
 }
@@ -1415,7 +1415,7 @@
     return mStrictMath;
 }
 
-const EntryPointMetadata& ShaderModuleBase::GetEntryPoint(const std::string& entryPoint) const {
+const EntryPointMetadata& ShaderModuleBase::GetEntryPoint(std::string_view entryPoint) const {
     DAWN_ASSERT(HasEntryPoint(entryPoint));
     return *mEntryPoints.at(entryPoint);
 }
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index 406a10e..f91609d 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -304,18 +304,18 @@
     ObjectType GetType() const override;
 
     // Return true iff the program has an entrypoint called `entryPoint`.
-    bool HasEntryPoint(const std::string& entryPoint) const;
+    bool HasEntryPoint(std::string_view entryPoint) const;
 
     // Return the number of entry points for a stage.
     size_t GetEntryPointCount(SingleShaderStage stage) const { return mEntryPointCounts[stage]; }
 
     // Return the entry point for a stage. If no entry point name, returns the default one.
-    ShaderModuleEntryPoint ReifyEntryPointName(const char* entryPointName,
+    ShaderModuleEntryPoint ReifyEntryPointName(StringView entryPointName,
                                                SingleShaderStage stage) const;
 
     // Return the metadata for the given `entryPoint`. HasEntryPoint with the same argument
     // must be true.
-    const EntryPointMetadata& GetEntryPoint(const std::string& entryPoint) const;
+    const EntryPointMetadata& GetEntryPoint(std::string_view entryPoint) const;
 
     // Functions necessary for the unordered_set<ShaderModuleBase*>-based cache.
     size_t ComputeContentHash() override;
diff --git a/src/dawn/tests/unittests/wire/WireArgumentTests.cpp b/src/dawn/tests/unittests/wire/WireArgumentTests.cpp
index c7ffc0c..20da662 100644
--- a/src/dawn/tests/unittests/wire/WireArgumentTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireArgumentTests.cpp
@@ -166,7 +166,7 @@
     EXPECT_CALL(api,
                 DeviceCreateRenderPipeline(
                     apiDevice, MatchesLambda([](const WGPURenderPipelineDescriptor* desc) -> bool {
-                        return desc->vertex.entryPoint == std::string("main");
+                        return std::string_view(desc->vertex.entryPoint.data) == "main";
                     })))
         .WillOnce(Return(apiPlaceholderPipeline));
 
diff --git a/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp b/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp
index 3a251ae..1666bcc 100644
--- a/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp
@@ -344,7 +344,7 @@
 
     WGPUShaderModule sm = wgpuDeviceCreateShaderModule(device, &smDesc);
 
-    WGPUComputePipelineDescriptor computeDesc = {};
+    WGPUComputePipelineDescriptor computeDesc = WGPU_COMPUTE_PIPELINE_DESCRIPTOR_INIT;
     computeDesc.compute.module = sm;
 
     WGPUComputePipeline pipeline = nullptr;