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_manager.h>
21 #include "buffer_consumer_listener.h"
22 #include "sync_fence.h"
23
24 using namespace testing;
25 using namespace testing::ext;
26
27 namespace OHOS::Rosen {
28 class BufferQueueTest : public testing::Test {
29 public:
30 static void SetUpTestCase();
31 static void TearDownTestCase();
32
33 static inline BufferRequestConfig requestConfig = {
34 .width = 0x100,
35 .height = 0x100,
36 .strideAlignment = 0x8,
37 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
38 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
39 .timeout = 0,
40 };
41 static inline BufferFlushConfig flushConfig = {
42 .damage = {
43 .w = 0x100,
44 .h = 0x100,
45 },
46 };
47 static inline int64_t timestamp = 0;
48 static inline Rect damage = {};
49 static inline sptr<BufferQueue> bq = nullptr;
50 static inline std::map<int32_t, sptr<SurfaceBuffer>> cache;
51 static inline sptr<BufferExtraData> bedata = nullptr;
52 };
53
SetUpTestCase()54 void BufferQueueTest::SetUpTestCase()
55 {
56 bq = new BufferQueue("test");
57 sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
58 bq->RegisterConsumerListener(listener);
59 bedata = new OHOS::BufferExtraDataImpl;
60 }
61
TearDownTestCase()62 void BufferQueueTest::TearDownTestCase()
63 {
64 bq = nullptr;
65 }
66
67 /*
68 * Function: Init
69 * Type: Function
70 * Rank: Important(2)
71 * EnvConditions: N/A
72 * CaseDescription: 1. call Init and check ret
73 */
74 HWTEST_F(BufferQueueTest, Init001, Function | MediumTest | Level2)
75 {
76 GSError ret = bq->Init();
77 ASSERT_EQ(ret, OHOS::GSERROR_OK);
78 }
79
80 /*
81 * Function: SetQueueSize and GetQueueSize
82 * Type: Function
83 * Rank: Important(2)
84 * EnvConditions: N/A
85 * CaseDescription: 1. call GetQueueSize for default
86 * 2. call SetQueueSize
87 * 3. call SetQueueSize again with abnormal input
88 * 4. check ret and call GetQueueSize
89 */
90 HWTEST_F(BufferQueueTest, QueueSize001, Function | MediumTest | Level2)
91 {
92 ASSERT_EQ(bq->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
93
94 GSError ret = bq->SetQueueSize(2);
95 ASSERT_EQ(ret, OHOS::GSERROR_OK);
96
97 ret = bq->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
98 ASSERT_NE(ret, OHOS::GSERROR_OK);
99
100 ASSERT_EQ(bq->GetQueueSize(), 2u);
101 }
102
103 /*
104 * Function: SetQueueSize and GetQueueSize
105 * Type: Function
106 * Rank: Important(2)
107 * EnvConditions: N/A
108 * CaseDescription: 1. call SetQueueSize 2 times both with abnormal input
109 * 2. call GetQueueSize
110 * 3. check ret
111 */
112 HWTEST_F(BufferQueueTest, QueueSize002, Function | MediumTest | Level2)
113 {
114 GSError ret = bq->SetQueueSize(-1);
115 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
116 ASSERT_EQ(bq->GetQueueSize(), 2u);
117
118 ret = bq->SetQueueSize(0);
119 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
120 ASSERT_EQ(bq->GetQueueSize(), 2u);
121 }
122
123 /*
124 * Function: RequestBuffer, FlushBuffer, AcquireBuffer and ReleaseBuffer
125 * Type: Function
126 * Rank: Important(2)
127 * EnvConditions: N/A
128 * CaseDescription: 1. call RequestBuffer and FlushBuffer
129 * 2. call AcquireBuffer and ReleaseBuffer
130 * 3. check ret
131 */
132 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel001, Function | MediumTest | Level2)
133 {
134 IBufferProducer::RequestBufferReturnValue retval;
135
136 // first request
137 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
138 ASSERT_EQ(ret, OHOS::GSERROR_OK);
139 ASSERT_NE(retval.buffer, nullptr);
140 ASSERT_GE(retval.sequence, 0);
141
142 // add cache
143 cache[retval.sequence] = retval.buffer;
144
145 // buffer queue will map
146 uint8_t *addr1 = reinterpret_cast<uint8_t*>(retval.buffer->GetVirAddr());
147 ASSERT_NE(addr1, nullptr);
148 addr1[0] = 5;
149
150 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
151 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
152 ASSERT_EQ(ret, OHOS::GSERROR_OK);
153
154 ret = bq->AcquireBuffer(retval.buffer, retval.fence, timestamp, damage);
155 ASSERT_EQ(ret, OHOS::GSERROR_OK);
156 ASSERT_NE(retval.buffer, nullptr);
157
158 uint8_t *addr2 = reinterpret_cast<uint8_t*>(retval.buffer->GetVirAddr());
159 ASSERT_NE(addr2, nullptr);
160 if (addr2 != nullptr) {
161 ASSERT_EQ(addr2[0], 5u);
162 }
163
164 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
165 ret = bq->ReleaseBuffer(retval.buffer, releaseFence);
166 ASSERT_EQ(ret, OHOS::GSERROR_OK);
167 }
168
169 /*
170 * Function: RequestBuffer and CancelBuffer
171 * Type: Function
172 * Rank: Important(2)
173 * EnvConditions: N/A
174 * CaseDescription: 1. call RequestBuffer
175 * 2. call CancelBuffer
176 * 3. check ret
177 */
178 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel002, Function | MediumTest | Level2)
179 {
180 IBufferProducer::RequestBufferReturnValue retval;
181
182 // not first request
183 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
184 ASSERT_EQ(ret, OHOS::GSERROR_OK);
185 ASSERT_GE(retval.sequence, 0);
186 ASSERT_EQ(retval.buffer, nullptr);
187
188 ret = bq->CancelBuffer(retval.sequence, bedata);
189 ASSERT_EQ(ret, OHOS::GSERROR_OK);
190 }
191
192 /*
193 * Function: RequestBuffer and CancelBuffer
194 * Type: Function
195 * Rank: Important(2)
196 * EnvConditions: N/A
197 * CaseDescription: 1. call RequestBuffer
198 * 2. call CancelBuffer 2 times
199 * 3. check ret
200 */
201 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel003, Function | MediumTest | Level2)
202 {
203 IBufferProducer::RequestBufferReturnValue retval;
204
205 // not first request
206 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
207 ASSERT_EQ(ret, OHOS::GSERROR_OK);
208 ASSERT_GE(retval.sequence, 0);
209 ASSERT_EQ(retval.buffer, nullptr);
210
211 ret = bq->CancelBuffer(retval.sequence, bedata);
212 ASSERT_EQ(ret, OHOS::GSERROR_OK);
213
214 ret = bq->CancelBuffer(retval.sequence, bedata);
215 ASSERT_NE(ret, OHOS::GSERROR_OK);
216 }
217
218 /*
219 * Function: RequestBuffer and FlushBuffer
220 * Type: Function
221 * Rank: Important(2)
222 * EnvConditions: N/A
223 * CaseDescription: 1. call RequestBuffer
224 * 2. call FlushBuffer 2 times
225 * 3. check ret
226 */
227 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel004, Function | MediumTest | Level2)
228 {
229 IBufferProducer::RequestBufferReturnValue retval;
230
231 // not first request
232 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
233 ASSERT_EQ(ret, OHOS::GSERROR_OK);
234 ASSERT_GE(retval.sequence, 0);
235 ASSERT_EQ(retval.buffer, nullptr);
236
237 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
238 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
239 ASSERT_EQ(ret, OHOS::GSERROR_OK);
240
241 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
242 ASSERT_NE(ret, OHOS::GSERROR_OK);
243 }
244
245 /*
246 * Function: AcquireBuffer and ReleaseBuffer
247 * Type: Function
248 * Rank: Important(2)
249 * EnvConditions: N/A
250 * CaseDescription: 1. call AcquireBuffer
251 * 2. call ReleaseBuffer 2 times
252 * 3. check ret
253 */
254 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel005, Function | MediumTest | Level2)
255 {
256 sptr<SurfaceBuffer> buffer;
257
258 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
259 GSError ret = bq->AcquireBuffer(buffer, acquireFence, timestamp, damage);
260 ASSERT_EQ(ret, OHOS::GSERROR_OK);
261
262 sptr<SyncFence> ReleaseFence = SyncFence::INVALID_FENCE;
263 ret = bq->ReleaseBuffer(buffer, ReleaseFence);
264 ASSERT_EQ(ret, OHOS::GSERROR_OK);
265
266 ret = bq->ReleaseBuffer(buffer, ReleaseFence);
267 ASSERT_NE(ret, OHOS::GSERROR_OK);
268 }
269
270 /*
271 * Function: RequestBuffer, and CancelBuffer
272 * Type: Function
273 * Rank: Important(2)
274 * EnvConditions: N/A
275 * CaseDescription: 1. call RequestBuffer and CancelBuffer by different retval
276 * 2. check ret
277 */
278 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel006, Function | MediumTest | Level2)
279 {
280 IBufferProducer::RequestBufferReturnValue retval1;
281 IBufferProducer::RequestBufferReturnValue retval2;
282 IBufferProducer::RequestBufferReturnValue retval3;
283 GSError ret;
284
285 // not alloc
286 ret = bq->RequestBuffer(requestConfig, bedata, retval1);
287 ASSERT_EQ(ret, OHOS::GSERROR_OK);
288 ASSERT_GE(retval1.sequence, 0);
289 ASSERT_EQ(retval1.buffer, nullptr);
290
291 // alloc
292 ret = bq->RequestBuffer(requestConfig, bedata, retval2);
293 ASSERT_EQ(ret, OHOS::GSERROR_OK);
294 ASSERT_GE(retval2.sequence, 0);
295 ASSERT_NE(retval2.buffer, nullptr);
296
297 cache[retval2.sequence] = retval2.buffer;
298
299 // no buffer
300 ret = bq->RequestBuffer(requestConfig, bedata, retval3);
301 ASSERT_NE(ret, OHOS::GSERROR_OK);
302 ASSERT_EQ(retval3.buffer, nullptr);
303
304 ret = bq->CancelBuffer(retval1.sequence, bedata);
305 ASSERT_EQ(ret, OHOS::GSERROR_OK);
306
307 ret = bq->CancelBuffer(retval2.sequence, bedata);
308 ASSERT_EQ(ret, OHOS::GSERROR_OK);
309
310 ret = bq->CancelBuffer(retval3.sequence, bedata);
311 ASSERT_NE(ret, OHOS::GSERROR_OK);
312 }
313
314 /*
315 * Function: RequestBuffer, ReleaseBuffer and FlushBuffer
316 * Type: Function
317 * Rank: Important(2)
318 * EnvConditions: N/A
319 * CaseDescription: 1. call RequestBuffer
320 * 2. call ReleaseBuffer
321 * 3. call FlushBuffer
322 * 4. check ret
323 */
324 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel007, Function | MediumTest | Level2)
325 {
326 IBufferProducer::RequestBufferReturnValue retval;
327
328 // not alloc
329 GSError ret = bq->RequestBuffer(requestConfig, bedata, retval);
330 ASSERT_EQ(ret, OHOS::GSERROR_OK);
331 ASSERT_GE(retval.sequence, 0);
332 ASSERT_EQ(retval.buffer, nullptr);
333
334 retval.buffer = cache[retval.sequence];
335
336 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
337 ret = bq->ReleaseBuffer(retval.buffer, releaseFence);
338 ASSERT_NE(ret, OHOS::GSERROR_OK);
339
340 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
341 ret = bq->FlushBuffer(retval.sequence, bedata, acquireFence, flushConfig);
342 ASSERT_EQ(ret, OHOS::GSERROR_OK);
343 }
344
345 /*
346 * Function: AcquireBuffer, FlushBuffer and ReleaseBuffer
347 * Type: Function
348 * Rank: Important(2)
349 * EnvConditions: N/A
350 * CaseDescription: 1. call AcquireBuffer
351 * 2. call FlushBuffer
352 * 3. call ReleaseBuffer
353 * 4. check ret
354 */
355 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel008, Function | MediumTest | Level2)
356 {
357 sptr<SurfaceBuffer> buffer;
358 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
359
360 // acq from last test
361 GSError ret = bq->AcquireBuffer(buffer, acquireFence, timestamp, damage);
362 ASSERT_EQ(ret, OHOS::GSERROR_OK);
363
364 uint32_t sequence;
365 for (auto it = cache.begin(); it != cache.end(); it++) {
366 if (it->second.GetRefPtr() == buffer.GetRefPtr()) {
367 sequence = it->first;
368 }
369 }
370 ASSERT_GE(sequence, 0);
371
372 ret = bq->FlushBuffer(sequence, bedata, acquireFence, flushConfig);
373 ASSERT_NE(ret, OHOS::GSERROR_OK);
374
375 sptr<SyncFence> releaseFence = SyncFence::INVALID_FENCE;
376 ret = bq->ReleaseBuffer(buffer, releaseFence);
377 ASSERT_EQ(ret, OHOS::GSERROR_OK);
378 }
379
380 /*
381 * Function: RequestBuffer and CancelBuffer
382 * Type: Function
383 * Rank: Important(2)
384 * EnvConditions: N/A
385 * CaseDescription: 1. call RequestBuffer
386 * 2. call CancelBuffer
387 * 3. check retval and ret
388 */
389 HWTEST_F(BufferQueueTest, ReqCanFluAcqRel009, Function | MediumTest | Level2)
390 {
391 IBufferProducer::RequestBufferReturnValue retval;
392 BufferRequestConfig deleteconfig = requestConfig;
393 deleteconfig.width = 1921;
394
395 GSError ret = bq->RequestBuffer(deleteconfig, bedata, retval);
396 ASSERT_EQ(ret, OHOS::GSERROR_OK);
397 ASSERT_EQ(retval.deletingBuffers.size(), 1u);
398 ASSERT_GE(retval.sequence, 0);
399 ASSERT_NE(retval.buffer, nullptr);
400
401 ret = bq->CancelBuffer(retval.sequence, bedata);
402 ASSERT_EQ(ret, OHOS::GSERROR_OK);
403 }
404
405 /*
406 * Function: RequestBuffer
407 * Type: Function
408 * Rank: Important(2)
409 * EnvConditions: N/A
410 * CaseDescription: 1. set BufferRequestConfig with abnormal value
411 * 2. call RequestBuffer
412 * 3. check ret
413 */
414 HWTEST_F(BufferQueueTest, RequestBuffer001, Function | MediumTest | Level2)
415 {
416 IBufferProducer::RequestBufferReturnValue retval;
417 BufferRequestConfig config = requestConfig;
418 config.width = -1;
419
420 GSError ret = bq->RequestBuffer(config, bedata, retval);
421 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
422 }
423
424 /*
425 * Function: RequestBuffer
426 * Type: Function
427 * Rank: Important(2)
428 * EnvConditions: N/A
429 * CaseDescription: 1. set BufferRequestConfig with abnormal value
430 * 2. call RequestBuffer
431 * 3. check ret
432 */
433 HWTEST_F(BufferQueueTest, RequestBuffer002, Function | MediumTest | Level2)
434 {
435 IBufferProducer::RequestBufferReturnValue retval;
436 BufferRequestConfig config = requestConfig;
437 config.height = -1;
438
439 GSError ret = bq->RequestBuffer(config, bedata, retval);
440 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
441 }
442
443
444 /*
445 * Function: RequestBuffer
446 * Type: Function
447 * Rank: Important(2)
448 * EnvConditions: N/A
449 * CaseDescription: 1. set BufferRequestConfig with abnormal value
450 * 2. call RequestBuffer
451 * 3. check ret
452 */
453 HWTEST_F(BufferQueueTest, RequestBuffer003, Function | MediumTest | Level2)
454 {
455 IBufferProducer::RequestBufferReturnValue retval;
456 BufferRequestConfig config = requestConfig;
457 config.strideAlignment = SURFACE_MIN_STRIDE_ALIGNMENT - 1;
458
459 GSError ret = bq->RequestBuffer(config, bedata, retval);
460 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
461 }
462
463 /*
464 * Function: RequestBuffer
465 * Type: Function
466 * Rank: Important(2)
467 * EnvConditions: N/A
468 * CaseDescription: 1. set BufferRequestConfig with abnormal value
469 * 2. call RequestBuffer
470 * 3. check ret
471 */
472 HWTEST_F(BufferQueueTest, RequestBuffer004, Function | MediumTest | Level2)
473 {
474 IBufferProducer::RequestBufferReturnValue retval;
475 BufferRequestConfig config = requestConfig;
476 config.strideAlignment = SURFACE_MAX_STRIDE_ALIGNMENT + 1;
477
478 GSError ret = bq->RequestBuffer(config, bedata, retval);
479 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
480 }
481
482 /*
483 * Function: RequestBuffer
484 * Type: Function
485 * Rank: Important(2)
486 * EnvConditions: N/A
487 * CaseDescription: 1. set BufferRequestConfig with abnormal value
488 * 2. call RequestBuffer
489 * 3. check ret
490 */
491 HWTEST_F(BufferQueueTest, RequestBuffer005, Function | MediumTest | Level2)
492 {
493 IBufferProducer::RequestBufferReturnValue retval;
494 BufferRequestConfig config = requestConfig;
495 config.strideAlignment = 3;
496
497 GSError ret = bq->RequestBuffer(config, bedata, retval);
498 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
499 }
500
501 /*
502 * Function: RequestBuffer
503 * Type: Function
504 * Rank: Important(2)
505 * EnvConditions: N/A
506 * CaseDescription: 1. set BufferRequestConfig with abnormal value
507 * 2. call RequestBuffer
508 * 3. check ret
509 */
510 HWTEST_F(BufferQueueTest, RequestBuffer006, Function | MediumTest | Level2)
511 {
512 IBufferProducer::RequestBufferReturnValue retval;
513 BufferRequestConfig config = requestConfig;
514 config.format = -1;
515
516 GSError ret = bq->RequestBuffer(config, bedata, retval);
517 ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
518 }
519 }
520