OSDN Git Service

Overhual DvrBuffer and DvrBufferQueue API: Step 1
[android-x86/frameworks-native.git] / libs / vr / libdvr / tests / dvr_buffer_queue-test.cpp
1 #include <android/log.h>
2 #include <android/native_window.h>
3 #include <android-base/unique_fd.h>
4 #include <dvr/dvr_api.h>
5 #include <dvr/dvr_buffer_queue.h>
6
7 #include <gtest/gtest.h>
8
9 #include <array>
10 #include <unordered_map>
11
12 #ifndef ALOGD
13 #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
14 #endif
15
16 #ifndef ALOGD_IF
17 #define ALOGD_IF(cond, ...) \
18   ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
19 #endif
20
21 namespace {
22
23 static constexpr uint32_t kBufferWidth = 100;
24 static constexpr uint32_t kBufferHeight = 1;
25 static constexpr uint32_t kLayerCount = 1;
26 static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB;
27 static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
28 static constexpr size_t kQueueCapacity = 3;
29
30 class DvrBufferQueueTest : public ::testing::Test {
31  public:
32   static void BufferAvailableCallback(void* context) {
33     DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
34     thiz->HandleBufferAvailable();
35   }
36
37   static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
38     DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
39     thiz->HandleBufferRemoved(buffer);
40   }
41
42  protected:
43   void TearDown() override {
44     if (write_queue_ != nullptr) {
45       dvrWriteBufferQueueDestroy(write_queue_);
46       write_queue_ = nullptr;
47     }
48   }
49
50   void HandleBufferAvailable() {
51     buffer_available_count_ += 1;
52     ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
53   }
54
55   void HandleBufferRemoved(DvrReadBuffer* buffer) {
56     buffer_removed_count_ += 1;
57     ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
58              buffer_removed_count_);
59   }
60
61   DvrWriteBufferQueue* write_queue_{nullptr};
62   int buffer_available_count_{0};
63   int buffer_removed_count_{0};
64 };
65
66 TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
67   int ret = dvrWriteBufferQueueCreate(
68       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
69       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
70   ASSERT_EQ(0, ret);
71
72   dvrWriteBufferQueueDestroy(write_queue_);
73   write_queue_ = nullptr;
74 }
75
76 TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
77   int ret = dvrWriteBufferQueueCreate(
78       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
79       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
80   ASSERT_EQ(0, ret);
81
82   size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
83
84   ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
85   ASSERT_EQ(kQueueCapacity, capacity);
86 }
87
88 TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
89   int ret = dvrWriteBufferQueueCreate(
90       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
91       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
92   ASSERT_EQ(0, ret);
93
94   DvrReadBufferQueue* read_queue = nullptr;
95   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
96
97   ASSERT_EQ(0, ret);
98   ASSERT_NE(nullptr, read_queue);
99
100   dvrReadBufferQueueDestroy(read_queue);
101 }
102
103 TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
104   int ret = dvrWriteBufferQueueCreate(
105       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
106       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
107   ASSERT_EQ(0, ret);
108
109   DvrReadBufferQueue* read_queue1 = nullptr;
110   DvrReadBufferQueue* read_queue2 = nullptr;
111   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
112
113   ASSERT_EQ(0, ret);
114   ASSERT_NE(nullptr, read_queue1);
115
116   ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
117   ASSERT_EQ(0, ret);
118   ASSERT_NE(nullptr, read_queue2);
119   ASSERT_NE(read_queue1, read_queue2);
120
121   dvrReadBufferQueueDestroy(read_queue1);
122   dvrReadBufferQueueDestroy(read_queue2);
123 }
124
125 TEST_F(DvrBufferQueueTest, GainBuffer) {
126   int ret = dvrWriteBufferQueueCreate(
127       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
128       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
129   ASSERT_EQ(ret, 0);
130
131   DvrWriteBuffer* wb = nullptr;
132   EXPECT_FALSE(dvrWriteBufferIsValid(wb));
133
134   DvrNativeBufferMetadata meta = {0};
135   int fence_fd = -1;
136   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
137                                       &fence_fd);
138   ASSERT_EQ(ret, 0);
139   EXPECT_EQ(fence_fd, -1);
140   EXPECT_NE(wb, nullptr);
141   EXPECT_TRUE(dvrWriteBufferIsValid(wb));
142 }
143
144 TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
145   int ret = dvrWriteBufferQueueCreate(
146       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
147       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
148   ASSERT_EQ(ret, 0);
149
150   DvrReadBufferQueue* read_queue = nullptr;
151   DvrReadBuffer* rb = nullptr;
152   DvrWriteBuffer* wb = nullptr;
153   DvrNativeBufferMetadata meta1 = {0};
154   DvrNativeBufferMetadata meta2 = {0};
155   int fence_fd = -1;
156
157   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
158
159   ASSERT_EQ(ret, 0);
160   ASSERT_NE(read_queue, nullptr);
161
162   dvrReadBufferQueueSetBufferAvailableCallback(read_queue,
163                                                &BufferAvailableCallback, this);
164
165   // Gain buffer for writing.
166   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta1,
167                                       &fence_fd);
168   ASSERT_EQ(ret, 0);
169   ASSERT_NE(wb, nullptr);
170   ASSERT_TRUE(dvrWriteBufferIsValid(wb));
171   ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
172            wb, fence_fd);
173   android::base::unique_fd release_fence(fence_fd);
174
175   // Post buffer to the read_queue.
176   meta1.timestamp = 42;
177   ret = dvrWriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
178   ASSERT_EQ(ret, 0);
179   ASSERT_FALSE(dvrWriteBufferIsValid(wb));
180   wb = nullptr;
181
182   // Acquire buffer for reading.
183   ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/0, &rb, &meta2,
184                                         &fence_fd);
185   ASSERT_EQ(ret, 0);
186   ASSERT_NE(rb, nullptr);
187
188   // Dequeue is successfully, BufferAvailableCallback should be fired once.
189   ASSERT_EQ(buffer_available_count_, 1);
190   ASSERT_TRUE(dvrReadBufferIsValid(rb));
191
192   // Metadata should be passed along from producer to consumer properly.
193   ASSERT_EQ(meta1.timestamp, meta2.timestamp);
194
195   ALOGD_IF(TRACE,
196            "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
197            fence_fd);
198   android::base::unique_fd acquire_fence(fence_fd);
199
200   // Release buffer to the write_queue.
201   ret = dvrReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
202                                         /*release_fence_fd=*/-1);
203   ASSERT_EQ(ret, 0);
204   ASSERT_FALSE(dvrReadBufferIsValid(rb));
205   rb = nullptr;
206
207   // TODO(b/34387835) Currently buffer allocation has to happen after all queues
208   // are initialized.
209   size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
210
211   ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
212   ASSERT_EQ(kQueueCapacity, capacity);
213
214   dvrReadBufferQueueDestroy(read_queue);
215 }
216
217 TEST_F(DvrBufferQueueTest, GetANativeWindow) {
218   int ret = dvrWriteBufferQueueCreate(
219       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
220       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
221   ASSERT_EQ(0, ret);
222   ASSERT_NE(nullptr, write_queue_);
223
224   ANativeWindow* window = nullptr;
225   ret = dvrWriteBufferQueueGetANativeWindow(write_queue_, &window);
226   ASSERT_EQ(0, ret);
227   ASSERT_NE(nullptr, window);
228
229   uint32_t width = ANativeWindow_getWidth(window);
230   uint32_t height = ANativeWindow_getHeight(window);
231   uint32_t format = ANativeWindow_getFormat(window);
232   ASSERT_EQ(kBufferWidth, width);
233   ASSERT_EQ(kBufferHeight, height);
234   ASSERT_EQ(kBufferFormat, format);
235 }
236
237 // Create buffer queue of three buffers and dequeue three buffers out of it.
238 // Before each dequeue operation, we resize the buffer queue and expect the
239 // queue always return buffer with desired dimension.
240 TEST_F(DvrBufferQueueTest, ResizeBuffer) {
241   int ret = dvrWriteBufferQueueCreate(
242       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
243       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
244   ASSERT_EQ(0, ret);
245
246   int fence_fd = -1;
247
248   DvrNativeBufferMetadata meta = {0};
249   DvrReadBufferQueue* read_queue = nullptr;
250   DvrWriteBuffer* wb1 = nullptr;
251   DvrWriteBuffer* wb2 = nullptr;
252   DvrWriteBuffer* wb3 = nullptr;
253   AHardwareBuffer* ahb1 = nullptr;
254   AHardwareBuffer* ahb2 = nullptr;
255   AHardwareBuffer* ahb3 = nullptr;
256   AHardwareBuffer_Desc buffer_desc;
257
258   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
259
260   ASSERT_EQ(0, ret);
261   ASSERT_NE(nullptr, read_queue);
262
263   dvrReadBufferQueueSetBufferRemovedCallback(read_queue, &BufferRemovedCallback,
264                                              this);
265
266   // Handle all pending events on the read queue.
267   ret = dvrReadBufferQueueHandleEvents(read_queue);
268   ASSERT_EQ(0, ret);
269
270   size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
271   ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
272   ASSERT_EQ(kQueueCapacity, capacity);
273
274   // Resize before dequeuing.
275   constexpr uint32_t w1 = 10;
276   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
277   ASSERT_EQ(0, ret);
278
279   // Gain first buffer for writing. All buffers will be resized.
280   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1, &meta,
281                                       &fence_fd);
282   ASSERT_EQ(0, ret);
283   ASSERT_TRUE(dvrWriteBufferIsValid(wb1));
284   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
285   android::base::unique_fd release_fence1(fence_fd);
286
287   // Check the buffer dimension.
288   ret = dvrWriteBufferGetAHardwareBuffer(wb1, &ahb1);
289   ASSERT_EQ(0, ret);
290   AHardwareBuffer_describe(ahb1, &buffer_desc);
291   ASSERT_EQ(w1, buffer_desc.width);
292   ASSERT_EQ(kBufferHeight, buffer_desc.height);
293   AHardwareBuffer_release(ahb1);
294
295   // For the first resize, all buffers are reallocated.
296   int expected_buffer_removed_count = kQueueCapacity;
297   ret = dvrReadBufferQueueHandleEvents(read_queue);
298   ASSERT_EQ(0, ret);
299   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
300
301   // Resize the queue. We are testing with blob format, keep height to be 1.
302   constexpr uint32_t w2 = 20;
303   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
304   ASSERT_EQ(0, ret);
305
306   // The next buffer we dequeued should have new width.
307   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2, &meta,
308                                       &fence_fd);
309   ASSERT_EQ(0, ret);
310   ASSERT_TRUE(dvrWriteBufferIsValid(wb2));
311   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
312            fence_fd);
313   android::base::unique_fd release_fence2(fence_fd);
314
315   // Check the buffer dimension, should be new width
316   ret = dvrWriteBufferGetAHardwareBuffer(wb2, &ahb2);
317   ASSERT_EQ(0, ret);
318   AHardwareBuffer_describe(ahb2, &buffer_desc);
319   ASSERT_EQ(w2, buffer_desc.width);
320   AHardwareBuffer_release(ahb2);
321
322   // For the second resize, all but one buffers are reallocated.
323   expected_buffer_removed_count += (kQueueCapacity - 1);
324   ret = dvrReadBufferQueueHandleEvents(read_queue);
325   ASSERT_EQ(0, ret);
326   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
327
328   // Resize the queue for the third time.
329   constexpr uint32_t w3 = 30;
330   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
331   ASSERT_EQ(0, ret);
332
333   // The next buffer we dequeued should have new width.
334   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3, &meta,
335                                       &fence_fd);
336   ASSERT_EQ(0, ret);
337   ASSERT_TRUE(dvrWriteBufferIsValid(wb3));
338   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
339            fence_fd);
340   android::base::unique_fd release_fence3(fence_fd);
341
342   // Check the buffer dimension, should be new width
343   ret = dvrWriteBufferGetAHardwareBuffer(wb3, &ahb3);
344   ASSERT_EQ(0, ret);
345   AHardwareBuffer_describe(ahb3, &buffer_desc);
346   ASSERT_EQ(w3, buffer_desc.width);
347   AHardwareBuffer_release(ahb3);
348
349   // For the third resize, all but two buffers are reallocated.
350   expected_buffer_removed_count += (kQueueCapacity - 2);
351   ret = dvrReadBufferQueueHandleEvents(read_queue);
352   ASSERT_EQ(0, ret);
353   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
354
355   dvrReadBufferQueueDestroy(read_queue);
356 }
357
358 TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
359   int ret = dvrWriteBufferQueueCreate(
360       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
361       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
362   ASSERT_EQ(0, ret);
363
364   DvrReadBufferQueue* read_queue = nullptr;
365   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
366
367   ASSERT_EQ(0, ret);
368   ASSERT_NE(nullptr, read_queue);
369
370   int event_fd = dvrReadBufferQueueGetEventFd(read_queue);
371   ASSERT_GT(event_fd, 0);
372 }
373
374 // Verifies a Dvr{Read,Write}BufferQueue contains the same set of
375 // Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
376 // the corresponding AHardwareBuffer handle stays the same.
377 TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
378   int ret = dvrWriteBufferQueueCreate(
379       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
380       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
381   ASSERT_EQ(0, ret);
382
383   int fence_fd = -1;
384   DvrReadBufferQueue* read_queue = nullptr;
385   EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
386
387   // Read buffers.
388   std::array<DvrReadBuffer*, kQueueCapacity> rbs;
389   // Write buffers.
390   std::array<DvrWriteBuffer*, kQueueCapacity> wbs;
391   // Buffer metadata.
392   std::array<DvrNativeBufferMetadata, kQueueCapacity> metas;
393   // Hardware buffers for Read buffers.
394   std::unordered_map<int, AHardwareBuffer*> rhbs;
395   // Hardware buffers for Write buffers.
396   std::unordered_map<int, AHardwareBuffer*> whbs;
397
398   constexpr int kNumTests = 100;
399
400   // This test runs the following operations many many times. Thus we prefer to
401   // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
402   std::function<void(size_t i)> Gain = [&](size_t i) {
403     int ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0,
404                                             &wbs[i], &metas[i], &fence_fd);
405     ASSERT_EQ(ret, 0);
406     ASSERT_LT(fence_fd, 0);  // expect invalid fence.
407     ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
408     int buffer_id = dvrWriteBufferGetId(wbs[i]);
409     ASSERT_GT(buffer_id, 0);
410
411     AHardwareBuffer* hb = nullptr;
412     ASSERT_EQ(0, dvrWriteBufferGetAHardwareBuffer(wbs[i], &hb));
413
414     auto whb_it = whbs.find(buffer_id);
415     if (whb_it == whbs.end()) {
416       // If this is a new buffer id, check that total number of unique
417       // hardware buffers won't exceed queue capacity.
418       ASSERT_LT(whbs.size(), kQueueCapacity);
419       whbs.emplace(buffer_id, hb);
420     } else {
421       // If this is a buffer id we have seen before, check that the
422       // buffer_id maps to the same AHardwareBuffer handle.
423       ASSERT_EQ(hb, whb_it->second);
424     }
425   };
426
427   std::function<void(size_t i)> Post = [&](size_t i) {
428     ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
429
430     metas[i].timestamp++;
431     int ret = dvrWriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
432                                             /*fence=*/-1);
433     ASSERT_EQ(ret, 0);
434   };
435
436   std::function<void(size_t i)> Acquire = [&](size_t i) {
437     int ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/0,
438                                               &rbs[i], &metas[i], &fence_fd);
439     ASSERT_EQ(ret, 0);
440     ASSERT_LT(fence_fd, 0);  // expect invalid fence.
441     ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
442
443     int buffer_id = dvrReadBufferGetId(rbs[i]);
444     ASSERT_GT(buffer_id, 0);
445
446     AHardwareBuffer* hb = nullptr;
447     ASSERT_EQ(0, dvrReadBufferGetAHardwareBuffer(rbs[i], &hb));
448
449     auto rhb_it = rhbs.find(buffer_id);
450     if (rhb_it == rhbs.end()) {
451       // If this is a new buffer id, check that total number of unique hardware
452       // buffers won't exceed queue capacity.
453       ASSERT_LT(rhbs.size(), kQueueCapacity);
454       rhbs.emplace(buffer_id, hb);
455     } else {
456       // If this is a buffer id we have seen before, check that the buffer_id
457       // maps to the same AHardwareBuffer handle.
458       ASSERT_EQ(hb, rhb_it->second);
459     }
460   };
461
462   std::function<void(size_t i)> Release = [&](size_t i) {
463     ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
464
465     int ret = dvrReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
466                                               /*release_fence_fd=*/-1);
467     ASSERT_EQ(ret, 0);
468   };
469
470   // Scenario one:
471   for (int i = 0; i < kNumTests; i++) {
472     // Gain all write buffers.
473     for (size_t i = 0; i < kQueueCapacity; i++) {
474       ASSERT_NO_FATAL_FAILURE(Gain(i));
475     }
476     // Post all write buffers.
477     for (size_t i = 0; i < kQueueCapacity; i++) {
478       ASSERT_NO_FATAL_FAILURE(Post(i));
479     }
480     // Acquire all read buffers.
481     for (size_t i = 0; i < kQueueCapacity; i++) {
482       ASSERT_NO_FATAL_FAILURE(Acquire(i));
483     }
484     // Release all read buffers.
485     for (size_t i = 0; i < kQueueCapacity; i++) {
486       ASSERT_NO_FATAL_FAILURE(Release(i));
487     }
488   }
489
490   // Scenario two:
491   for (int i = 0; i < kNumTests; i++) {
492     // Gain and post all write buffers.
493     for (size_t i = 0; i < kQueueCapacity; i++) {
494       ASSERT_NO_FATAL_FAILURE(Gain(i));
495       ASSERT_NO_FATAL_FAILURE(Post(i));
496     }
497     // Acquire and release all read buffers.
498     for (size_t i = 0; i < kQueueCapacity; i++) {
499       ASSERT_NO_FATAL_FAILURE(Acquire(i));
500       ASSERT_NO_FATAL_FAILURE(Release(i));
501     }
502   }
503
504   // Scenario three:
505   for (int i = 0; i < kNumTests; i++) {
506     // Gain all write buffers then post them in reversed order.
507     for (size_t i = 0; i < kQueueCapacity; i++) {
508       ASSERT_NO_FATAL_FAILURE(Gain(i));
509     }
510     for (size_t i = 0; i < kQueueCapacity; i++) {
511       ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i));
512     }
513
514     // Acquire all write buffers then release them in reversed order.
515     for (size_t i = 0; i < kQueueCapacity; i++) {
516       ASSERT_NO_FATAL_FAILURE(Acquire(i));
517     }
518     for (size_t i = 0; i < kQueueCapacity; i++) {
519       ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i));
520     }
521   }
522 }
523
524 }  // namespace