haltest: support hwc mode
[platform/core/uifw/libtdm.git] / haltests / src / tc_tdm_hwc.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 #define HWC_WIN_NUM 5
36
37 class TDMHwc : public TDMOutput
38 {
39 public:
40         TDMHwc();
41         void SetUp(void);
42         void TearDown(void);
43
44         tdm_error error;
45 };
46
47 TDMHwc::TDMHwc()
48 {
49         error = TDM_ERROR_NONE;
50 }
51
52 void TDMHwc::SetUp(void)
53 {
54         TDMOutput::SetUp();
55 }
56
57 void TDMHwc::TearDown(void)
58 {
59         TDMOutput::TearDown();
60 }
61
62 static void
63 _tc_tdm_hwc_commit_cb(tdm_hwc *hwc, unsigned int sequence,
64                                                 unsigned int tv_sec, unsigned int tv_usec,
65                                                 void *user_data)
66 {
67         bool *done = (bool*)user_data;
68         if (done)
69                 *done = true;
70 }
71
72 /* tdm_hwc_window * tdm_hwc_create_window(tdm_output *output, tdm_error *error); */
73 TEST_P(TDMHwc, CreateWindowFailNull)
74 {
75         TDM_UT_SKIP_FLAG(has_outputs);
76
77         ASSERT_EQ(NULL, tdm_hwc_create_window(NULL, &error));
78         ASSERT_NE(TDM_ERROR_NONE, error);
79 }
80
81 TEST_P(TDMHwc, CreateWindowSuccessful)
82 {
83         TDM_UT_SKIP_FLAG(has_outputs);
84
85         tdm_hwc *hwc = NULL;
86         tdm_error error;
87         tdm_hwc_window * hw = NULL;
88
89         for (int o = 0; o < output_count; o++) {
90                 hwc = tdm_output_get_hwc(outputs[o], &error);
91                 if (hwc) {
92                         hw = tdm_hwc_create_window(hwc, &error);
93                         ASSERT_EQ(TDM_ERROR_NONE, error);
94                         tdm_hwc_window_destroy(hw);
95                 } else {
96                         ASSERT_EQ(NULL, tdm_hwc_create_window(hwc, &error));
97                         ASSERT_NE(TDM_ERROR_NONE, error);
98                 }
99         }
100 }
101
102 /* tdm_hwc_get_supported_formats() */
103 TEST_P(TDMHwc, GetSupportedFormatsFailNull)
104 {
105         TDM_UT_SKIP_FLAG(has_outputs);
106
107         tdm_error error;
108
109         error = tdm_hwc_get_video_supported_formats(NULL, NULL, NULL);
110         ASSERT_NE(TDM_ERROR_NONE, error);
111 }
112
113 TEST_P(TDMHwc, GetSupportedFormatsSuccessful)
114 {
115         TDM_UT_SKIP_FLAG(has_outputs);
116
117         tdm_hwc *hwc = NULL;
118         tdm_error error = TDM_ERROR_NONE;
119         const tbm_format *formats;
120         int count;
121
122         for (int o = 0; o < output_count; o++) {
123                 hwc = tdm_output_get_hwc(outputs[o], &error);
124                 if (hwc) {
125                         error = tdm_hwc_get_video_supported_formats(hwc, &formats, &count);
126                         if (error != TDM_ERROR_NOT_IMPLEMENTED) {
127                                 ASSERT_EQ(TDM_ERROR_NONE, error);
128                                 if (count > 0)
129                                         ASSERT_NE(NULL, formats);
130                         }
131                 } else {
132                         error = tdm_hwc_get_video_supported_formats(hwc, &formats, &count);
133                         ASSERT_NE(TDM_ERROR_NONE, error);
134                 }
135         }
136 }
137
138 /* tdm_hwc_get_available_properties() */
139 TEST_P(TDMHwc, GetAvailablePropertiesFailNullWin)
140 {
141         TDM_UT_SKIP_FLAG(has_outputs);
142
143         tdm_hwc *hwc = NULL;
144         tdm_error error = TDM_ERROR_NONE;
145         const tdm_prop *props;
146         int count;
147
148         for (int o = 0; o < output_count; o++) {
149                 hwc = tdm_output_get_hwc(outputs[o], &error);
150                 if (hwc) {
151                         error = tdm_hwc_get_available_properties(NULL, &props, &count);
152                         ASSERT_NE(TDM_ERROR_NONE, error);
153
154                         error = tdm_hwc_get_available_properties(hwc, NULL, &count);
155                         ASSERT_NE(TDM_ERROR_NONE, error);
156
157                         error = tdm_hwc_get_available_properties(hwc, &props, NULL);
158                         ASSERT_NE(TDM_ERROR_NONE, error);
159                 } else {
160                         error = tdm_hwc_get_available_properties(hwc, &props, &count);
161                         ASSERT_NE(TDM_ERROR_NONE, error);
162                 }
163         }
164 }
165
166 TEST_P(TDMHwc, GetAvailablePropertiesSuccess)
167 {
168         TDM_UT_SKIP_FLAG(has_outputs);
169
170         tdm_hwc *hwc = NULL;
171         tdm_error error = TDM_ERROR_NONE;
172         const tdm_prop *props;
173         int count;
174
175         for (int o = 0; o < output_count; o++) {
176                 hwc = tdm_output_get_hwc(outputs[o], &error);
177                 if (hwc) {
178                         error = tdm_hwc_get_available_properties(hwc, &props, &count);
179                         ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error);
180                 } else {
181                         error = tdm_hwc_get_available_properties(hwc, &props, &count);
182                         ASSERT_NE(TDM_ERROR_NONE, error);
183                 }
184         }
185
186 }
187
188 /* tdm_hwc_get_client_target_buffer_queue() */
189 TEST_P(TDMHwc, GetClientTargetBufferQueueFailNullObject)
190 {
191         TDM_UT_SKIP_FLAG(has_outputs);
192
193         tdm_hwc *hwc = NULL;
194         tdm_error error = TDM_ERROR_NONE;
195         tbm_surface_queue_h queue = NULL;
196
197         for (int o = 0; o < output_count; o++) {
198                 hwc = tdm_output_get_hwc(outputs[o], &error);
199                 if (hwc) {
200                         queue = tdm_hwc_get_client_target_buffer_queue(NULL, &error);
201                         ASSERT_NE(TDM_ERROR_NONE, error);
202                         ASSERT_EQ(NULL, queue);
203
204                         queue = tdm_hwc_get_client_target_buffer_queue(NULL, NULL);
205                         ASSERT_EQ(NULL, queue);
206                 } else {
207                         ASSERT_EQ(NULL, queue);
208                 }
209         }
210 }
211
212 TEST_P(TDMHwc, GetClientTargetBufferQueueFailNoHwc)
213 {
214         TDM_UT_SKIP_FLAG(has_outputs);
215
216         tdm_hwc *hwc = NULL;
217         tdm_error error = TDM_ERROR_NONE;
218         tbm_surface_queue_h queue = NULL;
219
220         for (int o = 0; o < output_count; o++) {
221                 hwc = tdm_output_get_hwc(outputs[o], &error);
222                 if (hwc) {
223                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, &error);
224                         ASSERT_NE(TDM_ERROR_NONE, error);
225                         ASSERT_EQ(NULL, queue);
226                 } else {
227                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, &error);
228                         ASSERT_NE(TDM_ERROR_NONE, error);
229                         ASSERT_EQ(NULL, queue);
230                 }
231         }
232 }
233
234 TEST_P(TDMHwc, GetClientTargetBufferQueueSuccessful)
235 {
236         TDM_UT_SKIP_FLAG(has_outputs);
237
238         tdm_hwc *hwc = NULL;
239         tdm_error error = TDM_ERROR_NONE;
240         tbm_surface_queue_h queue = NULL;
241
242         for (int o = 0; o < output_count; o++) {
243                 ASSERT_EQ(tc_tdm_output_prepare(dpy, outputs[o], true), true);
244                 hwc = tdm_output_get_hwc(outputs[o], &error);
245                 if (hwc) {
246                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, &error);
247                         tbm_surface_queue_destroy(queue);
248                         ASSERT_EQ(TDM_ERROR_NONE, error);
249                         ASSERT_NE(NULL, queue);
250
251                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, NULL);
252                         tbm_surface_queue_destroy(queue);
253                         ASSERT_EQ(TDM_ERROR_NONE, error);
254                         ASSERT_NE(NULL, queue);
255                 } else {
256                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, &error);
257                         ASSERT_NE(TDM_ERROR_NONE, error);
258                         ASSERT_EQ(NULL, queue);
259
260                         queue = tdm_hwc_get_client_target_buffer_queue(hwc, NULL);
261                         ASSERT_NE(TDM_ERROR_NONE, error);
262                         ASSERT_EQ(NULL, queue);
263                 }
264         }
265 }
266
267 /* tdm_hwc_set_client_target_buffer() */
268 TEST_P(TDMHwc, SetClientTargetBufferFailNullOutput)
269 {
270         TDM_UT_SKIP_FLAG(has_outputs);
271
272         tdm_region damage = {.num_rects = 0, .rects = NULL};
273         tbm_surface_h target_buff = NULL;
274
275         target_buff = tbm_surface_internal_create_with_flags(720, 1024,
276                                                                         TBM_FORMAT_ARGB8888, TBM_BO_DEFAULT);
277         ASSERT_NE(NULL, target_buff);
278
279         error = tdm_hwc_set_client_target_buffer(NULL, target_buff, damage);
280         tbm_surface_internal_destroy(target_buff);
281         ASSERT_NE(TDM_ERROR_NONE, error);
282 }
283
284 TEST_P(TDMHwc, SetClientTargetBufferSuccessfulSetBuff)
285 {
286         TDM_UT_SKIP_FLAG(has_outputs);
287
288         tdm_hwc *hwc = NULL;
289         tdm_error error = TDM_ERROR_NONE;
290         tdm_region damage = {.num_rects = 0, .rects = NULL};
291         const tdm_output_mode *mode = NULL;
292         tbm_surface_h target_buff = NULL;
293
294         for (int o = 0; o < output_count; o++) {
295                 ASSERT_EQ(tc_tdm_output_prepare(dpy, outputs[o], true), true);
296                 hwc = tdm_output_get_hwc(outputs[o], &error);
297                 if (hwc) {
298                         ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE);
299                         ASSERT_NE(mode, NULL);
300                         target_buff = tbm_surface_internal_create_with_flags(mode->hdisplay, mode->vdisplay,
301                                                                         TBM_FORMAT_ARGB8888, TBM_BO_DEFAULT);
302                         ASSERT_NE(NULL, target_buff);
303
304                         error = tdm_hwc_set_client_target_buffer(hwc, target_buff, damage);
305                         tbm_surface_internal_destroy(target_buff);
306                         ASSERT_EQ(TDM_ERROR_NONE, error);
307                 } else {
308                         error = tdm_hwc_set_client_target_buffer(hwc, target_buff, damage);
309                         ASSERT_NE(TDM_ERROR_NONE, error);
310                 }
311         }
312 }
313
314 TEST_P(TDMHwc, SetClientTargetBufferSuccessfulResetBuff)
315 {
316         TDM_UT_SKIP_FLAG(has_outputs);
317
318         tdm_hwc *hwc = NULL;
319         tdm_error error = TDM_ERROR_NONE;
320         tdm_region damage = {.num_rects = 0, .rects = NULL};
321
322         for (int o = 0; o < output_count; o++) {
323                 ASSERT_EQ(tc_tdm_output_prepare(dpy, outputs[o], true), true);
324                 hwc = tdm_output_get_hwc(outputs[o], &error);
325                 if (hwc) {
326                         error = tdm_hwc_set_client_target_buffer(hwc, NULL, damage);
327                         ASSERT_EQ(TDM_ERROR_NONE, error);
328                 } else {
329                         error = tdm_hwc_set_client_target_buffer(hwc, NULL, damage);
330                         ASSERT_NE(TDM_ERROR_NONE, error);
331                 }
332         }
333 }
334
335 /* tdm_hwc_validate() */
336 TEST_P(TDMHwc, ValidateFailNull)
337 {
338         TDM_UT_SKIP_FLAG(has_outputs);
339
340         tdm_hwc *hwc = NULL;
341         tdm_error error = TDM_ERROR_NONE;
342         uint32_t num_types;
343
344         error = tdm_hwc_validate(NULL, NULL, 0, &num_types);
345         ASSERT_NE(TDM_ERROR_NONE, error);
346
347         for (int o = 0; o < output_count; o++) {
348                 hwc = tdm_output_get_hwc(outputs[o], &error);
349                 if (hwc) {
350                         error = tdm_hwc_validate(hwc, NULL, 0, NULL);
351                         ASSERT_NE(TDM_ERROR_NONE, error);
352                 } else {
353                         error = tdm_hwc_validate(hwc, NULL, 0, NULL);
354                         ASSERT_NE(TDM_ERROR_NONE, error);
355                 }
356         }
357 }
358
359 /* tdm_hwc_get_changed_composition_types() */
360 TEST_P(TDMHwc, GetChangedCompositionTypesFailNull)
361 {
362         TDM_UT_SKIP_FLAG(has_outputs);
363
364         tdm_hwc *hwc = NULL;
365         tdm_error error = TDM_ERROR_NONE;
366         uint32_t num_elements;
367
368         error = tdm_hwc_get_changed_composition_types(NULL, &num_elements, NULL, NULL);
369         ASSERT_NE(TDM_ERROR_NONE, error);
370
371         for (int o = 0; o < output_count; o++) {
372                 hwc = tdm_output_get_hwc(outputs[o], &error);
373                 if (hwc) {
374                         error = tdm_hwc_get_changed_composition_types(hwc, NULL, NULL, NULL);
375                         ASSERT_NE(TDM_ERROR_NONE, error);
376                 } else {
377                         error = tdm_hwc_get_changed_composition_types(hwc, NULL, NULL, NULL);
378                         ASSERT_NE(TDM_ERROR_NONE, error);
379                 }
380         }
381 }
382
383 /* tdm_error tdm_hwc_accept_validation() */
384 TEST_P(TDMHwc, AcceptChangesFailNull)
385 {
386         TDM_UT_SKIP_FLAG(has_outputs);
387
388         error = tdm_hwc_accept_validation(NULL);
389         ASSERT_NE(TDM_ERROR_NONE, error);
390 }
391
392 TEST_P(TDMHwc, AcceptChangesFailNoHwc)
393 {
394         tdm_hwc *hwc = NULL;
395         tdm_error error = TDM_ERROR_NONE;
396
397         for (int o = 0; o < output_count; o++) {
398                 hwc = tdm_output_get_hwc(outputs[o], &error);
399                 if (hwc) {
400                         error = tdm_hwc_accept_validation(hwc);
401                         ASSERT_EQ(TDM_ERROR_NONE, error);
402                 } else {
403                         error = tdm_hwc_accept_validation(hwc);
404                         ASSERT_NE(TDM_ERROR_NONE, error);
405                 }
406         }
407 }
408
409 TEST_P(TDMHwc, AcceptChangesSuccessful)
410 {
411         TDM_UT_SKIP_FLAG(has_outputs);
412
413         tdm_hwc *hwc = NULL;
414         tdm_error error = TDM_ERROR_NONE;
415         tdm_hwc_window *hwc_wnds[HWC_WIN_NUM];
416         tdm_hwc_window **changed_hwc_window = NULL;
417         tdm_hwc_window_composition *composition_types = NULL;
418         uint32_t num_types;
419         uint32_t get_num = 0;
420
421         for (int o = 0; o < output_count; o++) {
422                 ASSERT_EQ(tc_tdm_output_prepare(dpy, outputs[o], true), true);
423                 hwc = tdm_output_get_hwc(outputs[o], &error);
424                 if (hwc) {
425                         for (int w = 0; w < HWC_WIN_NUM; w++) {
426                                 hwc_wnds[w] = tdm_hwc_create_window(hwc, &error);
427                                 ASSERT_EQ(TDM_ERROR_NONE, error);
428                                 error = tdm_hwc_window_set_composition_type(hwc_wnds[w], TDM_HWC_WIN_COMPOSITION_DEVICE);
429                                 ASSERT_EQ(TDM_ERROR_NONE, error);
430                         }
431
432                         error = tdm_hwc_validate(hwc, hwc_wnds, HWC_WIN_NUM, &num_types);
433                         ASSERT_EQ(TDM_ERROR_NONE, error);
434
435                         if (num_types > 0) {
436                                 changed_hwc_window = (tdm_hwc_window **)calloc(num_types, sizeof(tdm_hwc_window *));
437                                 composition_types = (tdm_hwc_window_composition *)calloc(num_types, sizeof(tdm_hwc_window_composition));
438
439                                 get_num = num_types;
440                                 error = tdm_hwc_get_changed_composition_types(hwc, &get_num, changed_hwc_window, composition_types);
441                                 ASSERT_EQ(TDM_ERROR_NONE, error);
442                                 ASSERT_EQ(get_num, num_types);
443
444                                 error = tdm_hwc_accept_validation(hwc);
445                                 ASSERT_EQ(TDM_ERROR_NONE, error);
446
447                                 free(composition_types);
448                                 free(changed_hwc_window);
449                         }
450
451                         for (int w = 0; w < HWC_WIN_NUM; w++)
452                                 tdm_hwc_window_destroy(hwc_wnds[w]);
453
454                                 ASSERT_EQ(TDM_ERROR_NONE, error);
455                         }
456         }
457 }
458
459 /* tdm_error tdm_hwc_commit() */
460 TEST_P(TDMHwc, CommitFailNull)
461 {
462         TDM_UT_SKIP_FLAG(has_outputs);
463
464         error = tdm_hwc_commit(NULL, 1, NULL, NULL);
465         ASSERT_NE(TDM_ERROR_NONE, error);
466 }
467
468 TEST_P(TDMHwc, CommitSuccessful)
469 {
470         TDM_UT_SKIP_FLAG(has_outputs);
471
472         tdm_hwc *hwc = NULL;
473         tdm_error error = TDM_ERROR_NONE;
474         tdm_hwc_window *hwc_wnds[HWC_WIN_NUM];
475         tdm_hwc_window **changed_hwc_window = NULL;
476         tdm_hwc_window_composition *composition_types = NULL;
477         uint32_t num_types;
478         uint32_t get_num = 0;
479
480         for (int o = 0; o < output_count; o++) {
481                 ASSERT_EQ(tc_tdm_output_prepare(dpy, outputs[o], true), true);
482                 hwc = tdm_output_get_hwc(outputs[o], &error);
483                 if (hwc) {
484                         for (int w = 0; w < HWC_WIN_NUM; w++) {
485                                 hwc_wnds[w] = tdm_hwc_create_window(hwc, &error);
486                                 ASSERT_EQ(TDM_ERROR_NONE, error);
487                                 error = tdm_hwc_window_set_composition_type(hwc_wnds[w], TDM_HWC_WIN_COMPOSITION_DEVICE);
488                                 ASSERT_EQ(TDM_ERROR_NONE, error);
489                         }
490
491                         error = tdm_hwc_validate(hwc, hwc_wnds, HWC_WIN_NUM, &num_types);
492                         ASSERT_EQ(TDM_ERROR_NONE, error);
493
494                         if (num_types > 0) {
495                                 changed_hwc_window = (tdm_hwc_window **)calloc(num_types, sizeof(tdm_hwc_window *));
496                                 composition_types = (tdm_hwc_window_composition *)calloc(num_types, sizeof(tdm_hwc_window_composition));
497
498                                 get_num = num_types;
499                                 error = tdm_hwc_get_changed_composition_types(hwc, &get_num, changed_hwc_window, composition_types);
500                                 ASSERT_EQ(TDM_ERROR_NONE, error);
501                                 ASSERT_EQ(get_num, num_types);
502
503                                 error =  tdm_hwc_accept_validation(hwc);
504                                 ASSERT_EQ(TDM_ERROR_NONE, error);
505
506                                 free(composition_types);
507                                 free(changed_hwc_window);
508                         }
509
510                         error = tdm_hwc_commit(hwc, 0, _tc_tdm_hwc_commit_cb, NULL);
511                         ASSERT_EQ(TDM_ERROR_NONE, error);
512
513                         for (int w = 0; w < HWC_WIN_NUM; w++)
514                                 tdm_hwc_window_destroy(hwc_wnds[w]);
515
516                                 ASSERT_EQ(TDM_ERROR_NONE, error);
517                         }
518         }
519 }
520
521 #ifdef TDM_UT_TEST_WITH_PARAMS
522 INSTANTIATE_TEST_CASE_P(TDMHwcParams,
523                                                 TDMHwc,
524                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
525 #else
526 INSTANTIATE_TEST_CASE_P(TDMHwcParams,
527                                                 TDMHwc,
528                                                 Values(TDM_DEFAULT_MODULE));
529 #endif
530
531 /* LCOV_EXCL_END */