tizen 2.4 release
[framework/uifw/e17-mod-tizen-comp.git] / src / hwcomp / hwcomp.c
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"
6
7 #include "hwcomp_debug.h"
8 #include "hwcomp.h"
9 #include <X11/extensions/hwc.h>
10
11 #include "hwcomp_util.h"
12 #include "hwcomp_mobile.h"
13
14 #define E_HWCOMP_FULL_PENDING_COUNT 2
15 static Eina_Bool _hwcomp_mod_idle_timer_cb(const void *data);
16
17 EAPI Eina_Bool     e_mod_comp_hwcomp_mod_init(E_Comp *c)
18 {
19    E_CHECK_RETURN(c, 0);
20 #ifdef USE_HWC
21    c->hwcomp_funcs.hwcomp_new                = _hwcomp_mod_hwcomp_new;
22    c->hwcomp_funcs.hwcomp_free               = _hwcomp_mod_hwcomp_free;
23    c->hwcomp_funcs.update_composite          = _hwcomp_mod_update_composite;
24    c->hwcomp_funcs.set_full_composite        = _hwcomp_mod_set_full_composite;
25    c->hwcomp_funcs.force_composite_set       = _hwcomp_mod_force_composite_set;
26    c->hwcomp_funcs.force_composite_get       = _hwcomp_mod_force_composite_get;
27    c->hwcomp_funcs.cb_update                 = _hwcomp_mod_cb_update;
28    c->hwcomp_funcs.process_event             = _hwcomp_mod_process_event;
29    c->hwcomp_funcs.check_win_update          = _hwcomp_mod_check_win_update;
30    c->hwcomp_funcs.win_update                = _hwcomp_mod_win_update;
31    c->hwcomp_funcs.set_resize                = _hwcomp_mod_set_resize;
32    c->hwcomp_funcs.reset_idle_timer          = _hwcomp_mod_reset_idle_timer;
33    c->hwcomp_funcs.win_del                   = _hwcomp_mod_win_del;
34    c->hwcomp_funcs.mode_get                  = _hwcomp_mod_mode_get;
35    c->hwcomp_funcs.update_null_set_drawables = _hwcomp_mod_update_null_set_drawables;
36    c->hwcomp_funcs.fullcomp_pending_release  = _hwcomp_mod_fullcomp_pending_release;
37    c->hwcomp_funcs.cb_rotation_begin         = _hwcomp_mod_cb_rotation_begin;
38    c->hwcomp_funcs.cb_rotation_end           = _hwcomp_mod_cb_rotation_end;
39    c->hwcomp_funcs.set_drawables             = _hwcomp_mod_update_set_drawables;
40    c->hwcomp_funcs.verify_update_mode        = _hwcomp_mod_verify_update_mode;
41
42    _hwcomp_mod_mobile_mobile_init(c);
43 #else
44    c->hwcomp_funcs.hwcomp_new                = NULL;
45    c->hwcomp_funcs.hwcomp_free               = NULL;
46    c->hwcomp_funcs.update_composite          = NULL;
47    c->hwcomp_funcs.set_full_composite        = NULL;
48    c->hwcomp_funcs.force_composite_set       = NULL;
49    c->hwcomp_funcs.force_composite_get       = NULL;
50    c->hwcomp_funcs.cb_update                 = NULL;
51    c->hwcomp_funcs.process_event             = NULL;
52    c->hwcomp_funcs.check_win_update          = NULL;
53    c->hwcomp_funcs.win_update                = NULL;
54    c->hwcomp_funcs.set_resize                = NULL;
55    c->hwcomp_funcs.reset_idle_timer          = NULL;
56    c->hwcomp_funcs.win_del                   = NULL;
57    c->hwcomp_funcs.mode_get                  = NULL;
58    c->hwcomp_funcs.update_null_set_drawables = NULL;
59    c->hwcomp_funcs.cb_rotation_begin         = NULL;
60    c->hwcomp_funcs.cb_rotation_end           = NULL;
61    c->hwcomp_funcs.set_drawables             = NULL;
62    c->hwcomp_funcs.verify_update_mode        = NULL;
63
64    _hwcomp_mod_mobile_mobile_init(c);
65
66 #endif
67    return EINA_TRUE;
68 }
69
70 EAPI void          e_mod_comp_hwcomp_mod_shutdown(E_Comp *c)
71 {
72    E_CHECK(c);
73
74    c->hwcomp_funcs.hwcomp_new                = NULL;
75    c->hwcomp_funcs.hwcomp_free               = NULL;
76    c->hwcomp_funcs.update_composite          = NULL;
77    c->hwcomp_funcs.set_full_composite        = NULL;
78    c->hwcomp_funcs.force_composite_set       = NULL;
79    c->hwcomp_funcs.force_composite_get       = NULL;
80    c->hwcomp_funcs.cb_update                 = NULL;
81    c->hwcomp_funcs.process_event             = NULL;
82    c->hwcomp_funcs.check_win_update          = NULL;
83    c->hwcomp_funcs.win_update                = NULL;
84    c->hwcomp_funcs.set_resize                = NULL;
85    c->hwcomp_funcs.reset_idle_timer          = NULL;
86    c->hwcomp_funcs.win_del                   = NULL;
87    c->hwcomp_funcs.mode_get                  = NULL;
88    c->hwcomp_funcs.update_null_set_drawables = NULL;
89    c->hwcomp_funcs.cb_rotation_begin         = NULL;
90    c->hwcomp_funcs.cb_rotation_end           = NULL;
91 }
92
93 #ifdef USE_HWC
94 static Eina_Bool
95 _hwcomp_mod_idle_timer_cb(const void *data)
96 {
97    /*
98     * This call back means comp is entered real idle (nothing happened in 2 seconds)
99     * Almost of this timer may expired in _e_mod_comp_cb_update()
100     */
101    E_Comp_HWComp *hwcomp = NULL;
102    E_Comp_HWComp_Update *update = NULL;
103    E_Comp *c = NULL;
104
105    hwcomp = (E_Comp_HWComp *)data;
106    if (!hwcomp) return ECORE_CALLBACK_DONE;
107
108    update = hwcomp->hwc_update;
109    c = hwcomp->c;
110
111    if (!update || !c)
112       return ECORE_CALLBACK_DONE;
113
114    if (update->update_mode != E_HWCOMP_USE_HYBRIDCOMP_MODE)
115       return ECORE_CALLBACK_DONE;
116
117    /*1. expire self*/
118    if (hwcomp->idle_timer)
119      {
120         ecore_timer_del(hwcomp->idle_timer);
121         hwcomp->idle_timer = NULL;
122         /*2.  set flag comp-tizen is idle now*/
123         hwcomp->idle_status = EINA_TRUE;
124         /*3. do compositing 1 time by GL*/
125         if (c->hwcomp_funcs.set_full_composite)
126            c->hwcomp_funcs.set_full_composite(hwcomp);
127
128         _hwcomp_dbg_print_update(update, "HWC:IdleTimerCB");
129      }
130
131    return ECORE_CALLBACK_DONE;
132 }
133
134 static void
135 _hwcomp_mod_append_idle_timer(E_Comp_HWComp *hwcomp)
136 {
137    E_Comp_HWComp_Update *update = NULL;
138    E_Comp_HWComp_Drawable *drawable = NULL;
139    int i;
140    int num_set_drawable = 0;
141
142    E_CHECK(hwcomp);
143
144    update = hwcomp->hwc_update;
145    E_CHECK(update);
146
147    if (!hwcomp->idle_timer)
148      {
149         for (i = 0; i < update->num_drawable; i++)
150           {
151              drawable = update->hwc_drawable[i];
152              if (drawable && drawable->set_drawable == EINA_TRUE)
153                 num_set_drawable++;
154           }
155
156         if (num_set_drawable > 1)
157           {
158              hwcomp->idle_timer = ecore_timer_add(2.0, (Ecore_Task_Cb)_hwcomp_mod_idle_timer_cb, hwcomp);
159              hwcomp->idle_status = EINA_FALSE;
160           }
161      }
162 }
163
164 void
165 _hwcomp_mod_update_set_drawables(E_Comp_HWComp_Update *hwc_update, Ecore_X_Window win)
166 {
167    E_Comp_HWComp_Drawable *hwc_drawable = NULL;
168    Ecore_X_Drawable *d = NULL;
169    int count = 0, idx = 0;
170    int i;
171    XRectangle *src_rects = NULL;
172    XRectangle *dst_rects = NULL;
173    int *comp_method = NULL;
174    int zone_x = 0, zone_y = 0, zone_w = 0, zone_h = 0;
175    int zone_rot = 0;
176
177    if (!hwc_update) return;
178
179    for (i = 0; i < hwc_update->num_drawable; i++)
180      {
181         hwc_drawable = hwc_update->hwc_drawable[i];
182         if (hwc_drawable->set_drawable)
183            count++;
184      }
185
186    if (count <= 0) return;
187
188    d = E_NEW(Ecore_X_Drawable, count);
189    if (!d)
190       return;
191
192    src_rects = E_NEW(XRectangle, count);
193    if (!src_rects)
194      {
195         E_FREE(d);
196         return;
197      }
198
199    dst_rects = E_NEW(XRectangle, count);
200    if (!dst_rects)
201      {
202         E_FREE(d);
203         E_FREE(src_rects);
204         return;
205      }
206
207    comp_method = E_NEW(int, count);
208    if (!comp_method)
209      {
210         E_FREE(d);
211         E_FREE(src_rects);
212         E_FREE(dst_rects);
213         return;
214      }
215
216    if (hwc_update->hwcomp->canvas && hwc_update->hwcomp->canvas->zone)
217      {
218         zone_x = hwc_update->hwcomp->canvas->zone->x;
219         zone_y = hwc_update->hwcomp->canvas->zone->y;
220         zone_w = hwc_update->hwcomp->canvas->zone->w;
221         zone_h = hwc_update->hwcomp->canvas->zone->h;
222
223         zone_rot = e_zone_rotation_get(hwc_update->hwcomp->canvas->zone);
224      }
225    else
226      {
227         zone_x = 0;
228         zone_y = 0;
229         zone_w = hwc_update->hwcomp->screen_width;
230         zone_h = hwc_update->hwcomp->screen_height;
231         zone_rot = 0;
232      }
233
234    for (i = 0; i < hwc_update->num_drawable; i++)
235      {
236         hwc_drawable = hwc_update->hwc_drawable[i];
237         if (hwc_drawable->set_drawable)
238           {
239              _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|SET_DRAWABLES: id (%d) , cnt(%d), fu()", "HWC",
240                               i, hwc_drawable->update_count);
241              hwc_drawable->update_count++;
242
243              if (hwc_drawable->cw)
244                {
245                   src_rects[idx].x = hwc_drawable->cw->x;
246                   src_rects[idx].y = hwc_drawable->cw->y;
247                   src_rects[idx].width = hwc_drawable->cw->w;
248                   src_rects[idx].height = hwc_drawable->cw->h;
249                }
250              else
251                {
252                   src_rects[idx].x = zone_x;
253                   src_rects[idx].y = zone_y;
254                   src_rects[idx].width = zone_w;
255                   src_rects[idx].height = zone_h;
256                }
257
258              memcpy(&dst_rects[idx], &src_rects[idx], sizeof(XRectangle));
259              comp_method[idx] = HWC_COMPOSITE_METHOD_DEFAULT;
260              d[idx] = hwc_drawable->d;
261              idx++;
262           }
263      }
264
265    for (i = 0; i < count; i++)
266       _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%s|Sree : t:%d, c(%d) w:0x%08x: [%d,%d,%d,%d]=>[%d,%d,%d,%d]", "HWC",
267                        count, i + 1, d[i], src_rects[i].x, src_rects[i].y, src_rects[i].width, src_rects[i].height, dst_rects[i].x, dst_rects[i].y, dst_rects[i].width, dst_rects[i].height);
268
269    HWCSetDrawables(hwcomp_util_display_get(), 0, win, (Drawable *)d, (XRectangle *)src_rects, (XRectangle *)dst_rects, (int *) comp_method, count);
270
271    E_FREE(d);
272    E_FREE(src_rects);
273    E_FREE(dst_rects);
274    E_FREE(comp_method);
275 }
276
277 Eina_Bool
278 _hwcomp_mod_verify_update_mode(E_Comp_HWComp *hwcomp, E_Comp_HWComp_Update *hwc_update)
279 {
280    E_Comp *c = NULL;
281    E_Comp_Canvas *canvas = NULL;
282    E_Zone *zone = NULL;
283    E_Comp_Layer *ly = NULL;
284    Eina_Bool effect_status = EINA_FALSE, move_status = EINA_FALSE, rotation_status = EINA_FALSE;
285
286    E_Comp_Win *cw;
287    E_Comp_Object *co = NULL, *_co = NULL;
288    Eina_List *l;
289    Eina_Bool check_nocomp = EINA_TRUE;
290    int hybrid_idx = 0;
291
292    c = hwcomp->c;
293    E_CHECK_RETURN(c, 0);
294
295    canvas = hwcomp->canvas;
296    E_CHECK_RETURN(canvas, 0);
297
298    zone = canvas->zone;
299    E_CHECK_RETURN(zone, 0);
300
301    /* pre-check full composite condition */
302    ly = e_mod_comp_canvas_layer_get(canvas, "effect");
303    if (ly)
304       effect_status = evas_object_visible_get(ly->layout);
305    ly = e_mod_comp_canvas_layer_get(canvas, "move");
306    if (ly)
307       move_status = evas_object_visible_get(ly->layout);
308    if ((canvas->zone) && (canvas->zone->rot.block_count))
309       rotation_status = EINA_TRUE;
310
311    /*
312     * basically canvas->ee_win always will be set at top layer0
313     * this drawable drawn by GLES
314     */
315    hwc_update->hwc_drawable[0]->cw = NULL;
316    hwc_update->hwc_drawable[0]->d = canvas->ee_win;
317    hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
318    hwc_update->hwc_drawable[0]->first_update = 0;
319    hwc_update->hwc_drawable[0]->update_count = 0;  //for debugging
320
321    if ((hwcomp_util_max_layer_get() == 1) || (hwcomp->force_composite))
322       goto full_comp;
323
324    if (effect_status || move_status || rotation_status)
325       goto full_comp;
326
327 #if HWC_ROTATION_PATCH
328    if (hwcomp->doing_rotation)
329       goto full_comp;
330 #endif
331    /*
332     * I have 2 special cases
333     *
334     * CASE 1 : 1 full screen app overlapes full screen
335     *
336     * CASE 2: Some windows are can be set at HW layer
337     *   - If num of windows are bigger than "hwcomp->num_overlays-1" additional algorithm should be used.
338     */
339
340    EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
341      {
342         EINA_LIST_FOREACH(cw->objs, l, co)
343           {
344              if (!co) continue;
345              if (co->canvas != canvas) continue;
346
347              _co = co;
348              break;
349           }
350
351         if ((_co) && (cw->bd) && (cw->bd->client.win) &&
352             (!cw->shaped) && (!cw->rects) && (cw->hwc.set_drawable))
353           {
354              int abs_x, abs_y, abs_w, abs_h;
355
356              abs_x = cw->x;
357              abs_y = cw->y;
358              abs_w = cw->w;
359              abs_h = cw->h;
360
361              if (E_CONTAINS(zone->x, zone->y, zone->w, zone->h, abs_x, abs_y, abs_w, abs_h))
362                {
363                   /* check nocomp mode with the first cw once */
364
365                   if (check_nocomp && REGION_EQUAL_TO_ZONE(cw, zone) && cw->use_dri2 && (!cw->argb)
366                       && !cw->hwc.resize_pending)
367                     {
368                        if (!(cw->bd && e_border_transform_enable_get(cw->bd)))
369                          {
370                             hwc_update->update_mode = E_HWCOMP_USE_NOCOMP_MODE;
371                             hwc_update->num_drawable = 1;
372                             hwc_update->hwc_drawable[0]->cw = cw;
373                             hwc_update->hwc_drawable[0]->d = cw->bd->client.win;
374                             hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
375                             hwc_update->hwc_drawable[0]->first_update = 0;
376                             hwc_update->hwc_drawable[0]->update_count = 0;  //for debugging
377
378                             ELBF(ELBT_COMP, 0, 0, "NO-COMP with canvas - 2");
379                             goto done;
380                          }
381                     }
382
383                   if (check_nocomp) check_nocomp = EINA_FALSE;
384
385
386                   _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);
387                   _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);
388                   _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);
389                   _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);
390
391                   /* skip the cw if the cw is not the use_dri2 */
392                   if (!cw->use_dri2 && !cw->argb)
393                      continue;
394
395                   // skip condition add
396
397                   /* argb */
398                   if (cw->argb) goto full_comp;
399
400                   if (hybrid_idx < hwc_update->num_overlays-1)
401                     {
402                        hybrid_idx++;
403
404                        /* I think there are some windows which is no full screen */
405                        /* Mini app || Splited window || No magnifier of keypad */
406                        hwc_update->update_mode = E_HWCOMP_USE_HYBRIDCOMP_MODE;
407                        hwc_update->num_drawable = hybrid_idx + 1;
408                        hwc_update->hwc_drawable[hybrid_idx]->cw = cw;
409                        hwc_update->hwc_drawable[hybrid_idx]->d = cw->bd->client.win;
410                        hwc_update->hwc_drawable[hybrid_idx]->update_count = 0;  //for debugging
411
412                        if ((REGION_EQUAL_TO_ZONE(cw, zone) && (!cw->argb))) break;
413                     }
414                }
415              /* full composite */
416              else if (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, abs_x, abs_y, abs_w, abs_h))
417                 goto full_comp;
418
419              /* full composite */
420              if (hwcomp_util_check_fullcomp_mode(cw) == EINA_TRUE)
421                 goto full_comp;
422
423           }
424         else if ((_co) && (cw->redirected) && (!cw->bd) &&
425                  (!cw->shaped) && (!cw->rects) && (cw->hwc.set_drawable))
426            goto full_comp;
427      }
428    if (hwc_update->num_drawable == 0)
429       goto full_comp;
430 done:
431    return EINA_TRUE;
432 full_comp:
433    hwcomp_util_update_clear(hwc_update);
434
435    hwc_update->update_mode = E_HWCOMP_USE_FULLCOMP_MODE;
436    hwc_update->num_drawable = 1;
437    hwc_update->hwc_drawable[0]->cw = NULL;
438    hwc_update->hwc_drawable[0]->d = canvas->ee_win;
439    hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
440
441    return EINA_TRUE;
442 }
443
444 E_Comp_HWComp*
445 _hwcomp_mod_hwcomp_new(E_Comp_Canvas *canvas)
446 {
447    E_Comp_HWComp *hwcomp = NULL;
448    E_CHECK_RETURN(canvas, 0);
449
450    hwcomp = E_NEW(E_Comp_HWComp, 1);
451    E_CHECK_RETURN(hwcomp, 0);
452
453    hwcomp_util_hwcomp_enable(canvas->comp->man->root);
454
455    hwcomp->c = canvas->comp;
456    hwcomp->canvas = canvas;
457
458    if (hwcomp_util_hwcomp_query() == EINA_TRUE)
459      {
460         hwcomp->num_overlays = hwcomp_util_max_layer_get();
461         if (hwcomp->num_overlays <= 0) goto fail;
462      }
463
464    hwcomp->hwc_update = hwcomp_util_update_create(hwcomp, hwcomp->num_overlays);
465    if (!hwcomp->hwc_update) goto fail;
466
467    //get the screen size
468    ecore_x_screen_size_get(ecore_x_default_screen_get(), &(hwcomp->screen_width), &(hwcomp->screen_height));
469    _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|Default Screen Size : (%d, %d)", "HWC:SCREEN_SIZE", hwcomp->screen_width, hwcomp->screen_height);
470
471    return hwcomp;
472
473 fail:
474    if (hwcomp)
475      {
476         if (hwcomp->hwc_update)
477            hwcomp_util_update_destroy(hwcomp->hwc_update);
478         E_FREE(hwcomp);
479      }
480    return 0;
481 }
482
483 void
484 _hwcomp_mod_hwcomp_free(E_Comp_HWComp *hwcomp)
485 {
486    if (!hwcomp) return;
487
488    hwcomp_util_update_destroy(hwcomp->hwc_update);
489
490    if (hwcomp->idle_enterer) ecore_idle_enterer_del(hwcomp->idle_enterer);
491    if (hwcomp->idle_timer) ecore_timer_del(hwcomp->idle_timer);
492
493    E_FREE(hwcomp);
494 }
495
496 void
497 _hwcomp_mod_update_composite(E_Comp_HWComp *hwcomp)
498 {
499    E_CHECK(hwcomp);
500    E_CHECK(hwcomp->hwc_update);
501
502    E_Comp_HWComp_Update *hwc_update = hwcomp->hwc_update;
503    Ecore_X_Window root_win = hwcomp->canvas->comp->man->root;
504
505    if (hwcomp_util_update_check_resized(hwc_update))
506      {
507         _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|canvas->ee_win : %p", "HWC:SKIP(RESIZE)", hwcomp->canvas->ee_win);
508         _hwcomp_dbg_print_update(hwc_update, "HWC:SKIP(RESIZE)");
509         return;
510      }
511
512    if (hwcomp->fullcomp_pending)
513      {
514         _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|canvas->ee_win : %p", "HWC:PENDING(FULL)", hwcomp->canvas->ee_win);
515         _hwcomp_dbg_print_update(hwc_update, "HWC:PENDING(FULL)");
516         return;
517      }
518
519    if (hwcomp_util_update_check_comp(hwc_update))
520      {
521         _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s|canvas->ee_win : %p", "HWC:DRAW_DONE", hwcomp->canvas->ee_win);
522         _hwcomp_dbg_print_update(hwc_update, "HWC:Comp");
523
524         hwcomp_util_update_set_comp(hwc_update, EINA_FALSE);
525
526         if (hwcomp->c && hwcomp->c->hwcomp_funcs.set_drawables)
527            hwcomp->c->hwcomp_funcs.set_drawables(hwc_update, root_win);
528         if (hwcomp->force_swap)
529           {
530              E_Comp_Canvas *canvas = hwcomp->canvas;
531              if ((canvas) && (canvas->evas) && (canvas->ee))
532                {
533                   evas_obscured_clear(canvas->evas);
534                   evas_damage_rectangle_add(canvas->evas, 0, 0, canvas->w, canvas->h);
535                   ecore_evas_manual_render(canvas->ee);
536                   hwcomp->force_swap = 0;
537                }
538           }
539      }
540 }
541
542 void
543 _hwcomp_mod_set_full_composite(E_Comp_HWComp *hwcomp)
544 {
545    E_CHECK(hwcomp);
546    E_CHECK(hwcomp->hwc_update);
547
548    E_Comp_HWComp_Update *hwc_update = hwcomp->hwc_update;
549    E_Comp_HWComp_Drawable *hwc_drawable = NULL;
550    E_Comp_Win *hide_cw = NULL;
551    int i;
552
553    /* do not change the update until ee_win has done the update */
554    if (hwcomp_util_update_check_comp(hwcomp->hwc_update))
555       return;
556
557    _hwcomp_dbg_print_update(hwc_update, "HWC:Set Comp");
558
559    /* draw all hwc_drawables at the next ee_win update.
560       1. hide mask objs
561       2. trigger the compositing ee_win
562       */
563
564    /* hide mask objs */
565    for (i = 1; i < hwc_update->num_drawable; i++)
566      {
567         hwc_drawable = hwc_update->hwc_drawable[i];
568         hide_cw = hwc_drawable->cw;
569         e_mod_comp_win_hwcomp_mask_objs_hide(hide_cw);
570         hwcomp_util_reset_comp_countdown(hwc_drawable);
571         hwcomp_util_reset_set_countdown(hwc_drawable);
572         hwc_drawable->set_drawable = EINA_FALSE;
573      }
574
575    hwcomp_util_update_set_comp(hwc_update, EINA_TRUE);
576    hwcomp_util_turn_composite(hwcomp, EINA_TRUE);
577
578    hwc_update->hwc_drawable[0]->cw = NULL;
579    hwc_update->hwc_drawable[0]->d = hwcomp->canvas->ee_win;
580    hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
581
582    //    ecore_evas_manual_render(hwcomp->canvas->ee);
583 }
584
585 Eina_Bool
586 _hwcomp_mod_cb_update(E_Comp_HWComp *hwcomp)
587 {
588    E_CHECK_RETURN(hwcomp, 0);
589
590    E_Comp *c = NULL;
591    E_Comp_Canvas *canvas = NULL;
592    E_Comp_Win *show_cw = NULL;
593    E_Comp_Win *hide_cw = NULL;
594    E_Comp_HWComp_Update *cur_hwc_update = NULL;
595    E_Comp_HWComp_Update *new_hwc_update = NULL;
596    E_Comp_HWComp_Drawable *hwc_drawable = NULL;
597    E_HWComp_Mode cur_mode = E_HWCOMP_USE_INVALID;
598    E_HWComp_Mode new_mode = E_HWCOMP_USE_INVALID;
599    int i = 0;
600
601    c = hwcomp->c;
602    E_CHECK_RETURN(c, EINA_FALSE);
603    E_CHECK_RETURN(!(c->lock.locked), EINA_FALSE);
604
605    canvas = hwcomp->canvas;
606    E_CHECK_RETURN(canvas, EINA_FALSE);
607
608    cur_hwc_update = hwcomp->hwc_update;
609    if (!cur_hwc_update)
610       return EINA_FALSE;
611
612    if (hwcomp->idle_timer)
613      {
614         ecore_timer_del(hwcomp->idle_timer);
615         hwcomp->idle_timer = NULL;
616      }
617
618    new_hwc_update = hwcomp_util_update_create(hwcomp, hwcomp->num_overlays);
619    if (!new_hwc_update)
620       return EINA_FALSE;
621
622
623    if (c->hwcomp_funcs.verify_update_mode)
624      {
625         if (!c->hwcomp_funcs.verify_update_mode(hwcomp, new_hwc_update))
626           {
627              if (c->hwcomp_funcs.update_null_set_drawables)
628                 c->hwcomp_funcs.update_null_set_drawables(hwcomp);
629              hwcomp_util_update_destroy(new_hwc_update);
630              return EINA_FALSE;
631           }
632      }
633    else
634      {
635         hwcomp_util_update_destroy(new_hwc_update);
636         return EINA_FALSE;
637      }
638
639    cur_mode = hwcomp->hwc_update->update_mode;
640    new_mode = new_hwc_update->update_mode;
641
642    if (cur_mode != new_mode)
643      {
644         /* do not change the update until resized is done. */
645         if (hwcomp_util_update_check_resized(cur_hwc_update))
646           {
647              if (cur_hwc_update->update_mode != E_HWCOMP_USE_NOCOMP_MODE)
648                {
649                   _hwcomp_dbg_print_update(cur_hwc_update, "HWC:SKIP(RESIZE)");
650                   hwcomp_util_update_destroy(new_hwc_update);
651                   return EINA_TRUE;
652                }
653           }
654
655         if ((cur_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE) &&
656             (new_mode == E_HWCOMP_USE_FULLCOMP_MODE))
657           {
658              hwcomp->fullcomp_pending = E_HWCOMP_FULL_PENDING_COUNT;
659           }
660
661
662         if ((cur_mode == E_HWCOMP_USE_NOCOMP_MODE) &&
663             (new_mode == E_HWCOMP_USE_FULLCOMP_MODE))
664           {
665              hwcomp->force_swap = 1;
666           }
667
668
669         _hwcomp_dbg_print_change_update(cur_hwc_update, new_hwc_update, "HWC:Mode Change");
670
671         if (cur_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE)
672           {
673              /* hide mask_objs */
674              hwcomp_util_update_reset_maskobj(cur_hwc_update);
675           }
676
677
678
679         /* change the new hwc_update */
680         hwcomp_util_update_destroy(hwcomp->hwc_update);
681         hwcomp->hwc_update = new_hwc_update;
682
683         /* set drawable is 1 at this case */
684         hwcomp->hwc_update->hwc_drawable[0]->set_drawable = EINA_TRUE;
685
686         /* reset count */
687         for (i = 0; i < hwcomp->hwc_update->num_drawable; i++)
688           {
689              hwcomp_util_reset_comp_countdown(hwcomp->hwc_update->hwc_drawable[i]);
690              hwcomp_util_reset_set_countdown(hwcomp->hwc_update->hwc_drawable[i]);
691           }
692
693         /* check ee_win update */
694         if (hwcomp->hwc_update->update_mode == E_HWCOMP_USE_NOCOMP_MODE)
695           {
696              /* update client win. set_drawable */
697              if (c->hwcomp_funcs.set_drawables)
698                 c->hwcomp_funcs.set_drawables(hwcomp->hwc_update,  hwcomp->canvas->comp->man->root);
699              hwcomp_util_turn_composite(hwcomp, EINA_FALSE);
700           }
701         else if (hwcomp->hwc_update->update_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE)
702           {
703 #if OPTIMIZED_HWC_MOBILE
704              hwcomp_util_set_hybrid_composite(hwcomp->hwc_update);
705 #endif
706              /* update ee_win at the next draw_done of the ee_win */
707              hwcomp_util_update_set_comp(hwcomp->hwc_update, EINA_TRUE);
708              hwcomp_util_turn_composite(hwcomp, EINA_TRUE);
709           }
710         else if (hwcomp->hwc_update->update_mode == E_HWCOMP_USE_FULLCOMP_MODE)
711           {
712              /* update ee_win at the next draw_done of the ee_win */
713              hwcomp_util_update_set_comp(hwcomp->hwc_update, EINA_TRUE);
714              hwcomp_util_turn_composite(hwcomp, EINA_TRUE);
715           }
716      }
717    else
718      {
719         Eina_Bool compare = hwcomp_util_update_compare_drawables(cur_hwc_update, new_hwc_update);
720
721         if (!compare && cur_mode != E_HWCOMP_USE_FULLCOMP_MODE)
722           {
723              hwcomp_util_update_migrate_drawables(cur_hwc_update, new_hwc_update);
724
725              if (cur_mode == E_HWCOMP_USE_NOCOMP_MODE)
726                {
727                   _hwcomp_dbg_print_change_update(cur_hwc_update, new_hwc_update, "HWC:NOCOMP Draw Change");
728
729                   if (c->hwcomp_funcs.set_drawables)
730                      c->hwcomp_funcs.set_drawables(new_hwc_update,  hwcomp->canvas->comp->man->root);
731                }
732              else if (cur_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE)
733                {
734                   _hwcomp_dbg_print_change_update(cur_hwc_update, new_hwc_update, "HWC:HIB Draw Change");
735
736 #if OPTIMIZED_HWC_MOBILE
737                   if (c->hwcomp_funcs.set_drawables)
738                      c->hwcomp_funcs.set_drawables(new_hwc_update,  hwcomp->canvas->comp->man->root);
739 #endif
740                }
741
742              hwcomp_util_update_destroy(hwcomp->hwc_update);
743              hwcomp->hwc_update = new_hwc_update;
744           }
745         else
746           {
747              /* destory new hwc_update */
748              hwcomp_util_update_destroy(new_hwc_update);
749
750              if (cur_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE)
751                {
752                   /* do not set/comp util the first update of ee_win has doen. */
753                   if (hwcomp_util_update_check_comp(cur_hwc_update))
754                     {
755                        for (i = 1 ; i < cur_hwc_update->num_drawable ; ++i)
756                          {
757                             hwc_drawable = cur_hwc_update->hwc_drawable[i];
758                             if (!hwc_drawable) break;
759                             hwcomp_util_reset_comp_countdown(hwc_drawable);
760                             hwcomp_util_reset_set_countdown(hwc_drawable);
761                          }
762                     }
763                   else
764                     {
765                        Eina_Bool partial_update = EINA_TRUE;
766                        Eina_Bool set_flag = EINA_FALSE;
767                        // index 0 id composite overlay window
768                        for (i = 1 ; i < cur_hwc_update->num_drawable ; ++i)
769                          {
770                             hwc_drawable = cur_hwc_update->hwc_drawable[i];
771                             if (!hwc_drawable) break;
772
773                             if (hwc_drawable->set_drawable)
774                               {
775                                  hwcomp_util_dec_comp_countdown(hwc_drawable);
776                                  /* composite */
777                                  if (hwc_drawable->comp_countdown <= 0)
778                                    {
779                                       hwc_drawable->set_drawable = EINA_FALSE;
780                                       e_mod_comp_win_hwcomp_mask_objs_hide(hwc_drawable->cw);
781                                    }
782                                  partial_update = EINA_FALSE;
783                               }
784                             else
785                               {
786                                  // set drawables
787                                  if (hwc_drawable->set_countdown <= 0)
788                                    {
789                                       ELBF(ELBT_COMP, 0, 0, "%15.15s|### [%d]: %p, %d, %d, %d", "HWC:BEFORE",
790                                            i, hwc_drawable->d, hwc_drawable->set_drawable, hwc_drawable->set_countdown, hwc_drawable->comp_countdown);
791
792                                       hwc_drawable->set_drawable = EINA_TRUE;
793                                       hwcomp_util_reset_set_countdown(hwc_drawable);
794
795                                       // show mask obj
796                                       e_mod_comp_win_hwcomp_mask_objs_show(hwc_drawable->cw);
797
798                                       // set flags
799                                       set_flag = EINA_TRUE;
800                                       ELBF(ELBT_COMP, 0, 0, "%15.15s|### [%d]: %p, %d, %d, %d", "HWC:AFTER",
801                                            i, hwc_drawable->d, hwc_drawable->set_drawable, hwc_drawable->set_countdown, hwc_drawable->comp_countdown);
802                                       partial_update = EINA_FALSE;
803
804                                    }
805                               }
806                          }
807
808                        if (set_flag)
809                          {
810                             _hwcomp_dbg_print_update(cur_hwc_update, "HWC:HIB State Change");
811                             /* update client win. set_drawable */
812                             if (c->hwcomp_funcs.set_drawables)
813                                c->hwcomp_funcs.set_drawables(cur_hwc_update,  canvas->comp->man->root);
814                          }
815
816                        if (partial_update) return partial_update;
817                     }
818
819                }
820           }
821      }
822    if ((hwcomp) && (new_mode == E_HWCOMP_USE_HYBRIDCOMP_MODE))
823       _hwcomp_mod_append_idle_timer(hwcomp);
824
825    return EINA_TRUE;
826 }
827
828 void
829 _hwcomp_mod_process_event(E_Comp *c, Ecore_X_Event_Generic *e)
830 {
831    Eina_List *l = NULL;
832    E_Comp_Canvas *canvas = NULL;
833    E_Comp_HWComp *hwcomp = NULL;
834    int num_overlays = 0;
835    E_HWComp_Mode mode = E_HWCOMP_USE_INVALID;
836    int i;
837
838    if (!c || !e) return;
839    if (hwcomp_util_hwcomp_query() == EINA_FALSE) return;
840
841    if ((num_overlays = hwcomp_util_get_event_data(e)) != -1)
842      {
843         EINA_LIST_FOREACH(c->canvases, l, canvas)
844           {
845              if (!canvas->hwcomp) continue;
846
847              hwcomp = canvas->hwcomp;
848              if (hwcomp && hwcomp->hwc_update)
849                 mode = hwcomp->hwc_update->update_mode;
850
851              if (mode != E_HWCOMP_USE_FULLCOMP_MODE)
852                {
853                   hwcomp_util_update_reset_maskobj(hwcomp->hwc_update);
854                   hwcomp_util_update_destroy(hwcomp->hwc_update);
855
856                   /* recreate the hwc update with the updated overlays */
857                   hwcomp->hwc_update = hwcomp_util_update_create(hwcomp, num_overlays);
858                   _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s| maxLayers = %d", "HWC:MAXLAYER CHANGE", num_overlays);
859
860                   if (c->hwcomp_funcs.set_full_composite)
861                      c->hwcomp_funcs.set_full_composite(hwcomp);
862                   e_mod_comp_render_queue(c);
863                }
864              hwcomp->num_overlays = num_overlays;
865              hwcomp_util_max_layer_set(num_overlays);
866
867              _hwcomp_dbg_print_update(hwcomp->hwc_update, "HWC:Change MAX Layers");
868           }
869      }
870 }
871
872 void
873 _hwcomp_mod_check_win_update(E_Comp_Win *cw, int w, int h)
874 {
875    E_CHECK(cw);
876    E_CHECK(w > 0);
877    E_CHECK(h > 0);
878
879    Eina_List *l = NULL;
880    E_Comp_Canvas *canvas = NULL;
881    E_Comp_HWComp *hwcomp = NULL;
882    E_Comp_HWComp_Update *hwc_update = NULL;
883    E_Comp *c = cw->c;
884    E_Comp_HWComp_Drawable *hwc_drawable = NULL;
885    int i = 0;
886    int num_drawable = 0;
887    int max_w = 0, max_h = 0;
888
889    const char *name=NULL;
890    name = hwcomp_util_border_name_get(cw->bd);
891
892
893    EINA_LIST_FOREACH(c->canvases, l, canvas)
894      {
895         if (!canvas->hwcomp) continue;
896
897         hwcomp = canvas->hwcomp;
898         hwc_update = hwcomp->hwc_update;
899
900         if (hwc_update->update_mode != E_HWCOMP_USE_HYBRIDCOMP_MODE) continue;
901
902         max_w = canvas->zone->w;
903         max_h = canvas->zone->h;
904         num_drawable = hwc_update->num_drawable;
905
906         for (i = 0; i < num_drawable; i++)
907           {
908              hwc_drawable = hwc_update->hwc_drawable[i];
909
910              if (hwc_drawable && hwc_drawable->cw == cw)
911                {
912                   /* Mini app */
913                   if (STATE_INSET_CHECK(cw) && name && !strcmp(name, "video-player"))
914                      hwc_drawable->region_update = EINA_TRUE;
915                   else
916                     {
917                        if (hwcomp_util_update_check_region(hwc_update, cw, w, h, max_w, max_h))
918                           hwc_drawable->region_update = EINA_TRUE;
919                        else
920                           hwc_drawable->region_update = EINA_FALSE;
921                     }
922                }
923           }
924      }
925 }
926
927
928 void
929 _hwcomp_mod_win_update(E_Comp_Win *cw)
930 {
931    E_CHECK(cw);
932    E_CHECK(cw->bd);
933
934    Eina_List *l = NULL;
935    E_Comp_Canvas *canvas = NULL;
936    E_Comp_HWComp *hwcomp = NULL;
937    E_Comp_HWComp_Update *hwc_update = NULL;
938    E_Comp *c = cw->c;
939
940    EINA_LIST_FOREACH(c->canvases, l, canvas)
941      {
942         if (!canvas->hwcomp) continue;
943
944         hwcomp = canvas->hwcomp;
945         hwc_update = hwcomp->hwc_update;
946
947         /* unset the resized flag here */
948         hwcomp_util_update_unset_resized(hwc_update, cw);
949
950         /* do not update the countdown when there are the resized drawables */
951         if (!hwcomp_util_update_check_resized(hwc_update))
952            hwcomp_util_update_countdown(hwc_update, cw);
953      }
954 }
955
956 void
957 _hwcomp_mod_set_resize(E_Comp_Win *cw)
958 {
959    E_CHECK(cw);
960    E_CHECK(cw->bd);
961
962    Eina_List *l = NULL;
963    E_Comp_Canvas *canvas = NULL;
964    E_Comp_HWComp *hwcomp = NULL;
965    E_Comp_HWComp_Update *hwc_update = NULL;
966    E_Comp *c = cw->c;
967
968    EINA_LIST_FOREACH(c->canvases, l, canvas)
969      {
970         if (!canvas->hwcomp) continue;
971
972         hwcomp = canvas->hwcomp;
973         hwc_update = hwcomp->hwc_update;
974
975         hwcomp_util_update_set_resized(hwc_update, cw);
976      }
977 }
978
979 void
980 _hwcomp_mod_force_composite_set(E_Comp_HWComp *hwcomp, Eina_Bool set)
981 {
982    E_CHECK(hwcomp);
983
984    if (set)
985      {
986         hwcomp->comp_ref++;
987         if (!hwcomp->force_composite)
988           {
989              hwcomp->force_composite = set;
990           }
991      }
992    else
993      {
994         hwcomp->comp_ref--;
995         if (hwcomp->comp_ref <= 0)
996           {
997              hwcomp->comp_ref = 0;
998              hwcomp->force_composite = EINA_FALSE;
999           }
1000      }
1001 }
1002
1003 Eina_Bool
1004 _hwcomp_mod_force_composite_get(E_Comp_HWComp *hwcomp)
1005 {
1006    E_CHECK_RETURN(hwcomp, 0);
1007    return hwcomp->force_composite;
1008 }
1009
1010 void
1011 _hwcomp_mod_reset_idle_timer(E_Comp_Canvas *canvas)
1012 {
1013
1014    E_Comp_HWComp *hwcomp = NULL;
1015    E_CHECK(canvas);
1016
1017    hwcomp = canvas->hwcomp;
1018    E_CHECK(hwcomp);
1019
1020    if (hwcomp->idle_timer)
1021      {
1022         ecore_timer_del(hwcomp->idle_timer);
1023         hwcomp->idle_timer = NULL;
1024      }
1025
1026    return;
1027 }
1028
1029 void
1030 _hwcomp_mod_win_del(E_Comp_Win *cw)
1031 {
1032
1033    E_CHECK(cw);
1034
1035    Eina_List *l = NULL;
1036    E_Comp_Canvas *canvas = NULL;
1037    E_Comp_HWComp *hwcomp = NULL;
1038    E_Comp_HWComp_Update *hwc_update = NULL;
1039    E_Comp_HWComp_Drawable **drawables = NULL;
1040    E_Comp *c = cw->c;
1041    int i;
1042
1043    EINA_LIST_FOREACH(c->canvases, l, canvas)
1044      {
1045         if (!canvas || !canvas->hwcomp) continue;
1046
1047         hwcomp = canvas->hwcomp;
1048         hwc_update = hwcomp->hwc_update;
1049         drawables = hwc_update->hwc_drawable;
1050
1051         for (i=0; i < hwc_update->num_drawable; i++)
1052           {
1053              if (drawables[i]->cw && (cw == drawables[i]->cw))
1054                {
1055                   _hwcomp_dbg_elbf(ELBT_COMP, 0, 0, "%15.15s| cw : %p deleted", "HWC:CW DEL", cw);
1056                   hwcomp_util_update_clear(hwc_update);
1057                   return;
1058                }
1059           }
1060      }
1061
1062    return;
1063 }
1064
1065 E_HWComp_Mode
1066 _hwcomp_mod_mode_get(E_Comp_HWComp *hwcomp)
1067 {
1068    E_CHECK_RETURN(hwcomp, E_HWCOMP_USE_INVALID);
1069    E_CHECK_RETURN(hwcomp->hwc_update, E_HWCOMP_USE_INVALID);
1070
1071    return hwcomp->hwc_update->update_mode;
1072 }
1073
1074 void
1075 _hwcomp_mod_update_null_set_drawables(E_Comp_HWComp *hwcomp)
1076 {
1077    E_CHECK(hwcomp);
1078    Ecore_X_Window root_win = hwcomp->canvas->comp->man->root;
1079    E_CHECK(root_win);
1080
1081    _hwcomp_dbg_elbf(ELBT_COMP,0, 0, "HWC|NULL DRAWABLE SET");
1082
1083    HWCSetDrawables(hwcomp_util_display_get(), 0, root_win, NULL, NULL, NULL, NULL, 0);
1084 }
1085
1086 void
1087 _hwcomp_mod_fullcomp_pending_release(E_Comp_HWComp *hwcomp)
1088 {
1089    E_CHECK(hwcomp);
1090
1091    if (hwcomp->fullcomp_pending)
1092       hwcomp->fullcomp_pending--;
1093
1094    return;
1095 }
1096
1097 void
1098 _hwcomp_mod_cb_rotation_begin(E_Comp_HWComp *hwcomp)
1099 {
1100 #if HWC_ROTATION_PATCH
1101    E_CHECK(hwcomp);
1102
1103    ELBF(ELBT_COMP, 0, 0, "[ROTATION BEGIN]");
1104    hwcomp->doing_rotation = 1;
1105
1106    if (hwcomp->hwc_update->update_mode != E_HWCOMP_USE_FULLCOMP_MODE)
1107      {
1108         if (hwcomp->c && hwcomp->c->hwcomp_funcs.cb_update)
1109            hwcomp->c->hwcomp_funcs.cb_update(hwcomp);
1110
1111         E_Comp_Canvas *canvas = hwcomp->canvas;
1112
1113         ELBF(ELBT_COMP, 0, 0, "[OVERLAY Window Manual Render!]");
1114
1115         Eina_Bool back = ecore_evas_manual_render_get(canvas->ee);
1116         ecore_evas_manual_render_set(canvas->ee, EINA_TRUE);
1117         ecore_evas_manual_render(canvas->ee);
1118         ecore_evas_manual_render_set(canvas->ee, back);
1119      }
1120 #endif
1121 }
1122
1123 void
1124 _hwcomp_mod_cb_rotation_end(E_Comp_HWComp *hwcomp)
1125 {
1126 #if HWC_ROTATION_PATCH
1127    E_CHECK(hwcomp);
1128
1129    ELBF(ELBT_COMP, 0, 0, "[ROTATION END]");
1130    hwcomp->doing_rotation = 0;
1131 #endif
1132 }
1133
1134 #endif
1135
1136
1137