Changeset 3448 for libcaca/trunk


Ignore:
Timestamp:
May 14, 2009, 2:18:23 AM (10 years ago)
Author:
Sam Hocevar
Message:

Finish the dirty rectangle architecture. They are now reliable in the sense
that anything outside the dirty rectangle is guaranteed to be unchanged, but
we currently mark far too many cells as dirty. This must be optimised.

Location:
libcaca/trunk/caca
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/attr.c

    r2826 r3448  
    131131{
    132132    uint32_t *curattr, *curchar;
     133    int xmin, xmax;
    133134
    134135    if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height)
    135136        return 0;
     137
     138    xmin = xmax = x;
    136139
    137140    curchar = cv->chars + x + y * cv->width;
     
    144147
    145148    if(x && curchar[0] == CACA_MAGIC_FULLWIDTH)
     149    {
    146150        curattr[-1] = curattr[0];
     151        xmin--;
     152    }
    147153    else if(x + 1 < (int)cv->width && curchar[1] == CACA_MAGIC_FULLWIDTH)
     154    {
    148155        curattr[1] = curattr[0];
     156        xmax++;
     157    }
     158
     159    caca_add_dirty_rectangle(cv, xmin, xmax, y, y);
    149160
    150161    return 0;
  • libcaca/trunk/caca/caca_internals.h

    r3443 r3448  
    4040    uint32_t curattr;
    4141
    42     /* Dirty rectangle */
    43     int dirty_xmin, dirty_xmax, dirty_ymin, dirty_ymax;
    44 
    4542    /* Frame name */
    4643    char *name;
     
    6158    int (*resize_callback)(void *);
    6259    void *resize_data;
     60
     61    /* Dirty rectangle */
     62    int dirty_xmin, dirty_xmax, dirty_ymin, dirty_ymax;
    6363
    6464    /* Shortcut to the active frame information */
  • libcaca/trunk/caca/canvas.c

    r3443 r3448  
    9090    cv->frames[0].curattr = 0;
    9191    cv->frames[0].name = strdup("frame#00000000");
    92     cv->frames[0].dirty_xmin = 0;
    93     cv->frames[0].dirty_xmax = -1;
    94     cv->frames[0].dirty_ymin = 0;
    95     cv->frames[0].dirty_ymax = -1;
    9692
    9793    _caca_load_frame_info(cv);
    9894    caca_set_color_ansi(cv, CACA_DEFAULT, CACA_TRANSPARENT);
     95
     96    cv->dirty_xmin = 0;
     97    cv->dirty_xmax = -1;
     98    cv->dirty_ymin = 0;
     99    cv->dirty_ymax = -1;
    99100
    100101    cv->ff = NULL;
     
    332333                             int *ymin, int *ymax)
    333334{
    334     *xmin = cv->frames[cv->frame].dirty_xmin;
    335     *xmax = cv->frames[cv->frame].dirty_xmax;
    336     *ymin = cv->frames[cv->frame].dirty_ymin;
    337     *ymax = cv->frames[cv->frame].dirty_ymax;
     335    *xmin = cv->dirty_xmin;
     336    *xmax = cv->dirty_xmax;
     337    *ymin = cv->dirty_ymin;
     338    *ymax = cv->dirty_ymax;
    338339
    339340    return 0;
     
    372373        return 0;
    373374
    374     if(xmin < cv->frames[cv->frame].dirty_xmin)
    375         cv->frames[cv->frame].dirty_xmin = xmin;
    376 
    377     if(xmax > cv->frames[cv->frame].dirty_xmax)
    378         cv->frames[cv->frame].dirty_xmax = xmax;
    379 
    380     if(ymin < cv->frames[cv->frame].dirty_ymin)
    381         cv->frames[cv->frame].dirty_ymin = ymin;
    382 
    383     if(ymax > cv->frames[cv->frame].dirty_ymax)
    384         cv->frames[cv->frame].dirty_ymax = ymax;
     375    if(xmin < cv->dirty_xmin)
     376        cv->dirty_xmin = xmin;
     377
     378    if(xmax > cv->dirty_xmax)
     379        cv->dirty_xmax = xmax;
     380
     381    if(ymin < cv->dirty_ymin)
     382        cv->dirty_ymin = ymin;
     383
     384    if(ymax > cv->dirty_ymax)
     385        cv->dirty_ymax = ymax;
    385386
    386387    return 0;
     
    417418    }
    418419
    419     cv->frames[cv->frame].dirty_xmin = xmin;
    420     cv->frames[cv->frame].dirty_xmax = xmax;
    421     cv->frames[cv->frame].dirty_ymin = ymin;
    422     cv->frames[cv->frame].dirty_ymax = ymax;
     420    cv->dirty_xmin = xmin;
     421    cv->dirty_xmax = xmax;
     422    cv->dirty_ymin = ymin;
     423    cv->dirty_ymax = ymax;
    423424
    424425    return 0;
     
    556557            }
    557558        }
     559
     560        caca_add_dirty_rectangle(cv, old_width, 0, width - 1, old_height - 1);
    558561    }
    559562    else
     
    595598            }
    596599        }
    597     }
     600
     601        caca_add_dirty_rectangle(cv, 0, old_height, old_width - 1, height - 1);
     602    }
     603
     604    /* XXX: technically we should not worry about the dirty rectangle in
     605     * the bottom-right corner, because we only handle one dirty rectangle,
     606     * but in case the API changes later, we make sure this is handled. */
     607    if(width > old_width && height > old_height)
     608        caca_add_dirty_rectangle(cv, old_width, old_height,
     609                                 width - 1, height - 1);
    598610
    599611    /* Step 4: if new area is smaller, resize memory area now. */
  • libcaca/trunk/caca/frame.c

    r2826 r3448  
    6565    }
    6666
     67    /* Bail out if no operation is required */
     68    if(id == cv->frame)
     69        return 0;
     70
    6771    _caca_save_frame_info(cv);
    6872    cv->frame = id;
    6973    _caca_load_frame_info(cv);
     74
     75    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    7076
    7177    return 0;
     
    231237        cv->frame = 0;
    232238        _caca_load_frame_info(cv);
     239        caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    233240    }
    234241
  • libcaca/trunk/caca/graphics.c

    r3412 r3448  
    155155    dp->drv.display(dp);
    156156
     157    /* Invalidate the dirty rectangle */
     158    caca_set_dirty_rectangle(dp->cv, -1, -1, -1, -1);
     159
    157160    /* Once the display is finished, we can ack resizes */
    158161    if(dp->resize.resized)
  • libcaca/trunk/caca/string.c

    r2826 r3448  
    113113{
    114114    uint32_t *curchar, *curattr, attr;
    115     int fullwidth;
     115    int fullwidth, xmin, xmax;
    116116
    117117    if(x >= (int)cv->width || y < 0 || y >= (int)cv->height)
     
    136136    attr = cv->curattr;
    137137
     138    xmin = xmax = x;
     139
    138140    /* When overwriting the right part of a fullwidth character,
    139141     * replace its left part with a space. */
    140142    if(x && curchar[0] == CACA_MAGIC_FULLWIDTH)
     143    {
    141144        curchar[-1] = ' ';
     145        xmin--;
     146    }
    142147
    143148    if(fullwidth)
     
    147152        else
    148153        {
     154            xmax++;
     155
    149156            /* When overwriting the left part of a fullwidth character,
    150157             * replace its right part with a space. */
    151158            if(x + 2 < (int)cv->width && curchar[2] == CACA_MAGIC_FULLWIDTH)
     159            {
    152160                curchar[2] = ' ';
     161                xmax++;
     162            }
    153163
    154164            curchar[1] = CACA_MAGIC_FULLWIDTH;
     
    163173            curchar[1] = ' ';
    164174    }
     175
     176    caca_add_dirty_rectangle(cv, xmin, xmax, y, y);
    165177
    166178    curchar[0] = ch;
     
    308320    }
    309321
     322    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     323
    310324    return 0;
    311325}
     
    376390 */
    377391int caca_blit(caca_canvas_t *dst, int x, int y,
    378                caca_canvas_t const *src, caca_canvas_t const *mask)
    379 {
    380     int i, j, starti, startj, endi, endj;
     392              caca_canvas_t const *src, caca_canvas_t const *mask)
     393{
     394    int i, j, starti, startj, endi, endj, stride, bleed_left, bleed_right;
    381395
    382396    if(mask && (src->width != mask->width || src->height != mask->height))
     
    393407    endi = (x + src->width >= dst->width) ? dst->width - x : src->width;
    394408    endj = (y + src->height >= dst->height) ? dst->height - y : src->height;
     409    stride = endi - starti;
    395410
    396411    if(starti > src->width || startj > src->height
     
    398413        return 0;
    399414
     415    bleed_left = bleed_right = 0;
     416
    400417    for(j = startj; j < endj; j++)
    401418    {
    402419        int dstix = (j + y) * dst->width + starti + x;
    403420        int srcix = j * src->width + starti;
    404         int stride = endi - starti;
    405421
    406422        /* FIXME: we are ignoring the mask here */
    407423        if((starti + x) && dst->chars[dstix] == CACA_MAGIC_FULLWIDTH)
     424        {
    408425            dst->chars[dstix - 1] = ' ';
     426            bleed_left = 1;
     427        }
    409428
    410429        if(endi + x < dst->width
    411430                && dst->chars[dstix + stride] == CACA_MAGIC_FULLWIDTH)
     431        {
    412432            dst->chars[dstix + stride] = ' ';
     433            bleed_right = 1;
     434        }
    413435
    414436        if(mask)
     
    437459    }
    438460
     461    caca_add_dirty_rectangle(dst, starti + x - bleed_left, startj + y,
     462                             endi + x - 1 + bleed_right, endj + y - 1);
     463
    439464    return 0;
    440465}
     
    499524    caca_set_frame(cv, saved_f);
    500525    _caca_load_frame_info(cv);
     526
     527    /* FIXME: this may be optimised somewhat */
     528    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    501529
    502530    return 0;
  • libcaca/trunk/caca/transform.c

    r3406 r3448  
    5454        attrs++;
    5555    }
     56
     57    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    5658
    5759    return 0;
     
    114116    }
    115117
     118    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     119
    116120    return 0;
    117121}
     
    158162            *ctop = flopchar(*ctop);
    159163    }
     164
     165    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    160166
    161167    return 0;
     
    216222    }
    217223
     224    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     225
    218226    return 0;
    219227}
     
    333341    _caca_load_frame_info(cv);
    334342
     343    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     344
    335345    return 0;
    336346}
     
    450460    _caca_load_frame_info(cv);
    451461
     462    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     463
    452464    return 0;
    453465}
     
    541553    _caca_load_frame_info(cv);
    542554
     555    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
     556
    543557    return 0;
    544558}
     
    631645    /* Reset the current frame shortcuts */
    632646    _caca_load_frame_info(cv);
     647
     648    caca_set_dirty_rectangle(cv, 0, 0, cv->width - 1, cv->height - 1);
    633649
    634650    return 0;
Note: See TracChangeset for help on using the changeset viewer.