/*refreshes the content of the array to have only non-overlapping rects*/ void ra_refresh(GF_RectArray *ra) { u32 i, j, k; for (i=0; i<ra->count; i++) { for (j=i+1; j<ra->count; j++) { switch (gf_irect_relation(&ra->list[j].rect, &ra->list[i].rect)) { /*both rectangles overlap, merge them and remove opaque node info*/ case 1: gf_irect_union(&ra->list[i].rect, &ra->list[j].rect); #ifdef TRACK_OPAQUE_REGIONS /*current dirty rect is no longer opaque*/ ra->list[i].opaque_node_index = 0; #endif /*FALLTHROUGH*/ /*first rectangle covers second, just remove*/ case 2: /*remove rect*/ k = ra->count - j - 1; if (k) { memmove(&ra->list[j], & ra->list[j+1], sizeof(GF_IRect)*k); } ra->count--; if (ra->count>=2) ra_refresh(ra); return; default: break; } } } }
static void register_dirty_rect(GF_RectArray *ra, GF_IRect *rc) { /*technically this is correct however the gain is not that big*/ #if 0 #ifdef TRACK_OPAQUE_REGIONS u32 i; for (i=0; i<ra->count; i++) { switch (gf_irect_relation(rc, &ra->list[i])) { /*dirty area intersects this dirty rectangle, merge them and remove opaque idx info*/ case 1: gf_irect_union(&ra->list[i], rc); ra->opaque_node_index[i]= 0; return; /*dirty area is covered by this dirty rectangle, nothing to do*/ case 2: return; } } #endif /*not found, add rect*/ ra_add(ra, rc); #ifdef TRACK_OPAQUE_REGIONS if (!ra->opaque_node_index) ra->opaque_node_index = gf_malloc(sizeof(u32)*ra->alloc); ra->opaque_node_index[ra->count-1] = 0; #endif #else ra_add(ra, rc); #ifdef TRACK_OPAQUE_REGIONS if (!ra->opaque_node_index) ra->opaque_node_index = gf_malloc(sizeof(u32)*ra->alloc); ra->opaque_node_index[ra->count-1] = 0; #endif #endif }
static u32 register_context_rect(GF_RectArray *ra, DrawableContext *ctx, u32 ctx_idx, DrawableContext **first_opaque) { u32 i; Bool needs_redraw; #ifdef TRACK_OPAQUE_REGIONS Bool is_transparent = 1; #endif GF_IRect *rc = &ctx->bi->clip; assert(rc->width && rc->height); /*node is modified*/ needs_redraw = (ctx->flags & CTX_REDRAW_MASK) ? 1 : 0; #ifndef GPAC_DISABLE_3D if (ctx->flags & CTX_HYBOGL_NO_CLEAR) { return 2; } #endif /*node is not transparent*/ if ((ctx->flags & CTX_NO_ANTIALIAS) && !(ctx->flags & CTX_IS_TRANSPARENT) ) { #ifdef TRACK_OPAQUE_REGIONS is_transparent = 0; #endif if ((*first_opaque==NULL) && needs_redraw) *first_opaque = ctx; } for (i=0; i<ra->count; i++) { if (needs_redraw) { switch (gf_irect_relation(&ra->list[i].rect, rc)) { /*context intersects an existing rectangle, merge them and remove opaque idx info*/ case 1: gf_irect_union(&ra->list[i].rect, rc); #ifdef TRACK_OPAQUE_REGIONS ra->list[i].opaque_node_index = 0; #endif return 1; /*context covers an existing rectangle, replace rect and add opaque idx info*/ case 2: ra->list[i].rect= *rc; #ifdef TRACK_OPAQUE_REGIONS ra->list[i].opaque_node_index = is_transparent ? 0 : ctx_idx; #endif return 1; } } #ifdef TRACK_OPAQUE_REGIONS /*context unchanged coverring an entire area*/ else if (!is_transparent && gf_irect_inside(rc, &ra->list[i].rect)) { /*remove rect*/ u32 k = ra->count - i - 1; if (k) { memmove(&ra->list[i], & ra->list[i+1], sizeof(GF_RectArrayEntry)*k); } ra->count--; i--; } #endif } /*not found, add rect*/ if (needs_redraw) { ra_add(ra, rc); #ifdef TRACK_OPAQUE_REGIONS ra->list[ra->count-1].opaque_node_index = is_transparent ? 0 : ctx_idx; #endif } return 1; }