4e40e822fb50b1b6a4a8272b81495ab76d3b932a
[platform/core/uifw/libtdm.git] / utests / src / ut_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 "ut_tdm.h"
32
33 class TDMBackendPP : public TDMBackendDisplay
34 {
35 public:
36         tdm_pp *pp;
37         tdm_pp_capability capabilities;
38         const tbm_format *formats;
39         int format_count;
40         int min_w;
41         int min_h;
42         int max_w;
43         int max_h;
44         int preferred_align;
45
46         tbm_surface_h srcbuf[3];
47         tbm_surface_h dstbuf[3];
48
49         tdm_info_pp info;
50
51         tdm_output *output;
52         unsigned int pipe;
53         const tdm_output_mode *mode;
54
55         tdm_layer *dst_layer;
56         const tbm_format *dst_formats;
57         int dst_format_count;
58         int dst_zpos;
59         int dst_layer_index;
60
61         TDMBackendPP();
62         void SetUp(void);
63         void TearDown(void);
64
65         bool FindLayerUnderPrimary(void);
66         bool FindLayerOverPrimary(void);
67         bool PreparePP(void);
68         bool PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t);
69         void ShowBuffer(int b);
70         void HideLayer(void);
71         void DumpBuffer(int b, char *test);
72         void DestroyBuffers(void);
73         void DestroyPP(void);
74 };
75
76 TDMBackendPP::TDMBackendPP()
77 {
78         pp = NULL;
79         capabilities = (tdm_pp_capability)0;
80         formats = NULL;
81         format_count = 0;
82         min_w = min_h = max_w = max_h = preferred_align = -1;
83
84         for (int b = 0; b < 3; b++)
85                 srcbuf[b] = dstbuf[b] = NULL;
86         memset(&info, 0, sizeof info);
87
88         output = NULL;
89         pipe = 0;
90         mode = NULL;
91
92         dst_layer = NULL;
93         dst_formats = NULL;
94         dst_format_count = 0;
95         dst_zpos = 0;
96         dst_layer_index = 0;
97 }
98
99 void TDMBackendPP::SetUp(void)
100 {
101         TDMBackendDisplay::SetUp();
102
103         if (!ut_tdm_display_has_pp_capability(dpy))
104                 return;
105
106         ASSERT_EQ(tdm_display_get_pp_capabilities(dpy, &capabilities), TDM_ERROR_NONE);
107         ASSERT_GT(capabilities, 0);
108         ASSERT_EQ(tdm_display_get_pp_available_formats(dpy, &formats, &format_count), TDM_ERROR_NONE);
109         ASSERT_NE(formats, NULL);
110         ASSERT_GT(format_count, 0);
111         ASSERT_EQ(tdm_display_get_pp_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_NONE);
112         ASSERT_TRUE(min_w == -1 || min_w > 0);
113         ASSERT_TRUE(min_h == -1 || min_h > 0);
114         ASSERT_TRUE(max_w == -1 || max_w > 0);
115         ASSERT_TRUE(max_h == -1 || max_h > 0);
116         ASSERT_TRUE(preferred_align == -1 || preferred_align > 0);
117
118         for (int o = 0; o < output_count; o++) {
119                 if (!ut_tdm_output_is_connected(outputs[o]))
120                         continue;
121
122                 output = outputs[o];
123                 ASSERT_EQ(tdm_output_get_pipe(output, &pipe), TDM_ERROR_NONE);
124                 ASSERT_EQ(ut_tdm_output_prepare(dpy, output, false), true);
125                 ASSERT_EQ(tdm_output_get_mode(output, &mode), TDM_ERROR_NONE);
126                 ASSERT_NE(mode, NULL);
127                 break;
128         }
129 }
130
131 void TDMBackendPP::TearDown(void)
132 {
133         if (pp)
134                 tdm_pp_destroy(pp);
135
136         DestroyBuffers();
137
138         TDMBackendDisplay::TearDown();
139 }
140
141 bool TDMBackendPP::PreparePP(void)
142 {
143         tdm_error ret;
144         pp = tdm_display_create_pp(dpy, &ret);
145         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
146         TDM_UT_RETURN_FALSE_IF_FAIL(pp != NULL);
147         return true;
148 }
149
150 void TDMBackendPP::DestroyPP(void)
151 {
152         if (pp) {
153                 tdm_pp_destroy(pp);
154                 pp = NULL;
155         }
156 }
157
158 bool TDMBackendPP::PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t)
159 {
160         int src_flags = 0, dst_flags = 0;
161
162         sw = TDM_UT_SIZE_ALIGN(sw, preferred_align);
163         dw = TDM_UT_SIZE_ALIGN(dw, preferred_align);
164
165         if (capabilities & TDM_PP_CAPABILITY_SCANOUT)
166                 src_flags = dst_flags |= TBM_BO_SCANOUT;
167
168         if (dst_layer) {
169                 tdm_layer_capability capabilities;
170                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_capabilities(dst_layer, &capabilities) == TDM_ERROR_NONE);
171                 if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT)
172                         dst_flags |= TBM_BO_SCANOUT;
173         }
174
175         TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(sw, sh, sf, src_flags, true, 3, srcbuf) == true);
176         TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(dw, dh, df, dst_flags, false, 3, dstbuf) == true);
177         TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_pp_fill_info(srcbuf[0], dstbuf[0], t, &info) == true);
178         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_pp_set_info(pp, &info) == TDM_ERROR_NONE);
179
180         return true;
181 }
182
183 bool TDMBackendPP::FindLayerUnderPrimary(void)
184 {
185         tdm_error ret;
186         int count;
187         int primary_zpos, zpos;
188         tdm_layer *primary = ut_tdm_output_get_primary_layer(output);
189         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
190         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
191         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
192
193         for (int l = 0; l < count; l++) {
194                 unsigned int usable;
195                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
196                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
197                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_is_usable(temp, &usable) == TDM_ERROR_NONE);
198                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
199                 if (zpos < primary_zpos && usable) {
200                         dst_layer = temp;
201                         dst_zpos = zpos;
202                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
203                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
204                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
205                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
206                         break;
207                 }
208         }
209
210         return true;
211 }
212
213 bool TDMBackendPP::FindLayerOverPrimary(void)
214 {
215         tdm_error ret;
216         int count;
217         int primary_zpos, zpos;
218         tdm_layer *primary = ut_tdm_output_get_primary_layer(output);
219         TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL);
220         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
221         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE);
222
223         for (int l = 0; l < count; l++) {
224                 tdm_layer *temp = tdm_output_get_layer(output, l, &ret);
225                 TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL);
226                 TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE);
227                 if (zpos > primary_zpos) {
228                         dst_layer = temp;
229                         dst_zpos = zpos;
230                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE);
231                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL);
232                         TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0);
233                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE);
234                         break;
235                 }
236         }
237
238         return true;
239
240 }
241
242 static void
243 _ut_tdm_backend_pp_output_commit_cb(tdm_output *output, unsigned int sequence,
244                                                                         unsigned int tv_sec, unsigned int tv_usec,
245                                                                         void *user_data)
246 {
247         bool *done = (bool *)user_data;
248         if (done)
249                 *done = true;
250 }
251
252 void TDMBackendPP::ShowBuffer(int b)
253 {
254         ASSERT_NE(output, NULL);
255         ASSERT_NE(dst_layer, NULL);
256
257         bool done = false;
258
259         ASSERT_EQ(ut_tdm_layer_set_buffer(dst_layer, dstbuf[b]), true);
260         ASSERT_EQ(tdm_output_commit(output, 0, _ut_tdm_backend_pp_output_commit_cb, &done), TDM_ERROR_NONE);
261         while (!done) {
262                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
263         }
264 }
265
266 void TDMBackendPP::HideLayer(void)
267 {
268         ASSERT_NE(output, NULL);
269         ASSERT_NE(dst_layer, NULL);
270
271         tdm_layer_unset_buffer(dst_layer);
272         tdm_output_commit(output, 0, NULL, NULL);
273 }
274
275 void TDMBackendPP::DumpBuffer(int b, char *test)
276 {
277         char filename[256];
278         if (test)
279                 snprintf(filename, sizeof filename, "%s_%s_src_%d", typeid(*this).name(), test, b);
280         else
281                 snprintf(filename, sizeof filename, "%s_src_%d", typeid(*this).name(), b);
282         tdm_helper_dump_buffer_str(srcbuf[b], NULL, filename);
283         if (test)
284                 snprintf(filename, sizeof filename, "%s_%s_dst_%d", typeid(*this).name(), test, b);
285         else
286                 snprintf(filename, sizeof filename, "%s_dst_%d", typeid(*this).name(), b);
287         tdm_helper_dump_buffer_str(dstbuf[b], NULL, filename);
288 }
289
290 void TDMBackendPP::DestroyBuffers(void)
291 {
292         for (int b = 0; b < 3; b++) {
293                 if (srcbuf[b])
294                         tbm_surface_destroy(srcbuf[b]);
295                 if (dstbuf[b])
296                         tbm_surface_destroy(dstbuf[b]);
297                 srcbuf[b] = dstbuf[b] = NULL;
298         }
299 }
300
301 bool
302 ut_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info)
303 {
304         int bw, bh;
305
306         memset(info, 0, sizeof *info);
307
308         bw = bh = TDM_UT_INVALID_VALUE;
309         tdm_helper_get_buffer_full_size(srcbuf, &bw, &bh);
310         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
311         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(srcbuf));
312         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
313         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(srcbuf));
314         info->src_config.size.h = bw;
315         info->src_config.size.v = bh;
316         info->src_config.pos.x = 0;
317         info->src_config.pos.y = 0;
318         info->src_config.pos.w = tbm_surface_get_width(srcbuf);
319         info->src_config.pos.h = tbm_surface_get_height(srcbuf);
320         info->src_config.format = tbm_surface_get_format(srcbuf);
321
322         bw = bh = TDM_UT_INVALID_VALUE;
323         tdm_helper_get_buffer_full_size(dstbuf, &bw, &bh);
324         TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
325         TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(dstbuf));
326         TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
327         TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(dstbuf));
328         info->dst_config.size.h = bw;
329         info->dst_config.size.v = bh;
330         info->dst_config.pos.x = 0;
331         info->dst_config.pos.y = 0;
332         info->dst_config.pos.w = tbm_surface_get_width(dstbuf);
333         info->dst_config.pos.h = tbm_surface_get_height(dstbuf);
334         info->dst_config.format = tbm_surface_get_format(dstbuf);
335
336         info->transform = transform;
337         info->sync = 0;
338         info->flags = 0;
339
340         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)",
341                                 info->src_config.size.h, info->src_config.size.v,
342                                 info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
343                                 FOURCC_STR(info->src_config.format),
344                                 info->dst_config.size.h, info->dst_config.size.v,
345                                 info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h,
346                                 FOURCC_STR(info->dst_config.format),
347                                 tdm_transform_str(transform), info->sync, info->flags);
348
349         return true;
350 }
351
352 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullObject)
353 {
354         const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
355         int count = TDM_UT_INVALID_VALUE;
356         if (ut_tdm_display_has_pp_capability(dpy))
357                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
358         else
359                 ASSERT_EQ(tdm_display_get_pp_available_formats(NULL, &formats, &count), TDM_ERROR_INVALID_PARAMETER);
360         ASSERT_EQ(formats, (const tbm_format *)TDM_UT_INVALID_VALUE);
361         ASSERT_EQ(count, TDM_UT_INVALID_VALUE);
362 }
363
364 TEST_P(TDMBackendPP, PPDispalyGetAvaiableFormatsNullOther)
365 {
366         if (ut_tdm_display_has_pp_capability(dpy)) {
367                 ASSERT_EQ(PreparePP(), true);
368                 ASSERT_EQ(tdm_display_get_pp_available_formats(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
369         }
370 }
371
372 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullObject)
373 {
374         int min_w = TDM_UT_INVALID_VALUE;
375         int min_h = TDM_UT_INVALID_VALUE;
376         int max_w = TDM_UT_INVALID_VALUE;
377         int max_h = TDM_UT_INVALID_VALUE;
378         int preferred_align = TDM_UT_INVALID_VALUE;
379         if (ut_tdm_display_has_pp_capability(dpy))
380                 ASSERT_EQ(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_INVALID_PARAMETER);
381         else
382                 ASSERT_EQ(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_INVALID_PARAMETER);
383         ASSERT_EQ(min_w, TDM_UT_INVALID_VALUE);
384         ASSERT_EQ(min_h, TDM_UT_INVALID_VALUE);
385         ASSERT_EQ(max_w, TDM_UT_INVALID_VALUE);
386         ASSERT_EQ(max_h, TDM_UT_INVALID_VALUE);
387         ASSERT_EQ(preferred_align, TDM_UT_INVALID_VALUE);
388 }
389
390 TEST_P(TDMBackendPP, PPDispalyGetAvaiableSizeNullOther)
391 {
392         if (ut_tdm_display_has_pp_capability(dpy)) {
393                 ASSERT_EQ(PreparePP(), true);
394                 ASSERT_EQ(tdm_display_get_pp_available_size(dpy, NULL, NULL, NULL, NULL, NULL), TDM_ERROR_NONE);
395         }
396 }
397
398 TEST_P(TDMBackendPP, PPDestroy)
399 {
400         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
401
402         ASSERT_EQ(PreparePP(), true);
403         tdm_pp_destroy(pp);
404         pp = NULL;
405 }
406
407 TEST_P(TDMBackendPP, PPDestroyNullObject)
408 {
409         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
410
411         tdm_pp_destroy(NULL);
412 }
413
414 TEST_P(TDMBackendPP, PPSetInfo)
415 {
416         /* tested in PPNoScaleNoTransformNoCSC */
417 }
418
419 TEST_P(TDMBackendPP, PPSetInfoNullObject)
420 {
421         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
422
423         tdm_info_pp info;
424         memset(&info, 0, sizeof info);
425         ASSERT_EQ(tdm_pp_set_info(NULL, &info), TDM_ERROR_INVALID_PARAMETER);
426 }
427
428 TEST_P(TDMBackendPP, PPSetInfoNullOther)
429 {
430         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
431
432         ASSERT_EQ(PreparePP(), true);
433         ASSERT_EQ(tdm_pp_set_info(pp, NULL), TDM_ERROR_INVALID_PARAMETER);
434 }
435
436 static void
437 _ut_tdm_pp_done_cb(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
438 {
439         bool *done = (bool*)user_data;
440         if (done)
441                 *done = true;
442 }
443
444 TEST_P(TDMBackendPP, PPSetDoneHandler)
445 {
446         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
447
448         ASSERT_EQ(PreparePP(), true);
449         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, NULL), TDM_ERROR_NONE);
450 }
451
452 TEST_P(TDMBackendPP, PPSetDoneHandlerNullObject)
453 {
454         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
455
456         ASSERT_EQ(tdm_pp_set_done_handler(NULL, _ut_tdm_pp_done_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
457 }
458
459 TEST_P(TDMBackendPP, PPSetDoneHandlerNullOther)
460 {
461         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
462
463         ASSERT_EQ(PreparePP(), true);
464         ASSERT_EQ(tdm_pp_set_done_handler(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
465 }
466
467 TEST_P(TDMBackendPP, PPAttach)
468 {
469         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
470
471         ASSERT_EQ(PreparePP(), true);
472
473         for (int f = 0; f < format_count; f++) {
474                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
475                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
476                                                                  TDM_TRANSFORM_NORMAL), true);
477
478                 for (int b = 0; b < 3; b++)
479                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
480
481                 DestroyBuffers();
482         }
483 }
484
485 TEST_P(TDMBackendPP, PPAttachNullObject)
486 {
487         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
488
489         tbm_surface_h srcbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
490         tbm_surface_h dstbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
491
492         ASSERT_EQ(tdm_pp_attach(NULL, srcbuf, dstbuf), TDM_ERROR_INVALID_PARAMETER);
493 }
494
495 TEST_P(TDMBackendPP, PPAttachNullOther)
496 {
497         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
498
499         ASSERT_EQ(PreparePP(), true);
500
501         ASSERT_EQ(tdm_pp_attach(pp, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
502 }
503
504 TEST_P(TDMBackendPP, PPCommit)
505 {
506         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
507
508         ASSERT_EQ(PreparePP(), true);
509
510         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
511 }
512
513 TEST_P(TDMBackendPP, PPCommitNullOBject)
514 {
515         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
516
517         ASSERT_EQ(tdm_pp_commit(NULL), TDM_ERROR_INVALID_PARAMETER);
518 }
519
520 TEST_P(TDMBackendPP, PPConvertUnderlay)
521 {
522         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
523
524         FindLayerUnderPrimary();
525
526         ASSERT_NE(dst_layer, NULL);
527
528         for (int f = 0; f < dst_format_count; f++) {
529                 bool done;
530
531                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
532
533                 ASSERT_EQ(PreparePP(), true);
534
535                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
536                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
537                                                                  TDM_TRANSFORM_NORMAL), true);
538
539                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
540
541 retry:
542                 for (int b = 0; b < 3; b++) {
543                         done = false;
544
545                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
546                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
547
548                         while (!done)
549                                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
550
551 #if 0
552                         char temp[256];
553                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
554                         DumpBuffer(b, temp);
555 #endif
556                         ShowBuffer(b);
557                 }
558
559                 TDM_UT_ASK_YNR("* Successed to convert to '%c%c%c%c' buffers and show them to a underlay layer? (output: %d, layer: %d)",
560                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
561
562                 DestroyPP();
563                 DestroyBuffers();
564         }
565 }
566
567 TEST_P(TDMBackendPP, PPConvertOverlay)
568 {
569         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
570
571         FindLayerOverPrimary();
572
573         TDM_UT_SKIP_FLAG(dst_layer != NULL);
574
575         for (int f = 0; f < dst_format_count; f++) {
576                 bool done;
577
578                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
579
580                 ASSERT_EQ(PreparePP(), true);
581
582                 ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
583                                                                  TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
584                                                                  TDM_TRANSFORM_NORMAL), true);
585
586                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
587
588 retry:
589                 for (int b = 0; b < 3; b++) {
590                         done = false;
591
592                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
593                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
594
595                         while (!done)
596                                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
597
598 #if 0
599                         char temp[256];
600                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
601                         DumpBuffer(b, temp);
602 #endif
603                         ShowBuffer(b);
604                 }
605
606                 TDM_UT_ASK_YNR("* Successed to convert '%c%c%c%c' buffers and show them to a overlay layer? (output: %d, layer: %d)",
607                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
608
609                 DestroyPP();
610                 DestroyBuffers();
611         }
612 }
613
614 TEST_P(TDMBackendPP, PPConvertScale)
615 {
616         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
617
618         FindLayerUnderPrimary();
619
620         ASSERT_NE(dst_layer, NULL);
621
622         for (int f = 0; f < dst_format_count; f++) {
623                 bool done;
624
625                 TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
626
627                 ASSERT_EQ(PreparePP(), true);
628
629                 ASSERT_EQ(PrepareBuffers(mode->hdisplay / 2, mode->vdisplay / 4, dst_formats[f],
630                                                                  mode->hdisplay, mode->vdisplay / 2, dst_formats[f],
631                                                                  TDM_TRANSFORM_NORMAL), true);
632
633                 ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
634
635 retry:
636                 for (int b = 0; b < 3; b++) {
637                         done = false;
638
639                         ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
640                         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
641
642                         while (!done)
643                                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
644
645 #if 0
646                         char temp[256];
647                         snprintf(temp, sizeof temp, "f%d_b%d", f, b);
648                         DumpBuffer(b, temp);
649 #endif
650                         ShowBuffer(b);
651                 }
652
653                 TDM_UT_ASK_YNR("* Successed to scale '%c%c%c%c' buffers? (output: %d, layer: %d)",
654                                            FOURCC_STR(dst_formats[f]), pipe, dst_layer_index);
655
656                 DestroyPP();
657                 DestroyBuffers();
658         }
659 }
660
661 TEST_P(TDMBackendPP, PPConvertTransform)
662 {
663         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
664
665         FindLayerUnderPrimary();
666
667         ASSERT_NE(dst_layer, NULL);
668
669         for (int f = 0; f < dst_format_count; f++) {
670                 for (int t = (int)TDM_TRANSFORM_90; t <= (int)TDM_TRANSFORM_FLIPPED_270; t++) {
671                         bool done;
672
673                         TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f]));
674
675                         ASSERT_EQ(PreparePP(), true);
676
677                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
678                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f],
679                                                                          (tdm_transform)t), true);
680
681                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
682
683 retry:
684                         for (int b = 0; b < 3; b++) {
685                                 done = false;
686
687                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
688                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
689
690                                 while (!done)
691                                         ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
692
693 #if 0
694                                 char temp[256];
695                                 snprintf(temp, sizeof temp, "f%d_b%d_t%d", f, b, t);
696                                 DumpBuffer(b, temp);
697 #endif
698                                 ShowBuffer(b);
699                         }
700
701                         TDM_UT_ASK_YNR("* Successed to rotate '%c%c%c%c' buffers? (transform: %s, output: %d, layer: %d)",
702                                                    FOURCC_STR(dst_formats[f]), tdm_transform_str(t), pipe, dst_layer_index);
703
704                         DestroyPP();
705                         DestroyBuffers();
706                 }
707         }
708 }
709
710 TEST_P(TDMBackendPP, PPConvertCSC)
711 {
712         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
713         TDM_UT_SKIP_FLAG(!(capabilities & TDM_PP_CAPABILITY_NO_CSC));
714
715         FindLayerUnderPrimary();
716
717         ASSERT_NE(dst_layer, NULL);
718
719         for (int df = 0; df < dst_format_count; df++) {
720                 for (int sf = 0; sf < format_count; sf++) {
721                         bool done;
722
723                         TDM_UT_INFO("* testing for format(%c%c%c%c) -> format(%c%c%c%c)",
724                                                 FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]));
725
726                         ASSERT_EQ(PreparePP(), true);
727
728                         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[sf],
729                                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[df],
730                                                                          TDM_TRANSFORM_NORMAL), true);
731
732                         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE);
733
734 retry:
735                         for (int b = 0; b < 3; b++) {
736                                 done = false;
737
738                                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
739                                 ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
740
741                                 while (!done)
742                                         ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
743
744 #if 0
745                                 char temp[256];
746                                 snprintf(temp, sizeof temp, "sf%d_df%d_b%d", sf, df, b);
747                                 DumpBuffer(b, temp);
748 #endif
749                                 ShowBuffer(b);
750                         }
751
752                         TDM_UT_ASK_YNR("* Successed to convert from '%c%c%c%c' to '%c%c%c%c'? (output: %d, layer: %d)",
753                                                    FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]), pipe, dst_layer_index);
754
755                         DestroyPP();
756                         DestroyBuffers();
757                 }
758         }
759 }
760
761
762
763 static void
764 _ut_tdm_pp_done_cb2(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
765 {
766         int *done = (int*)user_data;
767         if (done)
768                 (*done)++;
769 }
770
771 /* some backend doens't implement correctly for attaching */
772 TEST_P(TDMBackendPP, DISABLED_PPAttachFewTimesInOneCommit)
773 {
774         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
775
776         ASSERT_EQ(PreparePP(), true);
777
778         int done = 0;
779         int f = 0;
780         char temp[256];
781         snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[f]));
782
783         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
784                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
785                                                          TDM_TRANSFORM_NORMAL), true);
786
787         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, &done), TDM_ERROR_NONE);
788         for (int b = 0; b < 3; b++)
789                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
790
791         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
792
793         while (done != 3)
794                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
795
796         for (int b = 0; b < 3; b++)
797                 ShowBuffer(b);
798
799         DestroyBuffers();
800 }
801
802 TEST_P(TDMBackendPP, PPDestroyWithoutCommit)
803 {
804         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
805
806         ASSERT_EQ(PreparePP(), true);
807
808         int f = 0;
809
810         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
811                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
812                                                          TDM_TRANSFORM_NORMAL), true);
813
814         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
815         for (int b = 0; b < 3; b++)
816                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
817
818         tdm_pp_destroy(pp);
819         pp = NULL;
820
821         DestroyBuffers();
822 }
823
824 TEST_P(TDMBackendPP, PPDestroyBeforeDone)
825 {
826         TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy));
827
828         ASSERT_EQ(PreparePP(), true);
829
830         int f = 0;
831
832         ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
833                                                          TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
834                                                          TDM_TRANSFORM_NORMAL), true);
835
836         ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, NULL), TDM_ERROR_NONE);
837         for (int b = 0; b < 3; b++)
838                 ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE);
839
840         ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE);
841
842         tdm_pp_destroy(pp);
843         pp = NULL;
844
845         DestroyBuffers();
846 }
847
848 #ifdef TDM_UT_TEST_WITH_PARAMS
849 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
850                                                 TDMBackendPP,
851                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
852 #else
853 INSTANTIATE_TEST_CASE_P(TDMBackendPPParams,
854                                                 TDMBackendPP,
855                                                 Values(TDM_DEFAULT_MODULE));
856 #endif