f739d96df9f9f956ecf6e4afa7b4eb529eb005d8
[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                 pp_formats[0] = TBM_FORMAT_NV12;
200                 pp_formats[1] = TBM_FORMAT_YUV420;
201                 dst_formats = pp_formats;
202                 dst_format_count = 2;
203                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
204                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
205                 dst_layer = NULL;
206                 return true;
207         }
208
209         tdm_layer *primary = tc_tdm_output_get_primary_layer(output);
210         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
211         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
212         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
213
214         for (int l = 0; l < count; l++) {
215                 unsigned int usable;
216                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
217                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
218                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_is_usable(temp, &usable) == TDM_ERROR_NONE);
219                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
220                 if (zpos < primary_zpos && usable) {
221                         dst_layer = temp;
222                         dst_zpos = zpos;
223                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
224                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
225                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
226                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
227                         break;
228                 }
229         }
230
231         return true;
232 }
233
234 bool TDMBackendPP::FindLayerOverPrimary(void)
235 {
236         tdm_error ret;
237         int count;
238         int primary_zpos, zpos;
239
240         if (tc_tdm_output_is_hwc_enable(output)) {
241                 pp_formats = (tbm_format *)calloc(1, sizeof(tbm_format) * 2);
242                 pp_formats[0] = TBM_FORMAT_ARGB8888;
243                 pp_formats[1] = TBM_FORMAT_XRGB8888;
244                 dst_formats = formats;
245                 dst_format_count = 2;
246                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
247                 TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
248                 dst_layer = NULL;
249                 return true;
250         }
251
252         tdm_layer *primary = tc_tdm_output_get_primary_layer(output);
253         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
254         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
255         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
256
257         for (int l = 0; l < count; l++) {
258                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
259                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
260                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
261                 if (zpos > primary_zpos) {
262                         dst_layer = temp;
263                         dst_zpos = zpos;
264                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
265                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
266                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
267                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
268                         break;
269                 }
270         }
271
272         return true;
273
274 }
275
276 static void
277 _tc_tdm_backend_pp_output_commit_cb(tdm_output *output, unsigned int sequence,
278                                                                         unsigned int tv_sec, unsigned int tv_usec,
279                                                                         void *user_data)
280 {
281         bool *done = (bool *)user_data;
282         if (done)
283                 *done = true;
284 }
285
286 void TDMBackendPP::ShowBuffer(int b)
287 {
288         ASSERT_NE(output, NULL);
289         if (tc_tdm_output_is_hwc_enable(output))
290                 TDM_UT_SKIP_FLAG(0);
291
292         ASSERT_NE(dst_layer, NULL);
293
294         bool done = false;
295
296         ASSERT_EQ(tc_tdm_layer_set_buffer(dst_layer, dstbuf[b]), true);
297         ASSERT_EQ(tdm_output_commit(output, 0, _tc_tdm_backend_pp_output_commit_cb, &done), TDM_ERROR_NONE);
298         while (!done) {
299                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
300         }
301 }
302
303 void TDMBackendPP::HideLayer(void)
304 {
305         ASSERT_NE(output, NULL);
306         if (tc_tdm_output_is_hwc_enable(output))
307                 TDM_UT_SKIP_FLAG(0);
308
309         ASSERT_NE(dst_layer, NULL);
310
311         tdm_layer_unset_buffer(dst_layer);
312         tdm_output_commit(output, 0, NULL, NULL);
313 }
314
315 void TDMBackendPP::DumpBuffer(int b, char *test)
316 {
317         char filename[256];
318         if (test)
319                 snprintf(filename, sizeof filename, "%s_%s_src_%d", typeid(*this).name(), test, b);
320         else
321                 snprintf(filename, sizeof filename, "%s_src_%d", typeid(*this).name(), b);
322         tdm_helper_dump_buffer_str(srcbuf[b], NULL, filename);
323         if (test)
324                 snprintf(filename, sizeof filename, "%s_%s_dst_%d", typeid(*this).name(), test, b);
325         else
326                 snprintf(filename, sizeof filename, "%s_dst_%d", typeid(*this).name(), b);
327         tdm_helper_dump_buffer_str(dstbuf[b], NULL, filename);
328 }
329
330 void TDMBackendPP::DestroyBuffers(void)
331 {
332         for (int b = 0; b < 3; b++) {
333                 if (srcbuf[b])
334                         tbm_surface_destroy(srcbuf[b]);
335                 if (dstbuf[b])
336                         tbm_surface_destroy(dstbuf[b]);
337                 srcbuf[b] = dstbuf[b] = NULL;
338         }
339 }
340
341 bool
342 tc_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info)
343 {
344         int bw, bh;
345
346         memset(info, 0, sizeof *info);
347
348         bw = bh = TDM_UT_INVALID_VALUE;
349         tdm_helper_get_buffer_full_size(srcbuf, &bw, &bh);
350         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
351         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(srcbuf));
352         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
353         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(srcbuf));
354         info->src_config.size.h = bw;
355         info->src_config.size.v = bh;
356         info->src_config.pos.x = 0;
357         info->src_config.pos.y = 0;
358         info->src_config.pos.w = tbm_surface_get_width(srcbuf);
359         info->src_config.pos.h = tbm_surface_get_height(srcbuf);
360         info->src_config.format = tbm_surface_get_format(srcbuf);
361
362         bw = bh = TDM_UT_INVALID_VALUE;
363         tdm_helper_get_buffer_full_size(dstbuf, &bw, &bh);
364         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
365         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(dstbuf));
366         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
367         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(dstbuf));
368         info->dst_config.size.h = bw;
369         info->dst_config.size.v = bh;
370         info->dst_config.pos.x = 0;
371         info->dst_config.pos.y = 0;
372         info->dst_config.pos.w = tbm_surface_get_width(dstbuf);
373         info->dst_config.pos.h = tbm_surface_get_height(dstbuf);
374         info->dst_config.format = tbm_surface_get_format(dstbuf);
375
376         info->transform = transform;
377         info->sync = 0;
378         info->flags = 0;
379
380         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)",
381                                 info->src_config.size.h, info->src_config.size.v,
382                                 info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
383                                 FOURCC_STR(info->src_config.format),
384                                 info->dst_config.size.h, info->dst_config.size.v,
385                                 info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h,
386                                 FOURCC_STR(info->dst_config.format),
387                                 tdm_transform_str(transform), info->sync, info->flags);
388
389         return true;
390 }
391
392 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullObject)
393 {
394         const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
395         int count = TDM_UT_INVALID_VALUE;
396         if (tc_tdm_display_has_pp_capability(dpy))
397                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
398         else
399                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
400         ASSERT_EQ(formats, (const tbm_format *)TDM_UT_INVALID_VALUE);
401         ASSERT_EQ(count, TDM_UT_INVALID_VALUE);
402 }
403
404 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullOther)
405 {
406         if (tc_tdm_display_has_pp_capability(dpy)) {
407                 ASSERT_EQ(PreparePP(), true);
408                 ASSERT_EQ(tdm_display_get_pp_available_formats(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
409         }
410 }
411
412 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullObject)
413 {
414         int min_w = TDM_UT_INVALID_VALUE;
415         int min_h = TDM_UT_INVALID_VALUE;
416         int max_w = TDM_UT_INVALID_VALUE;
417         int max_h = TDM_UT_INVALID_VALUE;
418         int preferred_align = TDM_UT_INVALID_VALUE;
419         if (tc_tdm_display_has_pp_capability(dpy))
420                 ASSERT_EQ(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_INVALID_PARAMETER);
421         else
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         ASSERT_EQ(min_w, TDM_UT_INVALID_VALUE);
424         ASSERT_EQ(min_h, TDM_UT_INVALID_VALUE);
425         ASSERT_EQ(max_w, TDM_UT_INVALID_VALUE);
426         ASSERT_EQ(max_h, TDM_UT_INVALID_VALUE);
427         ASSERT_EQ(preferred_align, TDM_UT_INVALID_VALUE);
428 }
429
430 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullOther)
431 {
432         if (tc_tdm_display_has_pp_capability(dpy)) {
433                 ASSERT_EQ(PreparePP(), true);
434                 ASSERT_EQ(tdm_display_get_pp_available_size(dpy, NULL, NULL, NULL, NULL, NULL), TDM_ERROR_NONE);
435         }
436 }
437
438 TEST_P(TDMBackendPP, PPDestroy)
439 {
440         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
441
442         ASSERT_EQ(PreparePP(), true);
443         tdm_pp_destroy(pp);
444         pp = NULL;
445 }
446
447 TEST_P(TDMBackendPP, PPDestroyNullObject)
448 {
449         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
450
451         tdm_pp_destroy(NULL);
452 }
453
454 TEST_P(TDMBackendPP, PPSetInfo)
455 {
456         /* tested in PPNoScaleNoTransformNoCSC */
457 }
458
459 TEST_P(TDMBackendPP, PPSetInfoNullObject)
460 {
461         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
462
463         tdm_info_pp info;
464         memset(&info, 0, sizeof info);
465         ASSERT_EQ(tdm_pp_set_info(NULL, &info), TDM_ERROR_INVALID_PARAMETER);
466 }
467
468 TEST_P(TDMBackendPP, PPSetInfoNullOther)
469 {
470         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
471
472         ASSERT_EQ(PreparePP(), true);
473         ASSERT_EQ(tdm_pp_set_info(pp, NULL), TDM_ERROR_INVALID_PARAMETER);
474 }
475
476 static void
477 _tc_tdm_pp_done_cb(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
478 {
479         bool *done = (bool*)user_data;
480         if (done)
481                 *done = true;
482 }
483
484 TEST_P(TDMBackendPP, PPSetDoneHandler)
485 {
486         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
487
488         ASSERT_EQ(PreparePP(), true);
489         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, NULL), TDM_ERROR_NONE);
490 }
491
492 TEST_P(TDMBackendPP, PPSetDoneHandlerNullObject)
493 {
494         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
495
496         ASSERT_EQ(tdm_pp_set_done_handler(NULL, _tc_tdm_pp_done_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
497 }
498
499 TEST_P(TDMBackendPP, PPSetDoneHandlerNullOther)
500 {
501         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
502
503         ASSERT_EQ(PreparePP(), true);
504         ASSERT_EQ(tdm_pp_set_done_handler(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
505 }
506
507 TEST_P(TDMBackendPP, PPAttach)
508 {
509         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
510
511         ASSERT_EQ(PreparePP(), true);
512
513         for (int f = 0; f < format_count; f++) {
514                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
515                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
516                                                                  TDM_TRANSFORM_NORMAL), true);
517
518                 for (int b = 0; b < 3; b++)
519                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
520
521                 DestroyBuffers();
522         }
523 }
524
525 TEST_P(TDMBackendPP, PPAttachNullObject)
526 {
527         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
528
529         tbm_surface_h srcbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
530         tbm_surface_h dstbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
531
532         ASSERT_EQ(tdm_pp_attach(NULL, srcbuf, dstbuf), TDM_ERROR_INVALID_PARAMETER);
533 }
534
535 TEST_P(TDMBackendPP, PPAttachNullOther)
536 {
537         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
538
539         ASSERT_EQ(PreparePP(), true);
540
541         ASSERT_EQ(tdm_pp_attach(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
542 }
543
544 TEST_P(TDMBackendPP, PPCommit)
545 {
546         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
547
548         ASSERT_EQ(PreparePP(), true);
549
550         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
551 }
552
553 TEST_P(TDMBackendPP, PPCommitNullOBject)
554 {
555         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
556
557         ASSERT_EQ(tdm_pp_commit(NULL), TDM_ERROR_INVALID_PARAMETER);
558 }
559
560 TEST_P(TDMBackendPP, PPConvertUnderlay)
561 {
562         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
563
564         FindLayerUnderPrimary();
565
566         if (!tc_tdm_output_is_hwc_enable(output))
567                 ASSERT_NE(dst_layer, NULL);
568
569         for (int f = 0; f < dst_format_count; f++) {
570                 bool done;
571
572                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
573
574                 ASSERT_EQ(PreparePP(), true);
575
576                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
577                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
578                                                                  TDM_TRANSFORM_NORMAL), true);
579
580                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
581
582 retry:
583                 for (int b = 0; b < 3; b++) {
584                         done = false;
585
586                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
587                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
588
589                         while (!done)
590                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
591
592 #if 0
593                         char temp[256];
594                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
595                         DumpBuffer(b, temp);
596 #endif
597                         ShowBuffer(b);
598                 }
599
600                 TDM_UT_ASK_YNR("* Successed to convert to '%c%c%c%c' buffers and show them to a underlay layer? (output: %d, layer: %d)",
601                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
602
603                 DestroyPP();
604                 DestroyBuffers();
605         }
606         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
607                 free(pp_formats);
608                 pp_formats = NULL;
609         }
610 }
611
612 TEST_P(TDMBackendPP, PPConvertOverlay)
613 {
614         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
615
616         FindLayerOverPrimary();
617
618         if (!tc_tdm_output_is_hwc_enable(output))
619                 TDM_UT_SKIP_FLAG(dst_layer != NULL);
620
621         for (int f = 0; f < dst_format_count; f++) {
622                 bool done;
623
624                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
625
626                 ASSERT_EQ(PreparePP(), true);
627
628                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
629                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
630                                                                  TDM_TRANSFORM_NORMAL), true);
631
632                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
633
634 retry:
635                 for (int b = 0; b < 3; b++) {
636                         done = false;
637
638                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
639                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
640
641                         while (!done)
642                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
643
644 #if 0
645                         char temp[256];
646                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
647                         DumpBuffer(b, temp);
648 #endif
649                         ShowBuffer(b);
650                 }
651
652                 TDM_UT_ASK_YNR("* Successed to convert '%c%c%c%c' buffers and show them to a overlay layer? (output: %d, layer: %d)",
653                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
654
655                 DestroyPP();
656                 DestroyBuffers();
657         }
658         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
659                 free(pp_formats);
660                 pp_formats = NULL;
661         }
662 }
663
664 TEST_P(TDMBackendPP, PPConvertScale)
665 {
666         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
667
668         FindLayerUnderPrimary();
669
670         if (!tc_tdm_output_is_hwc_enable(output))
671                 ASSERT_NE(dst_layer, NULL);
672
673         for (int f = 0; f < dst_format_count; f++) {
674                 bool done;
675
676                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
677
678                 ASSERT_EQ(PreparePP(), true);
679
680                 ASSERT_EQ(PrepareBuffers(640, 480, dst_formats[f],
681                                                                  mode->hdisplay, mode->vdisplay, dst_formats[f],
682                                                                  TDM_TRANSFORM_NORMAL), true);
683
684                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
685
686 retry:
687                 for (int b = 0; b < 3; b++) {
688                         done = false;
689
690                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
691                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
692
693                         while (!done)
694                                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
695
696 #if 0
697                         char temp[256];
698                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
699                         DumpBuffer(b, temp);
700 #endif
701                         ShowBuffer(b);
702                 }
703
704                 TDM_UT_ASK_YNR("* Successed to scale '%c%c%c%c' buffers? (output: %d, layer: %d)",
705                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
706
707                 DestroyPP();
708                 DestroyBuffers();
709         }
710         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
711                 free(pp_formats);
712                 pp_formats = NULL;
713         }
714 }
715
716 TEST_P(TDMBackendPP, PPConvertTransform)
717 {
718         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
719
720         FindLayerUnderPrimary();
721
722         if (!tc_tdm_output_is_hwc_enable(output))
723                 ASSERT_NE(dst_layer, NULL);
724
725         for (int f = 0; f < dst_format_count; f++) {
726                 for (int t = (int)TDM_TRANSFORM_90; t <= (int)TDM_TRANSFORM_FLIPPED_270; t++) {
727                         bool done;
728
729                         TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
730
731                         ASSERT_EQ(PreparePP(), true);
732
733                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
734                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
735                                                                          (tdm_transform)t), true);
736
737                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
738
739 retry:
740                         for (int b = 0; b < 3; b++) {
741                                 done = false;
742
743                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
744                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
745
746                                 while (!done)
747                                         ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
748
749 #if 0
750                                 char temp[256];
751                                 snprintf(temp, sizeof temp, "f%d_b%d_t%d", f, b, t);
752                                 DumpBuffer(b, temp);
753 #endif
754                                 ShowBuffer(b);
755                         }
756
757                         TDM_UT_ASK_YNR("* Successed to rotate '%c%c%c%c' buffers? (transform: %s, output: %d, layer: %d)",
758                                                    FOURCC_STR(dst_formats[f]), tdm_transform_str(t), pipe, dst_layer_index);
759
760                         DestroyPP();
761                         DestroyBuffers();
762                 }
763         }
764         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
765                 free(pp_formats);
766                 pp_formats = NULL;
767         }
768 }
769
770 TEST_P(TDMBackendPP, PPConvertCSC)
771 {
772         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
773         TDM_UT_SKIP_FLAG(!(capabilities & TDM_PP_CAPABILITY_NO_CSC));
774
775         FindLayerUnderPrimary();
776
777         if (!tc_tdm_output_is_hwc_enable(output))
778                 ASSERT_NE(dst_layer, NULL);
779
780         for (int df = 0; df < dst_format_count; df++) {
781                 for (int sf = 0; sf < format_count; sf++) {
782                         bool done;
783
784                         TDM_UT_INFO("* testing for format(%c%c%c%c) -> format(%c%c%c%c)",
785                                                 FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]));
786
787                         ASSERT_EQ(PreparePP(), true);
788
789                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[sf],
790                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[df],
791                                                                          TDM_TRANSFORM_NORMAL), true);
792
793                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
794
795 retry:
796                         for (int b = 0; b < 3; b++) {
797                                 done = false;
798
799                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
800                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
801
802                                 while (!done)
803                                         ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
804
805 #if 0
806                                 char temp[256];
807                                 snprintf(temp, sizeof temp, "sf%d_df%d_b%d", sf, df, b);
808                                 DumpBuffer(b, temp);
809 #endif
810                                 ShowBuffer(b);
811                         }
812
813                         TDM_UT_ASK_YNR("* Successed to convert from '%c%c%c%c' to '%c%c%c%c'? (output: %d, layer: %d)",
814                                                    FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]), pipe, dst_layer_index);
815
816                         DestroyPP();
817                         DestroyBuffers();
818                 }
819         }
820         if (tc_tdm_output_is_hwc_enable(output) && pp_formats) {
821                 free(pp_formats);
822                 pp_formats = NULL;
823         }
824 }
825
826
827
828 static void
829 _tc_tdm_pp_done_cb2(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
830 {
831         int *done = (int*)user_data;
832         if (done)
833                 (*done)++;
834 }
835
836 /* some backend doens't implement correctly for attaching */
837 TEST_P(TDMBackendPP, DISABLED_PPAttachFewTimesInOneCommit)
838 {
839         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
840
841         ASSERT_EQ(PreparePP(), true);
842
843         int done = 0;
844         int f = 0;
845         char temp[256];
846         snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[f]));
847
848         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
849                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
850                                                          TDM_TRANSFORM_NORMAL), true);
851
852         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, &done), TDM_ERROR_NONE);
853         for (int b = 0; b < 3; b++)
854                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
855
856         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
857
858         while (done != 3)
859                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
860
861         for (int b = 0; b < 3; b++)
862                 ShowBuffer(b);
863
864         DestroyBuffers();
865 }
866
867 TEST_P(TDMBackendPP, PPDestroyWithoutCommit)
868 {
869         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
870
871         ASSERT_EQ(PreparePP(), true);
872
873         int f = 0;
874
875         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
876                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
877                                                          TDM_TRANSFORM_NORMAL), true);
878
879         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
880         for (int b = 0; b < 3; b++)
881                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
882
883         tdm_pp_destroy(pp);
884         pp = NULL;
885
886         DestroyBuffers();
887 }
888
889 TEST_P(TDMBackendPP, PPDestroyBeforeDone)
890 {
891         TDM_UT_SKIP_FLAG(tc_tdm_display_has_pp_capability(dpy));
892
893         ASSERT_EQ(PreparePP(), true);
894
895         int f = 0;
896
897         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
898                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
899                                                          TDM_TRANSFORM_NORMAL), true);
900
901         ASSERT_EQ(tdm_pp_set_done_handler(pp, _tc_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
902         for (int b = 0; b < 3; b++)
903                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
904
905         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
906
907         tdm_pp_destroy(pp);
908         pp = NULL;
909
910         DestroyBuffers();
911 }
912
913 #ifdef TDM_UT_TEST_WITH_PARAMS
914 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
915                                                 TDMBackendPP,
916                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
917 #else
918 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
919                                                 TDMBackendPP,
920                                                 Values(TDM_DEFAULT_MODULE));
921 #endif
922
923 /* LCOV_EXCL_END */