📄 visualsurface2d.c
字号:
#if CHECK_UNCHANGED if (remove && gf_rect_overlaps(&ctx->bi->clip, ra->list[k])) { if (ctx->need_redraw) remove = 0; }#endif continue; } /*which opaquely covers the given area */ if (! (ctx->flags & CTX_IS_TRANSPARENT) ) {#if CHECK_UNCHANGED /*the opaque area has nothing changed above, remove the dirty rect*/ if (remove && !ctx->need_redraw) { u32 j = ra->count - k - 1; if (j) { memmove(&ra->list[j], &ra->list[j+1], sizeof(GF_IRect)*j); memmove(&ra->opaque_node_index[j], &ra->opaque_node_index[j+1], sizeof(u32)*j); } ra->count--; k--; } /*opaque area has something changed above, mark index */ else #endif { ra->opaque_node_index[k] = i; } break;#if CHECK_UNCHANGED } else { if (ctx->need_redraw) remove = 0;#endif } } }}#endif/*this defines a partition of the rendering area in small squares of the given width. If the number of nodesto redraw exceeds the possible number of squares on the surface, the entire area is redrawn - this avoids computingdirty rects algo when a lot of small shapes are moving*/#define MIN_BBOX_SIZE 16#if 0#define CHECK_MAX_NODE if (surf->to_redraw.count > max_nodes_allowed) redraw_all = 1;#else#define CHECK_MAX_NODE#endifBool VS2D_TerminateDraw(VisualSurface2D *surf, RenderEffect2D *eff){ u32 k, i, count, max_nodes_allowed, num_nodes, num_changed; GF_IRect refreshRect, *check_rect; Bool redraw_all; M_Background2D *bck; DrawableContext *bck_ctx, *ctx; struct _drawable_store *it, *prev;#ifndef TRACK_OPAQUE_REGIONS DrawableContext *first_opaque = NULL;#endif Bool has_changed = 0; /*in direct mode the surface is always redrawn*/ if (eff->trav_flags & TF_RENDER_DIRECT) { VS2D_TerminateSurface(surf); VS2D_ReverseContexts(surf); return 1; } num_changed = 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; bck = (M_Background2D*)gf_list_get(surf->back_stack, 0); if (bck) { if (!bck->isBound) { if (surf->last_had_back) redraw_all = 1; surf->last_had_back = 0; } else { if (!surf->last_had_back) redraw_all = 1; surf->last_had_back = 1; bck_ctx = b2D_GetContext(bck, surf->back_stack); if (bck_ctx->flags & CTX_REDRAW_MASK) redraw_all = 1; } } else if (surf->last_had_back) { surf->last_had_back = 0; redraw_all = 1; } max_nodes_allowed = (u32) ((surf->top_clipper.width / MIN_BBOX_SIZE) * (surf->top_clipper.height / MIN_BBOX_SIZE)); num_nodes = 0; ctx = surf->context; while (ctx && ctx->drawable) { num_nodes++; drawctx_update_info(ctx, surf); if (ctx->flags & CTX_REDRAW_MASK) { num_changed ++;#ifndef TRACK_OPAQUE_REGIONS if (!first_opaque && !(ctx->flags & CTX_IS_TRANSPARENT) && (ctx->flags & CTX_NO_ANTIALIAS)) first_opaque = ctx;#endif /*node has changed, add to redraw area*/ if (!redraw_all) { ra_union_rect(&surf->to_redraw, &ctx->bi->clip);// CHECK_MAX_NODE } } ctx = ctx->next; } /*garbage collection*/ /*clear all remaining bounds since last frames (the ones that moved or that are not drawn this frame)*/ prev = NULL; it = surf->prev_nodes; while (it) { while (drawable_get_previous_bound(it->drawable, &refreshRect, surf)) { if (!redraw_all) { ra_union_rect(&surf->to_redraw, &refreshRect);// CHECK_MAX_NODE } } /*if node is marked as undrawn, remove from surface*/ if (!(it->drawable->flags & DRAWABLE_DRAWN_ON_SURFACE)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Node %s no longer on surface - unregistering it\n", gf_node_get_class_name(it->drawable->node))); /*remove all bounds info related to this surface and unreg node */ drawable_reset_bounds(it->drawable, surf); it->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_SURFACE; if (prev) prev->next = it->next; else surf->prev_nodes = it->next; if (!it->next) surf->last_prev_entry = prev; free(it); it = prev ? prev->next : surf->prev_nodes; } else { prev = it; it = it->next; } } /*no visual rendering*/ //if (!surf->render->cur_width && !surf->render->cur_height) goto exit;// CHECK_MAX_NODE if (redraw_all) { ra_clear(&surf->to_redraw); ra_add(&surf->to_redraw, &surf->surf_rect); } else { ra_refresh(&surf->to_redraw); }#ifdef TRACK_OPAQUE_REGIONS /*mark opaque areas to speed up*/ mark_opaque_areas(surf);#endif /*nothing to redraw*/ if (ra_is_empty(&surf->to_redraw) ) { GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] No changes found since last frame - skipping redraw\n")); goto exit; } has_changed = 1; eff->traversing_mode = TRAVERSE_DRAW;#ifndef TRACK_OPAQUE_REGIONS if (first_opaque && (surf->to_redraw.count==1) && gf_rect_equal(first_opaque->bi->clip, surf->to_redraw.list[0])) goto skip_background;#endif /*redraw everything*/ if (bck_ctx) { drawable_check_bounds(bck_ctx, surf); eff->ctx = bck_ctx;#ifdef TRACK_OPAQUE_REGIONS surf->draw_node_index = 0;#endif bck_ctx->bi->unclip = gf_rect_ft(&surf->surf_rect); bck_ctx->bi->clip = surf->surf_rect; gf_node_render(bck_ctx->drawable->node, eff); } else { count = surf->to_redraw.count; if (bck_ctx) bck_ctx->bi->unclip = gf_rect_ft(&surf->surf_rect); for (k=0; k<count; k++) { GF_IRect rc; /*opaque area, skip*/#ifdef TRACK_OPAQUE_REGIONS if (surf->to_redraw.opaque_node_index[k] > 0) continue;#endif rc = surf->to_redraw.list[k]; gf_irect_intersect(&rc, &surf->top_clipper); VS2D_Clear(surf, &rc, 0); } }#ifndef TRACK_OPAQUE_REGIONSskip_background:#endif#ifndef GPAC_DISABLE_LOG if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RENDER)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Redraw %d / %d nodes (all: %s)", num_changed, num_nodes, redraw_all ? "yes" : "no")); if (surf->to_redraw.count>1) GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("\n")); for (i=0; i<surf->to_redraw.count; i++) GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("\tDirtyRect #%d: %d:%d@%dx%d\n", i+1, surf->to_redraw.list[i].x, surf->to_redraw.list[i].y, surf->to_redraw.list[i].width, surf->to_redraw.list[i].height)); }#endif #ifdef TRACK_OPAQUE_REGIONS i=0;#endif check_rect = (surf->to_redraw.count>1) ? NULL : &surf->to_redraw.list[0]; ctx = surf->context; while (ctx && ctx->drawable) { if (!check_rect || gf_irect_overlaps(&ctx->bi->clip, check_rect)) {#ifdef TRACK_OPAQUE_REGIONS i++; surf->draw_node_index = i;#endif eff->ctx = ctx; gf_node_render(ctx->drawable->node, eff); } ctx = ctx->next; }exit: /*clear dirty rects*/ ra_clear(&surf->to_redraw); /*terminate surface*/ VS2D_TerminateSurface(surf); VS2D_ReverseContexts(surf); return has_changed;}DrawableContext *VS2D_PickSensitiveNode(VisualSurface2D *surf, Fixed x, Fixed y){ RenderEffect2D eff; DrawableContext *ctx; eff.surface = surf; eff.traversing_mode = TRAVERSE_PICK; eff.pick_type = PICK_PATH; eff.x = x; eff.y = y; ctx = surf->context; while (ctx && ctx->drawable) { /*check over bounds*/ if (!ctx->drawable || ! gf_point_in_rect(&ctx->bi->clip, x, y)) { ctx = ctx->next; continue; } eff.ctx = ctx; eff.is_over = 0; gf_node_render(ctx->drawable->node, &eff); if (!eff.is_over) { ctx = ctx->next; continue; } /*check if has sensors */ if (ctx->sensor) return ctx; /*check for composite texture*/ if (ctx->h_texture && (ctx->h_texture->flags & GF_SR_TEXTURE_COMPOSITE) ) { return CT2D_FindNode(ctx->h_texture, ctx, x, y); } return NULL; } return NULL;}DrawableContext *VS2D_PickContext(VisualSurface2D *surf, Fixed x, Fixed y){ RenderEffect2D eff; DrawableContext *ctx; eff.surface = surf; eff.traversing_mode = TRAVERSE_PICK; eff.pick_type = PICK_FULL; eff.x = x; eff.y = y; ctx = surf->context; while (ctx && ctx->drawable) { /*check over bounds*/ if (ctx->drawable && gf_point_in_rect(&ctx->bi->clip, x, y)) { if (ctx->flags & CTX_SVG_PICK_BOUNDS) return ctx; eff.ctx = ctx; eff.is_over = 0; gf_node_render(ctx->drawable->node, &eff); if (eff.is_over) return ctx; } ctx = ctx->next; } return NULL;}/* this is to use carefully: picks a node based on the PREVIOUS frame state (no traversing)*/GF_Node *VS2D_PickNode(VisualSurface2D *surf, Fixed x, Fixed y){ RenderEffect2D eff; GF_Node *back; M_Background2D *bck; DrawableContext *ctx; bck = NULL; back = NULL; bck = (M_Background2D *) gf_list_get(surf->back_stack, 0); if (bck && bck->isBound) back = (GF_Node *) bck; eff.surface = surf; eff.traversing_mode = TRAVERSE_PICK; eff.pick_type = PICK_PATH_AND_OUTLINE; eff.x = x; eff.y = y; ctx = surf->context; while (ctx && ctx->drawable) { /*check over bounds*/ if (!ctx->drawable || ! gf_point_in_rect(&ctx->bi->clip, x, y)) { ctx = ctx->next; continue; } /*check over shape*/ eff.is_over = 0; gf_node_render(ctx->drawable->node, &eff); if (!eff.is_over) { ctx = ctx->next; continue; } /*check for composite texture*/ if (!ctx->h_texture && !ctx->aspect.line_texture) return ctx->drawable->node; if (ctx->h_texture && (ctx->h_texture->flags & GF_SR_TEXTURE_COMPOSITE)) { return CT2D_PickNode(ctx->h_texture, ctx, x, y); } else if (ctx->aspect.line_texture && (gf_node_get_tag(ctx->aspect.line_texture->owner)==TAG_MPEG4_CompositeTexture2D)) { return CT2D_PickNode(ctx->aspect.line_texture, ctx, x, y); } return ctx->drawable->node; } return back;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -