1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <map>
16 #include <gtest/gtest.h>
17 #include <surface.h>
18 #include <buffer_extra_data_impl.h>
19 #include <buffer_queue.h>
20 #include "buffer_consumer_listener.h"
21 #include "sync_fence.h"
22 #include "consumer_surface.h"
23 #include "producer_surface_delegator.h"
24
25 using namespace testing;
26 using namespace testing::ext;
27
28 namespace OHOS::Rosen {
29 class BufferQueueTest : public testing::Test {
30 public:
31 static void SetUpTestCase();
32 static void TearDownTestCase();
33
34 static inline BufferRequestConfig requestConfig = {
35 .width = 0x100,
36 .height = 0x100,
37 .strideAlignment = 0x8,
38 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
39 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
40 .timeout = 0,
41 };
42 static inline BufferFlushConfigWithDamages flushConfig = {
43 .damages = {
44 {
45 .w = 0x100,
46 .h = 0x100,
47 }
48 },
49 };
50 static inline int64_t timestamp = 0;
51 static inline std::vector<Rect> damages = {};
52 static inline sptr<BufferQueue> bq = nullptr;
53 static inline std::map<int32_t, sptr<SurfaceBuffer>> cache;
54 static inline sptr<BufferExtraData> bedata = nullptr;
55 static inline sptr<ProducerSurfaceDelegator> surfaceDelegator = nullptr;
56 static inline sptr<IConsumerSurface> csurface1 = nullptr;
57 };
58
SetUpTestCase()59 void BufferQueueTest::SetUpTestCase()
60 {
61 bq = new BufferQueue("test");
62 sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
63 bq->RegisterConsumerListener(listener);
64 bedata = new OHOS::BufferExtraDataImpl;
65 csurface1 = IConsumerSurface::Create();
66 }
67
TearDownTestCase()68 void BufferQueueTest::TearDownTestCase()
69 {
70 bq = nullptr;
71 }
72
73 /*
74 * Function: GetUsedSize
75 * Type: Function
76 * Rank: Important(2)
77 * EnvConditions: N/A
78 * CaseDescription: 1. call GetUsedSize and check ret
79 */
80 HWTEST_F(BufferQueueTest, GetUsedSize001, Function | MediumTest | Level2)
81 {
82 uint32_t usedSize = bq->GetUsedSize();
83 ASSERT_NE(usedSize, -1);
84 }
85
86 /*
87 * Function: SetQueueSize and GetQueueSize
88 * Type: Function
89 * Rank: Important(2)
90 * EnvConditions: N/A
91 * CaseDescription: 1. call GetQueueSize for default
92 * 2. call SetQueueSize
93 * 3. call SetQueueSize again with abnormal input
94 * 4. check ret and call GetQueueSize
95 */
96 HWTEST_F(BufferQueueTest, QueueSize001, Function | MediumTest | Level2)
97 {
98 ASSERT_EQ(bq->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
99
100 GSError ret = bq->SetQueueSize(2);
101 ASSERT_EQ(ret, OHOS::GSERROR_OK);
102
103 ret = bq->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
104 ASSERT_NE(ret, OHOS::GSERROR_OK);
105
106 ASSERT_EQ(bq->GetQueueSize(), 2u);
107 BufferQueue *bqTmp = new BufferQueue("testTmp");
108 EXPECT_EQ(bqTmp->SetQueueSize(1), GSERROR_OK);
109 bqTmp = nullptr;
110 }
111
112 /*
113 * Function: SetQueueSize and GetQueueSize
114 * Type: Function
115 * Rank: Important(2)
116 * EnvConditions: N/A
117 * CaseDescription: 1. call SetQueueSize 2 times both with abnormal input
118 * 2. call GetQueueSize
119 * 3. check ret
120 */
121 HWTEST_F(BufferQueueTest, QueueSize002, Function | MediumTest | Level2)
122 {
123 GSError ret = bq->SetQueueSize(-1);
124 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
125 ASSERT_EQ(bq->GetQueueSize(), 2u);
126
127 ret = bq->SetQueueSize(0);
128 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
129 ASSERT_EQ(bq->GetQueueSize(), 2u);
130 }
131
132 /*
133 * Function: RequestBuffer, FlushBuffer, AcquireBuffer and ReleaseBuffer
134 * Type: Function
135 * Rank: Important(2)
136 * EnvConditions: N/A
137 * CaseDescription: 1. call RequestBuffer and FlushBuffer
138 * 2. call AcquireBuffer and ReleaseBuffer
139 * 3. check ret
140 */
141 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel001, Function | MediumTest | Level2)
142 {
143 IBufferProducer::RequestBufferReturnValue retval;
144
145 // first request
146 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
147 ASSERT_EQ(ret, OHOS::GSERROR_OK);
148 ASSERT_NE(retval.buffer, nullptr);
149 ASSERT_GE(retval.sequence, 0);
150
151 // add cache
152 cache[retval.sequence] = retval.buffer;
153
154 // buffer queue will map
155 uint8_t *addr1 = reinterpret_cast<uint8_t*>(retval.buffer->GetVirAddr());
156 ASSERT_NE(addr1, nullptr);
157 addr1[0] = 5;
158
159 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
160 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
161 ASSERT_EQ(ret, OHOS::GSERROR_OK);
162
163 ret = bq->AcquireBuffer(retval.buffer, retval.fence, timestamp, damages);
164 ASSERT_EQ(ret, OHOS::GSERROR_OK);
165 ASSERT_NE(retval.buffer, nullptr);
166
167 uint8_t *addr2 = reinterpret_cast<uint8_t*>(retval.buffer->GetVirAddr());
168 ASSERT_NE(addr2, nullptr);
169 if (addr2 != nullptr) {
170 ASSERT_EQ(addr2[0], 5u);
171 }
172
173 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
174 ret = bq->ReleaseBuffer(retval.buffer, releaseFence);
175 ASSERT_EQ(ret, OHOS::GSERROR_OK);
176 }
177
178 /*
179 * Function: RequestBuffer and CancelBuffer
180 * Type: Function
181 * Rank: Important(2)
182 * EnvConditions: N/A
183 * CaseDescription: 1. call RequestBuffer
184 * 2. call CancelBuffer
185 * 3. check ret
186 */
187 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel002, Function | MediumTest | Level2)
188 {
189 IBufferProducer::RequestBufferReturnValue retval;
190
191 // not first request
192 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
193 ASSERT_EQ(ret, OHOS::GSERROR_OK);
194 ASSERT_GE(retval.sequence, 0);
195 ASSERT_EQ(retval.buffer, nullptr);
196
197 ret = bq->CancelBuffer(retval.sequence, bedata);
198 ASSERT_EQ(ret, OHOS::GSERROR_OK);
199 }
200
201 /*
202 * Function: RequestBuffer and CancelBuffer
203 * Type: Function
204 * Rank: Important(2)
205 * EnvConditions: N/A
206 * CaseDescription: 1. call RequestBuffer
207 * 2. call CancelBuffer 2 times
208 * 3. check ret
209 */
210 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel003, Function | MediumTest | Level2)
211 {
212 IBufferProducer::RequestBufferReturnValue retval;
213
214 // not first request
215 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
216 ASSERT_EQ(ret, OHOS::GSERROR_OK);
217 ASSERT_GE(retval.sequence, 0);
218 ASSERT_EQ(retval.buffer, nullptr);
219
220 ret = bq->CancelBuffer(retval.sequence, bedata);
221 ASSERT_EQ(ret, OHOS::GSERROR_OK);
222
223 ret = bq->CancelBuffer(retval.sequence, bedata);
224 ASSERT_NE(ret, OHOS::GSERROR_OK);
225 }
226
227 /*
228 * Function: RequestBuffer and FlushBuffer
229 * Type: Function
230 * Rank: Important(2)
231 * EnvConditions: N/A
232 * CaseDescription: 1. call RequestBuffer
233 * 2. call FlushBuffer 2 times
234 * 3. check ret
235 */
236 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel004, Function | MediumTest | Level2)
237 {
238 IBufferProducer::RequestBufferReturnValue retval;
239
240 // not first request
241 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
242 ASSERT_EQ(ret, OHOS::GSERROR_OK);
243 ASSERT_GE(retval.sequence, 0);
244 ASSERT_EQ(retval.buffer, nullptr);
245
246 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
247 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
248 ASSERT_EQ(ret, OHOS::GSERROR_OK);
249
250 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
251 ASSERT_NE(ret, OHOS::GSERROR_OK);
252 }
253
254 /*
255 * Function: AcquireBuffer and ReleaseBuffer
256 * Type: Function
257 * Rank: Important(2)
258 * EnvConditions: N/A
259 * CaseDescription: 1. call AcquireBuffer
260 * 2. call ReleaseBuffer 2 times
261 * 3. check ret
262 */
263 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel005, Function | MediumTest | Level2)
264 {
265 sptr<SurfaceBuffer> buffer;
266
267 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
268 GSError ret = bq->AcquireBuffer(buffer, acquireFence, timestamp, damages);
269 ASSERT_EQ(ret, OHOS::GSERROR_OK);
270
271 sptr<SyncFence> ReleaseFence = SyncFence::INVALID_FENCE;
272 ret = bq->ReleaseBuffer(buffer, ReleaseFence);
273 ASSERT_EQ(ret, OHOS::GSERROR_OK);
274
275 ret = bq->ReleaseBuffer(buffer, ReleaseFence);
276 ASSERT_NE(ret, OHOS::GSERROR_OK);
277 }
278
279 /*
280 * Function: RequestBuffer, and CancelBuffer
281 * Type: Function
282 * Rank: Important(2)
283 * EnvConditions: N/A
284 * CaseDescription: 1. call RequestBuffer and CancelBuffer by different retval
285 * 2. check ret
286 */
287 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel006, Function | MediumTest | Level2)
288 {
289 IBufferProducer::RequestBufferReturnValue retval1;
290 IBufferProducer::RequestBufferReturnValue retval2;
291 IBufferProducer::RequestBufferReturnValue retval3;
292 GSError ret;
293
294 // not alloc
295 ret = bq->RequestBuffer(requestConfig, bedata, retval1);
296 ASSERT_EQ(ret, OHOS::GSERROR_OK);
297 ASSERT_GE(retval1.sequence, 0);
298 ASSERT_EQ(retval1.buffer, nullptr);
299
300 // alloc
301 ret = bq->RequestBuffer(requestConfig, bedata, retval2);
302 ASSERT_EQ(ret, OHOS::GSERROR_OK);
303 ASSERT_GE(retval2.sequence, 0);
304 ASSERT_NE(retval2.buffer, nullptr);
305
306 cache[retval2.sequence] = retval2.buffer;
307
308 // no buffer
309 ret = bq->RequestBuffer(requestConfig, bedata, retval3);
310 ASSERT_NE(ret, OHOS::GSERROR_OK);
311 ASSERT_EQ(retval3.buffer, nullptr);
312
313 ret = bq->CancelBuffer(retval1.sequence, bedata);
314 ASSERT_EQ(ret, OHOS::GSERROR_OK);
315
316 ret = bq->CancelBuffer(retval2.sequence, bedata);
317 ASSERT_EQ(ret, OHOS::GSERROR_OK);
318
319 ret = bq->CancelBuffer(retval3.sequence, bedata);
320 ASSERT_NE(ret, OHOS::GSERROR_OK);
321 }
322
323 /*
324 * Function: RequestBuffer, ReleaseBuffer and FlushBuffer
325 * Type: Function
326 * Rank: Important(2)
327 * EnvConditions: N/A
328 * CaseDescription: 1. call RequestBuffer
329 * 2. call ReleaseBuffer
330 * 3. call FlushBuffer
331 * 4. check ret
332 */
333 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel007, Function | MediumTest | Level2)
334 {
335 IBufferProducer::RequestBufferReturnValue retval;
336
337 // not alloc
338 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
339 ASSERT_EQ(ret, OHOS::GSERROR_OK);
340 ASSERT_GE(retval.sequence, 0);
341 ASSERT_EQ(retval.buffer, nullptr);
342
343 retval.buffer = cache[retval.sequence];
344
345 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
346 ret = bq->ReleaseBuffer(retval.buffer, releaseFence);
347 ASSERT_NE(ret, OHOS::GSERROR_OK);
348
349 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
350 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
351 ASSERT_EQ(ret, OHOS::GSERROR_OK);
352 }
353
354 /*
355 * Function: AcquireBuffer, FlushBuffer and ReleaseBuffer
356 * Type: Function
357 * Rank: Important(2)
358 * EnvConditions: N/A
359 * CaseDescription: 1. call AcquireBuffer
360 * 2. call FlushBuffer
361 * 3. call ReleaseBuffer
362 * 4. check ret
363 */
364 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel008, Function | MediumTest | Level2)
365 {
366 sptr<SurfaceBuffer> buffer;
367 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
368
369 // acq from last test
370 GSError ret = bq->AcquireBuffer(buffer, acquireFence, timestamp, damages);
371 ASSERT_EQ(ret, OHOS::GSERROR_OK);
372
373 uint32_t sequence;
374 for (auto it = cache.begin(); it != cache.end(); it++) {
375 if (it->second.GetRefPtr() == buffer.GetRefPtr()) {
376 sequence = it->first;
377 }
378 }
379 ASSERT_GE(sequence, 0);
380
381 ret = bq->FlushBuffer(sequence, bedata, acquireFence, flushConfig);
382 ASSERT_NE(ret, OHOS::GSERROR_OK);
383
384 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
385 ret = bq->ReleaseBuffer(buffer, releaseFence);
386 ASSERT_EQ(ret, OHOS::GSERROR_OK);
387 }
388
389 /*
390 * Function: RequestBuffer and CancelBuffer
391 * Type: Function
392 * Rank: Important(2)
393 * EnvConditions: N/A
394 * CaseDescription: 1. call RequestBuffer
395 * 2. call CancelBuffer
396 * 3. check retval and ret
397 */
398 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel009, Function | MediumTest | Level2)
399 {
400 IBufferProducer::RequestBufferReturnValue retval;
401 BufferRequestConfig deleteconfig = requestConfig;
402 deleteconfig.width = 1921;
403
404 GSError ret = bq->RequestBuffer(deleteconfig, bedata, retval);
405 ASSERT_EQ(ret, OHOS::GSERROR_OK);
406 ASSERT_EQ(retval.deletingBuffers.size(), 1u);
407 ASSERT_GE(retval.sequence, 0);
408 ASSERT_NE(retval.buffer, nullptr);
409
410 ret = bq->CancelBuffer(retval.sequence, bedata);
411 ASSERT_EQ(ret, OHOS::GSERROR_OK);
412 }
413
414 /*
415 * Function: SetDesiredPresentTimestampAndUiTimestamp
416 * Type: Function
417 * Rank: Important(2)
418 * EnvConditions: N/A
419 * CaseDescription: 1. call SetDesiredPresentTimestampAndUiTimestamp with different parameter and check ret
420 * 2. call SetDesiredPresentTimestampAndUiTimestamp with empty parameter and check ret
421 * 3. repeatly call SetDesiredPresentTimestampAndUiTimestamp with different parameter and check ret
422 */
423 HWTEST_F(BufferQueueTest, SetDesiredPresentTimestampAndUiTimestamp001, Function | MediumTest | Level2)
424 {
425 IBufferProducer::RequestBufferReturnValue retval;
426 BufferRequestConfig config = requestConfig;
427 config.width = 1921;
428 GSError ret = bq->RequestBuffer(config, bedata, retval);
429 ASSERT_EQ(ret, OHOS::GSERROR_OK);
430 ASSERT_GE(retval.sequence, 0);
431
432 // call SetDesiredPresentTimestampAndUiTimestamp with different uiTimestamp and desireTimestamp, check ret
433 int64_t desiredPresentTimestamp = 0;
434 uint64_t uiTimestamp = 2;
435 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
436 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, uiTimestamp);
437 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
438 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, false);
439
440 desiredPresentTimestamp = -1;
441 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
442 ASSERT_GT(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, 0);
443 ASSERT_NE(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, uiTimestamp);
444 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
445 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, true);
446
447 desiredPresentTimestamp = 1;
448 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
449 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, desiredPresentTimestamp);
450 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
451 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, false);
452
453 // call SetDesiredPresentTimestampAndUiTimestamp with empty uiTimestamp and desireTimestamp, check ret
454 desiredPresentTimestamp = 0;
455 uiTimestamp = 0;
456 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
457 ASSERT_NE(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, desiredPresentTimestamp);
458 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
459 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, true);
460
461 //repeatly call SetDesiredPresentTimestampAndUiTimestamp with different uiTimestamp and desireTimestamp, check ret
462 desiredPresentTimestamp = 0;
463 uiTimestamp = 2;
464 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
465 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, uiTimestamp);
466 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
467 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, false);
468
469 desiredPresentTimestamp = -1;
470 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
471 ASSERT_GT(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, 0);
472 ASSERT_NE(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, uiTimestamp);
473 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
474 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, true);
475
476 desiredPresentTimestamp = 1;
477 bq->SetDesiredPresentTimestampAndUiTimestamp(retval.sequence, desiredPresentTimestamp, uiTimestamp);
478 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].desiredPresentTimestamp, desiredPresentTimestamp);
479 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].timestamp, uiTimestamp);
480 ASSERT_EQ(bq->bufferQueueCache_[retval.sequence].isAutoTimestamp, false);
481
482 ret = bq->CancelBuffer(retval.sequence, bedata);
483 ASSERT_EQ(ret, OHOS::GSERROR_OK);
484 }
485 }
486