Flutter Impeller
shader_archive_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <sstream>
6 #include <string>
7 #include <vector>
8 
9 #include "flutter/fml/mapping.h"
10 #include "flutter/testing/testing.h"
12 #include "impeller/shader_archive/shader_archive_flatbuffers.h"
14 
15 namespace impeller {
16 namespace testing {
17 
18 static std::shared_ptr<fml::Mapping> CreateMappingFromString(
19  std::string p_string) {
20  auto string = std::make_shared<std::string>(std::move(p_string));
21  return std::make_shared<fml::NonOwnedMapping>(
22  reinterpret_cast<const uint8_t*>(string->data()), string->size(),
23  [string](auto, auto) {});
24 }
25 
26 const std::string CreateStringFromMapping(const fml::Mapping& mapping) {
27  return std::string{reinterpret_cast<const char*>(mapping.GetMapping()),
28  mapping.GetSize()};
29 }
30 
31 TEST(ShaderArchiveTest, CanReadAndWriteBlobs) {
32  ShaderArchiveWriter writer;
33  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
34  CreateMappingFromString("World")));
35  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
36  CreateMappingFromString("Bar")));
37  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
38  CreateMappingFromString("Bang")));
39  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
40  CreateMappingFromString("Pong")));
41  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
42  CreateMappingFromString("World")));
43 
44  auto mapping = writer.CreateMapping();
45  ASSERT_NE(mapping, nullptr);
46 
47  auto library = ShaderArchive::Create(mapping);
48  ASSERT_TRUE(library.ok());
49  ASSERT_EQ(library->GetShaderCount(), 5u);
50 
51  // Wrong type.
52  ASSERT_EQ(library->GetMapping(ArchiveShaderType::kFragment, "Hello"),
53  nullptr);
54 
55  auto hello_vtx = library->GetMapping(ArchiveShaderType::kVertex, "Hello");
56  ASSERT_NE(hello_vtx, nullptr);
57  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
58 }
59 
60 TEST(ShaderArchiveTest, ReturnsErrorOnInvalidVersion) {
61  fb::ShaderArchiveT shader_archive;
62  shader_archive.format_version = -1;
63 
64  auto builder = std::make_shared<flatbuffers::FlatBufferBuilder>();
65  builder->Finish(fb::ShaderArchive::Pack(*builder.get(), &shader_archive),
66  fb::ShaderArchiveIdentifier());
67  auto mapping = std::make_shared<fml::NonOwnedMapping>(
68  builder->GetBufferPointer(), builder->GetSize(),
69  [builder](auto, auto) {});
70 
71  auto library = ShaderArchive::Create(mapping);
72  ASSERT_FALSE(library.ok());
73  ASSERT_EQ(library.status().code(), absl::StatusCode::kInvalidArgument);
74  std::stringstream stream;
75  stream << "Unsupported shader archive format version. Expected: "
76  << static_cast<uint32_t>(fb::ShaderArchiveFormatVersion::kVersion)
77  << ", Got: 4294967295";
78  ASSERT_EQ(library.status().message(), stream.str());
79 }
80 
81 TEST(ShaderArchiveTest, RejectsCorruptBufferWithValidIdentifier) {
82  // Construct a buffer with a valid "SHAR" file identifier at bytes 4-7
83  // but a root table offset that points beyond the buffer. This passes
84  // the identifier check but fails FlatBuffer structural verification.
85  auto data = std::make_shared<std::vector<uint8_t>>(32, 0);
86  (*data)[4] = 'S';
87  (*data)[5] = 'H';
88  (*data)[6] = 'A';
89  (*data)[7] = 'R';
90  // Root offset (little-endian uint32 at offset 0) pointing out of bounds.
91  (*data)[0] = 0xFF;
92  (*data)[1] = 0xFF;
93 
94  auto mapping = std::make_shared<fml::NonOwnedMapping>(
95  data->data(), data->size(), [data](auto, auto) {});
96  auto archive = ShaderArchive::Create(mapping);
97  ASSERT_FALSE(archive.ok());
98  EXPECT_EQ(archive.status().code(), absl::StatusCode::kInvalidArgument);
99 }
100 
101 } // namespace testing
102 } // namespace impeller
static absl::StatusOr< ShaderArchive > Create(std::shared_ptr< fml::Mapping > payload)
bool AddShader(ArchiveShaderType type, std::string name, std::shared_ptr< fml::Mapping > mapping)
std::shared_ptr< fml::Mapping > CreateMapping() const
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
TEST(AllocationSizeTest, CanCreateTypedAllocations)
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)