1 #include "e_mod_comp_shared_types.h"
2 #include "e_mod_comp.h"
3 #include "e_mod_comp_canvas.h"
4 #include "e_mod_comp_atoms.h"
5 #include "e_mod_comp_debug.h"
7 #include "hwcomp_debug.h"
9 #include <X11/extensions/hwc.h>
11 #include "hwcomp_util.h"
12 #include "hwcomp_debug.h"
13 #include "hwcomp_mobile.h"
15 #if OPTIMIZED_HWC_MOBILE
16 #define KEYBOARD_MAGNIFIER_WIDTH_PORTRAIT 200
17 #define KEYBOARD_MAGNIFIER_WIDTH_LANDSCAPE 160
20 Eina_Bool _hwcomp_mod_mobile_mobile_init(E_Comp *c)
22 E_CHECK_RETURN(c, EINA_FALSE);
25 c->hwcomp_funcs.set_drawables = _hwcomp_mod_mobile_update_set_drawables;
26 c->hwcomp_funcs.verify_update_mode = _hwcomp_mod_mobile_verify_update_mode;
33 _hwcomp_mod_mobile_update_set_drawables(E_Comp_HWComp_Update *hwc_update, Ecore_X_Window win)
35 E_Comp_HWComp_Drawable *hwc_drawable = NULL;
36 Ecore_X_Drawable *d = NULL;
37 int count = 0, idx = 0;
40 #if OPTIMIZED_HWC_MOBILE
41 XRectangle *src_rects = NULL;
42 XRectangle *dst_rects = NULL;
43 int *comp_method = NULL;
44 int zone_x = 0, zone_y = 0, zone_w = 0, zone_h = 0;
48 if (!hwc_update) return;
50 for (i = 0; i < hwc_update->num_drawable; i++)
52 hwc_drawable = hwc_update->hwc_drawable[i];
53 if (hwc_drawable->set_drawable)
57 if (count <= 0) return;
59 d = E_NEW(Ecore_X_Drawable, count);
63 #if OPTIMIZED_HWC_MOBILE
64 src_rects = E_NEW(XRectangle, count);
71 dst_rects = E_NEW(XRectangle, count);
79 comp_method = E_NEW(int, count);
88 if (hwc_update->hwcomp->canvas && hwc_update->hwcomp->canvas->zone)
90 zone_x = hwc_update->hwcomp->canvas->zone->x;
91 zone_y = hwc_update->hwcomp->canvas->zone->y;
92 zone_w = hwc_update->hwcomp->canvas->zone->w;
93 zone_h = hwc_update->hwcomp->canvas->zone->h;
99 zone_w = hwc_update->hwcomp->screen_width;
100 zone_h = hwc_update->hwcomp->screen_height;
104 if (hwc_update->hwcomp->canvas && hwc_update->hwcomp->canvas->zone)
106 zone_rot = e_zone_rotation_get(hwc_update->hwcomp->canvas->zone);
107 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES: Zone Rotation[%d]", "HWC:Zone",
112 //if zone is not present then what to do ?
113 if (hwc_update->ime_present)
115 if (hwc_update->ime_rect.h == hwc_update->hwcomp->screen_height)
117 if (hwc_update->ime_rect.x == 0)
126 for (i = 0; i < hwc_update->num_drawable; i++)
128 hwc_drawable = hwc_update->hwc_drawable[i];
129 if (hwc_drawable->set_drawable)
132 #if OPTIMIZED_HWC_MOBILE
134 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES: id (%d) , cnt(%d), fu(%d)", "HWC",
135 i, hwc_drawable->update_count, hwc_drawable->first_update);
136 hwc_drawable->update_count++ ; //for debugging
138 if (hwc_update->update_mode == E_HWCOMP_USE_FULLCOMP_MODE)
140 src_rects[idx].x = zone_x;
141 src_rects[idx].y = zone_y;
142 src_rects[idx].width = zone_w;
143 src_rects[idx].height = zone_h;
145 hwc_drawable->first_update = 0;
147 else if (i == 0 && hwc_update->hwcomp->miniapp_present)
149 src_rects[idx].x = zone_x;
150 src_rects[idx].y = zone_y;
151 src_rects[idx].width = zone_w;
152 src_rects[idx].height = zone_h;
154 hwc_drawable->first_update = 0;
156 else if (i == 0 && hwc_update->ime_present && hwc_update->split_launcher_rect_present)
158 src_rects[idx].x = zone_x;
159 src_rects[idx].y = zone_y;
160 src_rects[idx].width = zone_w;
161 src_rects[idx].height = zone_h;
163 hwc_drawable->first_update = 0;
165 else if (i == 0 && hwc_update->ime_present)
167 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES: kbgeo[%d, %d, %d, %d] zRot[%d]", "HWC:Zone-KB",
168 hwc_update->ime_rect.x,hwc_update->ime_rect.y, hwc_update->ime_rect.w,
169 hwc_update->ime_rect.h, zone_rot);
170 #if HWC_ROTATION_PATCH
171 src_rects[idx].x = zone_x;
172 src_rects[idx].y = zone_y;
173 src_rects[idx].width = zone_w;
174 src_rects[idx].height = zone_h;
176 hwc_drawable->first_update = 0;
178 if (zone_rot == 0 || (zone_rot != 0 && hwc_update->ime_rect.y != 0))
180 if (hwc_drawable->first_update == 0)
182 src_rects[idx].x = zone_x;
183 src_rects[idx].y = zone_y;
184 src_rects[idx].width = zone_w;
185 src_rects[idx].height = zone_h;
187 hwc_drawable->first_update = 1;
191 src_rects[idx].x = hwc_update->ime_rect.x;
192 src_rects[idx].y = hwc_update->ime_rect.y - KEYBOARD_MAGNIFIER_WIDTH_PORTRAIT; //includes magnifier
193 src_rects[idx].width = hwc_update->ime_rect.w;
194 src_rects[idx].height = hwc_update->ime_rect.h + KEYBOARD_MAGNIFIER_WIDTH_PORTRAIT; //includes magnifier
199 if (hwc_drawable->first_update == 0)
201 src_rects[idx].x = zone_x;
202 src_rects[idx].y = zone_y;
203 src_rects[idx].width = zone_w;
204 src_rects[idx].height = zone_h;
206 hwc_drawable->first_update = 1;
212 src_rects[idx].x = hwc_update->ime_rect.x - KEYBOARD_MAGNIFIER_WIDTH_LANDSCAPE;
214 else //case (zone_rot == 270), as already zone angle 0 and 90 handled
216 src_rects[idx].x = hwc_update->ime_rect.x;
218 src_rects[idx].y = hwc_update->ime_rect.y;
219 src_rects[idx].width = hwc_update->ime_rect.w + KEYBOARD_MAGNIFIER_WIDTH_LANDSCAPE;
220 src_rects[idx].height = hwc_update->ime_rect.h;
225 else if (i == 0 && hwc_update->split_launcher_rect_present)
227 src_rects[idx].x = zone_x;
228 src_rects[idx].y = zone_y;
229 src_rects[idx].width = zone_w;
230 src_rects[idx].height = zone_h;
232 hwc_drawable->first_update = 0;
236 if (hwc_drawable->cw)
238 src_rects[idx].x = hwc_drawable->cw->x;
239 src_rects[idx].y = hwc_drawable->cw->y;
240 src_rects[idx].width = hwc_drawable->cw->w;
241 src_rects[idx].height = hwc_drawable->cw->h;
245 src_rects[idx].x = zone_x;
246 src_rects[idx].y = zone_y;
247 src_rects[idx].width = zone_w;
248 src_rects[idx].height = zone_h;
253 //check for keyboard intersection
254 #if OPTIMIZED_HWC_MOBILE
255 if (hwc_update->ime_present && i != 0 && hwc_drawable->cw &&
256 E_INTERSECTS(hwc_drawable->cw->x, hwc_drawable->cw->y,
257 hwc_drawable->cw->w, hwc_drawable->cw->h,
258 hwc_update->ime_rect.x, hwc_update->ime_rect.y,
259 hwc_update->ime_rect.w, hwc_update->ime_rect.h)
261 !E_CONTAINS(hwc_update->ime_rect.x, hwc_update->ime_rect.y,
262 hwc_update->ime_rect.w, hwc_update->ime_rect.h,
263 hwc_drawable->cw->x, hwc_drawable->cw->y,
264 hwc_drawable->cw->w, hwc_drawable->cw->h))
266 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES:Drawable[%d] size [%d, %d, %d, %d]", "HWC:Reduce", i, hwc_drawable->cw->x, hwc_drawable->cw->y,
267 hwc_drawable->cw->w, hwc_drawable->cw->h);
269 if (zone_rot == 0 || (zone_rot != 0 && hwc_update->ime_rect.y != 0))
271 src_rects[idx].x = hwc_drawable->cw->x;
272 src_rects[idx].y = hwc_drawable->cw->y;
273 src_rects[idx].width = hwc_drawable->cw->w;
274 src_rects[idx].height = hwc_drawable->cw->h - (hwc_drawable->cw->y +
275 hwc_drawable->cw->h - hwc_update->ime_rect.y);
281 src_rects[idx].x = hwc_drawable->cw->x;
282 src_rects[idx].y = hwc_drawable->cw->y;
283 src_rects[idx].width = hwc_update->ime_rect.x - hwc_drawable->cw->x;
284 src_rects[idx].height = hwc_drawable->cw->h;
286 else // case (zone_rot == 270) as 0 and 90 zone angle already handled
288 int actualX = src_rects[idx].x;
289 src_rects[idx].x = hwc_update->ime_rect.x + hwc_update->ime_rect.w;
290 src_rects[idx].y = hwc_drawable->cw->y;
291 src_rects[idx].width = hwc_drawable->cw->w - (hwc_update->ime_rect.w - (actualX - hwc_update->ime_rect.x));
292 src_rects[idx].height = hwc_drawable->cw->h;
297 memcpy(&dst_rects[idx], &src_rects[idx], sizeof(XRectangle));
298 comp_method[idx] = HWC_COMPOSITE_METHOD_DEFAULT;
300 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES: id (%d) rect[%d, %d, %d, %d], cnt(%d), fu(%d)", "HWC",
301 i, dst_rects[i].x, dst_rects[i].y, dst_rects[i].width, dst_rects[i].height, hwc_drawable->update_count, hwc_drawable->first_update);
304 d[idx] = hwc_drawable->d;
311 for (i = 0; i < count; i++)
312 #if OPTIMIZED_HWC_MOBILE
313 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|Sree : total:%d, count(%d) win:0x%08x: rect[%d, %d, %d, %d]", "HWC",
314 count, i + 1, d[i], dst_rects[i].x, dst_rects[i].y, dst_rects[i].width, dst_rects[i].height);
316 for (i = 0; i < count; i++)
317 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|Sree : total:%d, count(%d) win:0x%08x:", "HWC",
322 #if OPTIMIZED_HWC_MOBILE
325 dst_rects[0].x = src_rects[0].x = zone_x;
326 dst_rects[0].y = src_rects[0].y = zone_y;
327 dst_rects[0].width = src_rects[0].width = zone_w;
328 dst_rects[0].height = src_rects[0].height = zone_h;
329 comp_method[0] = HWC_COMPOSITE_METHOD_DEFAULT;
331 /*TODO: Get Active Crtc */
332 HWCSetDrawables(hwcomp_util_display_get(), 0, win, (Drawable *)d, (XRectangle *)src_rects, (XRectangle *)dst_rects, (int *) comp_method, count);
334 // Build Error. when OPTIMIZED_HWC_MOBILE is 0
335 //HWCSetDrawables(hwcomp_util_display_get(), win, (Drawable *)d, count);
340 #if OPTIMIZED_HWC_MOBILE
348 _hwcomp_mod_mobile_verify_update_mode(E_Comp_HWComp *hwcomp, E_Comp_HWComp_Update *hwc_update)
351 E_Comp_Canvas *canvas = NULL;
353 E_Comp_Layer *ly = NULL;
354 Eina_Bool effect_status = EINA_FALSE, move_status = EINA_FALSE, rotation_status = EINA_FALSE;
357 E_Comp_Object *co = NULL, *_co = NULL;
359 Eina_Bool check_nocomp = EINA_TRUE;
361 const char *name = NULL;
363 #if OPTIMIZED_HWC_MOBILE
364 Eina_Rectangle total_rect = {0,};
365 Eina_Bool miniapp = EINA_FALSE;
366 Eina_Bool keyboard = EINA_FALSE;
367 Eina_Bool magnifier = EINA_FALSE;
368 Eina_Bool clipboard = EINA_FALSE;
369 Eina_Bool split_launcher = EINA_FALSE;
370 Eina_Rectangle clipboard_rect = {0,};
371 Eina_Rectangle zone_rect = {0,};
375 E_CHECK_RETURN(c, 0);
377 canvas = hwcomp->canvas;
378 E_CHECK_RETURN(canvas, 0);
381 E_CHECK_RETURN(zone, 0);
383 #if OPTIMIZED_HWC_MOBILE
384 zone_rect.x = zone->x;
385 zone_rect.y = zone->y;
386 zone_rect.w = zone->h;
387 zone_rect.h = zone->h;
390 /* pre-check full composite condition */
391 ly = e_mod_comp_canvas_layer_get(canvas, "effect");
393 effect_status = evas_object_visible_get(ly->layout);
394 ly = e_mod_comp_canvas_layer_get(canvas, "move");
396 move_status = evas_object_visible_get(ly->layout);
397 if ((canvas->zone) && (canvas->zone->rot.block_count))
398 rotation_status = EINA_TRUE;
401 * basically canvas->ee_win always will be set at top layer0
402 * this drawable drawn by GLES
404 hwc_update->hwc_drawable[0]->cw = NULL;
405 hwc_update->hwc_drawable[0]->d = canvas->ee_win;
406 hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
408 #if OPTIMIZED_HWC_MOBILE
409 hwc_update->hwc_drawable[0]->first_update = 0;
412 hwc_update->hwc_drawable[0]->update_count = 0; //for debugging
417 if (hwcomp_util_max_layer_get() == 1)
420 if (hwcomp->force_composite)
423 #if HWC_ROTATION_PATCH
424 if (hwcomp->doing_rotation)
429 if (effect_status == EINA_TRUE)
431 if (move_status == EINA_TRUE)
433 if (rotation_status == EINA_TRUE)
437 * I have 2 special cases
439 * CASE 1 : 1 full screen app overlapes full screen
441 * CASE 2: Some windows are can be set at HW layer
442 * - If num of windows are bigger than "hwcomp->num_overlays-1" additional algorithm should be used.
444 EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
446 EINA_LIST_FOREACH(cw->objs, l, co)
449 if (co->canvas != canvas) continue;
455 if ((_co) && (cw->bd) && (cw->bd->client.win) &&
456 (!cw->shaped) && (!cw->rects) && (cw->hwc.set_drawable))
458 int abs_x, abs_y, abs_w, abs_h;
460 name = hwcomp_util_border_name_get(cw->bd);
462 #if OPTIMIZED_HWC_MOBILE
468 ecore_x_window_geometry_get(cw->win, &abs_x, &abs_y, &abs_w, &abs_h);
471 if (E_CONTAINS(zone->x, zone->y, zone->w, zone->h, abs_x, abs_y, abs_w, abs_h) || (name && !strcmp(name, "SPLIT_LAUNCHER")))
473 /* check nocomp mode with the first cw once */
474 if (check_nocomp && REGION_EQUAL_TO_ZONE(cw, zone) && cw->use_dri2 && (!cw->argb)
475 && !cw->hwc.resize_pending)
477 hwc_update->update_mode = E_HWCOMP_USE_NOCOMP_MODE;
478 hwc_update->num_drawable = 1;
479 hwc_update->hwc_drawable[0]->cw = cw;
480 hwc_update->hwc_drawable[0]->d = cw->bd->client.win;
481 hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
483 #if OPTIMIZED_HWC_MOBILE
484 hwc_update->hwc_drawable[0]->first_update = 0;
486 hwc_update->hwc_drawable[0]->update_count = 0; //for debugging
494 if (check_nocomp) check_nocomp = EINA_FALSE;
497 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|VERIFY_UPDATE:win id:0x%08x name:%s", "HWC:NAME", cw->win, cw->bd->client.icccm.name);
498 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|VERIFY_UPDATE:win id:0x%08x class:%s", "HWC:NAME", cw->win, cw->bd->client.icccm.class);
499 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|VERIFY_UPDATE:win id:0x%08x title:%s", "HWC:NAME", cw->win, cw->bd->client.icccm.title);
500 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|VERIFY_UPDATE:win id:0x%08x iconname:%s", "HWC:NAME", cw->win, cw->bd->client.icccm.icon_name);
501 /* skip the cw if the cw is not the use_dri2 */
502 if (!cw->use_dri2 && !cw->argb)
505 /* skip the cw is the Key Magnifier */
506 #if OPTIMIZED_HWC_MOBILE
507 if (name && !strcmp(name, "Key Magnifier"))
510 magnifier = EINA_TRUE;
511 hwc_update->keymag_rect.x = cw->x;
512 hwc_update->keymag_rect.y = cw->y;
513 hwc_update->keymag_rect.w = cw->w;
514 hwc_update->keymag_rect.h = cw->h;
516 _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|KM_RECT rect(%d,%d,%d,%d)", "HWC:RECT", cw->x, cw->y, cw->w, cw->h);
521 if (cw->bd->client.icccm.name && !strcmp(cw->bd->client.icccm.name, "Key Magnifier"))
525 /* skip the cw is the Prediction Window */
526 #if OPTIMIZED_HWC_MOBILE
527 if (cw->argb && name && !strcmp(name, "Prediction Window"))
530 if ( cw->argb && (cw->bd->client.icccm.name && !strcmp(cw->bd->client.icccm.name, "Prediction Window")))
534 #if OPTIMIZED_HWC_MOBILE
535 /* skip the cw is the Key Board / Clipboard */
536 if (name && !strcmp(name, "Virtual Keyboard"))
538 keyboard = EINA_TRUE;
539 hwc_update->ime_rect.x = cw->x;
540 hwc_update->ime_rect.y = cw->y;
541 hwc_update->ime_rect.w = cw->w;
542 hwc_update->ime_rect.h = cw->h;
546 if (name && !strcmp(name, "Clipboard History Manager"))
548 clipboard = EINA_TRUE;
549 clipboard_rect.x = cw->x;
550 clipboard_rect.y = cw->y;
551 clipboard_rect.w = cw->w;
552 clipboard_rect.h = cw->h;
556 if (name && !strcmp(name, "SPLIT_LAUNCHER"))
558 split_launcher = EINA_TRUE;
559 hwc_update->split_launcher_rect.x = cw->x;
560 hwc_update->split_launcher_rect.y = cw->y;
561 hwc_update->split_launcher_rect.w = cw->w;
562 hwc_update->split_launcher_rect.h = cw->h;
563 eina_rectangle_intersection(&(hwc_update->split_launcher_rect), &zone_rect);
567 if (STATE_INSET_CHECK(cw) || (!cw->argb && (cw->w < zone->w || cw->h < zone->h)))
569 if (hwcomp_util_check_fullcomp_mode(cw) != EINA_TRUE)
571 e_mod_comp_win_hwcomp_mask_objs_hide(cw);
583 if (hybrid_idx < hwc_update->num_overlays-1)
587 /* I think there are some windows which is no full screen */
588 /* Mini app || Splited window || No magnifier of keypad */
589 hwc_update->update_mode = E_HWCOMP_USE_HYBRIDCOMP_MODE;
590 hwc_update->num_drawable = hybrid_idx + 1;
591 hwc_update->hwc_drawable[hybrid_idx]->cw = cw;
592 hwc_update->hwc_drawable[hybrid_idx]->d = cw->bd->client.win;
593 #if OPTIMIZED_HWC_MOBILE
596 hwc_update->hwc_drawable[hybrid_idx]->update_count = 0; //for debugging
599 if (hwc_update->keymag_present == EINA_FALSE &&
600 hwc_update->ime_present == EINA_FALSE)
601 /* Calculate all rects with union */
603 Eina_Rectangle this_rect;
609 eina_rectangle_union(&total_rect, &this_rect);
613 if ((REGION_EQUAL_TO_ZONE(cw, zone) && (!cw->argb))) break;
617 else if (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, abs_x, abs_y, abs_w, abs_h))
621 if (hwcomp_util_check_fullcomp_mode(cw) == EINA_TRUE)
625 else if ((_co) && (cw->redirected) && (!cw->bd) &&
626 (!cw->shaped) && (!cw->rects) && (cw->hwc.set_drawable))
629 if (hwc_update->num_drawable == 0)
631 #if HWC_ROTATION_PATCH
638 #if OPTIMIZED_HWC_MOBILE
640 if (!magnifier && !keyboard && !clipboard
641 && !miniapp && !split_launcher && hwc_update->update_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE
642 && total_rect.x == zone->x && total_rect.y == zone->y
643 && total_rect.w == zone->w && total_rect.h == zone->h)
645 //update the drawables
647 for (idx = 0; idx < hwc_update->num_drawable - 1; idx++)
649 hwc_update->hwc_drawable[idx]->cw = hwc_update->hwc_drawable[idx+1]->cw;
650 hwc_update->hwc_drawable[idx]->d = hwc_update->hwc_drawable[idx+1]->d;
651 hwc_update->hwc_drawable[idx]->set_drawable = EINA_TRUE;
654 hwc_update->hwc_drawable[idx]->update_count = hwc_update->hwc_drawable[idx+1]->update_count; //for debugging
657 hwc_update->num_drawable--;
663 #if OPTIMIZED_HWC_MOBILE
664 hwc_update->hwcomp->miniapp_present = miniapp;
665 hwc_update->ime_present = keyboard;
666 hwc_update->keymag_present = magnifier;
667 hwc_update->split_launcher_rect_present = split_launcher;
669 if (keyboard && clipboard)
671 if ((hwc_update->ime_rect.w * hwc_update->ime_rect.h) < (clipboard_rect.w * clipboard_rect.h))
673 hwc_update->ime_rect.x = clipboard_rect.x;
674 hwc_update->ime_rect.y = clipboard_rect.y;
675 hwc_update->ime_rect.w = clipboard_rect.w;
676 hwc_update->ime_rect.h = clipboard_rect.h;
684 hwcomp_util_update_clear(hwc_update);
686 hwc_update->update_mode = E_HWCOMP_USE_FULLCOMP_MODE;
687 hwc_update->num_drawable = 1;
688 hwc_update->hwc_drawable[0]->cw = NULL;
689 hwc_update->hwc_drawable[0]->d = canvas->ee_win;
690 hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
694 #endif /* End of HWC */