summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_render.c
diff options
context:
space:
mode:
authorRafael Antognolli <rafael.antognolli@intel.com>2013-04-18 16:10:53 -0300
committerRafael Antognolli <rafael.antognolli@intel.com>2013-04-18 16:38:16 -0300
commite937f1f5a385b44f37d943c34cdc06871483714e (patch)
tree94bd7d696c43c622c394988b46b2778a4a812b85 /src/lib/evas/canvas/evas_render.c
parent986244339b0dd8c429beba257a0566a18f3603fb (diff)
evas/wayland: Unclip objects from the framespace after rendering.
These objects should be clipped only during rendering, since keeping them clipped after that allows for unexpected behavior on the application side. For instance, an application could check if objects have clippers before doing something to them, assuming that some objects should have no clipper, but under wayland, after the first render iteration, there will be no objects without a clipper. This commit fixes this behavior by unclipping objects that had no clipper prior to the render iteration. Additionally, it fixes a bug where a maximized/fullscreen window could have not all of its content rendered immediately. This was occuring because some objects could be clipped to the framespace clipper, but considered invisible in the beginning of the render phase, where they are evaluated. They were considered invisible because the framespace clipper object was not resized at that phase yet, and thus these objects were being clipped out from the viewport.
Diffstat (limited to 'src/lib/evas/canvas/evas_render.c')
-rw-r--r--src/lib/evas/canvas/evas_render.c176
1 files changed, 100 insertions, 76 deletions
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index ecdad31..23c081d 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -1431,6 +1431,103 @@ _drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata
1431 return EINA_TRUE; 1431 return EINA_TRUE;
1432} 1432}
1433 1433
1434static void
1435_framespace_clipper_add(Evas *eo_e, Evas_Public_Data *e)
1436{
1437 Eina_Rectangle clip_rect;
1438 unsigned int i;
1439 Evas_Object *eo_obj;
1440 Evas_Object_Protected_Data *obj;
1441
1442 if (strncmp(e->engine.module->definition->name, "wayland", 7))
1443 return;
1444
1445 /* see if the master clip has been added yet, if not, then create */
1446 if (!e->framespace.clip)
1447 {
1448 e->framespace.clip = evas_object_rectangle_add(eo_e);
1449 evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
1450 evas_object_move(e->framespace.clip,
1451 e->framespace.x, e->framespace.y);
1452 evas_object_resize(e->framespace.clip,
1453 e->viewport.w - e->framespace.w,
1454 e->viewport.h - e->framespace.h);
1455 }
1456 else
1457 {
1458 /* master clip is already present. check for size changes in the
1459 * viewport, and update master clip size if needed */
1460 if ((e->viewport.changed) || (e->output.changed) ||
1461 (e->framespace.changed))
1462 {
1463 evas_object_move(e->framespace.clip,
1464 e->framespace.x, e->framespace.y);
1465 evas_object_resize(e->framespace.clip,
1466 e->viewport.w - e->framespace.w,
1467 e->viewport.h - e->framespace.h);
1468 }
1469 }
1470
1471 Evas_Object_Protected_Data *framespace_clip =
1472 eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS);
1473
1474 EINA_RECTANGLE_SET(&clip_rect,
1475 framespace_clip->cur->geometry.x,
1476 framespace_clip->cur->geometry.y,
1477 framespace_clip->cur->geometry.w,
1478 framespace_clip->cur->geometry.h);
1479
1480 evas_object_show(e->framespace.clip);
1481 /* With the master clip all setup, we need to loop the objects on this
1482 * canvas and determine if the object is in the viewport space. If it
1483 * is in the viewport space (and not in framespace), then we need to
1484 * clip the object to the master clip so that it does not draw on top
1485 * of the frame (eg: elm 3d test) */
1486 for (i = 0; i < e->render_objects.count; ++i)
1487 {
1488 Eina_Rectangle obj_rect;
1489 Evas_Object *pclip;
1490
1491 obj = eina_array_data_get(&e->render_objects, i);
1492 if (obj->is_frame) continue;
1493
1494 if (obj->delete_me) continue;
1495
1496 eo_obj = obj->object;
1497
1498 /* skip clipping if the object is itself the
1499 * framespace clip */
1500 if (eo_obj == framespace_clip->object) continue;
1501
1502 EINA_RECTANGLE_SET(&obj_rect,
1503 obj->cur->geometry.x, obj->cur->geometry.y,
1504 obj->cur->geometry.w, obj->cur->geometry.h);
1505
1506 /* if the object does not intersect our clip rect, ignore it */
1507 if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
1508 continue;
1509
1510 if (!(pclip = evas_object_clip_get(eo_obj)))
1511 {
1512 /* clip this object so it does not draw on the window frame */
1513 evas_object_clip_set(eo_obj, framespace_clip->object);
1514 eina_array_push(&e->clipped_objects, eo_obj);
1515 }
1516 }
1517}
1518
1519static void
1520_framespace_clipper_del(Evas_Public_Data *e)
1521{
1522 Evas_Object *eo_obj;
1523
1524 while ((eo_obj = eina_array_pop(&e->clipped_objects)))
1525 evas_object_clip_unset(eo_obj);
1526
1527 if (e->framespace.clip)
1528 evas_object_hide(e->framespace.clip);
1529}
1530
1434static Eina_Bool 1531static Eina_Bool
1435evas_render_updates_internal(Evas *eo_e, 1532evas_render_updates_internal(Evas *eo_e,
1436 unsigned char make_updates, 1533 unsigned char make_updates,
@@ -1574,82 +1671,7 @@ evas_render_updates_internal(Evas *eo_e,
1574 * NB: This is for the wayland engine(s). If we do not do this, then 1671 * NB: This is for the wayland engine(s). If we do not do this, then
1575 * objects will draw outside the viewport and potentially onto the frame 1672 * objects will draw outside the viewport and potentially onto the frame
1576 * itself */ 1673 * itself */
1577 if (!strncmp(e->engine.module->definition->name, "wayland", 7)) 1674 _framespace_clipper_add(eo_e, e);
1578 {
1579 Eina_Rectangle clip_rect;
1580
1581 /* see if the master clip has been added yet, if not, then create */
1582 if (!e->framespace.clip)
1583 {
1584 e->framespace.clip = evas_object_rectangle_add(eo_e);
1585 evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
1586 evas_object_move(e->framespace.clip,
1587 e->framespace.x, e->framespace.y);
1588 evas_object_resize(e->framespace.clip,
1589 e->viewport.w - e->framespace.w,
1590 e->viewport.h - e->framespace.h);
1591 evas_object_show(e->framespace.clip);
1592 }
1593 else
1594 {
1595 /* master clip is already present. check for size changes in the
1596 * viewport, and update master clip size if needed */
1597 if ((e->viewport.changed) || (e->output.changed) ||
1598 (e->framespace.changed))
1599 {
1600 evas_object_move(e->framespace.clip,
1601 e->framespace.x, e->framespace.y);
1602 evas_object_resize(e->framespace.clip,
1603 e->viewport.w - e->framespace.w,
1604 e->viewport.h - e->framespace.h);
1605 }
1606 }
1607
1608 Evas_Object_Protected_Data *framespace_clip =
1609 eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS);
1610
1611 EINA_RECTANGLE_SET(&clip_rect,
1612 framespace_clip->cur->geometry.x,
1613 framespace_clip->cur->geometry.y,
1614 framespace_clip->cur->geometry.w,
1615 framespace_clip->cur->geometry.h)
1616
1617 /* With the master clip all setup, we need to loop the objects on this
1618 * canvas and determine if the object is in the viewport space. If it
1619 * is in the viewport space (and not in framespace), then we need to
1620 * clip the object to the master clip so that it does not draw on top
1621 * of the frame (eg: elm 3d test) */
1622 for (i = 0; i < e->render_objects.count; ++i)
1623 {
1624 Eina_Rectangle obj_rect;
1625 Evas_Object *pclip;
1626
1627 obj = eina_array_data_get(&e->render_objects, i);
1628 if (obj->is_frame) continue;
1629
1630 if (obj->delete_me) continue;
1631
1632 eo_obj = obj->object;
1633
1634 /* skip clipping if the object is itself the
1635 * framespace clip */
1636 if (eo_obj == framespace_clip->object) continue;
1637
1638 EINA_RECTANGLE_SET(&obj_rect,
1639 obj->cur->geometry.x, obj->cur->geometry.y,
1640 obj->cur->geometry.w, obj->cur->geometry.h);
1641
1642 /* if the object does not intersect our clip rect, ignore it */
1643 if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
1644 continue;
1645
1646 if (!(pclip = evas_object_clip_get(eo_obj)))
1647 {
1648 /* clip this object so it does not draw on the window frame */
1649 evas_object_clip_set(eo_obj, framespace_clip->object);
1650 }
1651 }
1652 }
1653 1675
1654 if (redraw_all) 1676 if (redraw_all)
1655 { 1677 {
@@ -1938,6 +1960,8 @@ evas_render_updates_internal(Evas *eo_e,
1938 e->invalidate = EINA_TRUE; 1960 e->invalidate = EINA_TRUE;
1939 } 1961 }
1940 1962
1963 _framespace_clipper_del(e);
1964
1941 evas_module_clean(); 1965 evas_module_clean();
1942 1966
1943 if (!do_async) 1967 if (!do_async)