Mercurial > MadButterfly
comparison src/redraw_man.c @ 28:604bc90d509d
Refactory
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Mon, 04 Aug 2008 20:08:37 +0800 |
parents | 19c603dd6ff9 |
children | f56c96b035a8 |
comparison
equal
deleted
inserted
replaced
27:19c603dd6ff9 | 28:604bc90d509d |
---|---|
90 } | 90 } |
91 | 91 |
92 rdman->dirty_areas[rdman->n_dirty_areas++] = area; | 92 rdman->dirty_areas[rdman->n_dirty_areas++] = area; |
93 return OK; | 93 return OK; |
94 } | 94 } |
95 | |
96 static void area_to_positions(area_t *area, co_aix (*poses)[2]) { | |
97 poses[0][0] = area->x; | |
98 poses[0][1] = area->y; | |
99 poses[1][0] = area->x + area->w; | |
100 poses[1][1] = area->y + area->h;; | |
101 } | |
102 | |
103 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { | |
104 extern void redraw_man_destroy(redraw_man_t *rdman); | |
105 | |
106 memset(rdman, 0, sizeof(redraw_man_t)); | |
107 | |
108 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | |
109 if(rdman->geo_pool == NULL) | |
110 return ERR; | |
111 | |
112 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); | |
113 if(rdman->coord_pool == NULL) { | |
114 elmpool_free(rdman->geo_pool); | |
115 return ERR; | |
116 } | |
117 | |
118 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); | |
119 if(rdman->shnode_pool == NULL) { | |
120 elmpool_free(rdman->geo_pool); | |
121 elmpool_free(rdman->coord_pool); | |
122 return ERR; | |
123 } | |
124 | |
125 rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool); | |
126 if(rdman->root_coord == NULL) | |
127 redraw_man_destroy(rdman); | |
128 rdman->n_coords = 1; | |
129 coord_init(rdman->root_coord, NULL); | |
130 | |
131 rdman->cr = cr; | |
132 rdman->backend = backend; | |
133 | |
134 return OK; | |
135 } | |
136 | |
137 void redraw_man_destroy(redraw_man_t *rdman) { | |
138 elmpool_free(rdman->coord_pool); | |
139 elmpool_free(rdman->geo_pool); | |
140 elmpool_free(rdman->shnode_pool); | |
141 if(rdman->dirty_coords) | |
142 free(rdman->dirty_coords); | |
143 if(rdman->dirty_geos) | |
144 free(rdman->dirty_geos); | |
145 } | |
146 | |
147 | |
148 #define ASSERT(x) | |
149 /* | |
150 * Change transformation matrix | |
151 * - update aggregated transformation matrix | |
152 * - of coord_t object been changed. | |
153 * - of children coord_t objects. | |
154 * - redraw members of coord_t objects. | |
155 * - redraw shape objects they are overlaid with members. | |
156 * - find out overlaid shape objects. | |
157 * - geo_t of a coord_t object | |
158 * - can make finding more efficiency. | |
159 * - fill overlay geo_t objects of members. | |
160 * | |
161 * Change a shape object | |
162 * - redraw changed object. | |
163 * - redraw shape objects they are overlaid with changed object. | |
164 * - find out overlaid shape objects. | |
165 * | |
166 * That coord and geo of shape objects are setted by user code | |
167 * give user code a chance to collect coord and geo objects together | |
168 * and gain interest of higher cache hit rate. | |
169 */ | |
170 | |
171 /*! \brief Find out all affected shape objects. | |
172 * | |
173 * Find out all shape objects that are overalid with geo_t of | |
174 * a geometry changed object. | |
175 * | |
176 * Linear scan geo_t objects of all shape objects in all_shapes | |
177 * list of a redraw_man_t object. | |
178 */ | |
179 int rdman_find_overlaid_shapes(redraw_man_t *rdman, geo_t *geo, | |
180 geo_t ***overlays) { | |
181 int n_geos; | |
182 geo_t **geos; | |
183 geo_t *geo_cur; | |
184 int n_overlays; | |
185 geo_t **_overlays; | |
186 int i; | |
187 | |
188 n_geos = rdman->n_geos; | |
189 | |
190 geos = (geo_t **)malloc(sizeof(geo_t *) * n_geos); | |
191 if(geos == NULL) | |
192 return -1; | |
193 | |
194 _overlays = (geo_t **)malloc(sizeof(geo_t *) * n_geos); | |
195 if(geos == NULL) { | |
196 free(geos); | |
197 return -1; | |
198 } | |
199 | |
200 geo_cur = STAILQ_HEAD(rdman->all_geos); | |
201 for(i = 0; i < n_geos; i++) { | |
202 geos[i] = geo_cur; | |
203 geo_cur = STAILQ_NEXT(geo_t, next, geo_cur); | |
204 } | |
205 geo_mark_overlay(geo, n_geos, geos, &n_overlays, _overlays); | |
206 | |
207 free(geos); | |
208 *overlays = _overlays; | |
209 | |
210 return n_overlays; | |
211 } | |
212 | |
213 int rdman_add_shape(redraw_man_t *rdman, shape_t *shape, coord_t *coord) { | |
214 geo_t *geo; | |
215 #ifdef GEO_ORDER | |
216 geo_t *visit; | |
217 unsigned int next_order; | |
218 #endif | |
219 int r; | |
220 | |
221 geo = elmpool_elm_alloc(rdman->geo_pool); | |
222 if(geo == NULL) | |
223 return ERR; | |
224 | |
225 geo_init(geo); | |
226 | |
227 sh_attach_geo(shape, geo); | |
228 STAILQ_INS_TAIL(rdman->all_geos, geo_t, next, geo); | |
229 rdman->n_geos++; | |
230 | |
231 #ifdef GEO_ORDER | |
232 /* TODO: remove order number. */ | |
233 geo->order = ++rdman->next_geo_order; | |
234 if(geo->order == 0) { | |
235 next_order = 0; | |
236 for(visit = STAILQ_HEAD(rdman->all_geos); | |
237 visit != NULL; | |
238 visit = STAILQ_NEXT(geo_t, next, visit)) | |
239 visit->order = ++next_order; | |
240 rdman->next_geo_order = next_order; | |
241 } | |
242 #endif | |
243 | |
244 /* New one should be dirty to recompute it when drawing. */ | |
245 geo->flags |= GEF_DIRTY; | |
246 r = add_dirty_geo(rdman, geo); | |
247 if(r != OK) | |
248 return ERR; | |
249 | |
250 sh_attach_coord(shape, coord); | |
251 | |
252 return OK; | |
253 } | |
254 | |
255 /*! \brief Remove a shape object from redraw manager. | |
256 * | |
257 * TODO: redraw shape objects that overlaid with removed one. | |
258 */ | |
259 int rdman_remove_shape(redraw_man_t *rdman, shape_t *shape) { | |
260 STAILQ_REMOVE(rdman->all_geos, geo_t, next, shape->geo); | |
261 elmpool_elm_free(rdman->geo_pool, shape->geo); | |
262 sh_detach_geo(shape); | |
263 rdman->n_geos--; | |
264 sh_detach_coord(shape); | |
265 return OK; | |
266 } | |
267 | |
268 coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent) { | |
269 coord_t *coord, *root_coord; | |
270 coord_t *visit; | |
271 | |
272 coord = elmpool_elm_alloc(rdman->coord_pool); | |
273 if(coord == NULL) | |
274 return NULL; | |
275 | |
276 coord_init(coord, parent); | |
277 rdman->n_coords++; | |
278 | |
279 coord->order = ++rdman->next_coord_order; | |
280 if(coord->order == 0) { | |
281 rdman->next_coord_order = 0; | |
282 root_coord = visit = rdman->root_coord; | |
283 /* skip root coord. */ | |
284 visit = preorder_coord_subtree(root_coord, visit); | |
285 while(visit) { | |
286 visit->order = ++rdman->next_coord_order; | |
287 visit = preorder_coord_subtree(root_coord, visit); | |
288 } | |
289 } | |
290 | |
291 return coord; | |
292 } | |
293 | |
294 /*! \brief Free a coord of a redraw_man_t object. | |
295 * | |
296 * \param coord is a coord_t without children and members. | |
297 * \return 0 for successful, -1 for error. | |
298 */ | |
299 int rdman_coord_free(redraw_man_t *rdman, coord_t *coord) { | |
300 coord_t *parent; | |
301 | |
302 parent = coord->parent; | |
303 if(parent == NULL) | |
304 return ERR; | |
305 | |
306 if(STAILQ_HEAD(coord->members) != NULL) | |
307 return ERR; | |
308 | |
309 if(STAILQ_HEAD(coord->children) != NULL) | |
310 return ERR; | |
311 | |
312 STAILQ_REMOVE(parent->children, coord_t, sibling, coord); | |
313 elmpool_elm_free(rdman->coord_pool, coord); | |
314 rdman->n_coords--; | |
315 | |
316 return OK; | |
317 } | |
318 | |
319 /*! \brief Mark a coord is changed. | |
320 * | |
321 * A changed coord_t object is marked as dirty and put | |
322 * into dirty_coords list. | |
323 */ | |
324 int rdman_coord_changed(redraw_man_t *rdman, coord_t *coord) { | |
325 coord_t *child; | |
326 int max_dirty_coords; | |
327 int r; | |
328 | |
329 if(coord->flags & COF_DIRTY) | |
330 return OK; | |
331 | |
332 if(rdman->n_dirty_coords >= rdman->max_dirty_coords) { | |
333 /* Max of dirty_coords is not big enough. */ | |
334 max_dirty_coords = rdman->max_dirty_coords + 16; | |
335 | |
336 r = extend_memblk((void **)&rdman->dirty_coords, | |
337 sizeof(coord_t *) * rdman->n_dirty_coords, | |
338 sizeof(coord_t *) * max_dirty_coords); | |
339 rdman->max_dirty_coords = max_dirty_coords; | |
340 } | |
341 | |
342 /* Make the coord and child coords dirty. */ | |
343 for(child = coord; | |
344 child != NULL; | |
345 child = preorder_coord_subtree(coord, child)) { | |
346 rdman->dirty_coords[rdman->n_dirty_coords++] = coord; | |
347 coord->flags |= COF_DIRTY; | |
348 } | |
349 | |
350 return OK; | |
351 } | |
352 | |
353 static int _rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { | |
354 geo_t *geo; | |
355 int r; | |
356 | |
357 geo = shape->geo; | |
358 | |
359 if(geo->flags & GEF_DIRTY) | |
360 return OK; | |
361 | |
362 r = add_dirty_geo(rdman, geo); | |
363 if(r == ERR) | |
364 return ERR; | |
365 geo->flags |= GEF_DIRTY; | |
366 | |
367 return OK; | |
368 } | |
369 | |
370 /*! \brief Mark a shape is changed. | |
371 * | |
372 * The geo_t object of a changed shape is mark as dirty and | |
373 * put into dirty_geos list. | |
374 */ | |
375 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { | |
376 return _rdman_shape_changed(rdman, shape); | |
377 } | |
378 | |
379 /* Clean dirties */ | |
95 | 380 |
96 static void clean_shape(shape_t *shape) { | 381 static void clean_shape(shape_t *shape) { |
97 switch(shape->sh_type) { | 382 switch(shape->sh_type) { |
98 case SHT_PATH: | 383 case SHT_PATH: |
99 sh_path_transform(shape); | 384 sh_path_transform(shape); |
106 sh_dummy_transform(shape); | 391 sh_dummy_transform(shape); |
107 break; | 392 break; |
108 #endif /* UNITTEST */ | 393 #endif /* UNITTEST */ |
109 } | 394 } |
110 shape->geo->flags &= ~GEF_DIRTY; | 395 shape->geo->flags &= ~GEF_DIRTY; |
111 } | |
112 | |
113 static void area_to_positions(area_t *area, co_aix (*poses)[2]) { | |
114 poses[0][0] = area->x; | |
115 poses[0][1] = area->y; | |
116 poses[1][0] = area->x + area->w; | |
117 poses[1][1] = area->y + area->h;; | |
118 } | 396 } |
119 | 397 |
120 static int clean_coord(coord_t *coord) { | 398 static int clean_coord(coord_t *coord) { |
121 shape_t *shape; | 399 shape_t *shape; |
122 geo_t *geo; | 400 geo_t *geo; |
185 rdman->n_dirty_coords = 0; | 463 rdman->n_dirty_coords = 0; |
186 } | 464 } |
187 return OK; | 465 return OK; |
188 } | 466 } |
189 | 467 |
190 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { | 468 static int clean_rdman_geos(redraw_man_t *rdman) { |
191 extern void redraw_man_destroy(redraw_man_t *rdman); | |
192 | |
193 memset(rdman, 0, sizeof(redraw_man_t)); | |
194 | |
195 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | |
196 if(rdman->geo_pool == NULL) | |
197 return ERR; | |
198 | |
199 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); | |
200 if(rdman->coord_pool == NULL) { | |
201 elmpool_free(rdman->geo_pool); | |
202 return ERR; | |
203 } | |
204 | |
205 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); | |
206 if(rdman->shnode_pool == NULL) { | |
207 elmpool_free(rdman->geo_pool); | |
208 elmpool_free(rdman->coord_pool); | |
209 return ERR; | |
210 } | |
211 | |
212 rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool); | |
213 if(rdman->root_coord == NULL) | |
214 redraw_man_destroy(rdman); | |
215 rdman->n_coords = 1; | |
216 coord_init(rdman->root_coord, NULL); | |
217 | |
218 rdman->cr = cr; | |
219 rdman->backend = backend; | |
220 | |
221 return OK; | |
222 } | |
223 | |
224 void redraw_man_destroy(redraw_man_t *rdman) { | |
225 elmpool_free(rdman->coord_pool); | |
226 elmpool_free(rdman->geo_pool); | |
227 elmpool_free(rdman->shnode_pool); | |
228 if(rdman->dirty_coords) | |
229 free(rdman->dirty_coords); | |
230 if(rdman->dirty_geos) | |
231 free(rdman->dirty_geos); | |
232 } | |
233 | |
234 | |
235 #define ASSERT(x) | |
236 /* | |
237 * Change transformation matrix | |
238 * - update aggregated transformation matrix | |
239 * - of coord_t object been changed. | |
240 * - of children coord_t objects. | |
241 * - redraw members of coord_t objects. | |
242 * - redraw shape objects they are overlaid with members. | |
243 * - find out overlaid shape objects. | |
244 * - geo_t of a coord_t object | |
245 * - can make finding more efficiency. | |
246 * - fill overlay geo_t objects of members. | |
247 * | |
248 * Change a shape object | |
249 * - redraw changed object. | |
250 * - redraw shape objects they are overlaid with changed object. | |
251 * - find out overlaid shape objects. | |
252 * | |
253 * That coord and geo of shape objects are setted by user code | |
254 * give user code a chance to collect coord and geo objects together | |
255 * and gain interest of higher cache hit rate. | |
256 */ | |
257 | |
258 /*! \brief Find out all affected shape objects. | |
259 * | |
260 * Find out all shape objects that are overalid with geo_t of | |
261 * a geometry changed object. | |
262 * | |
263 * Linear scan geo_t objects of all shape objects in all_shapes | |
264 * list of a redraw_man_t object. | |
265 */ | |
266 int rdman_find_overlaid_shapes(redraw_man_t *rdman, geo_t *geo, | |
267 geo_t ***overlays) { | |
268 int n_geos; | |
269 geo_t **geos; | |
270 geo_t *geo_cur; | |
271 int n_overlays; | |
272 geo_t **_overlays; | |
273 int i; | 469 int i; |
274 | 470 int n_dirty_geos; |
275 n_geos = rdman->n_geos; | 471 geo_t **dirty_geos; |
276 | 472 geo_t *visit_geo; |
277 geos = (geo_t **)malloc(sizeof(geo_t *) * n_geos); | 473 |
278 if(geos == NULL) | 474 n_dirty_geos = rdman->n_dirty_geos; |
279 return -1; | 475 if(n_dirty_geos > 0) { |
280 | 476 dirty_geos = rdman->dirty_geos; |
281 _overlays = (geo_t **)malloc(sizeof(geo_t *) * n_geos); | 477 for(i = 0; i < n_dirty_geos; i++) { |
282 if(geos == NULL) { | 478 visit_geo = dirty_geos[i]; |
283 free(geos); | 479 if(!(visit_geo->flags & GEF_DIRTY)) |
284 return -1; | 480 continue; |
285 } | 481 |
286 | 482 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *); |
287 geo_cur = STAILQ_HEAD(rdman->all_geos); | 483 clean_shape(visit_geo->shape); |
288 for(i = 0; i < n_geos; i++) { | 484 add_dirty_area(rdman, visit_geo->cur_area); |
289 geos[i] = geo_cur; | 485 add_dirty_area(rdman, visit_geo->last_area); |
290 geo_cur = STAILQ_NEXT(geo_t, next, geo_cur); | |
291 } | |
292 geo_mark_overlay(geo, n_geos, geos, &n_overlays, _overlays); | |
293 | |
294 free(geos); | |
295 *overlays = _overlays; | |
296 | |
297 return n_overlays; | |
298 } | |
299 | |
300 int rdman_add_shape(redraw_man_t *rdman, shape_t *shape, coord_t *coord) { | |
301 geo_t *geo; | |
302 #ifdef GEO_ORDER | |
303 geo_t *visit; | |
304 unsigned int next_order; | |
305 #endif | |
306 int r; | |
307 | |
308 geo = elmpool_elm_alloc(rdman->geo_pool); | |
309 if(geo == NULL) | |
310 return ERR; | |
311 | |
312 geo_init(geo); | |
313 | |
314 sh_attach_geo(shape, geo); | |
315 STAILQ_INS_TAIL(rdman->all_geos, geo_t, next, geo); | |
316 rdman->n_geos++; | |
317 | |
318 #ifdef GEO_ORDER | |
319 /* TODO: remove order number. */ | |
320 geo->order = ++rdman->next_geo_order; | |
321 if(geo->order == 0) { | |
322 next_order = 0; | |
323 for(visit = STAILQ_HEAD(rdman->all_geos); | |
324 visit != NULL; | |
325 visit = STAILQ_NEXT(geo_t, next, visit)) | |
326 visit->order = ++next_order; | |
327 rdman->next_geo_order = next_order; | |
328 } | |
329 #endif | |
330 | |
331 /* New one should be dirty to recompute it when drawing. */ | |
332 geo->flags |= GEF_DIRTY; | |
333 r = add_dirty_geo(rdman, geo); | |
334 if(r != OK) | |
335 return ERR; | |
336 | |
337 sh_attach_coord(shape, coord); | |
338 | |
339 return OK; | |
340 } | |
341 | |
342 /*! \brief Remove a shape object from redraw manager. | |
343 * | |
344 * TODO: redraw shape objects that overlaid with removed one. | |
345 */ | |
346 int rdman_remove_shape(redraw_man_t *rdman, shape_t *shape) { | |
347 STAILQ_REMOVE(rdman->all_geos, geo_t, next, shape->geo); | |
348 elmpool_elm_free(rdman->geo_pool, shape->geo); | |
349 sh_detach_geo(shape); | |
350 rdman->n_geos--; | |
351 sh_detach_coord(shape); | |
352 return OK; | |
353 } | |
354 | |
355 coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent) { | |
356 coord_t *coord, *root_coord; | |
357 coord_t *visit; | |
358 | |
359 coord = elmpool_elm_alloc(rdman->coord_pool); | |
360 if(coord == NULL) | |
361 return NULL; | |
362 | |
363 coord_init(coord, parent); | |
364 rdman->n_coords++; | |
365 | |
366 coord->order = ++rdman->next_coord_order; | |
367 if(coord->order == 0) { | |
368 rdman->next_coord_order = 0; | |
369 root_coord = visit = rdman->root_coord; | |
370 /* skip root coord. */ | |
371 visit = preorder_coord_subtree(root_coord, visit); | |
372 while(visit) { | |
373 visit->order = ++rdman->next_coord_order; | |
374 visit = preorder_coord_subtree(root_coord, visit); | |
375 } | 486 } |
376 } | 487 rdman->n_dirty_geos = 0; |
377 | 488 } |
378 return coord; | 489 |
379 } | 490 return OK; |
380 | |
381 /*! \brief Free a coord of a redraw_man_t object. | |
382 * | |
383 * \param coord is a coord_t without children and members. | |
384 * \return 0 for successful, -1 for error. | |
385 */ | |
386 int rdman_coord_free(redraw_man_t *rdman, coord_t *coord) { | |
387 coord_t *parent; | |
388 | |
389 parent = coord->parent; | |
390 if(parent == NULL) | |
391 return ERR; | |
392 | |
393 if(STAILQ_HEAD(coord->members) != NULL) | |
394 return ERR; | |
395 | |
396 if(STAILQ_HEAD(coord->children) != NULL) | |
397 return ERR; | |
398 | |
399 STAILQ_REMOVE(parent->children, coord_t, sibling, coord); | |
400 elmpool_elm_free(rdman->coord_pool, coord); | |
401 rdman->n_coords--; | |
402 | |
403 return OK; | |
404 } | |
405 | |
406 /*! \brief Mark a coord is changed. | |
407 * | |
408 * A changed coord_t object is marked as dirty and put | |
409 * into dirty_coords list. | |
410 */ | |
411 int rdman_coord_changed(redraw_man_t *rdman, coord_t *coord) { | |
412 coord_t *child; | |
413 int max_dirty_coords; | |
414 int r; | |
415 | |
416 if(coord->flags & COF_DIRTY) | |
417 return OK; | |
418 | |
419 if(rdman->n_dirty_coords >= rdman->max_dirty_coords) { | |
420 /* Max of dirty_coords is not big enough. */ | |
421 max_dirty_coords = rdman->max_dirty_coords + 16; | |
422 | |
423 r = extend_memblk((void **)&rdman->dirty_coords, | |
424 sizeof(coord_t *) * rdman->n_dirty_coords, | |
425 sizeof(coord_t *) * max_dirty_coords); | |
426 rdman->max_dirty_coords = max_dirty_coords; | |
427 } | |
428 | |
429 /* Make the coord and child coords dirty. */ | |
430 for(child = coord; | |
431 child != NULL; | |
432 child = preorder_coord_subtree(coord, child)) { | |
433 rdman->dirty_coords[rdman->n_dirty_coords++] = coord; | |
434 coord->flags |= COF_DIRTY; | |
435 } | |
436 | |
437 return OK; | |
438 } | |
439 | |
440 static int _rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { | |
441 geo_t *geo; | |
442 int r; | |
443 | |
444 geo = shape->geo; | |
445 | |
446 if(geo->flags & GEF_DIRTY) | |
447 return OK; | |
448 | |
449 r = add_dirty_geo(rdman, geo); | |
450 if(r == ERR) | |
451 return ERR; | |
452 geo->flags |= GEF_DIRTY; | |
453 | |
454 return OK; | |
455 } | |
456 | |
457 /*! \brief Mark a shape is changed. | |
458 * | |
459 * The geo_t object of a changed shape is mark as dirty and | |
460 * put into dirty_geos list. | |
461 */ | |
462 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { | |
463 return _rdman_shape_changed(rdman, shape); | |
464 } | 491 } |
465 | 492 |
466 /* Drawing and Redrawing | 493 /* Drawing and Redrawing |
467 * ============================================================ | 494 * ============================================================ |
468 */ | 495 */ |
549 } | 576 } |
550 #else /* UNITTEST */ | 577 #else /* UNITTEST */ |
551 static void clean_canvas(cairo_t *cr) { | 578 static void clean_canvas(cairo_t *cr) { |
552 } | 579 } |
553 | 580 |
554 static void make_clip(cairo_t *cr, int n_dirty_areas, | |
555 area_t **dirty_areas) { | |
556 } | |
557 | |
558 static void reset_clip(redraw_man_t *rdman) { | 581 static void reset_clip(redraw_man_t *rdman) { |
559 } | 582 } |
560 | 583 |
561 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, | 584 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, |
562 area_t **dirty_areas) { | 585 area_t **dirty_areas) { |
615 * Clean dirty flag can prevent redundant computing for geo and | 638 * Clean dirty flag can prevent redundant computing for geo and |
616 * corod objects. | 639 * corod objects. |
617 * | 640 * |
618 */ | 641 */ |
619 int rdman_redraw_changed(redraw_man_t *rdman) { | 642 int rdman_redraw_changed(redraw_man_t *rdman) { |
620 int i, r; | 643 int r; |
621 geo_t *visit_geo, **dirty_geos; | |
622 int n_dirty_geos; | |
623 int n_dirty_areas; | 644 int n_dirty_areas; |
624 area_t **dirty_areas; | 645 area_t **dirty_areas; |
625 | 646 |
626 r = clean_rdman_coords(rdman); | 647 r = clean_rdman_coords(rdman); |
627 if(r != OK) | 648 if(r != OK) |
628 return ERR; | 649 return ERR; |
629 | 650 |
630 n_dirty_geos = rdman->n_dirty_geos; | 651 r = clean_rdman_geos(rdman); |
631 if(n_dirty_geos > 0) { | 652 if(r != OK) |
632 dirty_geos = rdman->dirty_geos; | 653 return ERR; |
633 for(i = 0; i < n_dirty_geos; i++) { | 654 |
634 visit_geo = dirty_geos[i]; | |
635 if(!(visit_geo->flags & GEF_DIRTY)) | |
636 continue; | |
637 | |
638 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *); | |
639 clean_shape(visit_geo->shape); | |
640 add_dirty_area(rdman, visit_geo->cur_area); | |
641 add_dirty_area(rdman, visit_geo->last_area); | |
642 } | |
643 rdman->n_dirty_geos = 0; | |
644 } | |
645 | |
646 n_dirty_areas = rdman->n_dirty_areas; | 655 n_dirty_areas = rdman->n_dirty_areas; |
647 dirty_areas = rdman->dirty_areas; | 656 dirty_areas = rdman->dirty_areas; |
648 if(n_dirty_areas > 0) { | 657 if(n_dirty_areas > 0) { |
649 clean_canvas(rdman->cr); | 658 clean_canvas(rdman->cr); |
650 draw_shapes_in_areas(rdman, n_dirty_areas, dirty_areas); | 659 draw_shapes_in_areas(rdman, n_dirty_areas, dirty_areas); |