Changeset 3443 for libcaca/trunk


Ignore:
Timestamp:
May 13, 2009, 8:40:48 AM (10 years ago)
Author:
Sam Hocevar
Message:

Set up the architecture for dirty rectangles.

Dirty rectangles are an upcoming optimisation that will tell the output
drivers which portion of the canvas has been really modified since the
last blit.

Location:
libcaca/trunk/caca
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/caca.h

    r2853 r3443  
    221221 *  @{ */
    222222#define CACA_MAGIC_FULLWIDTH 0x000ffffe /**< Used to indicate that the previous character was a fullwidth glyph. */
     223__extern int caca_get_dirty_rectangle(caca_canvas_t *, int *, int *,
     224                                      int *, int *);
     225__extern int caca_add_dirty_rectangle(caca_canvas_t *, int, int, int, int);
     226__extern int caca_set_dirty_rectangle(caca_canvas_t *, int, int, int, int);
    223227__extern int caca_gotoxy(caca_canvas_t *, int, int);
    224228__extern int caca_get_cursor_x(caca_canvas_t const *);
     
    233237__extern int caca_get_canvas_handle_y(caca_canvas_t const *);
    234238__extern int caca_blit(caca_canvas_t *, int, int, caca_canvas_t const *,
    235                         caca_canvas_t const *);
     239                       caca_canvas_t const *);
    236240__extern int caca_set_canvas_boundaries(caca_canvas_t *, int, int, int, int);
    237241/*  @} */
  • libcaca/trunk/caca/caca_internals.h

    r2896 r3443  
    4040    uint32_t curattr;
    4141
     42    /* Dirty rectangle */
     43    int dirty_xmin, dirty_xmax, dirty_ymin, dirty_ymax;
     44
    4245    /* Frame name */
    4346    char *name;
  • libcaca/trunk/caca/canvas.c

    r2826 r3443  
    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;
    9296
    9397    _caca_load_frame_info(cv);
     
    146150}
    147151
    148 /** \brief Unmanage a canvas.
    149  *
    150  *  Unlock a canvas previously locked by caca_manage_canvas(). For safety
     152/** \brief unmanage a canvas.
     153 *
     154 *  unlock a canvas previously locked by caca_manage_canvas(). for safety
    151155 *  reasons, the callback and callback data arguments must be the same as for
    152156 *  the caca_manage_canvas() call.
    153157 *
    154  *  This function is only useful for display drivers such as the \e libcaca
     158 *  this function is only useful for display drivers such as the \e libcaca
    155159 *  library.
    156160 *
    157  *  If an error occurs, -1 is returned and \b errno is set accordingly:
    158  *  - \c EINVAL The canvas is not managed, or the callback arguments do
     161 *  if an error occurs, -1 is returned and \b errno is set accordingly:
     162 *  - \c einval the canvas is not managed, or the callback arguments do
    159163 *              not match.
    160164 *
    161  *  \param cv A libcaca canvas.
    162  *  \param callback The \e callback argument previously passed to
    163                     caca_manage_canvas().
    164  *  \param p The \e p argument previously passed to caca_manage_canvas().
     165 *  \param cv a libcaca canvas.
     166 *  \param callback the \e callback argument previously passed to
     167 *                  caca_manage_canvas().
     168 *  \param p the \e p argument previously passed to caca_manage_canvas().
    165169 *  \return 0 in case of success, -1 if an error occurred.
    166170 */
     
    294298}
    295299
    296 /** \brief Uninitialise \e libcaca.
    297  *
    298  *  Free all resources allocated by caca_create_canvas(). After
    299  *  this function has been called, no other \e libcaca functions may be
    300  *  used unless a new call to caca_create_canvas() is done.
     300/** \brief Get a canvas's dirty rectangle.
     301 *
     302 *  Get the canvas's dirty rectangle coordinates. The dirty rectangle is
     303 *  the smallest area containing all the cells that have changed since it
     304 *  was last reset.
     305 *
     306 *  The dirty rectangle is used internally by display drivers to optimise
     307 *  rendering by avoiding to redraw the whole screen. Once the display driver
     308 *  has rendered the canvas, it resets the dirty rectangle.
     309 *
     310 *  Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
     311 *  the dirty rectangle is empty. It means that the canvas's contents have
     312 *  not changed since the dirty rectangle was last reset.
     313 *
     314 *  FIXME: having only one dirty rectangle instead of a list of rectangles
     315 *  is a severe limitation, but the potential gain does not yet look to be
     316 *  worth the implementation complexity of a multiple-rectangle scheme.
     317 *
     318 *  This function never fails.
     319 *
     320 *  \param cv A libcaca canvas.
     321 *  \param xmin A pointer to an integer where the leftmost edge of the
     322 *              dirty rectangle will be stored.
     323 *  \param xmax A pointer to an integer where the rightmost edge of the
     324 *              dirty rectangle will be stored.
     325 *  \param ymin A pointer to an integer where the topmost edge of the
     326 *              dirty rectangle will be stored.
     327 *  \param ymax A pointer to an integer where the bottommost edge of the
     328 *              dirty rectangle will be stored.
     329 *  \return This function always returns 0.
     330 */
     331int caca_get_dirty_rectangle(caca_canvas_t *cv, int *xmin, int *xmax,
     332                             int *ymin, int *ymax)
     333{
     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;
     338
     339    return 0;
     340}
     341
     342/** \brief Add a dirty rectangle to the canvas's dirty rectangle.
     343 *
     344 *  Add an invalidating zone to the canvas's dirty rectangle. For more
     345 *  information about the dirty rectangle, see caca_get_dirty_rectangle().
     346 *
     347 *  This function may be useful to force refresh of a given zone of the
     348 *  canvas even if the dirty rectangle tracking indicates that it is
     349 *  unchanged.
     350 *
     351 *  Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
     352 *  the dirty rectangle is empty. They will be silently ignored.
     353 *
     354 *  This function never fails.
     355 *
     356 *  \param cv A libcaca canvas.
     357 *  \param xmin The leftmost edge of the additional dirty rectangle.
     358 *  \param xmax The rightmost edge of the additional dirty rectangle.
     359 *  \param ymin The topmost edge of the additional dirty rectangle.
     360 *  \param ymax The bottommost edge of the additional dirty rectangle.
     361 *  \return This function always returns 0.
     362 */
     363int caca_add_dirty_rectangle(caca_canvas_t *cv, int xmin, int xmax,
     364                             int ymin, int ymax)
     365{
     366    /* Ignore empty rectangles. */
     367    if(xmin > xmax || ymin > ymax)
     368        return 0;
     369
     370    /* Ignore out-of-bounds rectangles. */
     371    if(xmax < 0 || xmin >= cv->width || ymax < 0 || ymin >= cv->height)
     372        return 0;
     373
     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;
     385
     386    return 0;
     387}
     388
     389/** \brief Set a canvas's dirty rectangle.
     390 *
     391 *  Set the canvas's dirty rectangle coordinates. For more information
     392 *  about the dirty rectangle, see caca_get_dirty_rectangle().
     393 *
     394 *  Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
     395 *  the dirty rectangle is empty.
     396 *
     397 *  This function never fails.
     398 *
     399 *  \param cv A libcaca canvas.
     400 *  \param xmin The leftmost edge of the desired dirty rectangle.
     401 *  \param xmax The rightmost edge of the desired dirty rectangle.
     402 *  \param ymin The topmost edge of the desired dirty rectangle.
     403 *  \param ymax The bottommost edge of the desired dirty rectangle.
     404 *  \return This function always returns 0.
     405 */
     406int caca_set_dirty_rectangle(caca_canvas_t *cv, int xmin, int xmax,
     407                             int ymin, int ymax)
     408{
     409    /* Normalise values indicating an empty or out-of-bounds rectangle. */
     410    if(xmin > xmax || ymin > ymax ||
     411        xmax < 0 || xmin >= cv->width || ymax < 0 || ymin >= cv->height)
     412    {
     413        xmin = cv->width;
     414        xmax = -1;
     415        ymin = cv->height;
     416        ymax = -1;
     417    }
     418
     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;
     423
     424    return 0;
     425}
     426
     427/** \brief Free a \e libcaca canvas.
     428 *
     429 *  Free all resources allocated by caca_create_canvas(). The canvas
     430 *  pointer becomes invalid and must no longer be used unless a new call
     431 *  to caca_create_canvas() is made.
    301432 *
    302433 *  If an error occurs, -1 is returned and \b errno is set accordingly:
Note: See TracChangeset for help on using the changeset viewer.