summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/efl_canvas_vg_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/evas/canvas/efl_canvas_vg_object.c')
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_object.c128
1 files changed, 85 insertions, 43 deletions
diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c
index 1027907..83a59bd 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_object.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_object.c
@@ -144,6 +144,8 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
144 // detach/free the old root_node 144 // detach/free the old root_node
145 if (pd->user_entry && pd->user_entry->root) 145 if (pd->user_entry && pd->user_entry->root)
146 { 146 {
147 // drop any surface cache attached to it.
148 ENFN->ector_surface_cache_drop(_evas_engine_context(obj->layer->evas), pd->user_entry->root);
147 efl_canvas_vg_node_vg_obj_set(pd->user_entry->root, NULL, NULL); 149 efl_canvas_vg_node_vg_obj_set(pd->user_entry->root, NULL, NULL);
148 efl_replace(&pd->user_entry->root, NULL); 150 efl_replace(&pd->user_entry->root, NULL);
149 } 151 }
@@ -152,22 +154,20 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
152 { 154 {
153 if (!pd->user_entry) 155 if (!pd->user_entry)
154 { 156 {
155 pd->user_entry = malloc(sizeof(Vg_User_Entry)); 157 pd->user_entry = calloc(1, sizeof(Vg_User_Entry));
156 if (!pd->user_entry) 158 if (!pd->user_entry)
157 { 159 {
158 ERR("Failed to alloc user entry data while setting root node"); 160 ERR("Failed to alloc user entry data while setting root node");
159 return; 161 return;
160 } 162 }
161 } 163 }
162 pd->user_entry->w = pd->user_entry->h = 0; 164 else pd->user_entry->w = pd->user_entry->h = 0;
163 165
164 efl_replace(&pd->user_entry->root, root_node); 166 efl_replace(&pd->user_entry->root, root_node);
165 efl_canvas_vg_node_vg_obj_set(root_node, eo_obj, pd); 167 efl_canvas_vg_node_vg_obj_set(root_node, eo_obj, pd);
166 } 168 }
167 else if (pd->user_entry) 169 else if (pd->user_entry)
168 { 170 {
169 // drop any surface cache attached to it.
170 ENFN->ector_surface_cache_drop(_evas_engine_context(obj->layer->evas), pd->user_entry->root);
171 free(pd->user_entry); 171 free(pd->user_entry);
172 pd->user_entry = NULL; 172 pd->user_entry = NULL;
173 } 173 }
@@ -345,7 +345,6 @@ _efl_canvas_vg_object_efl_object_invalidate(Eo *eo_obj, Efl_Canvas_Vg_Object_Dat
345 if (pd->user_entry) 345 if (pd->user_entry)
346 { 346 {
347 Vg_User_Entry *user_entry = pd->user_entry; 347 Vg_User_Entry *user_entry = pd->user_entry;
348
349 ENFN->ector_surface_cache_drop(ENC, user_entry->root); 348 ENFN->ector_surface_cache_drop(ENC, user_entry->root);
350 free(pd->user_entry); 349 free(pd->user_entry);
351 } 350 }
@@ -369,7 +368,7 @@ _efl_canvas_vg_object_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Vg_Object_Da
369 368
370 /* default root node */ 369 /* default root node */
371 pd->obj = obj; 370 pd->obj = obj;
372 pd->root = efl_add_ref(EFL_CANVAS_VG_CONTAINER_CLASS, eo_obj); 371 pd->root = efl_add_ref(EFL_CANVAS_VG_CONTAINER_CLASS, NULL);
373 372
374 eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8); 373 eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
375 374
@@ -381,6 +380,12 @@ _efl_canvas_vg_object_efl_object_finalize(Eo *obj, Efl_Canvas_Vg_Object_Data *pd
381{ 380{
382 Evas *e = evas_object_evas_get(obj); 381 Evas *e = evas_object_evas_get(obj);
383 382
383 /* Container must have a set parent after construction.
384 efl_add_ref() with a parent won't work this case
385 because container needs some jobs in overriding parent_set()
386 after proper intialization. */
387 efl_parent_set(pd->root, obj);
388
384 // TODO: If we start to have to many Evas_Object_VG per canvas, it may be nice 389 // TODO: If we start to have to many Evas_Object_VG per canvas, it may be nice
385 // to actually have one event per canvas and one array per canvas to. 390 // to actually have one event per canvas and one array per canvas to.
386 efl_event_callback_add(e, EFL_CANVAS_SCENE_EVENT_RENDER_POST, _cleanup_reference, pd); 391 efl_event_callback_add(e, EFL_CANVAS_SCENE_EVENT_RENDER_POST, _cleanup_reference, pd);
@@ -440,6 +445,15 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
440 memset(cd->blend.pixels, 0, cd->blend.length); 445 memset(cd->blend.pixels, 0, cd->blend.length);
441 } 446 }
442 447
448 //For recovery context
449 //FIXME: It may occur async issue?
450 int px, py, pw, ph, pstride;
451 void *ppixels;
452 ector_buffer_size_get(ector, &pw, &ph);
453 ector_buffer_pixels_get(ector, &ppixels, &px, &ph, &pstride);
454 Efl_Gfx_Colorspace pcspace = ector_buffer_cspace_get(ector);
455 ector_surface_reference_point_get(ector, &px, &py);
456
443 // Buffer change 457 // Buffer change
444 ector_buffer_pixels_set(ector, cd->blend.pixels, 458 ector_buffer_pixels_set(ector, cd->blend.pixels,
445 w, h, cd->blend.stride, 459 w, h, cd->blend.stride,
@@ -450,8 +464,9 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
450 EINA_LIST_FOREACH(cd->children, l, child) 464 EINA_LIST_FOREACH(cd->children, l, child)
451 _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async); 465 _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
452 466
453 // Re-set original surface 467 // Recover original surface
454 ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async); 468 ector_buffer_pixels_set(ector, ppixels, pw, ph, pstride, pcspace, EINA_TRUE);
469 ector_surface_reference_point_set(ector, px, py);
455 470
456 // Draw buffer to original surface.(Ector_Surface) 471 // Draw buffer to original surface.(Ector_Surface)
457 ector_surface_draw_image(ector, cd->blend.buffer, 0, 0, alpha); 472 ector_surface_draw_image(ector, cd->blend.buffer, 0, 0, alpha);
@@ -476,8 +491,8 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
476//renders a vg_tree to an offscreen buffer and push it to the cache. 491//renders a vg_tree to an offscreen buffer and push it to the cache.
477static void * 492static void *
478_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, 493_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
479 void *engine, Efl_VG *root, int w, int h, void *buffer, 494 void *engine, Efl_VG *root, int w, int h, void *buffer, void *ckey,
480 Eina_Bool do_async, Eina_Bool cacheable) 495 Eina_Bool do_async)
481{ 496{
482 Ector_Surface *ector; 497 Ector_Surface *ector;
483 RGBA_Draw_Context *context; 498 RGBA_Draw_Context *context;
@@ -501,12 +516,10 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
501 evas_common_draw_context_set_color(context, 255, 255, 255, 255); 516 evas_common_draw_context_set_color(context, 255, 255, 255, 255);
502 517
503 //ector begin - end for drawing composite images. 518 //ector begin - end for drawing composite images.
504 //ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_FALSE, EINA_FALSE);
505 _evas_vg_render_pre(obj, root, engine, buffer, context, ector, NULL, 255, NULL, 0); 519 _evas_vg_render_pre(obj, root, engine, buffer, context, ector, NULL, 255, NULL, 0);
506 //ENFN->ector_end(engine, buffer, context, ector, EINA_FALSE);
507 520
508 //Actual content drawing 521 //Actual content drawing
509 ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_TRUE, do_async); 522 ENFN->ector_begin(engine, buffer, context, ector, 0, 0, do_async);
510 523
511 //draw on buffer 524 //draw on buffer
512 _evas_vg_render(obj, pd, 525 _evas_vg_render(obj, pd,
@@ -520,12 +533,8 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
520 ENFN->ector_end(engine, buffer, context, ector, do_async); 533 ENFN->ector_end(engine, buffer, context, ector, do_async);
521 evas_common_draw_context_free(context); 534 evas_common_draw_context_free(context);
522 535
523 if (buffer_created && cacheable) 536 if (buffer_created && ckey)
524 { 537 ENFN->ector_surface_cache_set(engine, ckey, buffer);
525 //Use root as a cache key.
526 ENFN->ector_surface_cache_set(engine, root, buffer);
527 pd->cached_frame_idx = pd->frame_idx;
528 }
529 538
530 return buffer; 539 return buffer;
531} 540}
@@ -566,8 +575,8 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
566 Vg_Cache_Entry *vg_entry = pd->vg_entry; 575 Vg_Cache_Entry *vg_entry = pd->vg_entry;
567 Efl_VG *root; 576 Efl_VG *root;
568 Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio. 577 Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio.
569 Eina_Bool drop_cache = EINA_FALSE;
570 void *buffer = NULL; 578 void *buffer = NULL;
579 void *key = NULL;
571 580
572 evas_cache_vg_entry_value_provider_update(pd->vg_entry, efl_key_data_get(obj->object, "_vg_value_providers")); 581 evas_cache_vg_entry_value_provider_update(pd->vg_entry, efl_key_data_get(obj->object, "_vg_value_providers"));
573 582
@@ -603,7 +612,23 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
603 //Size is changed, cached data is invalid. 612 //Size is changed, cached data is invalid.
604 if ((size.w != vg_entry->w) || (size.h != vg_entry->h)) 613 if ((size.w != vg_entry->w) || (size.h != vg_entry->h))
605 { 614 {
606 drop_cache = EINA_TRUE; 615//Not necessary, but this might be helpful for precise caching.
616#if 0
617 if (cacheable)
618 {
619 //if the size doesn't match, drop previous cache surface.
620 key = evas_cache_vg_surface_key_get(pd->vg_entry->root, vg_entry->w, vg_entry->h, 0);
621 if (key) ENFN->ector_surface_cache_drop(engine, key);
622
623 //Animatable... Try to drop the last frame image.
624 int last_frame = (int) (evas_cache_vg_anim_frame_count_get(pd->vg_entry) - 1);
625 if (last_frame > 0)
626 {
627 key = evas_cache_vg_surface_key_get(pd->vg_entry->root, vg_entry->w, vg_entry->h, last_frame);
628 if (key) ENFN->ector_surface_cache_drop(engine, key);
629 }
630 }
631#endif
607 vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h); 632 vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h);
608 evas_cache_vg_entry_del(pd->vg_entry); 633 evas_cache_vg_entry_del(pd->vg_entry);
609 pd->vg_entry = vg_entry; 634 pd->vg_entry = vg_entry;
@@ -616,30 +641,25 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
616 if (offset.y > 0) offset.y /= 2; 641 if (offset.y > 0) offset.y /= 2;
617 w = size.w; 642 w = size.w;
618 h = size.h; 643 h = size.h;
619
620 } 644 }
621 root = evas_cache_vg_tree_get(vg_entry, pd->frame_idx); 645 root = evas_cache_vg_tree_get(vg_entry, pd->frame_idx);
622 if (!root) return; 646 if (!root) return;
623 647
624 if (cacheable) 648 if (cacheable)
625 { 649 {
626 //if the size doesn't match, drop previous cache surface. 650 key = evas_cache_vg_surface_key_get(root, w, h, pd->frame_idx);
627 if (drop_cache) 651 if (key) buffer = ENFN->ector_surface_cache_get(engine, key);
628 ENFN->ector_surface_cache_drop(engine, (void *) root);
629 //Cache Hit!
630 else if (pd->frame_idx == pd->cached_frame_idx)
631 buffer = ENFN->ector_surface_cache_get(engine, (void *) root);
632 //Drop invalid one.
633 else
634 ENFN->ector_surface_cache_drop(engine, (void *) root);
635 } 652 }
636 653
637 if (!buffer) 654 if (!buffer)
638 buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, 655 {
639 do_async, cacheable); 656 buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, key, do_async);
657 }
640 else 658 else
641 //cache reference was increased when we get the cache. 659 {
642 ENFN->ector_surface_cache_drop(engine, (void *) root); 660 //cache reference was increased when we get the cache.
661 if (key) ENFN->ector_surface_cache_drop(engine, key);
662 }
643 663
644 _render_buffer_to_screen(obj, 664 _render_buffer_to_screen(obj,
645 engine, output, context, surface, 665 engine, output, context, surface,
@@ -652,8 +672,7 @@ static void
652_user_vg_entry_render(Evas_Object_Protected_Data *obj, 672_user_vg_entry_render(Evas_Object_Protected_Data *obj,
653 Efl_Canvas_Vg_Object_Data *pd, 673 Efl_Canvas_Vg_Object_Data *pd,
654 void *engine, void *output, void *context, void *surface, 674 void *engine, void *output, void *context, void *surface,
655 int x, int y, int w, int h, Eina_Bool do_async, 675 int x, int y, int w, int h, Eina_Bool do_async)
656 Eina_Bool cacheable)
657{ 676{
658 Vg_User_Entry *user_entry = pd->user_entry; 677 Vg_User_Entry *user_entry = pd->user_entry;
659 678
@@ -669,14 +688,13 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
669 //if the buffer is not created yet 688 //if the buffer is not created yet
670 void *buffer = NULL; 689 void *buffer = NULL;
671 690
672 if (cacheable)
673 buffer = ENFN->ector_surface_cache_get(engine, user_entry->root); 691 buffer = ENFN->ector_surface_cache_get(engine, user_entry->root);
674 692
675 if (!buffer) 693 if (!buffer)
676 { 694 {
677 // render to the buffer 695 // render to the buffer
678 buffer = _render_to_buffer(obj, pd, engine, user_entry->root, 696 buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
679 w, h, buffer, do_async, cacheable); 697 w, h, buffer, user_entry->root, do_async);
680 } 698 }
681 else 699 else
682 { 700 {
@@ -684,8 +702,8 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
684 if (pd->changed) 702 if (pd->changed)
685 buffer = _render_to_buffer(obj, pd, engine, 703 buffer = _render_to_buffer(obj, pd, engine,
686 user_entry->root, 704 user_entry->root,
687 w, h, buffer, 705 w, h, buffer, NULL,
688 do_async, EINA_FALSE); 706 do_async);
689 //cache reference was increased when we get the cache. 707 //cache reference was increased when we get the cache.
690 ENFN->ector_surface_cache_drop(engine, user_entry->root); 708 ENFN->ector_surface_cache_drop(engine, user_entry->root);
691 } 709 }
@@ -694,7 +712,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
694 engine, output, context, surface, 712 engine, output, context, surface,
695 buffer, 713 buffer,
696 x, y, w, h, 714 x, y, w, h,
697 do_async, cacheable); 715 do_async, EINA_TRUE);
698} 716}
699 717
700static void 718static void
@@ -739,7 +757,7 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
739 _user_vg_entry_render(obj, pd, 757 _user_vg_entry_render(obj, pd,
740 engine, output, context, surface, 758 engine, output, context, surface,
741 obj->cur->geometry.x + x, obj->cur->geometry.y + y, 759 obj->cur->geometry.x + x, obj->cur->geometry.y + y,
742 obj->cur->geometry.w, obj->cur->geometry.h, do_async, cacheable); 760 obj->cur->geometry.w, obj->cur->geometry.h, do_async);
743 } 761 }
744 pd->changed = EINA_FALSE; 762 pd->changed = EINA_FALSE;
745} 763}
@@ -943,6 +961,30 @@ _efl_canvas_vg_object_efl_gfx_frame_controller_frame_duration_get(const Eo *eo_o
943 return evas_cache_vg_anim_duration_get(pd->vg_entry); 961 return evas_cache_vg_anim_duration_get(pd->vg_entry);
944} 962}
945 963
964Eina_Bool _efl_canvas_vg_object_efl_gfx_frame_controller_sector_set(Eo *obj EINA_UNUSED,
965 Efl_Canvas_Vg_Object_Data *pd,
966 const char *name,
967 int startframe,
968 int endframe)
969{
970 if (!pd->vg_entry) return EINA_FALSE;
971 if (!evas_cache_vg_anim_sector_set(pd->vg_entry, name, startframe, endframe))
972 return EINA_FALSE;
973 return EINA_TRUE;
974}
975
976Eina_Bool _efl_canvas_vg_object_efl_gfx_frame_controller_sector_get(const Eo *obj EINA_UNUSED,
977 Efl_Canvas_Vg_Object_Data *pd,
978 const char *name,
979 int *startframe,
980 int *endframe)
981{
982 if (!pd->vg_entry) return EINA_FALSE;
983 if (!evas_cache_vg_anim_sector_get(pd->vg_entry, name, startframe, endframe))
984 return EINA_FALSE;
985 return EINA_TRUE;
986}
987
946EOLIAN static Eina_Bool 988EOLIAN static Eina_Bool
947_efl_canvas_vg_object_efl_gfx_frame_controller_frame_set(Eo *eo_obj, 989_efl_canvas_vg_object_efl_gfx_frame_controller_frame_set(Eo *eo_obj,
948 Efl_Canvas_Vg_Object_Data *pd, 990 Efl_Canvas_Vg_Object_Data *pd,