Bool VS2D_TerminateDraw(VisualSurface2D *surf, RenderEffect2D *eff) { u32 j, k, i, num_to_draw, num_empty, count, max_nodes_allowed; M4IRect refreshRect; Bool redraw_all, is_empty; M_Background2D *bck; DrawableContext *bck_ctx; DrawableContext *ctx; Bool use_direct_render = 0; Bool has_changed = 0; /*in direct mode the surface is always redrawn*/ if (eff->trav_flags & TF_RENDER_DIRECT) { has_changed = 1; use_direct_render = 1; } VS2D_ResetSensors(surf); num_to_draw = 0; /*if the aspect ratio has changed redraw everything*/ redraw_all = eff->invalidate_all; /*check for background changes for transparent nodes*/ bck = NULL; bck_ctx = NULL; if (! use_direct_render) { bck = NULL; if (ChainGetCount(surf->back_stack)) bck = ChainGetEntry(surf->back_stack, 0); if (bck) { if (!bck->isBound) redraw_all = 1; surf->last_had_back = 1; bck_ctx = b2D_GetContext(bck, surf->back_stack); if (bck_ctx->redraw_flags) redraw_all = 1; } else if (surf->last_had_back) { surf->last_had_back = 0; redraw_all = 1; } surf->last_had_back = 0; } max_nodes_allowed = (u32) ((surf->top_clipper.width / MIN_BBOX_SIZE) * (surf->top_clipper.height / MIN_BBOX_SIZE)); num_empty = 0; count = surf->num_contexts; for (i=0; i<count; i++) { ctx = surf->contexts[i]; m4_irect_intersect(&ctx->clip, &surf->top_clipper); is_empty = m4_rect_is_empty(ctx->clip); /*store bounds even in direct render*/ if (!is_empty) { drawable_store_bounds(ctx); register_sensor(surf, ctx); } else if (!use_direct_render) { num_empty++; continue; } //register node to draw surf->nodes_to_draw[num_to_draw] = i; num_to_draw++; if (use_direct_render) { drawable_reset_previous_bounds(ctx->node); continue; } drawctx_update_info(ctx); /*node has changed, add to redraw area*/ if (!redraw_all && ctx->redraw_flags) { ra_union_rect(&surf->to_redraw, ctx->clip); CHECK_MAX_NODE } /*otherwise try to remove any sensor hidden below*/ if (!ctx->transparent) remove_hidden_sensors(surf, num_to_draw, ctx); }
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); }
void VS2D_InitDraw(VisualSurface2D *surf, RenderEffect2D *eff) { u32 i, count; M4Rect rc; DrawableContext *ctx; M_Background2D *bck; surf->num_contexts = 0; eff->surface = surf; eff->draw_background = 0; mx2d_copy(surf->top_transform, eff->transform); eff->back_stack = surf->back_stack; eff->view_stack = surf->view_stack; /*setup clipper*/ if (surf->center_coords) { m4_rect_center(&rc, (Float) surf->width, (Float) surf->height); } else { rc.x = 0; rc.width = (Float) surf->width; rc.y = rc.height = (Float) surf->height; } /*set top-transform to pixelMetrics*/ if (!eff->is_pixel_metrics) mx2d_add_scale(&eff->transform, eff->min_hsize, eff->min_hsize); surf->surf_rect = m4_rect_pixelize(&rc); /*setup surface, brush and pen */ VS2D_InitSurface(surf); /*setup viewport*/ if (ChainGetCount(surf->view_stack)) { M_Viewport *vp = (M_Viewport *) ChainGetEntry(surf->view_stack, 0); vp_setup((SFNode *) vp, eff, &rc); } surf->top_clipper = m4_rect_pixelize(&rc); /*reset prev nodes*/ count = ChainGetCount(surf->prev_nodes_drawn); for (i=0; i<count; i++) { Drawable *dr = ChainGetEntry(surf->prev_nodes_drawn, i); if (surf->last_was_direct_render != (Bool) (eff->trav_flags & TF_RENDER_DIRECT) ) drawable_reset_previous_bounds(dr); drawable_flush_bounds(dr); } surf->last_was_direct_render = (Bool) (eff->trav_flags & TF_RENDER_DIRECT); if (!surf->last_was_direct_render) return; /*direct mode, draw background*/ bck = NULL; if (ChainGetCount(surf->back_stack)) bck = ChainGetEntry(surf->back_stack, 0); if (bck && bck->isBound) { ctx = b2D_GetContext(bck, surf->back_stack); ctx->clip = surf->surf_rect; ctx->unclip = m4_rect_ft(&ctx->clip); eff->draw_background = 1; Node_Render((SFNode *) bck, eff); eff->draw_background = 0; } else { VS2D_Clear(surf, NULL, 0); } }