haltest: check calloc fail
[platform/core/uifw/libtdm.git] / haltests / src / tc_tdm_backend_pp.cpp
1 /**************************************************************************
2  *
3  * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
4  *
5  * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
6  * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
7  * Contact: Roman Marchenko <r.marchenko@samsung.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sub license, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice (including the
18  * next paragraph) shall be included in all copies or substantial portions
19  * of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  *
29 **************************************************************************/
30
31 #include "tc_tdm.h"
32
33 /* LCOV_EXCL_START */
34
35 class TDMBackendPP : public TDMBackendDisplay
36 {
37 public:
38         tdm_pp *pp;
39         tdm_pp_capability capabilities;
40         const tbm_format *formats;
41         int format_count;
42         int min_w;
43         int min_h;
44         int max_w;
45         int max_h;
46         int preferred_align;
47
48         tbm_surface_h srcbuf[3];
49         tbm_surface_h dstbuf[3];
50
51         tdm_info_pp info;
52
53         tdm_output *output;
54         unsigned int pipe;
55         const tdm_output_mode *mode;
56
57         tdm_layer *dst_layer;
58         const tbm_format *dst_formats;
59         tbm_format *pp_formats;
60         int dst_format_count;
61         int dst_zpos;
62         int dst_layer_index;
63
64         TDMBackendPP();
65         void SetUp(void);
66         void TearDown(void);
67
68         bool FindLayerUnderPrimary(void);
69         bool FindLayerOverPrimary(void);
70         bool PreparePP(void);
71         bool PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t);
72         void ShowBuffer(int b);
73         void HideLayer(void);
74         void DumpBuffer(int b, char *test);
75         void DestroyBuffers(void);
76         void DestroyPP(void);
77 };
78
79 TDMBackendPP::TDMBackendPP()
80 {
81         pp = NULL;
82         capabilities = (tdm_pp_capability)0;
83         formats = NULL;
84         format_count = 0;
85         min_w = min_h = max_w = max_h = preferred_align = -1;
86
87         for (int b = 0; b < 3; b++)
88                 srcbuf[b] = dstbuf[b] = NULL;
89         memset(&info, 0, sizeof info);
90
91         output = NULL;
92         pipe = 0;
93         mode = NULL;
94
95         dst_layer = NULL;
96         dst_formats = NULL;
97         dst_format_count = 0;
98         dst_zpos = 0;
99         dst_layer_index = 0;
100         pp_formats = NULL;
101 }
102
103 void TDMBackendPP::SetUp(void)
104 {
105         TDMBackendDisplay::SetUp();
106
107         if (!tc_tdm_display_has_pp_capability(dpy))
108                 return;
109
110         ASSERT_EQ(tdm_display_get_pp_capabilities(dpy, &capabilities), TDM_ERROR_NONE);
111         ASSERT_GT(capabilities, 0);
112         ASSERT_EQ(tdm_display_get_pp_available_formats(dpy, &formats, &format_count), TDM_ERROR_NONE);
113         ASSERT_NE(formats, NULL);
114         ASSERT_GT(format_count, 0);
115         ASSERT_EQ(tdm_display_get_pp_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_NONE);
116         ASSERT_TRUE(min_w == -1 || min_w > 0);
117         ASSERT_TRUE(min_h == -1 || min_h > 0);
118         ASSERT_TRUE(max_w == -1 || max_w > 0);
119         ASSERT_TRUE(max_h == -1 || max_h > 0);
120         ASSERT_TRUE(preferred_align == -1 || preferred_align > 0);
121
122         for (int o = 0; o < output_count; o++) {
123                 if (!tc_tdm_output_is_connected(outputs[o]))
124                         continue;
125
126                 output = outputs[o];
127                 ASSERT_EQ(tdm_output_get_pipe(output, &pipe), TDM_ERROR_NONE);
128                 ASSERT_EQ(tc_tdm_output_prepare(dpy, output, false), true);
129                 ASSERT_EQ(tdm_output_get_mode(output, &mode), TDM_ERROR_NONE);
130                 ASSERT_NE(mode, NULL);
131                 break;
132         }
133 }
134
135 void TDMBackendPP::TearDown(void)
136 {
137         if (pp)
138                 tdm_pp_destroy(pp);
139
140         DestroyBuffers();
141         ASSERT_EQ(tc_tdm_output_unset(dpy, output), true);
142
143         TDMBackendDisplay::TearDown();
144 }
145
146 bool TDMBackendPP::PreparePP(void)
147 {
148         tdm_error ret;
149         pp = tdm_display_create_pp(dpy, &ret);
150         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
151         TDM_UT_RETURN_FALSE_IF_FAIL(pp != NULL);
152         return true;
153 }
154
155 void TDMBackendPP::DestroyPP(void)
156 {
157         if (pp) {
158                 tdm_pp_destroy(pp);
159                 pp = NULL;
160         }
161 }
162
163 bool TDMBackendPP::PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t)
164 {
165         int src_flags = 0, dst_flags = 0;
166
167         sw = TDM_UT_SIZE_ALIGN(sw, preferred_align);
168         dw = TDM_UT_SIZE_ALIGN(dw, preferred_align);
169
170         if (capabilities & TDM_PP_CAPABILITY_SCANOUT)
171                 src_flags = dst_flags |= TBM_BO_SCANOUT;
172
173         if (dst_layer) {
174                 tdm_layer_capability capabilities;
175                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_capabilities(dst_layer, &capabilities) == TDM_ERROR_NONE);
176                 if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT)
177                         dst_flags |= TBM_BO_SCANOUT;
178         }
179
180         if (tc_tdm_output_is_hwc_enable(output))
181                 dst_flags |= TBM_BO_SCANOUT;
182
183         TDM_UT_RETURN_FALSE_IF_FAIL(tc_tdm_buffer_create(sw, sh, sf, src_flags, true, 3, srcbuf) == true);
184         TDM_UT_RETURN_FALSE_IF_FAIL(tc_tdm_buffer_create(dw, dh, df, dst_flags, false, 3, dstbuf) == true);
185         TDM_UT_RETURN_FALSE_IF_FAIL(tc_tdm_pp_fill_info(srcbuf[0], dstbuf[0], t, &info) == true);
186         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_pp_set_info(pp, &info) == TDM_ERROR_NONE);
187
188         return true;
189 }
190
191 bool TDMBackendPP::FindLayerUnderPrimary(void)
192 {
193         tdm_error ret;
194         int count;
195         int primary_zpos, zpos;
196
197         if (tc_tdm_output_is_hwc_enable(output)) {
198                 pp_formats = (tbm_format *)calloc(1, sizeof(tbm_format) * 2);
199                 TDM_UT_RETURN_FALSE_IF_FAIL(pp_formats != NULL);
200                 pp_formats[0] = TBM_FORMAT_NV12;
201                 pp_formats[1] = TBM_FORMAT_YUV420;
202                 dst_formats = pp_formats;
203                 dst_format_count = 2;
204                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
205                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
206                 dst_layer = NULL;
207                 return true;
208         }
209
210         tdm_layer *primary = tc_tdm_output_get_primary_layer(output);
211         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
212         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
213         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
214
215         for (int l = 0; l < count; l++) {
216                 unsigned int usable;
217                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
218                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
219                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_is_usable(temp, &usable) == TDM_ERROR_NONE);
220                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
221                 if (zpos < primary_zpos && usable) {
222                         dst_layer = temp;
223                         dst_zpos = zpos;
224                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
225                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
226                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
227                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
228                         break;
229                 }
230         }
231
232         return true;
233 }
234
235 bool TDMBackendPP::FindLayerOverPrimary(void)
236 {
237         tdm_error ret;
238         int count;
239         int primary_zpos, zpos;
240
241         if (tc_tdm_output_is_hwc_enable(output)) {
242                 pp_formats = (tbm_format *)calloc(1, sizeof(tbm_format) * 2);
243                 TDM_UT_RETURN_FALSE_IF_FAIL(pp_formats != NULL);
244                 pp_formats[0] = TBM_FORMAT_ARGB8888;
245                 pp_formats[1] = TBM_FORMAT_XRGB8888;
246                 dst_formats = formats;
247                 dst_format_count = 2;
248                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
249                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
250                 dst_layer = NULL;
251                 return true;
252         }
253
254         tdm_layer *primary = tc_tdm_output_get_primary_layer(output);
255         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
256         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
257         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
258
259         for (int l = 0; l < count; l++) {
260                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
261                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
262                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
263                 if (zpos > primary_zpos) {
264                         dst_layer = temp;
265                         dst_zpos = zpos;
266                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
267                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
268                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
269                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
270                         break;
271                 }
272         }
273
274         return true;
275
276 }
277
278 static void
279 _tc_tdm_backend_pp_output_commit_cb(tdm_output *output, unsigned int sequence,
280                                                                         unsigned int tv_sec, unsigned int tv_usec,
281                                                                         void *user_data)
282 {
283         bool *done = (bool *)user_data;
284         if (done)
285                 *done = true;
286 }
287
288 void TDMBackendPP::ShowBuffer(int b)
289 {
290         ASSERT_NE(output, NULL);
291         if (tc_tdm_output_is_hwc_enable(output))
292                 TDM_UT_SKIP_FLAG(0);
293
294         ASSERT_NE(dst_layer, NULL);
295
296         bool done = false;
297
298         ASSERT_EQ(tc_tdm_layer_set_buffer(dst_layer, dstbuf[b]), true);
299         ASSERT_EQ(tdm_output_commit(output, 0, _tc_tdm_backend_pp_output_commit_cb, &done), TDM_ERROR_NONE);
300         while (!done) {
301                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
302         }
303 }
304
305 void TDMBackendPP::HideLayer(void)
306 {
307         ASSERT_NE(output, NULL);
308         if (tc_tdm_output_is_hwc_enable(output))
309                 TDM_UT_SKIP_FLAG(0);
310
311         ASSERT_NE(dst_layer, NULL);
312
313         tdm_layer_unset_buffer(dst_layer);
314         tdm_output_commit(output, 0, NULL, NULL);
315 }
316
317 void TDMBackendPP::DumpBuffer(int b, char *test)
318 {
319         char filename[256];
320         if (test)
321                 snprintf(filename, sizeof filename, "%s_%s_src_%d", typeid(*this).name(), test, b);
322         else
323                 snprintf(filename, sizeof filename, "%s_src_%d", typeid(*this).name(), b);
324         tdm_helper_dump_buffer_str(srcbuf[b], NULL, filename);
325         if (test)
326                 snprintf(filename, sizeof filename, "%s_%s_dst_%d", typeid(*this).name(), test, b);
327         else
328                 snprintf(filename, sizeof filename, "%s_dst_%d", typeid(*this).name(), b);
329         tdm_helper_dump_buffer_str(dstbuf[b], NULL, filename);
330 }
331
332 void TDMBackendPP::DestroyBuffers(void)
333 {
334         for (int b = 0; b < 3; b++) {
335                 if (srcbuf[b])
336                         tbm_surface_destroy(srcbuf[b]);
337                 if (dstbuf[b])
338                         tbm_surface_destroy(dstbuf[b]);
339                 srcbuf[b] = dstbuf[b] = NULL;
340         }
341 }
342
343 bool
344 tc_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info)
345 {
346         int bw, bh;
347
348         memset(info, 0, sizeof *info);
349
350         bw = bh = TDM_UT_INVALID_VALUE;
351         tdm_helper_get_buffer_full_size(srcbuf, &bw, &bh);
352         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
353         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(srcbuf));
354         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
355         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(srcbuf));
356         info->src_config.size.h = bw;
357         info->src_config.size.v = bh;
358         info->src_config.pos.x = 0;
359         info->src_config.pos.y = 0;
360         info->src_config.pos.w = tbm_surface_get_width(srcbuf);
361         info->src_config.pos.h = tbm_surface_get_height(srcbuf);
362         info->src_config.format = tbm_surface_get_format(srcbuf);
363
364         bw = bh = TDM_UT_INVALID_VALUE;
365         tdm_helper_get_buffer_full_size(dstbuf, &bw, &bh);
366         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
367         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(dstbuf));
368         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
369         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(dstbuf));
370         info->dst_config.size.h = bw;
371         info->dst_config.size.v = bh;
372         info->dst_config.pos.x = 0;
373         info->dst_config.pos.y = 0;
374         info->dst_config.pos.w = tbm_surface_get_width(dstbuf);
375         info->dst_config.pos.h = tbm_surface_get_height(dstbuf);
376         info->dst_config.format = tbm_surface_get_format(dstbuf);
377
378         info->transform = transform;
379         info->sync = 0;
380         info->flags = 0;
381
382         TDM_UT_INFO("src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) sync(%d) info->flags(%x)",
383                                 info->src_config.size.h, info->src_config.size.v,
384                                 info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
385                                 FOURCC_STR(info->src_config.format),
386                                 info->dst_config.size.h, info->dst_config.size.v,
387                                 info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h,
388                                 FOURCC_STR(info->dst_config.format),
389                                 tdm_transform_str(transform), info->sync, info->flags);
390
391         return true;
392 }
393
394 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullObject)
395 {
396         const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
397         int count = TDM_UT_INVALID_VALUE;
398         if (tc_tdm_display_has_pp_capability(dpy))
399                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
400         else
401                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
402         ASSERT_EQ(formats, (const tbm_format *)TDM_UT_INVALID_VALUE);
403         ASSERT_EQ(count, TDM_UT_INVALID_VALUE);
404 }
405
406 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullOther)
407 {
408         if (tc_tdm_display_has_pp_capability(dpy)) {
409                 ASSERT_EQ(PreparePP(), true);
410                 ASSERT_EQ(tdm_display_get_pp_available_formats(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
411         }
412 }
413
414 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullObject)
415 {
416         int min_w = TDM_UT_INVALID_VALUE;
417         int min_h = TDM_UT_INVALID_VALUE;
418         int max_w = TDM_UT_INVALID_VALUE;
419         int max_h = TDM_UT_INVALID_VALUE;
420         int preferred_align = TDM_UT_INVALID_VALUE;
421         if (tc_tdm_display_has_pp_capability(dpy))
422                 ASSERT_EQ(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_INVALID_PARAMETER);
423         else
424                 ASSERT_EQ(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_INVALID_PARAMETER);
425         ASSERT_EQ(min_w, TDM_UT_INVALID_VALUE);
426         ASSERT_EQ(min_h, TDM_UT_INVALID_VALUE);
427         ASSERT_EQ(max_w, TDM_UT_INVALID_VALUE);
428         ASSERT_EQ(max_h, TDM_UT_INVALID_VALUE);
429         ASSERT_EQ(preferred_align, TDM_UT_INVALID_VALUE);
430 }
431
432 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullOther)
433 {
434         if (tc_tdm_display_has_pp_capability(dpy)) {
435                 ASSERT_EQ(PreparePP(), true);
436                 ASSERT_EQ(tdm_display_get_pp_available_size(dpy, NULL, NULL, NULL, NULL, NULL), TDM_ERROR_NONE);
437         }
438 }
439
440 TEST_P(TDMBackendPP, PPDestroy)
441 {
442         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
443
444         ASSERT_EQ(PreparePP(), true);
445         tdm_pp_destroy(pp);
446         pp = NULL;
447 }
448
449 TEST_P(TDMBackendPP, PPDestroyNullObject)
450 {
451         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
452
453         tdm_pp_destroy(NULL);
454 }
455
456 TEST_P(TDMBackendPP, PPSetInfo)
457 {
458         /* tested in PPNoScaleNoTransformNoCSC */
459 }
460
461 TEST_P(TDMBackendPP, PPSetInfoNullObject)
462 {
463         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
464
465         tdm_info_pp info;
466         memset(&info, 0, sizeof info);
467         ASSERT_EQ(tdm_pp_set_info(NULL, &info), TDM_ERROR_INVALID_PARAMETER);
468 }
469
470 TEST_P(TDMBackendPP, PPSetInfoNullOther)
471 {
472         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
473
474         ASSERT_EQ(PreparePP(), true);
475         ASSERT_EQ(tdm_pp_set_info(pp, NULL), TDM_ERROR_INVALID_PARAMETER);
476 }
477
478 static void
479 _tc_tdm_pp_done_cb(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
480 {
481         bool *done = (bool*)user_data;
482         if (done)
483                 *done = true;
484 }
485
486 TEST_P(TDMBackendPP, PPSetDoneHandler)
487 {
488         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
489
490         ASSERT_EQ(PreparePP(), true);
491         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, NULL), TDM_ERROR_NONE);
492 }
493
494 TEST_P(TDMBackendPP, PPSetDoneHandlerNullObject)
495 {
496         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
497
498         ASSERT_EQ(tdm_pp_set_done_handler(NULL, _tc_tdm_pp_done_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
499 }
500
501 TEST_P(TDMBackendPP, PPSetDoneHandlerNullOther)
502 {
503         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
504
505         ASSERT_EQ(PreparePP(), true);
506         ASSERT_EQ(tdm_pp_set_done_handler(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
507 }
508
509 TEST_P(TDMBackendPP, PPAttach)
510 {
511         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
512
513         ASSERT_EQ(PreparePP(), true);
514
515         for (int f = 0; f < format_count; f++) {
516                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
517                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
518                                                                  TDM_TRANSFORM_NORMAL), true);
519
520                 for (int b = 0; b < 3; b++)
521                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
522
523                 DestroyBuffers();
524         }
525 }
526
527 TEST_P(TDMBackendPP, PPAttachNullObject)
528 {
529         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
530
531         tbm_surface_h srcbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
532         tbm_surface_h dstbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
533
534         ASSERT_EQ(tdm_pp_attach(NULL, srcbuf, dstbuf), TDM_ERROR_INVALID_PARAMETER);
535 }
536
537 TEST_P(TDMBackendPP, PPAttachNullOther)
538 {
539         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
540
541         ASSERT_EQ(PreparePP(), true);
542
543         ASSERT_EQ(tdm_pp_attach(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
544 }
545
546 TEST_P(TDMBackendPP, PPCommit)
547 {
548         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
549
550         ASSERT_EQ(PreparePP(), true);
551
552         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
553 }
554
555 TEST_P(TDMBackendPP, PPCommitNullOBject)
556 {
557         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
558
559         ASSERT_EQ(tdm_pp_commit(NULL), TDM_ERROR_INVALID_PARAMETER);
560 }
561
562 TEST_P(TDMBackendPP, PPConvertUnderlay)
563 {
564         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
565
566         FindLayerUnderPrimary();
567
568         if (!tc_tdm_output_is_hwc_enable(output))
569                 ASSERT_NE(dst_layer, NULL);
570
571         for (int f = 0; f < dst_format_count; f++) {
572                 bool done;
573
574                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
575
576                 ASSERT_EQ(PreparePP(), true);
577
578                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
579                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
580                                                                  TDM_TRANSFORM_NORMAL), true);
581
582                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
583
584 retry:
585                 for (int b = 0; b < 3; b++) {
586                         done = false;
587
588                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
589                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
590
591                         while (!done)
592                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
593
594 #if 0
595                         char temp[256];
596                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
597                         DumpBuffer(b, temp);
598 #endif
599                         ShowBuffer(b);
600                 }
601
602                 TDM_UT_ASK_YNR("* Successed to convert to '%c%c%c%c' buffers and show them to a underlay layer? (output: %d, layer: %d)",
603                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
604
605                 DestroyPP();
606                 DestroyBuffers();
607         }
608         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
609                 free(pp_formats);
610                 pp_formats = NULL;
611         }
612 }
613
614 TEST_P(TDMBackendPP, PPConvertOverlay)
615 {
616         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
617
618         FindLayerOverPrimary();
619
620         if (!tc_tdm_output_is_hwc_enable(output))
621                 TDM_UT_SKIP_FLAG(dst_layer != NULL);
622
623         for (int f = 0; f < dst_format_count; f++) {
624                 bool done;
625
626                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
627
628                 ASSERT_EQ(PreparePP(), true);
629
630                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
631                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
632                                                                  TDM_TRANSFORM_NORMAL), true);
633
634                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
635
636 retry:
637                 for (int b = 0; b < 3; b++) {
638                         done = false;
639
640                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
641                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
642
643                         while (!done)
644                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
645
646 #if 0
647                         char temp[256];
648                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
649                         DumpBuffer(b, temp);
650 #endif
651                         ShowBuffer(b);
652                 }
653
654                 TDM_UT_ASK_YNR("* Successed to convert '%c%c%c%c' buffers and show them to a overlay layer? (output: %d, layer: %d)",
655                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
656
657                 DestroyPP();
658                 DestroyBuffers();
659         }
660         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
661                 free(pp_formats);
662                 pp_formats = NULL;
663         }
664 }
665
666 TEST_P(TDMBackendPP, PPConvertScale)
667 {
668         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
669
670         FindLayerUnderPrimary();
671
672         if (!tc_tdm_output_is_hwc_enable(output))
673                 ASSERT_NE(dst_layer, NULL);
674
675         for (int f = 0; f < dst_format_count; f++) {
676                 bool done;
677
678                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
679
680                 ASSERT_EQ(PreparePP(), true);
681
682                 ASSERT_EQ(PrepareBuffers(640, 480, dst_formats[f],
683                                                                  mode->hdisplay, mode->vdisplay, dst_formats[f],
684                                                                  TDM_TRANSFORM_NORMAL), true);
685
686                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
687
688 retry:
689                 for (int b = 0; b < 3; b++) {
690                         done = false;
691
692                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
693                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
694
695                         while (!done)
696                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
697
698 #if 0
699                         char temp[256];
700                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
701                         DumpBuffer(b, temp);
702 #endif
703                         ShowBuffer(b);
704                 }
705
706                 TDM_UT_ASK_YNR("* Successed to scale '%c%c%c%c' buffers? (output: %d, layer: %d)",
707                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
708
709                 DestroyPP();
710                 DestroyBuffers();
711         }
712         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
713                 free(pp_formats);
714                 pp_formats = NULL;
715         }
716 }
717
718 TEST_P(TDMBackendPP, PPConvertTransform)
719 {
720         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
721
722         FindLayerUnderPrimary();
723
724         if (!tc_tdm_output_is_hwc_enable(output))
725                 ASSERT_NE(dst_layer, NULL);
726
727         for (int f = 0; f < dst_format_count; f++) {
728                 for (int t = (int)TDM_TRANSFORM_90; t <= (int)TDM_TRANSFORM_FLIPPED_270; t++) {
729                         bool done;
730
731                         TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
732
733                         ASSERT_EQ(PreparePP(), true);
734
735                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
736                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
737                                                                          (tdm_transform)t), true);
738
739                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
740
741 retry:
742                         for (int b = 0; b < 3; b++) {
743                                 done = false;
744
745                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
746                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
747
748                                 while (!done)
749                                         ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
750
751 #if 0
752                                 char temp[256];
753                                 snprintf(temp, sizeof temp, "f%d_b%d_t%d", f, b, t);
754                                 DumpBuffer(b, temp);
755 #endif
756                                 ShowBuffer(b);
757                         }
758
759                         TDM_UT_ASK_YNR("* Successed to rotate '%c%c%c%c' buffers? (transform: %s, output: %d, layer: %d)",
760                                                    FOURCC_STR(dst_formats[f]), tdm_transform_str(t), pipe, dst_layer_index);
761
762                         DestroyPP();
763                         DestroyBuffers();
764                 }
765         }
766         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
767                 free(pp_formats);
768                 pp_formats = NULL;
769         }
770 }
771
772 TEST_P(TDMBackendPP, PPConvertCSC)
773 {
774         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
775         TDM_UT_SKIP_FLAG(!(capabilities & TDM_PP_CAPABILITY_NO_CSC));
776
777         FindLayerUnderPrimary();
778
779         if (!tc_tdm_output_is_hwc_enable(output))
780                 ASSERT_NE(dst_layer, NULL);
781
782         for (int df = 0; df < dst_format_count; df++) {
783                 for (int sf = 0; sf < format_count; sf++) {
784                         bool done;
785
786                         TDM_UT_INFO("* testing for format(%c%c%c%c) -> format(%c%c%c%c)",
787                                                 FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]));
788
789                         ASSERT_EQ(PreparePP(), true);
790
791                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[sf],
792                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[df],
793                                                                          TDM_TRANSFORM_NORMAL), true);
794
795                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
796
797 retry:
798                         for (int b = 0; b < 3; b++) {
799                                 done = false;
800
801                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
802                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
803
804                                 while (!done)
805                                         ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
806
807 #if 0
808                                 char temp[256];
809                                 snprintf(temp, sizeof temp, "sf%d_df%d_b%d", sf, df, b);
810                                 DumpBuffer(b, temp);
811 #endif
812                                 ShowBuffer(b);
813                         }
814
815                         TDM_UT_ASK_YNR("* Successed to convert from '%c%c%c%c' to '%c%c%c%c'? (output: %d, layer: %d)",
816                                                    FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]), pipe, dst_layer_index);
817
818                         DestroyPP();
819                         DestroyBuffers();
820                 }
821         }
822         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
823                 free(pp_formats);
824                 pp_formats = NULL;
825         }
826 }
827
828
829
830 static void
831 _tc_tdm_pp_done_cb2(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
832 {
833         int *done = (int*)user_data;
834         if (done)
835                 (*done)++;
836 }
837
838 /* some backend doens't implement correctly for attaching */
839 TEST_P(TDMBackendPP, DISABLED_PPAttachFewTimesInOneCommit)
840 {
841         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
842
843         ASSERT_EQ(PreparePP(), true);
844
845         int done = 0;
846         int f = 0;
847         char temp[256];
848         snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[f]));
849
850         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
851                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
852                                                          TDM_TRANSFORM_NORMAL), true);
853
854         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, &done), TDM_ERROR_NONE);
855         for (int b = 0; b < 3; b++)
856                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
857
858         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
859
860         while (done != 3)
861                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
862
863         for (int b = 0; b < 3; b++)
864                 ShowBuffer(b);
865
866         DestroyBuffers();
867 }
868
869 TEST_P(TDMBackendPP, PPDestroyWithoutCommit)
870 {
871         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
872
873         ASSERT_EQ(PreparePP(), true);
874
875         int f = 0;
876
877         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
878                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
879                                                          TDM_TRANSFORM_NORMAL), true);
880
881         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
882         for (int b = 0; b < 3; b++)
883                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
884
885         tdm_pp_destroy(pp);
886         pp = NULL;
887
888         DestroyBuffers();
889 }
890
891 TEST_P(TDMBackendPP, PPDestroyBeforeDone)
892 {
893         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
894
895         ASSERT_EQ(PreparePP(), true);
896
897         int f = 0;
898
899         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
900                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
901                                                          TDM_TRANSFORM_NORMAL), true);
902
903         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
904         for (int b = 0; b < 3; b++)
905                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
906
907         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
908
909         tdm_pp_destroy(pp);
910         pp = NULL;
911
912         DestroyBuffers();
913 }
914
915 #ifdef TDM_UT_TEST_WITH_PARAMS
916 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
917                                                 TDMBackendPP,
918                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
919 #else
920 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
921                                                 TDMBackendPP,
922                                                 Values(TDM_DEFAULT_MODULE));
923 #endif
924
925 /* LCOV_EXCL_END */