Exemplo n.º 1
0
GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state)
{
	GF_Err e;
	u32 rem, count;
	struct _drawable_store *it, *prev;
#ifndef GPAC_DISABLE_VRML
	DrawableContext *ctx;
	M_Background2D *bck;
#endif
	u32 draw_mode;

	/*reset display list*/
	visual->cur_context = visual->context;
	if (visual->context) visual->context->drawable = NULL;
	visual->has_modif = 0;
	visual->has_overlays = 0;

	visual_2d_setup_projection(visual, tr_state);
	if (!visual->top_clipper.width || !visual->top_clipper.height)
		return GF_OK;

	tr_state->traversing_mode = TRAVERSE_SORT;
	visual->num_nodes_current_frame = 0;

	/*setup raster surface, brush and pen */
	e = visual_2d_init_raster(visual);
	if (e)
		return e;

	draw_mode = 0;
	if (tr_state->immediate_draw) draw_mode = 1;
	/*if we're requested to invalidate everything, switch to direct drawing but don't reset bounds*/
	else if (tr_state->invalidate_all) {
		tr_state->immediate_draw = 1;
		draw_mode = 2;
	}
	tr_state->invalidate_all = 0;

	/*reset prev nodes if any (previous traverse was indirect)*/
	rem = count = 0;
	prev = NULL;
	it = visual->prev_nodes;
	while (it) {
		/*node was not drawn on this visual*/
		if (!drawable_flush_bounds(it->drawable, visual, draw_mode)) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Unregistering previously drawn node %s from visual\n", gf_node_get_class_name(it->drawable->node)));

			/*remove all bounds info related to this visual and unreg node */
			drawable_reset_bounds(it->drawable, visual);

			if (prev) prev->next = it->next;
			else visual->prev_nodes = it->next;
			if (!it->next) visual->last_prev_entry = prev;
			rem++;
			gf_free(it);
			it = prev ? prev->next : visual->prev_nodes;
		} else {
			/*mark drawable as already registered with visual*/
			it->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL;
			prev = it;
			it = it->next;
			count++;
		}
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Top visual initialized - %d nodes registered and %d removed - using %s rendering\n", count, rem, draw_mode ? "direct" : "dirty-rect"));
	if (!draw_mode) return GF_OK;

#ifndef GPAC_DISABLE_VRML
	/*direct mode, draw background*/
	bck = (M_Background2D*) gf_list_get(visual->back_stack, 0);
	if (bck && bck->isBound) {
		ctx = b2d_get_context(bck, visual->back_stack);
		if (ctx) {
			/*force clearing entire zone, not just viewport, when using color. If texture, we MUST
			use the VP clipper in order to compute offsets when blitting bitmaps*/
			if (ctx->aspect.fill_texture &&ctx->aspect.fill_texture->stream) {
				ctx->bi->clip = visual->top_clipper;
			} else {
				ctx->bi->clip = visual->surf_rect;
			}
			ctx->bi->unclip = gf_rect_ft(&ctx->bi->clip);
			tr_state->traversing_mode = TRAVERSE_BINDABLE;
			ctx->flags |= CTX_BACKROUND_NOT_LAYER;
			gf_node_traverse((GF_Node *) bck, tr_state);
			tr_state->traversing_mode = TRAVERSE_SORT;
			ctx->flags &= ~CTX_BACKROUND_NOT_LAYER;
		} else {
			visual->ClearSurface(visual, NULL, 0);
		}
	} else
#endif
	{
		visual->ClearSurface(visual, NULL, 0);
	}
	return GF_OK;
}
Exemplo n.º 2
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);
    }
}