Пример #1
0
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);
    }
Пример #2
0
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);
}
Пример #3
0
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);
    }
}