static void AS_CheckURL(AnimationStreamStack *stack, M_AnimationStream *as) { if (!stack->stream) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); stack->stream = gf_mo_find((GF_Node *)as, &as->url, 0); gf_sr_invalidate(stack->compositor, NULL); /*if changed while playing trigger*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } return; } /*check change*/ if (gf_mo_url_changed(stack->stream, &as->url)) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); /*if changed while playing stop old source*/ if (as->isActive) { gf_mo_set_flag(stack->stream, GF_MO_DISPLAY_REMOVE, 1); gf_mo_stop(stack->stream); } stack->stream = gf_mo_find((GF_Node *)as, &as->url, 0); /*if changed while playing play new source*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } gf_sr_invalidate(stack->compositor, NULL); } }
static void AS_Deactivate(AnimationStreamStack *stack, M_AnimationStream *as) { if (as->isActive) { as->isActive = 0; gf_node_event_out_str((GF_Node*)as, "isActive"); } if (stack->stream) { if (gf_mo_url_changed(stack->stream, &as->url)) gf_mo_set_flag(stack->stream, GF_MO_DISPLAY_REMOVE, 1); gf_mo_stop(stack->stream); } stack->time_handle.needs_unregister = 1; gf_sr_invalidate(stack->compositor, NULL); }
static void RenderLayer2D(GF_Node *node, void *rs, Bool is_destroy) { u32 i; GF_List *prevback, *prevviews; GF_Rect clip; M_Viewport *vp; ChildGroup2D *cg; GF_Matrix2D gf_mx2d_bck; GroupingNode2D *parent_bck; DrawableContext *back_ctx; Bool bool_bck; DrawableContext *ctx; M_Background2D *back; M_Layer2D *l = (M_Layer2D *)node; Layer2DStack *l2D = (Layer2DStack *) gf_node_get_private(node); RenderEffect2D *eff; if (is_destroy) { DeleteGroupingNode2D((GroupingNode2D *)l2D); gf_list_del(l2D->backs); gf_list_del(l2D->views); free(l2D); return; } eff = (RenderEffect2D *) rs; gf_mx2d_copy(gf_mx2d_bck, eff->transform); parent_bck = eff->parent; eff->parent = (GroupingNode2D *) l2D; gf_mx2d_init(eff->transform); bool_bck = eff->draw_background; prevback = eff->back_stack; prevviews = eff->view_stack; eff->back_stack = l2D->backs; eff->view_stack = l2D->views; if (l2D->first) { /*render on back first to register with stack*/ if (l->background) { eff->draw_background = 0; gf_node_render((GF_Node*) l->background, eff); group2d_reset_children((GroupingNode2D*) l2D); eff->draw_background = 1; } vp = (M_Viewport*)l->viewport; if (vp) { gf_list_add(l2D->views, vp); if (!vp->isBound) { vp->isBound = 1; gf_node_event_out_str((GF_Node*)vp, "isBound"); } } } back = NULL; if (gf_list_count(l2D->backs) ) { back = (M_Background2D*)gf_list_get(l2D->backs, 0); if (!back->isBound) back = NULL; } vp = NULL; if (gf_list_count(l2D->views)) { vp = (M_Viewport*)gf_list_get(l2D->views, 0); if (!vp->isBound) vp = NULL; } if (!eff->is_pixel_metrics) gf_mx2d_add_scale(&eff->transform, eff->min_hsize, eff->min_hsize); l2D->clip = R2D_ClipperToPixelMetrics(eff, l->size); /*apply viewport*/ if (vp) { clip = l2D->clip; vp_setup((GF_Node *) vp, eff, &clip); } back_ctx = NULL; if (back) { /*setup back size and render*/ group2d_start_child((GroupingNode2D *)l2D); eff->draw_background = 1; ctx = b2D_GetContext(back, l2D->backs); ctx->bi->unclip = l2D->clip; ctx->bi->clip = gf_rect_pixelize(&ctx->bi->unclip); gf_mx2d_init(ctx->transform); gf_node_render((GF_Node *) back, eff); eff->draw_background = 0; /*we need a trick since we're not using a dedicated surface for layer rendering, we emulate the back context: remove previous context and insert fake one*/ if (!(eff->trav_flags & TF_RENDER_DIRECT) && (gf_list_count(l2D->groups)==1)) { ChildGroup2D *cg = (ChildGroup2D *)gf_list_get(l2D->groups, 0); back_ctx = VS2D_GetDrawableContext(eff->surface); gf_list_rem(cg->contexts, 0); gf_list_add(cg->contexts, back_ctx); back_ctx->h_texture = ctx->h_texture; back_ctx->flags = ctx->flags; back_ctx->flags &= ~CTX_IS_TRANSPARENT; back_ctx->flags |= CTX_IS_BACKGROUND; back_ctx->aspect = ctx->aspect; back_ctx->drawable = ctx->drawable; drawable_check_bounds(back_ctx, eff->surface); back_ctx->bi->clip = ctx->bi->clip; back_ctx->bi->unclip = ctx->bi->unclip; } group2d_end_child((GroupingNode2D *)l2D); } group2d_traverse((GroupingNode2D *)l2D, l->children, eff); /*restore effect*/ eff->draw_background = bool_bck; gf_mx2d_copy(eff->transform, gf_mx2d_bck); eff->parent = parent_bck; eff->back_stack = prevback; eff->view_stack = prevviews; /*check bindables*/ if (l2D->first) { Bool redraw = 0; l2D->first = 0; if (!back && gf_list_count(l2D->backs)) redraw = 1; if (!vp && gf_list_count(l2D->views) ) redraw = 1; /*we missed background or viewport (was not declared as bound during traversal, and is bound now)*/ if (redraw) { group2d_reset_children((GroupingNode2D*)l2D); gf_sr_invalidate(l2D->compositor, NULL); return; } } i=0; while ((cg = (ChildGroup2D *)gf_list_enum(l2D->groups, &i))) { child2d_render_done(cg, eff, &l2D->clip); } group2d_reset_children((GroupingNode2D*)l2D); group2d_force_bounds(eff->parent, &l2D->clip); }
static void UpdateComposite2D(GF_TextureHandler *txh) { GF_Err e; u32 i; SensorHandler *hsens; RenderEffect2D *eff; M_CompositeTexture2D *ct2D = (M_CompositeTexture2D *)txh->owner; Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner); GF_Raster2D *r2d = st->surf->render->compositor->r2d; if (!gf_node_dirty_get(txh->owner)) { txh->needs_refresh = 0; return; } /*rebuild stencil*/ if (!st->surf->the_surface || !txh->hwtx || ((s32) st->width != ct2D->pixelWidth) || ( (s32) st->height != ct2D->pixelHeight) ) { if (txh->hwtx) r2d->stencil_delete(txh->hwtx); txh->hwtx = NULL; if (ct2D->pixelWidth<=0) return; if (ct2D->pixelHeight<=0) return; st->width = ct2D->pixelWidth; st->height = ct2D->pixelHeight; txh->hwtx = r2d->stencil_new(r2d, GF_STENCIL_TEXTURE); e = r2d->stencil_create_texture(txh->hwtx, st->width, st->height, GF_PIXEL_ARGB); if (e) { if (txh->hwtx) r2d->stencil_delete(txh->hwtx); txh->hwtx = NULL; } } if (!txh->hwtx) return; GF_SAFEALLOC(eff, RenderEffect2D); eff->sensors = gf_list_new(); eff->surface = st->surf; if (st->surf->render->top_effect->trav_flags & TF_RENDER_DIRECT) { eff->trav_flags = TF_RENDER_DIRECT; } gf_mx2d_init(eff->transform); gf_cmx_init(&eff->color_mat); st->surf->width = st->width; st->surf->height = st->height; eff->back_stack = st->surf->back_stack; eff->view_stack = st->surf->view_stack; eff->is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(st->txh.owner)); eff->min_hsize = INT2FIX( MIN(st->width, st->height) ) / 2; Composite_CheckBindables(st->txh.owner, eff, st->first); st->first = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Entering CompositeTexture2D Render Cycle\n")); e = VS2D_InitDraw(st->surf, eff); if (e) { effect_delete(eff); return; } /*render children*/ if (gf_node_dirty_get(st->txh.owner) & GF_SG_NODE_DIRTY) { GF_ChildNodeItem *l = ct2D->children; /*rebuild sensor list */ if (gf_list_count(st->sensors)) { gf_list_del(st->sensors); st->sensors = gf_list_new(); } while (l) { if (l->node && is_sensor_node(l->node) ) { hsens = get_sensor_handler(l->node); if (hsens) gf_list_add(st->sensors, hsens); } l = l->next; } /*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/ if (gf_list_count(st->sensors)) { effect_reset_sensors(eff); } } /*add sensor to effects*/ i=0; while ((hsens = (SensorHandler*)gf_list_enum(st->sensors, &i))) { effect_add_sensor(eff, hsens, &eff->transform); } gf_node_dirty_clear(st->txh.owner, 0); /*render*/ gf_node_render_children(st->txh.owner, eff); /*finalize draw*/ txh->needs_refresh = VS2D_TerminateDraw(st->surf, eff); st->txh.transparent = st->surf->last_had_back ? 0 : 1; /* st->txh.active_window.x = 0; st->txh.active_window.y = 0; st->txh.active_window.width = st->width; st->txh.active_window.height = st->height; */ st->txh.width = st->width; st->txh.height = st->height; /*set active viewport in image coordinates top-left=(0, 0), not in BIFS*/ if (gf_list_count(st->surf->view_stack)) { M_Viewport *vp = (M_Viewport *)gf_list_get(st->surf->view_stack, 0); if (vp->isBound) { SFVec2f size = vp->size; if (size.x >=0 && size.y>=0) { /* st->txh.active_window.width = size.x; st->txh.active_window.height = size.y; st->txh.active_window.x = (st->width - size.x) / 2; st->txh.active_window.y = (st->height - size.y) / 2; */ /*FIXME - we need tracking of VP changes*/ txh->needs_refresh = 1; } } } if (txh->needs_refresh) { if (r2d->stencil_texture_modified) r2d->stencil_texture_modified(st->txh.hwtx); gf_sr_invalidate(st->txh.compositor, NULL); } effect_delete(eff); GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Leaving CompositeTexture2D Render Cycle\n")); }