1 // Copyright (c) 2017 The Chromium 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 "gpu/command_buffer/service/client_service_map.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7
8 namespace gpu {
9 namespace gles2 {
10
11 using MapDataType = size_t;
12 using ClientServiceMapType = ClientServiceMap<MapDataType, MapDataType>;
13
TEST(ClientServiceMap,BasicMapping)14 TEST(ClientServiceMap, BasicMapping) {
15 static constexpr MapDataType kClientId = 1;
16 static constexpr MapDataType kServiceId = 2;
17 ClientServiceMapType map;
18
19 // Add just one mapping
20 map.SetIDMapping(kClientId, kServiceId);
21
22 // Check client -> service ID lookup
23 MapDataType service_id = 0;
24 EXPECT_TRUE(map.GetServiceID(kClientId, &service_id));
25 EXPECT_EQ(kServiceId, service_id);
26
27 // Check null is handled for GetServiceID
28 EXPECT_TRUE(map.HasClientID(kClientId));
29
30 // Check service -> client ID lookup
31 MapDataType client_id = 0;
32 EXPECT_TRUE(map.GetClientID(kServiceId, &client_id));
33 EXPECT_EQ(kClientId, client_id);
34
35 // Check null is handled for GetClientID
36 EXPECT_TRUE(map.GetClientID(kServiceId, nullptr));
37 }
38
TEST(ClientServiceMap,ZeroID)39 TEST(ClientServiceMap, ZeroID) {
40 static constexpr MapDataType kServiceId = 2;
41 ClientServiceMapType map;
42
43 // Check that the zero client ID always maps to the zero service ID
44 MapDataType service_id = 0;
45 EXPECT_TRUE(map.GetServiceID(0, &service_id));
46 EXPECT_EQ(0u, service_id);
47
48 // Check that it's possible to update the zero client ID
49 map.SetIDMapping(0, kServiceId);
50 EXPECT_TRUE(map.GetServiceID(0, &service_id));
51 EXPECT_EQ(kServiceId, service_id);
52 }
53
TEST(ClientServiceMap,InvalidIDs)54 TEST(ClientServiceMap, InvalidIDs) {
55 static constexpr MapDataType kClientId = 1;
56 static constexpr MapDataType kServiceId = 2;
57 ClientServiceMapType map;
58
59 // Add just one mapping
60 map.SetIDMapping(kClientId, kServiceId);
61
62 // Check that GetServiceIDOrInvalid returns the correct ID or the invalid ID
63 EXPECT_EQ(kServiceId, map.GetServiceIDOrInvalid(kClientId));
64 EXPECT_EQ(map.invalid_service_id(), map.GetServiceIDOrInvalid(kClientId + 1));
65
66 // Check that GetClientID returns false if the ID does not exist
67 EXPECT_FALSE(map.GetClientID(kServiceId + 1, nullptr));
68 }
69
TEST(ClientServiceMap,UpdateMapping)70 TEST(ClientServiceMap, UpdateMapping) {
71 static constexpr MapDataType kClientId = 1;
72 static constexpr MapDataType kServiceId = 2;
73 static constexpr MapDataType kNewServiceId =
74 ClientServiceMapType::kMaxFlatArraySize + 10;
75 ClientServiceMapType map;
76
77 map.SetIDMapping(kClientId, kServiceId);
78 EXPECT_EQ(kServiceId, map.GetServiceIDOrInvalid(kClientId));
79
80 map.RemoveClientID(kClientId);
81 map.SetIDMapping(kClientId, kNewServiceId);
82 EXPECT_EQ(kNewServiceId, map.GetServiceIDOrInvalid(kClientId));
83 }
84
TEST(ClientServiceMap,RemoveMapping)85 TEST(ClientServiceMap, RemoveMapping) {
86 static constexpr MapDataType kClientId = 1;
87 static constexpr MapDataType kServiceId = 2;
88 static constexpr MapDataType kLargeServiceId =
89 ClientServiceMapType::kMaxFlatArraySize + 10;
90 ClientServiceMapType map;
91
92 map.SetIDMapping(kClientId, kServiceId);
93 EXPECT_TRUE(map.HasClientID(kClientId));
94 map.RemoveClientID(kClientId);
95 EXPECT_FALSE(map.HasClientID(kClientId));
96
97 map.SetIDMapping(kClientId, kServiceId);
98 EXPECT_TRUE(map.HasClientID(kClientId));
99 map.Clear();
100 EXPECT_FALSE(map.HasClientID(kClientId));
101
102 map.SetIDMapping(kClientId, kLargeServiceId);
103 EXPECT_TRUE(map.HasClientID(kClientId));
104 map.RemoveClientID(kClientId);
105 EXPECT_FALSE(map.HasClientID(kClientId));
106 }
107
TEST(ClientServiceMap,ManyIDs)108 TEST(ClientServiceMap, ManyIDs) {
109 static constexpr MapDataType kFirstClientId = 1;
110 static constexpr MapDataType kFirstServiceId = 2;
111
112 // Make sure to cover the transition from a flat array to unordered map
113 static constexpr size_t kIdStep = 100;
114 static constexpr size_t kIdCount =
115 (ClientServiceMapType::kMaxFlatArraySize + 10) / kIdStep;
116
117 // Insert kIdCount mappings
118 ClientServiceMapType map;
119 for (size_t ii = 0; ii < kIdCount; ii++) {
120 map.SetIDMapping(kFirstClientId + (ii * kIdStep),
121 kFirstServiceId + (ii * kIdStep));
122 }
123
124 // Check each mapping
125 for (size_t ii = 0; ii < kIdCount; ii++) {
126 // Check client -> service ID lookup
127 EXPECT_EQ(kFirstServiceId + (ii * kIdStep),
128 map.GetServiceIDOrInvalid(kFirstClientId + (ii * kIdStep)));
129
130 // Check service -> client ID lookup
131 MapDataType client_id = 0;
132 EXPECT_TRUE(map.GetClientID(kFirstServiceId + (ii * kIdStep), &client_id));
133 EXPECT_EQ(kFirstClientId + (ii * kIdStep), client_id);
134 }
135 }
136
TEST(ClientServiceMap,DuplicateServiceIDs)137 TEST(ClientServiceMap, DuplicateServiceIDs) {
138 static constexpr MapDataType kFirstClientId = 1;
139 static constexpr MapDataType kSecondClientId =
140 ClientServiceMapType::kMaxFlatArraySize + 1000;
141 static constexpr MapDataType kServiceId = 2;
142
143 ClientServiceMapType map;
144
145 // Two client IDs point to the same service ID.
146 map.SetIDMapping(kFirstClientId, kServiceId);
147 map.SetIDMapping(kSecondClientId, kServiceId);
148
149 // Confirm that GetServiceID works in this case.
150 EXPECT_EQ(kServiceId, map.GetServiceIDOrInvalid(kFirstClientId));
151 EXPECT_EQ(kServiceId, map.GetServiceIDOrInvalid(kSecondClientId));
152
153 // GetClientID should return the first client ID.
154 MapDataType client_id = 0;
155 EXPECT_TRUE(map.GetClientID(kServiceId, &client_id));
156 EXPECT_EQ(kFirstClientId, client_id);
157 }
158
TEST(ClientServiceMap,ForEach)159 TEST(ClientServiceMap, ForEach) {
160 using MappingSet = std::set<std::pair<MapDataType, MapDataType>>;
161 const MappingSet kMappings = {
162 {0, 1},
163 {10, 10},
164 {100, 100},
165 {ClientServiceMapType::kMaxFlatArraySize - 1, 15},
166 {ClientServiceMapType::kMaxFlatArraySize, 5},
167 {ClientServiceMapType::kMaxFlatArraySize + 1000, 50},
168 };
169
170 ClientServiceMapType map;
171 for (const auto& mapping : kMappings) {
172 map.SetIDMapping(mapping.first, mapping.second);
173 }
174
175 MappingSet seen_mappings;
176 map.ForEach([&seen_mappings](MapDataType client_id, MapDataType service_id) {
177 seen_mappings.insert(std::make_pair(client_id, service_id));
178 });
179 EXPECT_EQ(kMappings, seen_mappings);
180 }
181
182 } // namespace gles2
183 } // namespace gpu
184