5 #include <tdm_helper.h>
6 #include "tdm_nexell.h"
10 tbm_format hwc_window_video_formats[] = {
16 _comp_to_str(tdm_hwc_window_composition composition_type)
18 if (composition_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
20 else if (composition_type == TDM_HWC_WIN_COMPOSITION_DEVICE)
22 else if (composition_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
24 else if (composition_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
26 else if (composition_type == TDM_HWC_WIN_COMPOSITION_NONE)
33 _nexell_hwc_cursor_buffer_unset(tdm_nexell_hwc_window_data *hwc_window_data)
35 hwc_window_data->surface = NULL;
36 hwc_window_data->cursor_img_surface = 0;
38 hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width;
39 hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height;
40 hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width;
41 hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height;
47 _nexell_hwc_cursor_adjust_pos(tdm_nexell_hwc_window_data *hwc_window_data)
51 /* dst pos of cursor is possible set by negative value
52 * this is temporary code.
55 x = hwc_window_data->info.dst_pos.x;
56 y = hwc_window_data->info.dst_pos.y;
58 if (x < 0) hwc_window_data->info.dst_pos.x = 0;
59 if (y < 0) hwc_window_data->info.dst_pos.y = 0;
63 _nexell_hwc_cursor_buffer_set(tdm_nexell_hwc_data *hwc_data, tdm_nexell_hwc_window_data *hwc_window_data)
65 tbm_surface_h cursor_tsurface = NULL;
66 tbm_surface_info_s tsurface_info;
67 tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE;
68 int img_w, img_h, new_w, new_h;
69 tbm_format new_format;
70 unsigned int flags = TBM_BO_SCANOUT;
71 void *src_ptr = NULL, *dst_ptr = NULL;
75 _nexell_hwc_cursor_adjust_pos(hwc_window_data);
77 if (!hwc_window_data->cursor_img_refresh && hwc_window_data->surface)
80 img_w = hwc_window_data->cursor_img.width;
81 img_h = hwc_window_data->cursor_img.height;
82 new_format = hwc_window_data->info.src_config.format;
84 /* cursor restriction to set the cursor layer */
85 new_w = (CURSOR_MIN_W > img_w) ? CURSOR_MIN_W : img_w;
86 new_h = (CURSOR_MIN_H > img_h) ? CURSOR_MIN_H : img_h;
88 if (hwc_data->cursor_tsurface) {
89 tbm_surface_internal_unref(hwc_data->cursor_tsurface);
90 hwc_data->cursor_tsurface = NULL;
93 cursor_tsurface = tbm_surface_internal_create_with_flags(new_w, new_h, new_format, flags);
94 RETURN_VAL_IF_FAIL(cursor_tsurface, 0);
96 hwc_data->cursor_tsurface = cursor_tsurface;
97 ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info);
98 if (ret != TBM_SURFACE_ERROR_NONE) {
99 TDM_ERR("Failed to map tsurface\n");
100 tbm_surface_internal_unref(hwc_data->cursor_tsurface);
101 hwc_data->cursor_tsurface = NULL;
105 src_ptr = hwc_window_data->cursor_img.ptr;
106 dst_ptr = tsurface_info.planes[0].ptr;
107 src_stride = hwc_window_data->cursor_img.stride;
109 memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height);
111 for (i = 0 ; i < img_h ; i++) {
112 memcpy(dst_ptr, src_ptr, src_stride);
113 dst_ptr += tsurface_info.planes[0].stride;
114 src_ptr += src_stride;
117 tbm_surface_unmap(hwc_data->cursor_tsurface);
119 hwc_window_data->surface = hwc_data->cursor_tsurface;
120 hwc_window_data->cursor_img_surface = 1;
122 /* fix the dst_pos info of the cursor window */
123 hwc_window_data->info.src_config.pos.w = new_w;
124 hwc_window_data->info.src_config.pos.h = new_h;
125 hwc_window_data->info.dst_pos.w = new_w;
126 hwc_window_data->info.dst_pos.h = new_h;
128 hwc_window_data->cursor_img_refresh = 0;
134 _print_validate_result(tdm_nexell_hwc_data *hwc_data, tdm_hwc_window **composited_wnds, uint32_t num_wnds)
136 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
140 for (i = 0; i < num_wnds; i++) {
141 hwc_window_data = composited_wnds[i];
142 lzpos_queue = hwc_window_data->lzpos_queue;
143 switch (hwc_window_data->validated_type) {
144 case TDM_HWC_WIN_COMPOSITION_CLIENT:
145 TDM_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p, ref_cnt:%d] -- {%s} on TARGET WINDOW", hwc_window_data,
146 _comp_to_str(hwc_window_data->client_type),
147 _comp_to_str(hwc_window_data->validated_type),
148 hwc_data->target_hwc_window->lzpos,
149 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
150 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
151 hwc_window_data->name ? hwc_window_data->name : "NONE");
153 case TDM_HWC_WIN_COMPOSITION_DEVICE:
154 case TDM_HWC_WIN_COMPOSITION_VIDEO:
155 case TDM_HWC_WIN_COMPOSITION_CURSOR:
156 case TDM_HWC_WIN_COMPOSITION_NONE:
157 TDM_DBG(" window(%p) %s -> %s : lzpos(%d) lzpos_queue(%d)[tqueue:%p ref_cnt:%d] -- {%s}", hwc_window_data,
158 _comp_to_str(hwc_window_data->client_type),
159 _comp_to_str(hwc_window_data->validated_type),
160 hwc_window_data->lzpos,
161 lzpos_queue, lzpos_queue == -1 ? NULL : hwc_data->ui_buffer_queue[lzpos_queue].tqueue,
162 lzpos_queue == -1 ? 0 : hwc_data->ui_buffer_queue[lzpos_queue].ref_cnt,
163 hwc_window_data->name ? hwc_window_data->name : "NONE");
172 _nexell_hwc_window_has_reserved_buffer(tdm_nexell_hwc_window_data *hwc_window_data) {
176 RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
177 RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, 0);
179 bo = tbm_surface_internal_get_bo(hwc_window_data->surface, 0);
180 RETURN_VAL_IF_FAIL(bo != NULL, 0);
182 flags = tbm_bo_get_flags(bo);
184 return flags & TBM_BO_SCANOUT;
188 _nexell_hwc_window_can_set_on_hw_layer(tdm_nexell_hwc_window_data *hwc_window_data)
190 if (!hwc_window_data->surface)
193 if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
196 if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
199 if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
202 if (!IS_RGB(hwc_window_data->info.src_config.format))
205 if (hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay ||
206 hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay)
209 if (hwc_window_data->info.src_config.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2)
216 tdm_nexell_hwc_window_create_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
218 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
219 tbm_surface_queue_h tqueue = NULL;
224 *error = TDM_ERROR_INVALID_PARAMETER;
226 RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
228 hwc_window_data = hwc_window;
230 width = hwc_window_data->info.src_config.size.h;
231 height = hwc_window_data->info.src_config.size.v;
232 format = hwc_window_data->info.src_config.format;
234 tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, format, TBM_BO_SCANOUT);
236 *error = TDM_ERROR_OPERATION_FAILED;
237 RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
240 *error = TDM_ERROR_NONE;
246 tdm_nexell_hwc_window_destroy_tbm_buffer_queue(tbm_surface_queue_h tqueue)
248 tbm_surface_queue_destroy(tqueue);
252 _nexell_hwc_layer_attach_window(tdm_nexell_layer_data *layer_data, tdm_nexell_hwc_window_data *hwc_window_data)
254 tdm_error ret = TDM_ERROR_NONE;
256 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
258 if (hwc_window_data == NULL || hwc_window_data->surface == NULL) {
259 if (layer_data->display_buffer)
260 ret = nexell_layer_unset_buffer(layer_data);
261 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
263 ret = nexell_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
264 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
265 RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, TDM_ERROR_INVALID_PARAMETER);
266 ret = nexell_layer_set_buffer(layer_data, hwc_window_data->surface);
267 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
274 _nexell_hwc_prepare_commit(tdm_nexell_hwc_data *hwc_data)
276 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
277 tdm_nexell_layer_data *layer_data = NULL;
278 int use_layers_zpos[NUM_LAYERS] = {0,};
281 /* set target hwc window to the layer */
282 if (hwc_data->need_target_window) {
283 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos);
284 _nexell_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window);
285 use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1;
288 /* set the hwc_windows to the layers */
289 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
290 if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_NONE ||
291 hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CLIENT) {
293 if (hwc_window_data->cursor_img_surface)
294 _nexell_hwc_cursor_buffer_unset(hwc_window_data);
299 if (hwc_window_data == hwc_data->target_hwc_window)
302 /* set the cursor buffer HERE if it needs */
303 if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
304 _nexell_hwc_cursor_buffer_set(hwc_data, hwc_window_data);
306 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos);
307 _nexell_hwc_layer_attach_window(layer_data, hwc_window_data);
308 use_layers_zpos[hwc_window_data->lzpos] = 1;
311 /* unset the unused layers */
312 for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) {
313 if (use_layers_zpos[lzpos])
316 layer_data = nexell_output_data_get_layer_data(hwc_data->output_data, lzpos);
320 _nexell_hwc_layer_attach_window(layer_data, NULL);
324 for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) {
325 if (use_layers_zpos[lzpos])
326 TDM_DBG(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET");
329 return TDM_ERROR_NONE;
332 /* assign the validated_type to the composited_wnds
333 * assign the layer_zpos to the composited_wnds
336 _nexell_hwc_apply_policy(tdm_nexell_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds)
338 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
339 tdm_nexell_hwc_window_data **composited_list = NULL;
340 int client_count = 0;
341 int device_count = 0;
343 int cursor_count = 0;
345 int top_index = 0; // index of top in composited_wnds
346 int bottom_index = num_wnds - 1; // index of bottom in comopsited_wnds
347 int available_device_num = NUM_LAYERS;
348 int use_hw_layers[NUM_LAYERS] = {0, }; // 2 is top, 0 is bottom
350 composited_list = (tdm_nexell_hwc_window_data **)composited_wnds;
355 for (i = 0; i < num_wnds; i++) {
356 TDM_DBG(" [%d] name(%s)", i, composited_list[i]->name);
357 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_NONE;
358 composited_list[i]->lzpos = -1;
359 composited_list[i]->lzpos_queue = -1;
363 goto set_clients_below;
366 /* initialize the need_target_window */
367 hwc_data->need_target_window = 0;
369 /* initialize the validated_types and constraints */
370 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
371 hwc_window_data->constraints = TDM_HWC_WIN_CONSTRAINT_NONE;
372 if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_NONE)
374 hwc_window_data->validated_type = TDM_HWC_WIN_COMPOSITION_NONE;
375 hwc_window_data->lzpos = -1;
376 hwc_window_data->lzpos_queue = -1;
379 /* use the target_window to commit when there is no window. */
381 hwc_data->need_target_window = 1;
382 hwc_data->target_hwc_window->lzpos = ZPOS_1;
383 hwc_data->target_hwc_window->lzpos_queue = ZPOS_1;
387 /* count the composited(visible) windows */
388 for (i = 0; i < num_wnds; i++) {
389 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
391 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
393 if (client_count == 0 && composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_DEVICE)
395 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
399 /* set the cursor layer pos and validated_type */
400 if (cursor_count > 0) {
401 composited_list[top_index]->validated_type = TDM_HWC_WIN_COMPOSITION_CURSOR;
402 composited_list[top_index]->lzpos = ZPOS_2;
403 use_hw_layers[ZPOS_2] = 1;
404 available_device_num--;
407 /* set the video layer pos and validated_type */
408 if (video_count > 0) {
409 composited_list[bottom_index]->validated_type = TDM_HWC_WIN_COMPOSITION_VIDEO;
410 composited_list[bottom_index]->lzpos = ZPOS_0;
411 use_hw_layers[ZPOS_0] = 1;
412 available_device_num--;
415 /* check if target_window is needed */
416 if (client_count > 0) {
417 hwc_data->need_target_window = 1;
418 use_hw_layers[ZPOS_1] = 1; // target_window must set to ZPOS_1 because it is primary layer.
419 available_device_num--;
422 /* set all client types when the number of devide types is over than available device_num */
423 if (available_device_num <= 0)
424 goto set_clients_below;
428 for (i = 0; i < num_wnds; i++) {
429 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
431 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
432 goto set_clients_below;
433 if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
436 /* set clients below when nexell can not set the window to the hw layer */
437 if (!_nexell_hwc_window_can_set_on_hw_layer(composited_list[i]))
438 goto set_clients_below;
440 //lzpos = _nexell_hwc_window_get_lzpos(composited_list[i]);
441 //if (lzpos == -1) break;
443 for (j = ZPOS_2; j >= ZPOS_0; j--) {
444 if (use_hw_layers[j]) continue;
448 /* check no available hw_layer */
449 if (lzpos == -1) break;
451 /* set clients below when the hwc_window does not have the reserved buffer */
452 if (!_nexell_hwc_window_has_reserved_buffer(composited_list[i]))
454 /* set the buffer_queue constraint */
455 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
456 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
457 composited_list[i]->lzpos = -1;
458 composited_list[i]->lzpos_queue = lzpos;
459 hwc_data->need_target_window = 1;
460 TDM_DBG(" NO reserved_buffer.(%s) Request acquire_buffer_queue(lzpos_queue:%d) for SCANOUT Buffer.", composited_list[i]->name, lzpos);
464 /* set the constraint_buffer_queue, validated_type, lzpos, lqueue of the UI layer */
465 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
466 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_DEVICE;
467 composited_list[i]->lzpos = lzpos;
468 composited_list[i]->lzpos_queue = lzpos;
469 use_hw_layers[lzpos] = 1;
470 TDM_DBG("YES reserved_buffer.(%s) Set the DEVICE_TYPE.", composited_list[i]->name);
474 for (i = 0; i < num_wnds; i++) {
475 if (composited_list[i]->validated_type != TDM_HWC_WIN_COMPOSITION_NONE)
478 composited_list[i]->constraints = TDM_HWC_WIN_CONSTRAINT_NONE;
479 composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
480 composited_list[i]->lzpos = -1;
481 composited_list[i]->lzpos_queue = -1;
483 if (!hwc_data->need_target_window) {
484 hwc_data->need_target_window = 1;
485 hwc_data->target_hwc_window->lzpos = ZPOS_1;
486 hwc_data->target_hwc_window->lzpos_queue = ZPOS_1;
492 _nexell_hwc_get_changed_number(tdm_nexell_hwc_data *hwc_data)
495 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
497 LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
498 if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
501 if (hwc_window_data->client_type != hwc_window_data->validated_type)
509 _nexell_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error)
511 tdm_nexell_hwc_data *hwc_data = hwc;
512 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
515 *error = TDM_ERROR_NONE;
518 TDM_ERR("invalid params");
520 *error = TDM_ERROR_INVALID_PARAMETER;
524 hwc_window_data = calloc(1, sizeof(tdm_nexell_hwc_window_data));
525 if (!hwc_window_data) {
526 TDM_ERR("alloc failed");
528 *error = TDM_ERROR_OUT_OF_MEMORY;
532 hwc_window_data->hwc_data = hwc_data;
535 memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
537 LIST_INITHEAD(&hwc_window_data->link);
539 return hwc_window_data;
543 nexell_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
545 tdm_nexell_hwc_data *hwc_data = hwc;
546 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
548 RETURN_VAL_IF_FAIL(hwc_data, NULL);
550 hwc_window_data = _nexell_hwc_create_window(hwc_data, NULL, error);
551 RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
553 LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
555 TDM_DBG("hwc_window(%p) create", hwc_window_data);
557 *error = TDM_ERROR_NONE;
559 return hwc_window_data;
563 nexell_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
565 RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
566 RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
567 RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
569 // TODO: fix these formats.
570 *formats = hwc_window_video_formats;
571 *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format);
573 return TDM_ERROR_NONE;
577 nexell_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
579 RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
580 RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
584 return TDM_ERROR_NONE;
588 nexell_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
590 tdm_nexell_hwc_data *hwc_data = hwc;
592 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
593 RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
594 RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
599 return TDM_ERROR_NONE;
603 nexell_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
605 tdm_nexell_hwc_data *hwc_data = hwc;
606 tbm_surface_queue_h tqueue = NULL;
609 *error = TDM_ERROR_INVALID_PARAMETER;
611 RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
613 if (hwc_data->target_hwc_window == NULL) {
615 *error = TDM_ERROR_OPERATION_FAILED;
619 tqueue = tdm_nexell_hwc_window_create_tbm_buffer_queue(hwc_data->target_hwc_window, error);
620 RETURN_VAL_IF_FAIL(tqueue, NULL);
623 *error = TDM_ERROR_NONE;
624 /* reference the target_buffer queue */
625 hwc_data->ui_buffer_queue[ZPOS_1].tqueue = tqueue;
626 hwc_data->ui_buffer_queue[ZPOS_1].ref_cnt = 1;
628 for (int i = NUM_LAYERS-1; i >= 0; i--) {
629 TDM_ERR("[%d]: lzpos_queue:%d tqueue:%p, ref_cnt:%d",
631 hwc_data->ui_buffer_queue[i].tqueue,
632 hwc_data->ui_buffer_queue[i].ref_cnt);
640 nexell_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
642 tdm_nexell_hwc_data *hwc_data = hwc;
645 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
646 RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, TDM_ERROR_OPERATION_FAILED);
648 err = nexell_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
649 RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
651 err = nexell_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
652 RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
654 return TDM_ERROR_NONE;
658 nexell_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
660 tdm_nexell_hwc_data *hwc_data = hwc;
661 tdm_nexell_output_data *output_data;
663 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
664 RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
666 output_data = hwc_data->output_data;
667 RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
669 TDM_INFO(" ==============Validate=================================");
672 _nexell_hwc_apply_policy(hwc_data, composited_wnds, num_wnds);
674 *num_types = _nexell_hwc_get_changed_number(hwc_data);
676 _print_validate_result(hwc_data, composited_wnds, num_wnds);
678 return TDM_ERROR_NONE;
682 nexell_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
683 tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types)
685 tdm_nexell_hwc_data *hwc_data = hwc;
686 tdm_nexell_hwc_window_data *hwc_window_data = NULL;
689 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
690 RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
692 if ((hwc_wnds == NULL) || (composition_types == NULL)) {
693 *num_elements = _nexell_hwc_get_changed_number(hwc_data);
694 return TDM_ERROR_NONE;
697 LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
698 if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
701 if (num >= *num_elements)
704 if (hwc_window_data->client_type != hwc_window_data->validated_type) {
705 composition_types[num] = hwc_window_data->validated_type;
706 hwc_wnds[num] = hwc_window_data;
711 /* set real num of changed composition types */
714 return TDM_ERROR_NONE;
718 nexell_hwc_accept_validation(tdm_hwc *hwc)
720 tdm_nexell_hwc_data *hwc_data = hwc;
721 tdm_error ret = TDM_ERROR_NONE;
723 RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
724 RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
726 TDM_DBG(" ==============Accept Changes Done=================================");
728 ret = _nexell_hwc_prepare_commit(hwc_data);
729 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
731 return TDM_ERROR_NONE;
735 nexell_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
737 tdm_nexell_hwc_data *hwc_data = hwc;
738 tdm_nexell_output_data *output_data = NULL;
741 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
743 output_data = hwc_data->output_data;
744 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
746 TDM_INFO(" ==============COMMIT=================================");
748 ret = nexell_output_commit(output_data, sync, user_data);
749 RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
751 return TDM_ERROR_NONE;
755 nexell_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
757 tdm_nexell_hwc_data *hwc_data = hwc;
759 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
760 RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
762 hwc_data->commit_func = func;
764 return TDM_ERROR_NONE;
768 nexell_hwc_target_window_set_info(tdm_nexell_hwc_data *hwc_data, int width, int height)
770 tdm_hwc_window_info info = {0};
771 tdm_nexell_hwc_window_data *target_hwc_window;
772 tdm_error ret = TDM_ERROR_NONE;
774 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
775 RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, TDM_ERROR_INVALID_PARAMETER);
777 target_hwc_window = hwc_data->target_hwc_window;
781 info.dst_pos.w = width;
782 info.dst_pos.h = height;
784 info.src_config.pos.x = 0;
785 info.src_config.pos.y = 0;
786 info.src_config.pos.w = width;
787 info.src_config.pos.h = height;
789 info.src_config.size.h = width;
790 info.src_config.size.v = height;
791 info.src_config.format = TBM_FORMAT_ARGB8888;
793 ret = nexell_hwc_window_set_info(target_hwc_window, &info);
794 if (ret != TDM_ERROR_NONE) {
795 TDM_ERR("set info target hwc window failed (%d)", ret);
796 return TDM_ERROR_OPERATION_FAILED;
799 return TDM_ERROR_NONE;
803 nexell_hwc_initailize_target_window(tdm_nexell_hwc_data *hwc_data)
805 tdm_hwc_window_info info = {0};
806 tdm_error ret = TDM_ERROR_NONE;
807 tdm_nexell_hwc_window_data *target_hwc_window;
809 RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
816 info.src_config.pos.x = 0;
817 info.src_config.pos.y = 0;
818 info.src_config.pos.w = 2;
819 info.src_config.pos.h = 1;
821 info.src_config.size.h = 2;
822 info.src_config.size.v = 1;
823 info.src_config.format = TBM_FORMAT_ARGB8888;
825 target_hwc_window = _nexell_hwc_create_window(hwc_data, &info, &ret);
826 if (ret != TDM_ERROR_NONE) {
827 TDM_ERR("create target hwc window failed (%d)", ret);
828 return TDM_ERROR_OPERATION_FAILED;
831 if (hwc_data->target_hwc_window)
832 nexell_hwc_window_destroy(hwc_data->target_hwc_window);
834 hwc_data->target_hwc_window = target_hwc_window;
835 hwc_data->need_set_crtc = 1;
837 return TDM_ERROR_NONE;