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_backend_nexell.h"
39 tbm_format hwc_window_video_formats[] = {
45 _comp_to_str(hal_tdm_hwc_window_composition composition_type)
47 if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT)
49 else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE)
51 else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR)
53 else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
55 else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
62 _nexell_hwc_cursor_buffer_image_render(tdm_nexell_hwc *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
64 tbm_surface_info_s tsurface_info;
65 tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE;
66 void *src_ptr = NULL, *dst_ptr = NULL;
67 int src_stride, transform, img_w, img_h;
68 pixman_image_t *src_img = NULL, *dst_img = NULL;
70 struct pixman_f_transform ft;
71 int c = 0, s = 0, tx = 0, ty = 0;
74 ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info);
75 if (ret != TBM_SURFACE_ERROR_NONE) {
76 TDM_BACKEND_ERR("Failed to map tsurface\n");
80 src_ptr = hwc_window_data->cursor_img.ptr;
81 src_stride = hwc_window_data->cursor_img.stride;
82 img_w = hwc_window_data->cursor_img.width;
83 img_h = hwc_window_data->cursor_img.height;
84 transform = hwc_window_data->info.transform;
86 dst_ptr = tsurface_info.planes[0].ptr;
88 memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height);
91 src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, img_w, img_h, (uint32_t*)src_ptr, src_stride);
93 TDM_BACKEND_ERR("Failed to create src pixman\n");
97 dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, tsurface_info.width, tsurface_info.height,
98 (uint32_t*)dst_ptr, tsurface_info.planes[0].stride);
100 TDM_BACKEND_ERR("Failed to create dst pixman\n");
101 pixman_image_unref(src_img);
105 pixman_f_transform_init_identity(&ft);
107 if (transform >= HAL_TDM_TRANSFORM_FLIPPED) {
108 pixman_f_transform_scale(&ft, NULL, -1, 1);
109 pixman_f_transform_translate(&ft, NULL, tsurface_info.width, 0);
113 case HAL_TDM_TRANSFORM_90:
114 case HAL_TDM_TRANSFORM_FLIPPED_90:
115 c = 0, s = 1, ty = -tsurface_info.height;
117 case HAL_TDM_TRANSFORM_180:
118 case HAL_TDM_TRANSFORM_FLIPPED_180:
119 c = -1, s = 0, tx = -tsurface_info.width, ty = -tsurface_info.height;
121 case HAL_TDM_TRANSFORM_270:
122 case HAL_TDM_TRANSFORM_FLIPPED_270:
123 c = 0, s = -1, tx = -tsurface_info.width;
129 pixman_f_transform_translate(&ft, NULL, tx, ty);
130 pixman_f_transform_rotate(&ft, NULL, c, s);
131 pixman_transform_from_pixman_f_transform(&t, &ft);
132 pixman_image_set_transform(src_img, &t);
133 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0,
134 tsurface_info.width, tsurface_info.height);
135 pixman_image_unref(src_img);
136 pixman_image_unref(dst_img);
139 for (i = 0 ; i < img_h ; i++) {
140 memcpy(dst_ptr, src_ptr, src_stride);
141 dst_ptr += tsurface_info.planes[0].stride;
142 src_ptr += src_stride;
146 tbm_surface_unmap(hwc_data->cursor_tsurface);
152 _nexell_hwc_cursor_window_surface_clear(tdm_nexell_hwc_window_data *hwc_window_data)
154 hwc_window_data->surface = NULL;
155 hwc_window_data->cursor_img_surface = 0;
157 hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width;
158 hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height;
159 hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width;
160 hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height;
166 _nexell_hwc_cursor_buffer_unset(tdm_nexell_hwc *hwc_data)
168 if (hwc_data->cursor_tsurface) {
169 tbm_surface_queue_release(hwc_data->cursor_tqueue, hwc_data->cursor_tsurface);
170 hwc_data->cursor_tsurface = NULL;
173 if (hwc_data->cursor_tqueue) {
174 tdm_nexell_hwc_window_destroy_tbm_buffer_queue(hwc_data->cursor_tqueue);
175 hwc_data->cursor_tqueue = NULL;
180 _nexell_hwc_cursor_adjust_pos(tdm_nexell_hwc *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
182 int x, y, width, height;
184 width = tbm_surface_get_width(hwc_data->cursor_tsurface);
185 height = tbm_surface_get_height(hwc_data->cursor_tsurface);
187 hwc_window_data->info.src_config.pos.w = width;
188 hwc_window_data->info.src_config.pos.h = height;
189 hwc_window_data->info.dst_pos.w = width;
190 hwc_window_data->info.dst_pos.h = height;
192 /* dst pos of cursor is possible set by negative value
193 * this is temporary code.
195 x = hwc_window_data->info.dst_pos.x;
196 y = hwc_window_data->info.dst_pos.y;
198 if (x < 0) hwc_window_data->info.dst_pos.x = 0;
199 if (y < 0) hwc_window_data->info.dst_pos.y = 0;
203 _nexell_hwc_cursor_buffer_set(tdm_nexell_hwc *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
205 tbm_surface_h cursor_tsurface = NULL;
206 tbm_surface_queue_error_e tsq_error = TBM_SURFACE_QUEUE_ERROR_NONE;
208 int tqueue_w, tqueue_h;
211 if (hwc_window_data->cursor_img_refresh || !hwc_window_data->surface) {
212 switch (hwc_window_data->info.transform) {
213 case HAL_TDM_TRANSFORM_90:
214 case HAL_TDM_TRANSFORM_FLIPPED_90:
215 case HAL_TDM_TRANSFORM_270:
216 case HAL_TDM_TRANSFORM_FLIPPED_270:
217 img_w = hwc_window_data->cursor_img.height;
218 img_h = hwc_window_data->cursor_img.width;
221 img_w = hwc_window_data->cursor_img.width;
222 img_h = hwc_window_data->cursor_img.height;
226 if (!hwc_data->cursor_tqueue) {
227 hwc_data->cursor_tqueue = tdm_nexell_hwc_window_create_cursor_tbm_buffer_queue(hwc_window_data, &error);
228 if (error != HAL_TDM_ERROR_NONE) {
229 TDM_BACKEND_ERR("Failed to create cursor buffer queue error:%d", error);
233 tqueue_w = tbm_surface_queue_get_width(hwc_data->cursor_tqueue);
234 tqueue_h = tbm_surface_queue_get_height(hwc_data->cursor_tqueue);
235 if ((img_w != tqueue_w) || (img_h != tqueue_h))
236 tbm_surface_queue_reset(hwc_data->cursor_tqueue, img_w, img_h, TBM_FORMAT_ARGB8888);
239 if (hwc_data->cursor_tsurface) {
240 tbm_surface_queue_release(hwc_data->cursor_tqueue, hwc_data->cursor_tsurface);
241 hwc_data->cursor_tsurface = NULL;
244 if (!tbm_surface_queue_can_dequeue(hwc_data->cursor_tqueue, 0)) {
245 TDM_BACKEND_ERR("Can't dequeue cursor tqueue");
249 tsq_error = tbm_surface_queue_dequeue(hwc_data->cursor_tqueue, &cursor_tsurface);
250 if (tsq_error != TBM_SURFACE_QUEUE_ERROR_NONE) {
251 TDM_BACKEND_ERR("Failed to dequeue cursor tqueue error:%d", tsq_error);
255 hwc_data->cursor_tsurface = cursor_tsurface;
257 _nexell_hwc_cursor_buffer_image_render(hwc_data, hwc_window_data);
259 hwc_window_data->surface = cursor_tsurface;
260 hwc_window_data->cursor_img_surface = 1;
261 hwc_window_data->cursor_img_refresh = 0;
264 _nexell_hwc_cursor_adjust_pos(hwc_data, hwc_window_data);
270 _print_validate_result(tdm_nexell_hwc *hwc_data, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds)
272 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
276 for (i = 0; i < num_wnds; i++) {
277 hwc_window_data = composited_wnds[i];
278 lzpos_queue = hwc_window_data->lzpos_queue;
279 switch (hwc_window_data->validated_type) {
280 case HAL_TDM_HWC_WIN_COMPOSITION_CLIENT:
281 TDM_BACKEND_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p ref_cnt:%d] -- {%s} on TARGET WINDOW", hwc_window_data,
282 _comp_to_str(hwc_window_data->client_type),
283 _comp_to_str(hwc_window_data->validated_type),
284 hwc_data->target_hwc_window->lzpos,
285 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
286 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
287 hwc_window_data->name ? hwc_window_data->name : "NONE");
289 case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE:
290 case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO:
291 case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR:
292 case HAL_TDM_HWC_WIN_COMPOSITION_NONE:
293 TDM_BACKEND_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p ref_cnt:%d] -- {%s}", hwc_window_data,
294 _comp_to_str(hwc_window_data->client_type),
295 _comp_to_str(hwc_window_data->validated_type),
296 hwc_window_data->lzpos,
297 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
298 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
299 hwc_window_data->name ? hwc_window_data->name : "NONE");
308 _nexell_hwc_window_has_reserved_buffer(tdm_nexell_hwc_window_data *hwc_window_data) {
312 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
313 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, 0);
315 bo = tbm_surface_internal_get_bo(hwc_window_data->surface, 0);
316 TDM_BACKEND_RETURN_VAL_IF_FAIL(bo != NULL, 0);
318 flags = tbm_bo_get_flags(bo);
320 return flags & TBM_BO_SCANOUT;
324 _nexell_hwc_window_can_set_on_hw_layer(tdm_nexell_hwc_window_data *hwc_window_data, int bottom)
326 if (!hwc_window_data->surface)
329 if (hwc_window_data->info.transform != HAL_TDM_TRANSFORM_NORMAL)
332 if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
335 if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
338 if (!IS_RGB(hwc_window_data->info.src_config.format))
341 if ((hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay) ||
342 (hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay))
346 if ((hwc_window_data->info.dst_pos.w != hwc_window_data->hwc_data->output_data->current_mode->hdisplay) ||
347 (hwc_window_data->info.dst_pos.h != hwc_window_data->hwc_data->output_data->current_mode->vdisplay))
355 tdm_nexell_hwc_window_create_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error)
357 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
358 tbm_surface_queue_h tqueue = NULL;
363 *error = HAL_TDM_ERROR_INVALID_PARAMETER;
365 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
367 hwc_window_data = hwc_window;
369 width = hwc_window_data->info.src_config.pos.w;
370 height = hwc_window_data->info.src_config.pos.h;
371 format = hwc_window_data->info.src_config.format;
373 tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, format, TBM_BO_SCANOUT);
375 *error = HAL_TDM_ERROR_OPERATION_FAILED;
376 TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
379 *error = HAL_TDM_ERROR_NONE;
385 tdm_nexell_hwc_window_create_cursor_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error)
387 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
388 tbm_surface_queue_h tqueue = NULL;
392 *error = HAL_TDM_ERROR_INVALID_PARAMETER;
394 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
396 hwc_window_data = hwc_window;
398 switch (hwc_window_data->info.transform) {
399 case HAL_TDM_TRANSFORM_90:
400 case HAL_TDM_TRANSFORM_FLIPPED_90:
401 case HAL_TDM_TRANSFORM_270:
402 case HAL_TDM_TRANSFORM_FLIPPED_270:
403 width = hwc_window_data->cursor_img.height;
404 height = hwc_window_data->cursor_img.width;
407 width = hwc_window_data->cursor_img.width;
408 height = hwc_window_data->cursor_img.height;
412 tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
414 *error = HAL_TDM_ERROR_OPERATION_FAILED;
415 TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
417 tbm_surface_queue_set_modes(tqueue, TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE);
420 *error = HAL_TDM_ERROR_NONE;
426 tdm_nexell_hwc_window_destroy_tbm_buffer_queue(tbm_surface_queue_h tqueue)
428 tbm_surface_queue_destroy(tqueue);
432 _nexell_hwc_layer_attach_window(tdm_nexell_layer *layer_data, tdm_nexell_hwc_window_data *hwc_window_data)
434 hal_tdm_error ret = HAL_TDM_ERROR_NONE;
436 TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_OPERATION_FAILED);
438 if (hwc_window_data == NULL || hwc_window_data->surface == NULL) {
439 if (layer_data->display_buffer)
440 ret = nexell_layer_unset_buffer(layer_data);
441 TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
443 ret = nexell_layer_set_info((tdm_nexell_layer *)layer_data, (tdm_nexell_layer_info *)&(hwc_window_data->info));
444 TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
445 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
446 ret = nexell_layer_set_buffer(layer_data, hwc_window_data->surface);
447 TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
454 _nexell_hwc_prepare_commit(tdm_nexell_hwc *hwc_data)
456 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
457 tdm_nexell_layer *layer_data = NULL;
458 int use_layers_zpos[NUM_LAYERS] = {0,};
460 int cursor_enabled = 0;
462 /* set target hwc window to the layer_data */
463 if (hwc_data->need_target_window) {
464 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos);
465 _nexell_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window);
466 use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1;
469 /* set the hwc_windows to the layers */
470 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
471 if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE ||
472 hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT) {
473 if (hwc_window_data->cursor_img_surface)
474 _nexell_hwc_cursor_window_surface_clear(hwc_window_data);
479 if (hwc_window_data == hwc_data->target_hwc_window)
482 /* set the cursor buffer HERE if it needs */
483 if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR) {
484 _nexell_hwc_cursor_buffer_set(hwc_data, hwc_window_data);
488 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos);
489 _nexell_hwc_layer_attach_window(layer_data, hwc_window_data);
490 use_layers_zpos[hwc_window_data->lzpos] = 1;
493 /* unset the unused layers */
494 for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) {
495 if (use_layers_zpos[lzpos])
498 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, lzpos);
502 _nexell_hwc_layer_attach_window(layer_data, NULL);
506 _nexell_hwc_cursor_buffer_unset(hwc_data);
509 for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) {
510 if (use_layers_zpos[lzpos])
511 TDM_BACKEND_DBG(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET");
514 return HAL_TDM_ERROR_NONE;
517 /* assign the validated_type to the composited_wnds
518 * assign the layer_zpos to the composited_wnds
521 _nexell_hwc_apply_policy(tdm_nexell_hwc *hwc_data , hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds)
523 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
524 tdm_nexell_hwc_window_data **composited_list = NULL;
525 int client_count = 0;
526 int device_count = 0;
528 int cursor_count = 0;
529 int ui_lzpos_top = ZPOS_2;
530 int ui_lzpos_bottom = ZPOS_1;
531 int num_ui_layers = NUM_UI_LAYERS;
532 int set_clients_below = 0;
535 composited_list = (tdm_nexell_hwc_window_data **)composited_wnds;
537 /* initialize the need_target_window */
538 hwc_data->need_target_window = 0;
540 /* initialize the validated_types and constraints */
541 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
542 hwc_window_data->constraints = HAL_TDM_HWC_WIN_CONSTRAINT_NONE;
543 hwc_window_data->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_NONE;
544 hwc_window_data->lzpos = -1;
545 hwc_window_data->lzpos_queue = -1;
548 /* use the target_window to commit when there is no window. */
550 hwc_data->need_target_window = 1;
551 hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom;
552 hwc_data->target_hwc_window->lzpos_queue = ui_lzpos_bottom;
556 /* 1. first check validate_type without target_window */
557 for (i = 0; i < num_wnds; i++) {
558 switch (composited_list[i]->client_type) {
559 case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO:
560 composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_VIDEO;
563 case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR:
564 if (set_clients_below) break;
565 if (num_ui_layers <= 0) break;
567 composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CURSOR;
571 case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE:
572 if (set_clients_below) break;
573 if (num_ui_layers <= 0) break;
575 if (!_nexell_hwc_window_can_set_on_hw_layer(composited_list[i], (i == num_wnds - 1)))
578 if (!_nexell_hwc_window_has_reserved_buffer(composited_list[i])) {
579 composited_list[i]->constraints = HAL_TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
583 composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_DEVICE;
584 composited_list[i]->constraints = HAL_TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
592 composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT;
594 set_clients_below = 1;
597 /* 2. check need target window and set ui_lzpos top and bottom */
598 num_ui_layers = NUM_UI_LAYERS;
599 if (client_count > 0) {
600 hwc_data->need_target_window = 1;
601 hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom;
606 if (num_ui_layers > (device_count + cursor_count))
607 ui_lzpos_top = ui_lzpos_bottom + device_count + cursor_count - 1;
609 /* 3. set lzpos and modify validate_type with target_window */
610 for (i = 0; i < num_wnds; i++) {
611 switch (composited_list[i]->validated_type) {
612 case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO:
613 composited_list[i]->lzpos = ZPOS_VIDEO1;
615 case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR:
616 case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE:
617 if (num_ui_layers <= 0) break;
619 composited_list[i]->lzpos = ui_lzpos_top;
620 composited_list[i]->lzpos_queue = ui_lzpos_top;
628 composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT;
630 if (composited_list[i]->constraints == HAL_TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE) {
631 if (i == num_wnds - 1) //set target window queue zpos
632 composited_list[i]->lzpos_queue = ui_lzpos_top;
633 else if(num_ui_layers > 0)
634 composited_list[i]->lzpos_queue = ui_lzpos_top + 1;
636 composited_list[i]->constraints = HAL_TDM_HWC_WIN_CONSTRAINT_NONE;
642 _nexell_hwc_get_changed_number(tdm_nexell_hwc *hwc_data)
645 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
647 LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
648 if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
651 if (hwc_window_data->client_type != hwc_window_data->validated_type)
659 _nexell_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info, hal_tdm_error *error)
661 tdm_nexell_hwc *hwc_data = hwc;
662 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
665 *error = HAL_TDM_ERROR_NONE;
668 TDM_BACKEND_ERR("invalid params");
670 *error = HAL_TDM_ERROR_INVALID_PARAMETER;
674 hwc_window_data = calloc(1, sizeof(tdm_nexell_hwc_window_data));
675 if (!hwc_window_data) {
676 TDM_BACKEND_ERR("alloc failed");
678 *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
682 hwc_window_data->hwc_data = hwc_data;
685 memcpy(&hwc_window_data->info, info, sizeof(hal_tdm_hwc_window_info));
687 LIST_INITHEAD(&hwc_window_data->link);
689 return hwc_window_data;
693 nexell_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error)
695 tdm_nexell_hwc *hwc_data = hwc;
696 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
698 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, NULL);
700 hwc_window_data = _nexell_hwc_create_window(hwc_data, NULL, error);
701 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
703 LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
705 TDM_BACKEND_DBG("hwc_window(%p) create", hwc_window_data);
707 *error = HAL_TDM_ERROR_NONE;
709 return hwc_window_data;
713 nexell_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count)
715 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
716 TDM_BACKEND_RETURN_VAL_IF_FAIL(formats != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
717 TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
719 // TODO: fix these formats.
720 *formats = hwc_window_video_formats;
721 *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format);
723 return HAL_TDM_ERROR_NONE;
727 nexell_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities)
729 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
730 TDM_BACKEND_RETURN_VAL_IF_FAIL(capabilities != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
732 *capabilities |= HAL_TDM_HWC_CAPABILITY_VIDEO_SCALE;
734 return HAL_TDM_ERROR_NONE;
738 nexell_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count)
740 tdm_nexell_hwc *hwc_data = hwc;
742 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
743 TDM_BACKEND_RETURN_VAL_IF_FAIL(props != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
744 TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
749 return HAL_TDM_ERROR_NONE;
753 nexell_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error)
755 tdm_nexell_hwc *hwc_data = hwc;
756 tbm_surface_queue_h tqueue = NULL;
759 *error = HAL_TDM_ERROR_INVALID_PARAMETER;
761 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
763 if (hwc_data->target_hwc_window == NULL) {
765 *error = HAL_TDM_ERROR_OPERATION_FAILED;
769 tqueue = tdm_nexell_hwc_window_create_tbm_buffer_queue(hwc_data->target_hwc_window, error);
770 TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue, NULL);
772 hwc_data->ui_buffer_queue[ZPOS_1].tqueue = tqueue;
773 hwc_data->ui_buffer_queue[ZPOS_1].ref_cnt = 1;
776 *error = HAL_TDM_ERROR_NONE;
782 nexell_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage)
784 tdm_nexell_hwc *hwc_data = hwc;
787 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
788 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, HAL_TDM_ERROR_OPERATION_FAILED);
790 err = nexell_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
791 TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
793 err = nexell_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
794 TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
796 return HAL_TDM_ERROR_NONE;
800 nexell_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
802 tdm_nexell_hwc *hwc_data = hwc;
803 tdm_nexell_output *output_data;
805 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
806 TDM_BACKEND_RETURN_VAL_IF_FAIL(num_types != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
808 output_data = hwc_data->output_data;
809 TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
811 TDM_BACKEND_DBG(" ==============Validate=================================");
814 _nexell_hwc_apply_policy(hwc_data, composited_wnds, num_wnds);
816 *num_types = _nexell_hwc_get_changed_number(hwc_data);
818 _print_validate_result(hwc_data, composited_wnds, num_wnds);
820 return HAL_TDM_ERROR_NONE;
824 nexell_hwc_get_changed_composition_types(hal_tdm_hwc *hwc, uint32_t *num_elements,
825 hal_tdm_hwc_window **hwc_wnds, hal_tdm_hwc_window_composition *composition_types)
827 tdm_nexell_hwc *hwc_data = hwc;
828 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
831 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
832 TDM_BACKEND_RETURN_VAL_IF_FAIL(num_elements != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
834 if ((hwc_wnds == NULL) || (composition_types == NULL)) {
835 *num_elements = _nexell_hwc_get_changed_number(hwc_data);
836 return HAL_TDM_ERROR_NONE;
839 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
840 if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
843 if (num >= *num_elements)
846 if (hwc_window_data->client_type != hwc_window_data->validated_type) {
847 composition_types[num] = hwc_window_data->validated_type;
848 hwc_wnds[num] = hwc_window_data;
853 /* set real num of changed composition types */
856 return HAL_TDM_ERROR_NONE;
860 nexell_hwc_accept_validation(hal_tdm_hwc *hwc)
862 tdm_nexell_hwc *hwc_data = hwc;
863 hal_tdm_error ret = HAL_TDM_ERROR_NONE;
865 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
866 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
868 TDM_BACKEND_DBG(" ==============Accept Changes Done=================================");
870 ret = _nexell_hwc_prepare_commit(hwc_data);
871 TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
873 return HAL_TDM_ERROR_NONE;
877 nexell_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data)
879 tdm_nexell_hwc *hwc_data = hwc;
880 tdm_nexell_output *output_data = NULL;
883 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
885 output_data = hwc_data->output_data;
886 TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
888 TDM_BACKEND_DBG(" ==============COMMIT=================================");
890 ret = nexell_output_commit(output_data, sync, user_data);
891 TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
893 return HAL_TDM_ERROR_NONE;
897 nexell_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func)
899 tdm_nexell_hwc *hwc_data = hwc;
901 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
902 TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
904 hwc_data->commit_func = func;
906 return HAL_TDM_ERROR_NONE;
910 nexell_hwc_target_window_set_info(tdm_nexell_hwc *hwc_data, int width, int height)
912 hal_tdm_hwc_window_info info = {0};
913 tdm_nexell_hwc_window_data *target_hwc_window;
914 hal_tdm_error ret = HAL_TDM_ERROR_NONE;
916 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
917 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, HAL_TDM_ERROR_INVALID_PARAMETER);
919 target_hwc_window = hwc_data->target_hwc_window;
923 info.dst_pos.w = width;
924 info.dst_pos.h = height;
926 info.src_config.pos.x = 0;
927 info.src_config.pos.y = 0;
928 info.src_config.pos.w = width;
929 info.src_config.pos.h = height;
931 info.src_config.size.h = width;
932 info.src_config.size.v = height;
933 info.src_config.format = TBM_FORMAT_ARGB8888;
935 ret = nexell_hwc_window_set_info(target_hwc_window, &info);
936 if (ret != HAL_TDM_ERROR_NONE) {
937 TDM_BACKEND_ERR("set info target hwc window failed (%d)", ret);
938 return HAL_TDM_ERROR_OPERATION_FAILED;
941 return HAL_TDM_ERROR_NONE;
945 tdm_nexell_hwc_initailize_target_window(tdm_nexell_hwc *hwc_data)
947 hal_tdm_hwc_window_info info = {0};
948 hal_tdm_error ret = HAL_TDM_ERROR_NONE;
949 tdm_nexell_hwc_window_data *target_hwc_window;
951 TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
958 info.src_config.pos.x = 0;
959 info.src_config.pos.y = 0;
960 info.src_config.pos.w = 2;
961 info.src_config.pos.h = 1;
963 info.src_config.size.h = 2;
964 info.src_config.size.v = 1;
965 info.src_config.format = TBM_FORMAT_ARGB8888;
967 target_hwc_window = _nexell_hwc_create_window(hwc_data, &info, &ret);
968 if (ret != HAL_TDM_ERROR_NONE) {
969 TDM_BACKEND_ERR("create target hwc window failed (%d)", ret);
970 return HAL_TDM_ERROR_OPERATION_FAILED;
973 if (hwc_data->target_hwc_window)
974 nexell_hwc_window_destroy(hwc_data->target_hwc_window);
976 hwc_data->target_hwc_window = target_hwc_window;
977 hwc_data->need_set_crtc = 1;
979 return HAL_TDM_ERROR_NONE;