1 /**************************************************************************
5 Copyright 2017 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>
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:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
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.
29 **************************************************************************/
35 #include <tdm_helper.h>
37 #include "tdm_nexell.h"
41 tbm_format hwc_window_video_formats[] = {
47 _comp_to_str(tdm_hwc_window_composition composition_type)
49 if (composition_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
51 else if (composition_type == TDM_HWC_WIN_COMPOSITION_DEVICE)
53 else if (composition_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
55 else if (composition_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
57 else if (composition_type == TDM_HWC_WIN_COMPOSITION_NONE)
64 _nexell_hwc_cursor_buffer_image_render(tdm_nexell_hwc_data *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
66 tbm_surface_info_s tsurface_info;
67 tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE;
68 void *src_ptr = NULL, *dst_ptr = NULL;
69 int src_stride, transform, img_w, img_h;
70 pixman_image_t *src_img = NULL, *dst_img = NULL;
72 struct pixman_f_transform ft;
73 int c = 0, s = 0, tx = 0, ty = 0;
76 ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info);
77 if (ret != TBM_SURFACE_ERROR_NONE) {
78 TDM_ERR("Failed to map tsurface\n");
82 src_ptr = hwc_window_data->cursor_img.ptr;
83 src_stride = hwc_window_data->cursor_img.stride;
84 img_w = hwc_window_data->cursor_img.width;
85 img_h = hwc_window_data->cursor_img.height;
86 transform = hwc_window_data->info.transform;
88 dst_ptr = tsurface_info.planes[0].ptr;
90 memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height);
93 src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, img_w, img_h, (uint32_t*)src_ptr, src_stride);
95 TDM_ERR("Failed to create src pixman\n");
99 dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, tsurface_info.width, tsurface_info.height,
100 (uint32_t*)dst_ptr, tsurface_info.planes[0].stride);
102 TDM_ERR("Failed to create dst pixman\n");
103 pixman_image_unref(src_img);
107 pixman_f_transform_init_identity(&ft);
109 if (transform >= TDM_TRANSFORM_FLIPPED) {
110 pixman_f_transform_scale(&ft, NULL, -1, 1);
111 pixman_f_transform_translate(&ft, NULL, tsurface_info.width, 0);
115 case TDM_TRANSFORM_90:
116 case TDM_TRANSFORM_FLIPPED_90:
117 c = 0, s = 1, ty = -tsurface_info.height;
119 case TDM_TRANSFORM_180:
120 case TDM_TRANSFORM_FLIPPED_180:
121 c = -1, s = 0, tx = -tsurface_info.width, ty = -tsurface_info.height;
123 case TDM_TRANSFORM_270:
124 case TDM_TRANSFORM_FLIPPED_270:
125 c = 0, s = -1, tx = -tsurface_info.width;
131 pixman_f_transform_translate(&ft, NULL, tx, ty);
132 pixman_f_transform_rotate(&ft, NULL, c, s);
133 pixman_transform_from_pixman_f_transform(&t, &ft);
134 pixman_image_set_transform(src_img, &t);
135 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0,
136 tsurface_info.width, tsurface_info.height);
137 pixman_image_unref(src_img);
138 pixman_image_unref(dst_img);
141 for (i = 0 ; i < img_h ; i++) {
142 memcpy(dst_ptr, src_ptr, src_stride);
143 dst_ptr += tsurface_info.planes[0].stride;
144 src_ptr += src_stride;
148 tbm_surface_unmap(hwc_data->cursor_tsurface);
154 _nexell_hwc_cursor_window_surface_clear(tdm_nexell_hwc_window_data *hwc_window_data)
156 hwc_window_data->surface = NULL;
157 hwc_window_data->cursor_img_surface = 0;
159 hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width;
160 hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height;
161 hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width;
162 hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height;
168 _nexell_hwc_cursor_buffer_unset(tdm_nexell_hwc_data *hwc_data)
170 if (hwc_data->cursor_tsurface) {
171 tbm_surface_queue_release(hwc_data->cursor_tqueue, hwc_data->cursor_tsurface);
172 hwc_data->cursor_tsurface = NULL;
175 if (hwc_data->cursor_tqueue) {
176 tdm_nexell_hwc_window_destroy_tbm_buffer_queue(hwc_data->cursor_tqueue);
177 hwc_data->cursor_tqueue = NULL;
182 _nexell_hwc_cursor_adjust_pos(tdm_nexell_hwc_data *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
184 int x, y, width, height;
186 width = tbm_surface_get_width(hwc_data->cursor_tsurface);
187 height = tbm_surface_get_height(hwc_data->cursor_tsurface);
189 hwc_window_data->info.src_config.pos.w = width;
190 hwc_window_data->info.src_config.pos.h = height;
191 hwc_window_data->info.dst_pos.w = width;
192 hwc_window_data->info.dst_pos.h = height;
194 /* dst pos of cursor is possible set by negative value
195 * this is temporary code.
197 x = hwc_window_data->info.dst_pos.x;
198 y = hwc_window_data->info.dst_pos.y;
200 if (x < 0) hwc_window_data->info.dst_pos.x = 0;
201 if (y < 0) hwc_window_data->info.dst_pos.y = 0;
205 _nexell_hwc_cursor_buffer_set(tdm_nexell_hwc_data *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
207 tbm_surface_h cursor_tsurface = NULL;
208 tbm_surface_queue_error_e tsq_error = TBM_SURFACE_QUEUE_ERROR_NONE;
210 int tqueue_w, tqueue_h;
213 if (hwc_window_data->cursor_img_refresh || !hwc_window_data->surface) {
214 switch (hwc_window_data->info.transform) {
215 case TDM_TRANSFORM_90:
216 case TDM_TRANSFORM_FLIPPED_90:
217 case TDM_TRANSFORM_270:
218 case TDM_TRANSFORM_FLIPPED_270:
219 img_w = hwc_window_data->cursor_img.height;
220 img_h = hwc_window_data->cursor_img.width;
223 img_w = hwc_window_data->cursor_img.width;
224 img_h = hwc_window_data->cursor_img.height;
228 if (!hwc_data->cursor_tqueue) {
229 hwc_data->cursor_tqueue = tdm_nexell_hwc_window_create_cursor_tbm_buffer_queue(hwc_window_data, &error);
230 if (error != TDM_ERROR_NONE) {
231 TDM_ERR("Failed to create cursor buffer queue error:%d", error);
235 tqueue_w = tbm_surface_queue_get_width(hwc_data->cursor_tqueue);
236 tqueue_h = tbm_surface_queue_get_height(hwc_data->cursor_tqueue);
237 if ((img_w != tqueue_w) || (img_h != tqueue_h))
238 tbm_surface_queue_reset(hwc_data->cursor_tqueue, img_w, img_h, TBM_FORMAT_ARGB8888);
241 if (hwc_data->cursor_tsurface) {
242 tbm_surface_queue_release(hwc_data->cursor_tqueue, hwc_data->cursor_tsurface);
243 hwc_data->cursor_tsurface = NULL;
246 if (!tbm_surface_queue_can_dequeue(hwc_data->cursor_tqueue, 0)) {
247 TDM_ERR("Can't dequeue cursor tqueue");
251 tsq_error = tbm_surface_queue_dequeue(hwc_data->cursor_tqueue, &cursor_tsurface);
252 if (tsq_error != TBM_SURFACE_QUEUE_ERROR_NONE) {
253 TDM_ERR("Failed to dequeue cursor tqueue error:%d", tsq_error);
257 hwc_data->cursor_tsurface = cursor_tsurface;
259 _nexell_hwc_cursor_buffer_image_render(hwc_data, hwc_window_data);
261 hwc_window_data->surface = cursor_tsurface;
262 hwc_window_data->cursor_img_surface = 1;
263 hwc_window_data->cursor_img_refresh = 0;
266 _nexell_hwc_cursor_adjust_pos(hwc_data, hwc_window_data);
272 _print_validate_result(tdm_nexell_hwc_data *hwc_data, tdm_hwc_window **composited_wnds, uint32_t num_wnds)
274 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
278 for (i = 0; i < num_wnds; i++) {
279 hwc_window_data = composited_wnds[i];
280 lzpos_queue = hwc_window_data->lzpos_queue;
281 switch (hwc_window_data->validated_type) {
282 case TDM_HWC_WIN_COMPOSITION_CLIENT:
283 TDM_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p ref_cnt:%d] -- {%s} on TARGET WINDOW", hwc_window_data,
284 _comp_to_str(hwc_window_data->client_type),
285 _comp_to_str(hwc_window_data->validated_type),
286 hwc_data->target_hwc_window->lzpos,
287 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
288 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
289 hwc_window_data->name ? hwc_window_data->name : "NONE");
291 case TDM_HWC_WIN_COMPOSITION_DEVICE:
292 case TDM_HWC_WIN_COMPOSITION_VIDEO:
293 case TDM_HWC_WIN_COMPOSITION_CURSOR:
294 case TDM_HWC_WIN_COMPOSITION_NONE:
295 TDM_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p ref_cnt:%d] -- {%s}", hwc_window_data,
296 _comp_to_str(hwc_window_data->client_type),
297 _comp_to_str(hwc_window_data->validated_type),
298 hwc_window_data->lzpos,
299 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
300 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
301 hwc_window_data->name ? hwc_window_data->name : "NONE");
310 _nexell_hwc_window_has_reserved_buffer(tdm_nexell_hwc_window_data *hwc_window_data) {
314 RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
315 RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, 0);
317 bo = tbm_surface_internal_get_bo(hwc_window_data->surface, 0);
318 RETURN_VAL_IF_FAIL(bo != NULL, 0);
320 flags = tbm_bo_get_flags(bo);
322 return flags & TBM_BO_SCANOUT;
326 _nexell_hwc_window_can_set_on_hw_layer(tdm_nexell_hwc_window_data *hwc_window_data, int bottom)
328 if (!hwc_window_data->surface)
331 if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
334 if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
337 if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
340 if (!IS_RGB(hwc_window_data->info.src_config.format))
343 if ((hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay) ||
344 (hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay))
348 if ((hwc_window_data->info.dst_pos.w != hwc_window_data->hwc_data->output_data->current_mode->hdisplay) ||
349 (hwc_window_data->info.dst_pos.h != hwc_window_data->hwc_data->output_data->current_mode->vdisplay))
357 tdm_nexell_hwc_window_create_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
359 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
360 tbm_surface_queue_h tqueue = NULL;
365 *error = TDM_ERROR_INVALID_PARAMETER;
367 RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
369 hwc_window_data = hwc_window;
371 width = hwc_window_data->info.src_config.pos.w;
372 height = hwc_window_data->info.src_config.pos.h;
373 format = hwc_window_data->info.src_config.format;
375 tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, format, TBM_BO_SCANOUT);
377 *error = TDM_ERROR_OPERATION_FAILED;
378 RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
381 *error = TDM_ERROR_NONE;
387 tdm_nexell_hwc_window_create_cursor_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
389 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
390 tbm_surface_queue_h tqueue = NULL;
394 *error = TDM_ERROR_INVALID_PARAMETER;
396 RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
398 hwc_window_data = hwc_window;
400 switch (hwc_window_data->info.transform) {
401 case TDM_TRANSFORM_90:
402 case TDM_TRANSFORM_FLIPPED_90:
403 case TDM_TRANSFORM_270:
404 case TDM_TRANSFORM_FLIPPED_270:
405 width = hwc_window_data->cursor_img.height;
406 height = hwc_window_data->cursor_img.width;
409 width = hwc_window_data->cursor_img.width;
410 height = hwc_window_data->cursor_img.height;
414 tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
416 *error = TDM_ERROR_OPERATION_FAILED;
417 RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
419 tbm_surface_queue_set_modes(tqueue, TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE);
422 *error = TDM_ERROR_NONE;
428 tdm_nexell_hwc_window_destroy_tbm_buffer_queue(tbm_surface_queue_h tqueue)
430 tbm_surface_queue_destroy(tqueue);
434 _nexell_hwc_layer_attach_window(tdm_nexell_layer_data *layer_data, tdm_nexell_hwc_window_data *hwc_window_data)
436 tdm_error ret = TDM_ERROR_NONE;
438 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
440 if (hwc_window_data == NULL || hwc_window_data->surface == NULL) {
441 if (layer_data->display_buffer)
442 ret = nexell_layer_unset_buffer(layer_data);
443 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
445 ret = nexell_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
446 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
447 RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, TDM_ERROR_INVALID_PARAMETER);
448 ret = nexell_layer_set_buffer(layer_data, hwc_window_data->surface);
449 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
456 _nexell_hwc_prepare_commit(tdm_nexell_hwc_data *hwc_data)
458 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
459 tdm_nexell_layer_data *layer_data = NULL;
460 int use_layers_zpos[NUM_LAYERS] = {0,};
462 int cursor_enabled = 0;
464 /* set target hwc window to the layer */
465 if (hwc_data->need_target_window) {
466 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos);
467 _nexell_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window);
468 use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1;
471 /* set the hwc_windows to the layers */
472 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
473 if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_NONE ||
474 hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CLIENT) {
475 if (hwc_window_data->cursor_img_surface)
476 _nexell_hwc_cursor_window_surface_clear(hwc_window_data);
481 if (hwc_window_data == hwc_data->target_hwc_window)
484 /* set the cursor buffer HERE if it needs */
485 if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR) {
486 _nexell_hwc_cursor_buffer_set(hwc_data, hwc_window_data);
490 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos);
491 _nexell_hwc_layer_attach_window(layer_data, hwc_window_data);
492 use_layers_zpos[hwc_window_data->lzpos] = 1;
495 /* unset the unused layers */
496 for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) {
497 if (use_layers_zpos[lzpos])
500 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, lzpos);
504 _nexell_hwc_layer_attach_window(layer_data, NULL);
508 _nexell_hwc_cursor_buffer_unset(hwc_data);
511 for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) {
512 if (use_layers_zpos[lzpos])
513 TDM_DBG(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET");
516 return TDM_ERROR_NONE;
519 /* assign the validated_type to the composited_wnds
520 * assign the layer_zpos to the composited_wnds
523 _nexell_hwc_apply_policy(tdm_nexell_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds)
525 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
526 tdm_nexell_hwc_window_data **composited_list = NULL;
527 int client_count = 0;
528 int device_count = 0;
530 int cursor_count = 0;
531 int ui_lzpos_top = ZPOS_2;
532 int ui_lzpos_bottom = ZPOS_1;
533 int num_ui_layers = NUM_UI_LAYERS;
534 int set_clients_below = 0;
537 composited_list = (tdm_nexell_hwc_window_data **)composited_wnds;
539 /* initialize the need_target_window */
540 hwc_data->need_target_window = 0;
542 /* initialize the validated_types and constraints */
543 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
544 hwc_window_data->constraints = TDM_HWC_WIN_CONSTRAINT_NONE;
545 hwc_window_data->validated_type = TDM_HWC_WIN_COMPOSITION_NONE;
546 hwc_window_data->lzpos = -1;
547 hwc_window_data->lzpos_queue = -1;
550 /* use the target_window to commit when there is no window. */
552 hwc_data->need_target_window = 1;
553 hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom;
554 hwc_data->target_hwc_window->lzpos_queue = ui_lzpos_bottom;
558 /* 1. first check validate_type without target_window */
559 for (i = 0; i < num_wnds; i++) {
560 switch (composited_list[i]->client_type) {
561 case TDM_HWC_WIN_COMPOSITION_VIDEO:
562 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_VIDEO;
565 case TDM_HWC_WIN_COMPOSITION_CURSOR:
566 if (set_clients_below) break;
567 if (num_ui_layers <= 0) break;
569 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CURSOR;
573 case TDM_HWC_WIN_COMPOSITION_DEVICE:
574 if (set_clients_below) break;
575 if (num_ui_layers <= 0) break;
577 if (!_nexell_hwc_window_can_set_on_hw_layer(composited_list[i], (i == num_wnds - 1)))
580 if (!_nexell_hwc_window_has_reserved_buffer(composited_list[i])) {
581 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
585 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_DEVICE;
586 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
594 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
596 set_clients_below = 1;
599 /* 2. check need target window and set ui_lzpos top and bottom */
600 num_ui_layers = NUM_UI_LAYERS;
601 if (client_count > 0) {
602 hwc_data->need_target_window = 1;
603 hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom;
608 if (num_ui_layers > (device_count + cursor_count))
609 ui_lzpos_top = ui_lzpos_bottom + device_count + cursor_count - 1;
611 /* 3. set lzpos and modify validate_type with target_window */
612 for (i = 0; i < num_wnds; i++) {
613 switch (composited_list[i]->validated_type) {
614 case TDM_HWC_WIN_COMPOSITION_VIDEO:
615 composited_list[i]->lzpos = ZPOS_VIDEO1;
617 case TDM_HWC_WIN_COMPOSITION_CURSOR:
618 case TDM_HWC_WIN_COMPOSITION_DEVICE:
619 if (num_ui_layers <= 0) break;
621 composited_list[i]->lzpos = ui_lzpos_top;
622 composited_list[i]->lzpos_queue = ui_lzpos_top;
630 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
632 if (composited_list[i]->constraints == TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE) {
633 if (i == num_wnds - 1) //set target window queue zpos
634 composited_list[i]->lzpos_queue = ui_lzpos_top;
635 else if(num_ui_layers > 0)
636 composited_list[i]->lzpos_queue = ui_lzpos_top + 1;
638 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_NONE;
644 _nexell_hwc_get_changed_number(tdm_nexell_hwc_data *hwc_data)
647 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
649 LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
650 if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
653 if (hwc_window_data->client_type != hwc_window_data->validated_type)
661 _nexell_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error)
663 tdm_nexell_hwc_data *hwc_data = hwc;
664 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
667 *error = TDM_ERROR_NONE;
670 TDM_ERR("invalid params");
672 *error = TDM_ERROR_INVALID_PARAMETER;
676 hwc_window_data = calloc(1, sizeof(tdm_nexell_hwc_window_data));
677 if (!hwc_window_data) {
678 TDM_ERR("alloc failed");
680 *error = TDM_ERROR_OUT_OF_MEMORY;
684 hwc_window_data->hwc_data = hwc_data;
687 memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
689 LIST_INITHEAD(&hwc_window_data->link);
691 return hwc_window_data;
695 nexell_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
697 tdm_nexell_hwc_data *hwc_data = hwc;
698 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
700 RETURN_VAL_IF_FAIL(hwc_data, NULL);
702 hwc_window_data = _nexell_hwc_create_window(hwc_data, NULL, error);
703 RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
705 LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
707 TDM_DBG("hwc_window(%p) create", hwc_window_data);
709 *error = TDM_ERROR_NONE;
711 return hwc_window_data;
715 nexell_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
717 RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
718 RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
719 RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
721 // TODO: fix these formats.
722 *formats = hwc_window_video_formats;
723 *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format);
725 return TDM_ERROR_NONE;
729 nexell_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
731 RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
732 RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
734 *capabilities |= TDM_HWC_CAPABILITY_VIDEO_SCALE;
736 return TDM_ERROR_NONE;
740 nexell_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
742 tdm_nexell_hwc_data *hwc_data = hwc;
744 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
745 RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
746 RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
751 return TDM_ERROR_NONE;
755 nexell_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
757 tdm_nexell_hwc_data *hwc_data = hwc;
758 tbm_surface_queue_h tqueue = NULL;
761 *error = TDM_ERROR_INVALID_PARAMETER;
763 RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
765 if (hwc_data->target_hwc_window == NULL) {
767 *error = TDM_ERROR_OPERATION_FAILED;
771 tqueue = tdm_nexell_hwc_window_create_tbm_buffer_queue(hwc_data->target_hwc_window, error);
772 RETURN_VAL_IF_FAIL(tqueue, NULL);
774 hwc_data->ui_buffer_queue[ZPOS_1].tqueue = tqueue;
775 hwc_data->ui_buffer_queue[ZPOS_1].ref_cnt = 1;
778 *error = TDM_ERROR_NONE;
784 nexell_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
786 tdm_nexell_hwc_data *hwc_data = hwc;
789 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
790 RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, TDM_ERROR_OPERATION_FAILED);
792 err = nexell_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
793 RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
795 err = nexell_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
796 RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
798 return TDM_ERROR_NONE;
802 nexell_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
804 tdm_nexell_hwc_data *hwc_data = hwc;
805 tdm_nexell_output_data *output_data;
807 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
808 RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
810 output_data = hwc_data->output_data;
811 RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
813 TDM_DBG(" ==============Validate=================================");
816 _nexell_hwc_apply_policy(hwc_data, composited_wnds, num_wnds);
818 *num_types = _nexell_hwc_get_changed_number(hwc_data);
820 _print_validate_result(hwc_data, composited_wnds, num_wnds);
822 return TDM_ERROR_NONE;
826 nexell_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
827 tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types)
829 tdm_nexell_hwc_data *hwc_data = hwc;
830 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
833 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
834 RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
836 if ((hwc_wnds == NULL) || (composition_types == NULL)) {
837 *num_elements = _nexell_hwc_get_changed_number(hwc_data);
838 return TDM_ERROR_NONE;
841 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
842 if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
845 if (num >= *num_elements)
848 if (hwc_window_data->client_type != hwc_window_data->validated_type) {
849 composition_types[num] = hwc_window_data->validated_type;
850 hwc_wnds[num] = hwc_window_data;
855 /* set real num of changed composition types */
858 return TDM_ERROR_NONE;
862 nexell_hwc_accept_validation(tdm_hwc *hwc)
864 tdm_nexell_hwc_data *hwc_data = hwc;
865 tdm_error ret = TDM_ERROR_NONE;
867 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
868 RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
870 TDM_DBG(" ==============Accept Changes Done=================================");
872 ret = _nexell_hwc_prepare_commit(hwc_data);
873 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
875 return TDM_ERROR_NONE;
879 nexell_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
881 tdm_nexell_hwc_data *hwc_data = hwc;
882 tdm_nexell_output_data *output_data = NULL;
885 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
887 output_data = hwc_data->output_data;
888 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
890 TDM_DBG(" ==============COMMIT=================================");
892 ret = nexell_output_commit(output_data, sync, user_data);
893 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
895 return TDM_ERROR_NONE;
899 nexell_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
901 tdm_nexell_hwc_data *hwc_data = hwc;
903 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
904 RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
906 hwc_data->commit_func = func;
908 return TDM_ERROR_NONE;
912 nexell_hwc_target_window_set_info(tdm_nexell_hwc_data *hwc_data, int width, int height)
914 tdm_hwc_window_info info = {0};
915 tdm_nexell_hwc_window_data *target_hwc_window;
916 tdm_error ret = TDM_ERROR_NONE;
918 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
919 RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, TDM_ERROR_INVALID_PARAMETER);
921 target_hwc_window = hwc_data->target_hwc_window;
925 info.dst_pos.w = width;
926 info.dst_pos.h = height;
928 info.src_config.pos.x = 0;
929 info.src_config.pos.y = 0;
930 info.src_config.pos.w = width;
931 info.src_config.pos.h = height;
933 info.src_config.size.h = width;
934 info.src_config.size.v = height;
935 info.src_config.format = TBM_FORMAT_ARGB8888;
937 ret = nexell_hwc_window_set_info(target_hwc_window, &info);
938 if (ret != TDM_ERROR_NONE) {
939 TDM_ERR("set info target hwc window failed (%d)", ret);
940 return TDM_ERROR_OPERATION_FAILED;
943 return TDM_ERROR_NONE;
947 nexell_hwc_initailize_target_window(tdm_nexell_hwc_data *hwc_data)
949 tdm_hwc_window_info info = {0};
950 tdm_error ret = TDM_ERROR_NONE;
951 tdm_nexell_hwc_window_data *target_hwc_window;
953 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
960 info.src_config.pos.x = 0;
961 info.src_config.pos.y = 0;
962 info.src_config.pos.w = 2;
963 info.src_config.pos.h = 1;
965 info.src_config.size.h = 2;
966 info.src_config.size.v = 1;
967 info.src_config.format = TBM_FORMAT_ARGB8888;
969 target_hwc_window = _nexell_hwc_create_window(hwc_data, &info, &ret);
970 if (ret != TDM_ERROR_NONE) {
971 TDM_ERR("create target hwc window failed (%d)", ret);
972 return TDM_ERROR_OPERATION_FAILED;
975 if (hwc_data->target_hwc_window)
976 nexell_hwc_window_destroy(hwc_data->target_hwc_window);
978 hwc_data->target_hwc_window = target_hwc_window;
979 hwc_data->need_set_crtc = 1;
981 return TDM_ERROR_NONE;