1 // Copyright (c) 2015 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 <stdint.h>
6 
7 #include <memory>
8 
9 #include "base/bind.h"
10 #include "base/containers/queue.h"
11 #include "gpu/command_buffer/service/sync_point_manager.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace gpu {
15 
16 class SyncPointManagerTest : public testing::Test {
17  public:
SyncPointManagerTest()18   SyncPointManagerTest() : sync_point_manager_(new SyncPointManager) {}
19   ~SyncPointManagerTest() override = default;
20 
21  protected:
22   // Simple static function which can be used to test callbacks.
SetIntegerFunction(int * test,int value)23   static void SetIntegerFunction(int* test, int value) { *test = value; }
24 
25   std::unique_ptr<SyncPointManager> sync_point_manager_;
26 };
27 
28 struct SyncPointStream {
29   scoped_refptr<SyncPointOrderData> order_data;
30   scoped_refptr<SyncPointClientState> client_state;
31   base::queue<uint32_t> order_numbers;
32 
SyncPointStreamgpu::SyncPointStream33   SyncPointStream(SyncPointManager* sync_point_manager,
34                   CommandBufferNamespace namespace_id,
35                   CommandBufferId command_buffer_id)
36       : order_data(sync_point_manager->CreateSyncPointOrderData()),
37         client_state(sync_point_manager->CreateSyncPointClientState(
38             namespace_id,
39             command_buffer_id,
40             order_data->sequence_id())) {}
41 
~SyncPointStreamgpu::SyncPointStream42   ~SyncPointStream() {
43     if (order_data)
44       order_data->Destroy();
45     if (client_state)
46       client_state->Destroy();
47   }
48 
AllocateOrderNumgpu::SyncPointStream49   void AllocateOrderNum() {
50     order_numbers.push(order_data->GenerateUnprocessedOrderNumber());
51   }
52 
BeginProcessinggpu::SyncPointStream53   void BeginProcessing() {
54     ASSERT_FALSE(order_numbers.empty());
55     order_data->BeginProcessingOrderNumber(order_numbers.front());
56   }
57 
EndProcessinggpu::SyncPointStream58   void EndProcessing() {
59     ASSERT_FALSE(order_numbers.empty());
60     order_data->FinishProcessingOrderNumber(order_numbers.front());
61     order_numbers.pop();
62   }
63 };
64 
TEST_F(SyncPointManagerTest,BasicSyncPointOrderDataTest)65 TEST_F(SyncPointManagerTest, BasicSyncPointOrderDataTest) {
66   scoped_refptr<SyncPointOrderData> order_data =
67       sync_point_manager_->CreateSyncPointOrderData();
68 
69   EXPECT_EQ(0u, order_data->current_order_num());
70   EXPECT_EQ(0u, order_data->processed_order_num());
71   EXPECT_EQ(0u, order_data->unprocessed_order_num());
72 
73   uint32_t order_num = order_data->GenerateUnprocessedOrderNumber();
74   EXPECT_EQ(1u, order_num);
75 
76   EXPECT_EQ(0u, order_data->current_order_num());
77   EXPECT_EQ(0u, order_data->processed_order_num());
78   EXPECT_EQ(order_num, order_data->unprocessed_order_num());
79 
80   order_data->BeginProcessingOrderNumber(order_num);
81   EXPECT_EQ(order_num, order_data->current_order_num());
82   EXPECT_EQ(0u, order_data->processed_order_num());
83   EXPECT_EQ(order_num, order_data->unprocessed_order_num());
84   EXPECT_TRUE(order_data->IsProcessingOrderNumber());
85 
86   order_data->PauseProcessingOrderNumber(order_num);
87   EXPECT_FALSE(order_data->IsProcessingOrderNumber());
88 
89   order_data->BeginProcessingOrderNumber(order_num);
90   EXPECT_TRUE(order_data->IsProcessingOrderNumber());
91 
92   order_data->FinishProcessingOrderNumber(order_num);
93   EXPECT_EQ(order_num, order_data->current_order_num());
94   EXPECT_EQ(order_num, order_data->processed_order_num());
95   EXPECT_EQ(order_num, order_data->unprocessed_order_num());
96   EXPECT_FALSE(order_data->IsProcessingOrderNumber());
97 
98   order_data->Destroy();
99 }
100 
TEST_F(SyncPointManagerTest,BasicFenceSyncRelease)101 TEST_F(SyncPointManagerTest, BasicFenceSyncRelease) {
102   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
103   CommandBufferId kBufferId = CommandBufferId::FromUnsafeValue(0x123);
104 
105   uint64_t release_count = 1;
106   SyncToken sync_token(kNamespaceId, kBufferId, release_count);
107 
108   // Can't wait for sync token before client is registered.
109   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
110 
111   SyncPointStream stream(sync_point_manager_.get(), kNamespaceId, kBufferId);
112 
113   stream.AllocateOrderNum();
114 
115   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
116 
117   stream.order_data->BeginProcessingOrderNumber(1);
118   stream.client_state->ReleaseFenceSync(release_count);
119   stream.order_data->FinishProcessingOrderNumber(1);
120 
121   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
122 }
123 
TEST_F(SyncPointManagerTest,OutOfOrderSyncTokenRelease)124 TEST_F(SyncPointManagerTest, OutOfOrderSyncTokenRelease) {
125   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
126   CommandBufferId kBufferId = CommandBufferId::FromUnsafeValue(0x123);
127 
128   uint64_t release_count_1 = 2;
129   SyncToken sync_token_1(kNamespaceId, kBufferId, release_count_1);
130   uint64_t release_count_2 = 1;
131   SyncToken sync_token_2(kNamespaceId, kBufferId, release_count_2);
132 
133   SyncPointStream stream(sync_point_manager_.get(), kNamespaceId, kBufferId);
134   stream.AllocateOrderNum();
135   stream.AllocateOrderNum();
136 
137   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
138   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
139 
140   // Releasing the first sync token also releases the second because the first
141   // token's release count is larger.
142   stream.order_data->BeginProcessingOrderNumber(1);
143   stream.client_state->ReleaseFenceSync(release_count_1);
144   stream.order_data->FinishProcessingOrderNumber(1);
145   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
146   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
147 
148   // Releasing the second token should be a no-op.
149   stream.order_data->BeginProcessingOrderNumber(2);
150   stream.client_state->ReleaseFenceSync(release_count_2);
151   stream.order_data->FinishProcessingOrderNumber(2);
152   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
153   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
154 }
155 
TEST_F(SyncPointManagerTest,MultipleClientsPerOrderData)156 TEST_F(SyncPointManagerTest, MultipleClientsPerOrderData) {
157   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
158   CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123);
159   CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234);
160 
161   SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId,
162                           kCmdBufferId1);
163   SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId,
164                           kCmdBufferId2);
165 
166   uint64_t release_count = 1;
167   SyncToken sync_token1(kNamespaceId, kCmdBufferId1, release_count);
168   stream1.AllocateOrderNum();
169 
170   SyncToken sync_token2(kNamespaceId, kCmdBufferId2, release_count);
171   stream2.AllocateOrderNum();
172 
173   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token1));
174   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token2));
175 
176   stream1.order_data->BeginProcessingOrderNumber(1);
177   stream1.client_state->ReleaseFenceSync(release_count);
178   stream1.order_data->FinishProcessingOrderNumber(1);
179 
180   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token1));
181   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token2));
182 }
183 
TEST_F(SyncPointManagerTest,BasicFenceSyncWaitRelease)184 TEST_F(SyncPointManagerTest, BasicFenceSyncWaitRelease) {
185   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
186   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
187   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
188 
189   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
190                                  kReleaseCmdBufferId);
191   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
192                               kWaitCmdBufferId);
193 
194   release_stream.AllocateOrderNum();
195   wait_stream.AllocateOrderNum();
196 
197   uint64_t release_count = 1;
198   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
199 
200   wait_stream.BeginProcessing();
201   int test_num = 10;
202   bool valid_wait = wait_stream.client_state->Wait(
203       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
204                                  &test_num, 123));
205   EXPECT_TRUE(valid_wait);
206   EXPECT_EQ(10, test_num);
207   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
208 
209   release_stream.BeginProcessing();
210   release_stream.client_state->ReleaseFenceSync(release_count);
211   EXPECT_EQ(123, test_num);
212   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
213 }
214 
TEST_F(SyncPointManagerTest,WaitWithOutOfOrderSyncTokenRelease)215 TEST_F(SyncPointManagerTest, WaitWithOutOfOrderSyncTokenRelease) {
216   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
217   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
218   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
219 
220   int test_num_1 = 10;
221   int test_num_2 = 10;
222   int test_num_3 = 10;
223   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
224                                  kReleaseCmdBufferId);
225   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
226                               kWaitCmdBufferId);
227 
228   release_stream.AllocateOrderNum();
229   uint64_t release_count_1 = 2;
230   SyncToken sync_token_1(kNamespaceId, kReleaseCmdBufferId, release_count_1);
231   release_stream.AllocateOrderNum();
232   uint64_t release_count_2 = 1;
233   SyncToken sync_token_2(kNamespaceId, kReleaseCmdBufferId, release_count_2);
234   release_stream.AllocateOrderNum();
235   uint64_t release_count_3 = 3;
236   SyncToken sync_token_3(kNamespaceId, kReleaseCmdBufferId, release_count_3);
237 
238   wait_stream.AllocateOrderNum();
239   wait_stream.BeginProcessing();
240   bool valid_wait = wait_stream.client_state->Wait(
241       sync_token_1, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
242                                    &test_num_1, 123));
243   EXPECT_TRUE(valid_wait);
244   EXPECT_EQ(10, test_num_1);
245   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
246   wait_stream.EndProcessing();
247 
248   wait_stream.AllocateOrderNum();
249   wait_stream.BeginProcessing();
250   valid_wait = wait_stream.client_state->Wait(
251       sync_token_2, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
252                                    &test_num_2, 123));
253   EXPECT_TRUE(valid_wait);
254   EXPECT_EQ(10, test_num_2);
255   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
256   wait_stream.EndProcessing();
257 
258   wait_stream.AllocateOrderNum();
259   wait_stream.BeginProcessing();
260   valid_wait = wait_stream.client_state->Wait(
261       sync_token_3, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
262                                    &test_num_3, 123));
263   EXPECT_TRUE(valid_wait);
264   EXPECT_EQ(10, test_num_3);
265   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_3));
266   wait_stream.EndProcessing();
267 
268   // Releasing the first sync token should release the second one. Then,
269   // releasing the second one should be a no-op.
270   release_stream.BeginProcessing();
271   release_stream.client_state->ReleaseFenceSync(release_count_1);
272   EXPECT_EQ(123, test_num_1);
273   EXPECT_EQ(123, test_num_2);
274   EXPECT_EQ(10, test_num_3);
275   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
276   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
277   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_3));
278   release_stream.EndProcessing();
279 
280   release_stream.BeginProcessing();
281   release_stream.client_state->ReleaseFenceSync(release_count_2);
282   EXPECT_EQ(123, test_num_1);
283   EXPECT_EQ(123, test_num_2);
284   EXPECT_EQ(10, test_num_3);
285   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_1));
286   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token_2));
287   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token_3));
288   release_stream.EndProcessing();
289 }
290 
TEST_F(SyncPointManagerTest,WaitOnSelfFails)291 TEST_F(SyncPointManagerTest, WaitOnSelfFails) {
292   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
293   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
294   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
295 
296   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
297                                  kReleaseCmdBufferId);
298   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
299                               kWaitCmdBufferId);
300 
301   release_stream.AllocateOrderNum();
302   wait_stream.AllocateOrderNum();
303 
304   uint64_t release_count = 1;
305   SyncToken sync_token(kNamespaceId, kWaitCmdBufferId, release_count);
306 
307   wait_stream.BeginProcessing();
308   int test_num = 10;
309   bool valid_wait = wait_stream.client_state->Wait(
310       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
311                                  &test_num, 123));
312   EXPECT_FALSE(valid_wait);
313   EXPECT_EQ(10, test_num);
314   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
315 }
316 
TEST_F(SyncPointManagerTest,ReleaseAfterWaitOrderNumber)317 TEST_F(SyncPointManagerTest, ReleaseAfterWaitOrderNumber) {
318   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
319   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
320   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
321 
322   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
323                                  kReleaseCmdBufferId);
324   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
325                               kWaitCmdBufferId);
326 
327   // Generate wait order number first.
328   wait_stream.AllocateOrderNum();
329   release_stream.AllocateOrderNum();
330 
331   uint64_t release_count = 1;
332   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
333 
334   wait_stream.BeginProcessing();
335   int test_num = 10;
336   bool valid_wait = wait_stream.client_state->Wait(
337       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
338                                  &test_num, 123));
339   EXPECT_FALSE(valid_wait);
340   EXPECT_EQ(10, test_num);
341   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
342 }
343 
TEST_F(SyncPointManagerTest,HigherOrderNumberRelease)344 TEST_F(SyncPointManagerTest, HigherOrderNumberRelease) {
345   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
346   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
347   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
348 
349   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
350                                  kReleaseCmdBufferId);
351   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
352                               kWaitCmdBufferId);
353 
354   // Generate wait order number first.
355   wait_stream.AllocateOrderNum();
356   release_stream.AllocateOrderNum();
357 
358   uint64_t release_count = 1;
359   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
360 
361   // Order number was higher but it was actually released.
362   release_stream.BeginProcessing();
363   release_stream.client_state->ReleaseFenceSync(release_count);
364   release_stream.EndProcessing();
365 
366   // Release stream has already released so there's no need to wait.
367   wait_stream.BeginProcessing();
368   int test_num = 10;
369   bool valid_wait = wait_stream.client_state->Wait(
370       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
371                                  &test_num, 123));
372   EXPECT_FALSE(valid_wait);
373   EXPECT_EQ(10, test_num);
374   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
375 }
376 
TEST_F(SyncPointManagerTest,DestroyedClientRelease)377 TEST_F(SyncPointManagerTest, DestroyedClientRelease) {
378   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
379   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
380   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
381 
382   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
383                                  kReleaseCmdBufferId);
384   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
385                               kWaitCmdBufferId);
386 
387   release_stream.AllocateOrderNum();
388   wait_stream.AllocateOrderNum();
389 
390   uint64_t release_count = 1;
391   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
392 
393   wait_stream.BeginProcessing();
394 
395   int test_num = 10;
396   bool valid_wait = wait_stream.client_state->Wait(
397       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
398                                  &test_num, 123));
399   EXPECT_TRUE(valid_wait);
400   EXPECT_EQ(10, test_num);
401 
402   // Destroying the client should release the wait.
403   release_stream.client_state->Destroy();
404   release_stream.client_state = nullptr;
405 
406   EXPECT_EQ(123, test_num);
407   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
408 }
409 
TEST_F(SyncPointManagerTest,NonExistentRelease)410 TEST_F(SyncPointManagerTest, NonExistentRelease) {
411   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
412   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
413   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
414 
415   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
416                                  kReleaseCmdBufferId);
417   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
418                               kWaitCmdBufferId);
419 
420   // Assign release stream order [1] and wait stream order [2].
421   // This test simply tests that a wait stream of order [2] waiting on
422   // release stream of order [1] will still release the fence sync even
423   // though nothing was released.
424   release_stream.AllocateOrderNum();
425   wait_stream.AllocateOrderNum();
426 
427   uint64_t release_count = 1;
428   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
429 
430   wait_stream.BeginProcessing();
431   int test_num = 10;
432   bool valid_wait = wait_stream.client_state->Wait(
433       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
434                                  &test_num, 123));
435   EXPECT_TRUE(valid_wait);
436   EXPECT_EQ(10, test_num);
437   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
438 
439   // No release but finishing the order number should automatically release.
440   release_stream.BeginProcessing();
441   EXPECT_EQ(10, test_num);
442   release_stream.EndProcessing();
443   EXPECT_EQ(123, test_num);
444   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
445 }
446 
TEST_F(SyncPointManagerTest,NonExistentRelease2)447 TEST_F(SyncPointManagerTest, NonExistentRelease2) {
448   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
449   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
450   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
451 
452   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
453                                  kReleaseCmdBufferId);
454   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
455                               kWaitCmdBufferId);
456 
457   // Assign Release stream order [1] and assign Wait stream orders [2, 3].
458   // This test is similar to the NonExistentRelease case except
459   // we place an extra order number in between the release and wait.
460   // The wait stream [3] is waiting on release stream [1] even though
461   // order [2] was also generated. Although order [2] only exists on the
462   // wait stream so the release stream should only know about order [1].
463   release_stream.AllocateOrderNum();
464   wait_stream.AllocateOrderNum();
465   wait_stream.AllocateOrderNum();
466 
467   uint64_t release_count = 1;
468   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
469 
470   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
471   // Have wait with order [3] to wait on release.
472   wait_stream.BeginProcessing();
473   EXPECT_EQ(2u, wait_stream.order_data->current_order_num());
474   wait_stream.EndProcessing();
475   wait_stream.BeginProcessing();
476   EXPECT_EQ(3u, wait_stream.order_data->current_order_num());
477   int test_num = 10;
478   bool valid_wait = wait_stream.client_state->Wait(
479       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
480                                  &test_num, 123));
481   EXPECT_TRUE(valid_wait);
482   EXPECT_EQ(10, test_num);
483   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
484 
485   // Even though release stream order [1] did not have a release, it
486   // should have changed test_num although the fence sync is still not released.
487   release_stream.BeginProcessing();
488   EXPECT_EQ(1u, release_stream.order_data->current_order_num());
489   release_stream.EndProcessing();
490   EXPECT_EQ(123, test_num);
491   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
492 
493   // Ensure that the wait callback does not get triggered again when it is
494   // actually released.
495   test_num = 1;
496   release_stream.AllocateOrderNum();
497   release_stream.BeginProcessing();
498   release_stream.client_state->ReleaseFenceSync(release_count);
499   release_stream.EndProcessing();
500   EXPECT_EQ(1, test_num);
501   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
502 }
503 
TEST_F(SyncPointManagerTest,NonExistentOrderNumRelease)504 TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) {
505   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
506   CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
507   CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234);
508 
509   SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId,
510                                  kReleaseCmdBufferId);
511   SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId,
512                               kWaitCmdBufferId);
513 
514   // Assign Release stream orders [1, 4] and assign Wait stream orders [2, 3].
515   // Here we are testing that wait order [3] will wait on a fence sync
516   // in either order [1] or order [2]. Order [2] was not actually assigned
517   // to the release stream so it is essentially non-existent to the release
518   // stream's point of view. Once the release stream begins processing the next
519   // order [3], it should realize order [2] didn't exist and release the fence.
520   release_stream.AllocateOrderNum();
521   wait_stream.AllocateOrderNum();
522   wait_stream.AllocateOrderNum();
523   release_stream.AllocateOrderNum();
524 
525   uint64_t release_count = 1;
526   SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count);
527 
528   // Have wait with order [3] to wait on release order [1] or [2].
529   wait_stream.BeginProcessing();
530   EXPECT_EQ(2u, wait_stream.order_data->current_order_num());
531   wait_stream.EndProcessing();
532   wait_stream.BeginProcessing();
533   EXPECT_EQ(3u, wait_stream.order_data->current_order_num());
534   int test_num = 10;
535   bool valid_wait = wait_stream.client_state->Wait(
536       sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction,
537                                  &test_num, 123));
538   EXPECT_TRUE(valid_wait);
539   EXPECT_EQ(10, test_num);
540 
541   // Release stream should know it should release fence sync by order [3], but
542   // it has no unprocessed order numbers less than 3, so it runs the callback.
543   release_stream.BeginProcessing();
544   EXPECT_EQ(1u, release_stream.order_data->current_order_num());
545   release_stream.EndProcessing();
546   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
547   EXPECT_EQ(123, test_num);
548 
549   // Ensure that the wait callback does not get triggered again when it is
550   // actually released.
551   release_stream.BeginProcessing();
552   test_num = 10;
553   release_stream.client_state->ReleaseFenceSync(1);
554   EXPECT_EQ(10, test_num);
555   EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token));
556 }
557 
TEST_F(SyncPointManagerTest,WaitOnSameSequenceFails)558 TEST_F(SyncPointManagerTest, WaitOnSameSequenceFails) {
559   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
560   CommandBufferId kCmdBufferId = CommandBufferId::FromUnsafeValue(0x123);
561 
562   SyncPointStream stream(sync_point_manager_.get(), kNamespaceId, kCmdBufferId);
563 
564   // Dummy order number to avoid the wait_order_num <= processed_order_num + 1
565   // check in SyncPointOrderData::ValidateReleaseOrderNum.
566   sync_point_manager_->GenerateOrderNumber();
567 
568   // Order number for the wait.
569   stream.AllocateOrderNum();
570 
571   uint64_t release_count = 1;
572   SyncToken sync_token(kNamespaceId, kCmdBufferId, release_count);
573 
574   int test_num = 10;
575   bool valid_wait = sync_point_manager_->Wait(
576       sync_token, stream.order_data->sequence_id(),
577       stream.order_data->unprocessed_order_num(),
578       base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num,
579                      123));
580   EXPECT_FALSE(valid_wait);
581   EXPECT_EQ(10, test_num);
582   EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token));
583 }
584 
TEST_F(SyncPointManagerTest,HandleInvalidWaitOrderNumber)585 TEST_F(SyncPointManagerTest, HandleInvalidWaitOrderNumber) {
586   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
587   CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123);
588   CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234);
589 
590   SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId,
591                           kCmdBufferId1);
592   SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId,
593                           kCmdBufferId2);
594 
595   stream1.AllocateOrderNum();  // stream 1, order num 1
596   stream2.AllocateOrderNum();  // stream 2, order num 2
597   stream2.AllocateOrderNum();  // stream 2, order num 3
598   stream1.AllocateOrderNum();  // stream 1, order num 4
599 
600   // Run stream 1, order num 1.
601   stream1.BeginProcessing();
602   stream1.EndProcessing();
603 
604   // Stream 2 waits on stream 1 with order num 3. This wait is invalid because
605   // there's no unprocessed order num less than 3 on stream 1.
606   int test_num = 10;
607   bool valid_wait = sync_point_manager_->Wait(
608       SyncToken(kNamespaceId, kCmdBufferId1, 1),
609       stream2.order_data->sequence_id(), 3,
610       base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num,
611                      123));
612   EXPECT_FALSE(valid_wait);
613   EXPECT_EQ(10, test_num);
614 }
615 
TEST_F(SyncPointManagerTest,RetireInvalidWaitAfterOrderNumberPasses)616 TEST_F(SyncPointManagerTest, RetireInvalidWaitAfterOrderNumberPasses) {
617   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
618   CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123);
619   CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234);
620 
621   SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId,
622                           kCmdBufferId1);
623   SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId,
624                           kCmdBufferId2);
625 
626   stream1.AllocateOrderNum();  // stream 1, order num 1
627   stream1.AllocateOrderNum();  // stream 1, order num 2
628   stream2.AllocateOrderNum();  // stream 2, order num 3
629 
630   // Stream 2 waits on stream 1 with order num 3.
631   int test_num = 10;
632   bool valid_wait = sync_point_manager_->Wait(
633       SyncToken(kNamespaceId, kCmdBufferId1, 1),
634       stream2.order_data->sequence_id(), 3,
635       base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num,
636                      123));
637   EXPECT_TRUE(valid_wait);
638   EXPECT_EQ(10, test_num);
639 
640   stream1.AllocateOrderNum();  // stream 1, order num 4
641 
642   // Run stream 1, order num 1. The wait isn't retired.
643   stream1.BeginProcessing();
644   stream1.EndProcessing();
645   EXPECT_EQ(10, test_num);
646 
647   // Run stream 1, order num 2. Wait is retired because we reach the last order
648   // number that was unprocessed at the time the wait was enqueued.
649   stream1.BeginProcessing();
650   stream1.EndProcessing();
651   EXPECT_EQ(123, test_num);
652 }
653 
TEST_F(SyncPointManagerTest,HandleInvalidCyclicWaits)654 TEST_F(SyncPointManagerTest, HandleInvalidCyclicWaits) {
655   CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO;
656   CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123);
657   CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234);
658 
659   SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId,
660                           kCmdBufferId1);
661   SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId,
662                           kCmdBufferId2);
663 
664   stream1.AllocateOrderNum();  // stream 1, order num 1
665   stream2.AllocateOrderNum();  // stream 2, order num 2
666   stream1.AllocateOrderNum();  // stream 1, order num 3
667   stream2.AllocateOrderNum();  // stream 2, order num 4
668 
669   // Stream 2 waits on stream 1 with order num 2.
670   int test_num1 = 10;
671   bool valid_wait = sync_point_manager_->Wait(
672       SyncToken(kNamespaceId, kCmdBufferId1, 1),
673       stream2.order_data->sequence_id(), 2,
674       base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num1,
675                      123));
676   EXPECT_TRUE(valid_wait);
677   EXPECT_EQ(10, test_num1);
678 
679   // Stream 1 waits on stream 2 with order num 3.
680   int test_num2 = 10;
681   valid_wait = sync_point_manager_->Wait(
682       SyncToken(kNamespaceId, kCmdBufferId2, 1),
683       stream1.order_data->sequence_id(), 3,
684       base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num2,
685                      123));
686   EXPECT_TRUE(valid_wait);
687   EXPECT_EQ(10, test_num2);
688 
689   // Run stream 1, order num 1.
690   stream1.BeginProcessing();
691   stream1.EndProcessing();
692 
693   // Since there's no unprocessed order num less than 2 on stream 1, the wait is
694   // released.
695   EXPECT_EQ(123, test_num1);
696   EXPECT_EQ(10, test_num2);
697 
698   // Run stream 2, order num 2.
699   stream2.BeginProcessing();
700   stream2.EndProcessing();
701 
702   // Since there's no unprocessed order num less than 3 on stream 2, the wait is
703   // released.
704   EXPECT_EQ(123, test_num1);
705   EXPECT_EQ(123, test_num2);
706 }
707 
708 }  // namespace gpu
709