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