void gf_svg_node_del(GF_Node *node) { SVG_Element *p = (SVG_Element *)node; if (p->sgprivate->interact && p->sgprivate->interact->animations) { gf_smil_anim_delete_animations((GF_Node *)p); } if (p->sgprivate->tag==TAG_SVG_listener) { /*remove from target's listener list*/ GF_DOMEventTarget *evt = node->sgprivate->UserPrivate; node->sgprivate->UserPrivate = NULL; if (evt) gf_list_del_item(evt->evt_list, p); #if 0 if (evt && (gf_node_get_attribute_by_tag(p, TAG_XMLEV_ATT_event, 0, 0, &info) == GF_OK)) { u32 type = ((XMLEV_Event *)info.far_ptr)->type; gf_sg_unregister_event_type(p->sgprivate->scenegraph, gf_dom_event_get_category(type)); } #endif } /*if this is a handler with a UserPrivate, this is a handler with an implicit listener (eg handler with ev:event=""). Destroy the associated listener*/ if (p->sgprivate->tag==TAG_SVG_handler) { GF_Node *listener = p->sgprivate->UserPrivate; if (listener && (listener->sgprivate->tag==TAG_SVG_listener)) { gf_node_unregister(listener, NULL); // gf_svg_node_del(listener); } } /*remove this node from associated listeners*/ if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { u32 i, count; count = gf_dom_listener_count(node); for (i=0; i<count; i++) { GF_Node *listener = gf_list_get(node->sgprivate->interact->dom_evt->evt_list, i); listener->sgprivate->UserPrivate = NULL; } } if (gf_svg_is_timing_tag(node->sgprivate->tag)) { SVGTimedAnimBaseElement *tap = (SVGTimedAnimBaseElement *)node; if (tap->animp) { gf_free(tap->animp); gf_smil_anim_remove_from_target((GF_Node *)tap, (GF_Node *)tap->xlinkp->href->target); } if (tap->timingp) { gf_smil_timing_delete_runtime_info((GF_Node *)tap, tap->timingp->runtime); gf_free(tap->timingp); } if (tap->xlinkp) gf_free(tap->xlinkp); } gf_node_delete_attributes(node); gf_sg_parent_reset(node); gf_node_free(node); }
void gf_svg_node_del(GF_Node *node) { SVG_Element *p = (SVG_Element *)node; if (p->sgprivate->interact && p->sgprivate->interact->animations) { gf_smil_anim_delete_animations((GF_Node *)p); } if (p->sgprivate->tag==TAG_SVG_listener) { /*remove from target's listener list*/ gf_dom_event_remove_listener_from_parent((GF_DOMEventTarget *)node->sgprivate->UserPrivate, (GF_Node *)p); } /*if this is a handler with a UserPrivate, this is a handler with an implicit listener (eg handler with ev:event=""). Destroy the associated listener*/ if (p->sgprivate->tag==TAG_SVG_handler) { GF_Node *listener = p->sgprivate->UserPrivate; if (listener && (listener->sgprivate->tag==TAG_SVG_listener)) { GF_FieldInfo info; if (gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_handler, 0, 0, &info) == GF_OK) { XMLRI *iri = (XMLRI *)info.far_ptr; if (iri->target) { assert(iri->target==p); iri->target = NULL; } } gf_node_unregister(listener, NULL); // gf_svg_node_del(listener); } } /*remove this node from associated listeners*/ if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { u32 i, count; count = gf_dom_listener_count(node); for (i=0; i<count; i++) { GF_Node *listener = (GF_Node *)gf_list_get(node->sgprivate->interact->dom_evt->listeners, i); listener->sgprivate->UserPrivate = NULL; } } if (gf_svg_is_timing_tag(node->sgprivate->tag)) { SVGTimedAnimBaseElement *tap = (SVGTimedAnimBaseElement *)node; if (tap->animp) { gf_free(tap->animp); gf_smil_anim_remove_from_target((GF_Node *)tap, (GF_Node *)tap->xlinkp->href->target); } if (tap->timingp) { gf_smil_timing_delete_runtime_info((GF_Node *)tap, tap->timingp->runtime); gf_free(tap->timingp); } if (tap->xlinkp) gf_free(tap->xlinkp); } gf_node_delete_attributes(node); gf_sg_parent_reset(node); gf_node_free(node); }
void gf_sr_simulation_tick(GF_Renderer *sr) { u32 in_time, end_time, i, count; /*lock renderer for the whole render cycle*/ gf_sr_lock(sr, 1); /*first thing to do, let the video output handle user event if it is not threaded*/ sr->video_out->ProcessEvent(sr->video_out, NULL); if (sr->freeze_display) { gf_sr_lock(sr, 0); gf_sleep(sr->frame_duration); return; } gf_sr_reconfig_task(sr); /* if there is no scene, we draw a black screen to flush the screen */ if (!sr->scene) { sr->visual_renderer->DrawScene(sr->visual_renderer); gf_sr_lock(sr, 0); gf_sleep(sr->frame_duration); return; } // GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[General] Time %f - Composing new frame #%d\n", gf_node_get_scene_time(gf_sg_get_root_node(sr->scene)), sr->frame_number)); in_time = gf_sys_clock(); if (sr->reset_graphics) sr->draw_next_frame = 1; #ifdef GF_SR_EVENT_QUEUE /*process pending user events*/ gf_mx_p(sr->ev_mx); while (gf_list_count(sr->events)) { GF_Event *ev = (GF_Event*)gf_list_get(sr->events, 0); gf_list_rem(sr->events, 0); if (!sr->visual_renderer->ExecuteEvent(sr->visual_renderer, ev)) { SR_ForwardUserEvent(sr, ev); } free(ev); } gf_mx_v(sr->ev_mx); #endif #if 0 if (sr->frame_number == 0 && sr->user->EventProc) { GF_Event evt; evt.type = GF_EVENT_UPDATE_RTI; evt.caption.caption = "UPDATE - Before first call to draw scene"; sr->user->EventProc(sr->user->opaque, &evt); } #endif /*execute all routes before updating textures, otherwise nodes inside composite texture may never see their dirty flag set*/ gf_sg_activate_routes(sr->scene); #ifndef GPAC_DISABLE_SVG #if SVG_FIXME { /* Experimental (Not SVG compliant system events (i.e. battery, cpu ...) triggered to the root node)*/ GF_Node *root = gf_sg_get_root_node(sr->scene); GF_DOM_Event evt; if (gf_dom_listener_count(root)) { u32 i, count; count = gf_dom_listener_count(root); for (i=0;i<count; i++) { SVG_SA_listenerElement *l = gf_dom_listener_get(root, i); if (l->event.type == GF_EVENT_CPU) { GF_SystemRTInfo sys_rti; if (gf_sys_get_rti(500, &sys_rti, GF_RTI_ALL_PROCESSES_TIMES)) { evt.type = GF_EVENT_CPU; evt.cpu_percentage = sys_rti.total_cpu_usage; //printf("%d\n",sys_rti.total_cpu_usage); gf_dom_event_fire(root, NULL, &evt); } } else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) { evt.type = GF_EVENT_BATTERY; gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel); gf_dom_event_fire(root, NULL, &evt); } } } } #endif if (gf_smil_notify_timed_elements(sr->scene)) { sr->draw_next_frame = 1; } #if 0 for (i=0; i<gf_list_count(sr->secondary_scenes); i++) { if (gf_smil_notify_timed_elements(gf_list_get(sr->secondary_scenes, i))) { sr->draw_next_frame = 1; } } #endif #endif /*update all textures*/ count = gf_list_count(sr->textures); for (i=0; i<count; i++) { GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i); /*signal graphics reset before updating*/ if (sr->reset_graphics && st->hwtx) sr->visual_renderer->TextureHWReset(st); st->update_texture_fcnt(st); } /*if invalidated, draw*/ if (sr->draw_next_frame) { /*video flush only*/ if (sr->draw_next_frame==2) { GF_Window rc; rc.x = rc.y = 0; rc.w = sr->width; rc.h = sr->height; sr->draw_next_frame = 0; sr->video_out->Flush(sr->video_out, &rc); } else { sr->draw_next_frame = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Redrawing scene\n")); sr->visual_renderer->DrawScene(sr->visual_renderer); #if 0 if (sr->frame_number == 0 && sr->user->EventProc) { GF_Event evt; evt.type = GF_EVENT_UPDATE_RTI; evt.caption.caption = "Before first call to draw scene"; sr->user->EventProc(sr->user->opaque, &evt); } #endif } sr->reset_graphics = 0; GF_LOG(GF_LOG_INFO, GF_LOG_RENDER, ("[Render] Scene drawn in %d ms\n", gf_sys_clock() - in_time)); if (sr->stress_mode) { sr->draw_next_frame = 1; sr->reset_graphics = 1; } } /*release all textures - we must release them to handle a same OD being used by several textures*/ count = gf_list_count(sr->textures); for (i=0; i<count; i++) { GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i); gf_sr_texture_release_stream(st); } /*update all timed nodes */ for (i=0; i<gf_list_count(sr->time_nodes); i++) { GF_TimeNode *tn = (GF_TimeNode *)gf_list_get(sr->time_nodes, i); if (!tn->needs_unregister) tn->UpdateTimeNode(tn); if (tn->needs_unregister) { tn->is_registered = 0; tn->needs_unregister = 0; gf_list_rem(sr->time_nodes, i); i--; continue; } } end_time = gf_sys_clock() - in_time; gf_sr_lock(sr, 0); sr->current_frame = (sr->current_frame+1) % GF_SR_FPS_COMPUTE_SIZE; sr->frame_time[sr->current_frame] = end_time; sr->frame_number++; #if 0 if (sr->user->EventProc) { char legend[100]; GF_Event evt; evt.type = GF_EVENT_UPDATE_RTI; sprintf(legend, "After rendering of frame %d", sr->frame_number); evt.caption.caption = legend; sr->user->EventProc(sr->user->opaque, &evt); } #endif /*step mode on, pause and return*/ if (sr->step_mode) { sr->step_mode = 0; if (sr->term) gf_term_set_option(sr->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); return; } /*not threaded, let the owner decide*/ if ((sr->user->init_flags & GF_TERM_NO_VISUAL_THREAD) || !sr->frame_duration) return; /*compute sleep time till next frame, otherwise we'll kill the CPU*/ i=1; while (i * sr->frame_duration < end_time) i++; in_time = i * sr->frame_duration - end_time; gf_sleep(in_time); }