source: libcaca/trunk/caca/dirty.c @ 3471

Last change on this file since 3471 was 3471, checked in by Sam Hocevar, 11 years ago

Optimise the dirty rectangle handling by keeping track of the number of
currently dirty rectangles.

  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  $Id: dirty.c 3471 2009-05-19 00:51:55Z sam $
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains the dirty rectangle handling functions.
17 */
18
19#include "config.h"
20
21#if !defined(__KERNEL__)
22#   include <stdio.h>
23#endif
24
25#include "caca.h"
26#include "caca_internals.h"
27
28/** \brief Get the number of dirty rectangles in the canvas.
29 *
30 *  Get the number of dirty rectangles in a canvas. Dirty rectangles are
31 *  areas that contain cells that have changed since the last reset.
32 *
33 *  The dirty rectangles are used internally by display drivers to optimise
34 *  rendering by avoiding to redraw the whole screen. Once the display driver
35 *  has rendered the canvas, it resets the dirty rectangle list.
36 *
37 *  Dirty rectangles are guaranteed not to overlap.
38 *
39 *  This function never fails.
40 *
41 *  \param cv A libcaca canvas.
42 *  \return The number of dirty rectangles in the given canvas.
43 */
44int caca_get_dirty_rectangle_count(caca_canvas_t *cv)
45{
46    return cv->ndirty;
47}
48
49/** \brief Get a canvas's dirty rectangle.
50 *
51 *  Get the canvas's given dirty rectangle coordinates. The index must be
52 *  within the dirty rectangle count. See caca_get_dirty_rectangle_count()
53 *  for how to compute this count.
54 *
55 *  If an error occurs, no coordinates are written in the pointer arguments,
56 *  -1 is returned and \b errno is set accordingly:
57 *  - \c EINVAL Specified rectangle index is out of bounds.
58 *
59 *  \param cv A libcaca canvas.
60 *  \param index The requested rectangle index.
61 *  \param xmin A pointer to an integer where the leftmost edge of the
62 *              dirty rectangle will be stored.
63 *  \param ymin A pointer to an integer where the topmost edge of the
64 *              dirty rectangle will be stored.
65 *  \param xmax A pointer to an integer where the rightmost edge of the
66 *              dirty rectangle will be stored.
67 *  \param ymax A pointer to an integer where the bottommost edge of the
68 *              dirty rectangle will be stored.
69 *  \return 0 in case of success, -1 if an error occurred.
70 */
71int caca_get_dirty_rectangle(caca_canvas_t *cv, int index,
72                             int *xmin, int *ymin, int *xmax, int *ymax)
73{
74    if(index < 0 || index >= cv->ndirty)
75    {
76        seterrno(EINVAL);
77        return -1;
78    }
79
80    /* Normalise dirty rectangle so that the values can be directly used. */
81    if(cv->dirty_xmin < 0)
82        cv->dirty_xmin = 0;
83
84    if(cv->dirty_xmax > cv->width - 1)
85        cv->dirty_xmax = cv->width - 1;
86
87    if(cv->dirty_ymin < 0)
88        cv->dirty_ymin = 0;
89
90    if(cv->dirty_ymax > cv->height - 1)
91        cv->dirty_ymax = cv->height - 1;
92
93    *xmin = cv->dirty_xmin;
94    *xmax = cv->dirty_xmax;
95    *ymin = cv->dirty_ymin;
96    *ymax = cv->dirty_ymax;
97
98    return 0;
99}
100
101/** \brief Add an area to the canvas's dirty rectangle list.
102 *
103 *  Add an invalidating zone to the canvas's dirty rectangle list. For more
104 *  information about the dirty rectangles, see caca_get_dirty_rectangle().
105 *
106 *  This function may be useful to force refresh of a given zone of the
107 *  canvas even if the dirty rectangle tracking indicates that it is
108 *  unchanged. This may happen if the canvas contents were somewhat
109 *  directly modified.
110 *
111 *  If an error occurs, -1 is returned and \b errno is set accordingly:
112 *  - \c EINVAL Specified rectangle coordinates are out of bounds.
113 *
114 *  \param cv A libcaca canvas.
115 *  \param xmin The leftmost edge of the additional dirty rectangle.
116 *  \param ymin The topmost edge of the additional dirty rectangle.
117 *  \param xmax The rightmost edge of the additional dirty rectangle.
118 *  \param ymax The bottommost edge of the additional dirty rectangle.
119 *  \return 0 in case of success, -1 if an error occurred.
120 */
121int caca_add_dirty_rectangle(caca_canvas_t *cv, int xmin, int ymin,
122                             int xmax, int ymax)
123{
124    /* Ignore empty and out-of-bounds rectangles */
125    if(xmin > xmax || ymin > ymax
126        || xmax < 0 || xmin >= cv->width || ymax < 0 || ymin >= cv->height)
127    {
128        seterrno(EINVAL);
129        return -1;
130    }
131
132    if(cv->ndirty == 0)
133    {
134        cv->ndirty = 1;
135        cv->dirty_xmin = xmin;
136        cv->dirty_xmax = xmax;
137        cv->dirty_ymin = ymin;
138        cv->dirty_ymax = ymax;
139    }
140    else
141    {
142        if(xmin < cv->dirty_xmin)
143            cv->dirty_xmin = xmin;
144        if(xmax > cv->dirty_xmax)
145            cv->dirty_xmax = xmax;
146        if(ymin < cv->dirty_ymin)
147            cv->dirty_ymin = ymin;
148        if(ymax > cv->dirty_ymax)
149            cv->dirty_ymax = ymax;
150    }
151
152    return 0;
153}
154
155/** \brief Remove an area from the dirty rectangle list.
156 *
157 *  Mark a cell area in the canvas as not dirty. For more information about
158 *  the dirty rectangles, see caca_get_dirty_rectangle().
159 *
160 *  Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
161 *  the dirty rectangle is empty. They will be silently ignored.
162 *
163 *  If an error occurs, -1 is returned and \b errno is set accordingly:
164 *  - \c EINVAL Specified rectangle coordinates are out of bounds.
165 *
166 *  \param cv A libcaca canvas.
167 *  \param xmin The leftmost edge of the clean rectangle.
168 *  \param ymin The topmost edge of the clean rectangle.
169 *  \param xmax The rightmost edge of the clean rectangle.
170 *  \param ymax The bottommost edge of the clean rectangle.
171 *  \return 0 in case of success, -1 if an error occurred.
172 */
173int caca_remove_dirty_rectangle(caca_canvas_t *cv, int xmin, int ymin,
174                                int xmax, int ymax)
175{
176    /* Ignore empty and out-of-bounds rectangles */
177    if(xmin > xmax || ymin > ymax
178        || xmax < 0 || xmin >= cv->width || ymax < 0 || ymin >= cv->height)
179    {
180        seterrno(EINVAL);
181        return -1;
182    }
183
184    /* FIXME: implement this function. It's OK to have it do nothing,
185     * since we take a conservative approach in dirty rectangle handling,
186     * but we ought to help the rendering eventually. */
187
188    return 0;
189}
190
191/** \brief Clear a canvas's dirty rectangle list.
192 *
193 *  Empty the canvas's dirty rectangle list.
194 *
195 *  This function never fails.
196 *
197 *  \param cv A libcaca canvas.
198 *  \return This function always returns 0.
199 */
200int caca_clear_dirty_rectangle_list(caca_canvas_t *cv)
201{
202    cv->ndirty = 0;
203
204    return 0;
205}
206
Note: See TracBrowser for help on using the repository browser.