comparison src/redraw_man.c @ 14:d34232f15863

-
author Thinker K.F. Li <thinker@branda.to>
date Thu, 31 Jul 2008 17:43:20 +0800
parents ed55009d96d3
children c2ce186a5c37
comparison
equal deleted inserted replaced
13:ed55009d96d3 14:d34232f15863
39 void redraw_man_destroy(redraw_man_t *rdman) { 39 void redraw_man_destroy(redraw_man_t *rdman) {
40 elmpool_free(rdman->coord_pool); 40 elmpool_free(rdman->coord_pool);
41 elmpool_free(rdman->geo_pool); 41 elmpool_free(rdman->geo_pool);
42 if(rdman->dirty_coords) 42 if(rdman->dirty_coords)
43 free(rdman->dirty_coords); 43 free(rdman->dirty_coords);
44 if(rdman->redrawing_geos) 44 if(rdman->dirty_geos)
45 free(rdman->redrawing_geos); 45 free(rdman->dirty_geos);
46 } 46 }
47 47
48 48
49 #define ASSERT(x) 49 #define ASSERT(x)
50 /* 50 /*
213 213
214 return OK; 214 return OK;
215 } 215 }
216 216
217 static int add_dirty_geo(redraw_man_t *rdman, geo_t *geo) { 217 static int add_dirty_geo(redraw_man_t *rdman, geo_t *geo) {
218 int max_redrawing_geos; 218 int max_dirty_geos;
219 int r; 219 int r;
220 220
221 if(rdman->n_redrawing_geos >= rdman->max_redrawing_geos) { 221 if(rdman->n_dirty_geos >= rdman->max_dirty_geos) {
222 max_redrawing_geos = rdman->n_geos + rdman->n_coords; 222 max_dirty_geos = rdman->n_geos;
223 r = extend_memblk((void **)&rdman->redrawing_geos, 223 r = extend_memblk((void **)&rdman->dirty_geos,
224 sizeof(geo_t *) * rdman->n_redrawing_geos, 224 sizeof(geo_t *) * rdman->n_dirty_geos,
225 sizeof(geo_t *) * max_redrawing_geos); 225 sizeof(geo_t *) * max_dirty_geos);
226 if(r != OK) 226 if(r != OK)
227 return ERR; 227 return ERR;
228 rdman->max_redrawing_geos = max_redrawing_geos; 228 rdman->max_dirty_geos = max_dirty_geos;
229 } 229 }
230 230
231 rdman->redrawing_geos[rdman->n_redrawing_geos++] = geo; 231 rdman->dirty_geos[rdman->n_dirty_geos++] = geo;
232 return OK; 232 return OK;
233 } 233 }
234 234
235 static int add_dirty_area(redraw_man_t *rdman, area_t *area) { 235 static int add_dirty_area(redraw_man_t *rdman, area_t *area) {
236 int max_dirty_areas; 236 int max_dirty_areas;
279 } 279 }
280 280
281 /*! \brief Mark a shape is changed. 281 /*! \brief Mark a shape is changed.
282 * 282 *
283 * The geo_t object of a changed shape is mark as dirty and 283 * The geo_t object of a changed shape is mark as dirty and
284 * put into redrawing_geos list. 284 * put into dirty_geos list.
285 */ 285 */
286 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { 286 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) {
287 geo_t *geo; 287 geo_t *geo;
288 int r; 288 int r;
289 289
329 shape->geo->flags &= ~GEF_DIRTY; 329 shape->geo->flags &= ~GEF_DIRTY;
330 add_dirty_geo(rdman, shape->geo); 330 add_dirty_geo(rdman, shape->geo);
331 } 331 }
332 } 332 }
333 333
334 static void compute_coord_geo(coord_t *coord) { 334 static void compute_coord_area(coord_t *coord) {
335 } 335 }
336 336
337 static void transform_shape(shape_t *shape) { 337 static void update_shape_geo(shape_t *shape) {
338 } 338 }
339 339
340 static void draw_shape(shape_t *shape) { 340 static void draw_shape(redraw_man_t *rdman, shape_t *shape) {
341 }
342
343 static void clip_and_show(redraw_man_t *rdman, int n_dirty_areas,
344 area_t **dirty_areas) {
341 } 345 }
342 346
343 /*! \brief Re-draw all changed shapes or shapes affected by changed coords. 347 /*! \brief Re-draw all changed shapes or shapes affected by changed coords.
344 * 348 *
345 * A coord object has a geo to keep track the range that it's members will 349 * A coord object has a geo to keep track the range that it's members will
354 * overlay shape objects, too. If a shape's coord is changed, shape's 358 * overlay shape objects, too. If a shape's coord is changed, shape's
355 * geo object is not used to find overlay shape objects any more. 359 * geo object is not used to find overlay shape objects any more.
356 * 360 *
357 * steps: 361 * steps:
358 * - update chagned coord objects 362 * - update chagned coord objects
359 * - recompute geo for changed coord objects 363 * - recompute area for changed coord objects
360 * - recompute geo for members shape objects 364 * - recompute geo for members shape objects
365 * - clear dirty of geo for members to prevent from
366 * recomputing for change of shape objects.
367 * - add old and new area value to list of dirty areas.
361 * - recompute geo for changed shape objects 368 * - recompute geo for changed shape objects
362 * - finding overlaid shape objects for recomputed geo objects. 369 * - only if a shape object is dirty.
363 * - overlaid shape objects is invoked by traveling tree of coord. 370 * - put new and old value of area of geo to list of dirty areas.
364 * - members of changed coord object are marked computed and dirty. 371 * - Scan all shapes and redraw shapes overlaid with dirty areas.
365 * 372 *
366 * assert(n_redrawing_geos <= (num_of(shape) + num_of(coord))) 373 * dirty flag of coord objects is cleared after update.
374 *
375 * assert(n_dirty_geos <= (num_of(shape) + num_of(coord)))
367 * Because 376 * Because
368 * - num_of(geo from coord) < num_of(coord) 377 * - num_of(geo from coord) < num_of(coord)
369 * - num_of(geo from shape) < num_of(shape) 378 * - num_of(geo from shape) < num_of(shape)
370 */ 379 */
371 int rdman_redraw_changed(redraw_man_t *rdman) { 380 int rdman_redraw_changed(redraw_man_t *rdman) {
372 int i, j; 381 int i;
373 int n_dirty_coords; 382 int n_dirty_coords;
374 coord_t **dirty_coords; 383 coord_t **dirty_coords;
375 coord_t *visit_coord; 384 coord_t *visit_coord;
376 geo_t *visit_geo, **redrawing_geos; 385 geo_t *visit_geo, **dirty_geos;
377 int n_redrawing_geos; 386 int n_dirty_geos;
378 int n_dirty_areas; 387 int n_dirty_areas;
388 area_t **dirty_areas;
379 389
380 if(rdman->n_dirty_coords > 0) { 390 if(rdman->n_dirty_coords > 0) {
381 _insert_sort((void **)rdman->dirty_coords, 391 _insert_sort((void **)rdman->dirty_coords,
382 rdman->n_dirty_coords, 392 rdman->n_dirty_coords,
383 OFFSET(coord_t, order)); 393 OFFSET(coord_t, order));
393 visit_coord = preorder_coord_subtree(dirty_coords[i], 403 visit_coord = preorder_coord_subtree(dirty_coords[i],
394 visit_coord)) { 404 visit_coord)) {
395 /* Dirty member, here, and members of this coord 405 /* Dirty member, here, and members of this coord
396 * will not be visited anymore. */ 406 * will not be visited anymore. */
397 visit_coord->flags &= ~COF_DIRTY; 407 visit_coord->flags &= ~COF_DIRTY;
398 visit_coord->flags |= COF_RECOMP;
399 408
400 SWAP(visit_coord->cur_area, visit_coord->last_area, area_t *); 409 SWAP(visit_coord->cur_area, visit_coord->last_area, area_t *);
401 compute_coord_geo(visit_coord); 410 compute_coord_area(visit_coord);
402 add_dirty_area(rdman, visit_coord->cur_area); 411 add_dirty_area(rdman, visit_coord->cur_area);
403 add_dirty_area(rdman, visit_coord->last_area); 412 add_dirty_area(rdman, visit_coord->last_area);
404 make_redrawing_members(rdman, visit_coord); 413 make_redrawing_members(rdman, visit_coord);
405 } 414 }
406 } 415 }
407 rdman->n_dirty_coords = 0; 416 rdman->n_dirty_coords = 0;
408 } 417 }
409 418
410 n_redrawing_geos = rdman->n_redrawing_geos; 419 n_dirty_geos = rdman->n_dirty_geos;
411 if(n_redrawing_geos > 0) { 420 if(n_dirty_geos > 0) {
412 redrawing_geos = rdman->redrawing_geos; 421 dirty_geos = rdman->dirty_geos;
413 for(i = 0; i < n_redrawing_geos; i++) { 422 for(i = 0; i < n_dirty_geos; i++) {
414 visit_geo = redrawing_geos[i]; 423 visit_geo = dirty_geos[i];
415 if(!(visit_geo->flags & GEF_DIRTY)) 424 if(!(visit_geo->flags & GEF_DIRTY))
416 continue; 425 continue;
417 426
427 visit_geo->flags &= ~GEF_DIRTY;
418 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *); 428 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *);
419 transform_shape(visit_geo->shape); 429 update_shape_geo(visit_geo->shape);
420 visit_geo->flags &= ~GEF_DIRTY;
421 add_dirty_area(rdman, visit_geo->cur_area); 430 add_dirty_area(rdman, visit_geo->cur_area);
422 add_dirty_area(rdman, visit_geo->last_area); 431 add_dirty_area(rdman, visit_geo->last_area);
423 } 432 }
424 433
425 n_dirty_areas = rdman->n_dirty_areas; 434 n_dirty_areas = rdman->n_dirty_areas;
435 dirty_areas = rdman->dirty_areas;
426 for(visit_geo = STAILQ_HEAD(rdman->all_geos); 436 for(visit_geo = STAILQ_HEAD(rdman->all_geos);
427 visit_geo != NULL; 437 visit_geo != NULL;
428 visit_geo = STAILQ_NEXT(geo_t, next, visit_geo)) { 438 visit_geo = STAILQ_NEXT(geo_t, next, visit_geo)) {
429 if(visit_geo->flags & GEF_DIRTY) 439 for(i = 0; i < n_dirty_areas; i++) {
430 continue; 440 if(is_overlay(visit_geo->cur_area,
431 441 dirty_areas[i])) {
442 draw_shape(rdman, visit_geo->shape);
443 break;
444 }
445 }
432 } 446 }
447 clip_and_show(rdman, n_dirty_areas, dirty_areas);
433 } 448 }
434 449
435 return OK; 450 return OK;
436 } 451 }
437 452