Mercurial > hg > xemacs-beta
diff src/redisplay-output.c @ 404:2f8bb876ab1d r21-2-32
Import from CVS: tag r21-2-32
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:16:07 +0200 |
parents | 74fd4e045ea6 |
children | b8cc9ab3f761 |
line wrap: on
line diff
--- a/src/redisplay-output.c Mon Aug 13 11:15:00 2007 +0200 +++ b/src/redisplay-output.c Mon Aug 13 11:16:07 2007 +0200 @@ -101,7 +101,7 @@ For the given LINE in window W, make the current display line equal the desired display line. ****************************************************************************/ -static void +void sync_display_line_structs (struct window *w, int line, int do_blocks, display_line_dynarr *cdla, display_line_dynarr *ddla) @@ -211,10 +211,7 @@ #### It would really be worth it to arrange for this function to be (almost) a single call to memcmp. */ - if ((crb->findex != drb->findex) || - (WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) - return 0; - else if (crb->xpos != drb->xpos) + if (crb->xpos != drb->xpos) return 0; else if (crb->width != drb->width) return 0; @@ -236,17 +233,67 @@ return 0; /* Only check dirtiness if we know something has changed. */ else if (crb->type == RUNE_DGLYPH && - XFRAME (w->frame)->glyphs_changed) + ((XFRAME (w->frame)->glyphs_changed && + XGLYPH_DIRTYP (crb->object.dglyph.glyph)) || + crb->findex != drb->findex)) { - glyph_index gindex = get_glyph_cachel_index (w, drb->object.dglyph.glyph); - /* Although doing the cachel lookup for every comparison is - very expensive.we have to do it to make sure the cache is - up-to-date. */ - if (GLYPH_CACHEL_DIRTYP (w, gindex)) + /* We need some way of telling redisplay_output_layout () that the + only reason we are outputting it is because something has + changed internally. That way we can optimize whether we need + to clear the layout first and also only output the components + that have changed. The image_instance dirty flag and + display_hash are no good to us because these will invariably + have been set anyway if the layout has changed. So it looks + like we need yet another change flag that we can set here and + then clear in redisplay_output_layout (). */ + Lisp_Object window, image; + Lisp_Image_Instance* ii; + XSETWINDOW (window, w); + image = glyph_image_instance (crb->object.dglyph.glyph, + window, ERROR_ME_NOT, 1); + ii = XIMAGE_INSTANCE (image); + + if (TEXT_IMAGE_INSTANCEP (image) && + (crb->findex != drb->findex || + WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) return 0; + + /* It is quite common of the two glyphs to be EQ since in many + cases they will actually be the same object. This does not + mean, however, that nothing has changed. We therefore need to + check the current hash of the glyph against the last recorded + display hash. See update_subwindow (). */ + if (IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0 || + IMAGE_INSTANCE_DISPLAY_HASH (ii) != + internal_hash (image, IMAGE_INSTANCE_HASH_DEPTH) || + crb->findex != drb->findex || + WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) + { + /* We now now we are going to re-output the glyph, but since + this is for some internal reason not related to geometry + changes, send a hint to the output routines that they can + take some short cuts. This is most useful for + layouts. This flag should get reset by the output + routines. + + #### It is possible for us to get here when the + face_cachel is dirty. I do not know what the implications + of this are.*/ + IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1; + return 0; + } else return 1; } + /* We now do this last so that glyph checks can do their own thing + for face changes. Face changes quite often happen when we are + trying to output something in the gutter, this would normally + lead to a lot of flashing. The indices can quite often be + different and yet the faces are the same, we do not want to + re-output in this instance. */ + else if (crb->findex != drb->findex || + WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) + return 0; else return 1; } @@ -1067,6 +1114,8 @@ { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); + /* Temporarily disabled until generalization is done. */ +#if 0 struct display_block *db = Dynarr_atp (dl->display_blocks, block); rune_dynarr *rba = db->runes; struct rune *rb; @@ -1084,6 +1133,7 @@ rb = Dynarr_atp (rba, end - 1); width = rb->xpos + rb->width - xpos; +#endif /* now actually output the block. */ DEVMETH (d, output_display_block, (w, dl, block, start, end, start_pixpos, @@ -1243,17 +1293,6 @@ struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); int layout_height, layout_width; - /* We bogusly don't take f->extents_changed and f->glyphs_changed - into account. This is because if we do we always redisplay the - entire layout. So far I have seen no ill effects so we'll see. */ - int frame_really_changed = (f->buffers_changed || - f->clip_changed || - f->faces_changed || - f->frame_changed || - f->modeline_changed || - f->subwindows_changed || - f->windows_changed || - f->windows_structure_changed); XSETWINDOW (window, w); @@ -1269,7 +1308,7 @@ /* Highly dodgy optimization. We want to only output the whole layout if we really have to. */ - if (frame_really_changed + if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p) || IMAGE_INSTANCE_LAYOUT_CHANGED (p) || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) || IMAGE_INSTANCE_SIZE_CHANGED (p) @@ -1342,6 +1381,7 @@ if (IMAGE_INSTANCEP (child)) { Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); + /* The enclosing layout offsets are +ve at this point */ struct display_glyph_area cdga; cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; @@ -1349,6 +1389,9 @@ cdga.width = glyph_width (child, window); cdga.height = glyph_height (child, window); + IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = + IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p); + /* Although normalization is done by the output routines we have to do it here so that they don't try and clear all of db. This is true below also. */ @@ -1375,7 +1418,8 @@ generalisation.*/ if (redisplay_normalize_glyph_area (&cdb, &cdga) && - (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii))) + (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || + IMAGE_INSTANCE_DIRTYP (childii))) { struct display_line dl; /* this is fake */ Lisp_Object string = @@ -1409,14 +1453,16 @@ case IMAGE_MONO_PIXMAP: case IMAGE_COLOR_PIXMAP: - if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) + if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) + || IMAGE_INSTANCE_DIRTYP (childii)) redisplay_output_pixmap (w, child, &cdb, &cdga, findex, 0, 0, 0, 0); break; case IMAGE_WIDGET: case IMAGE_SUBWINDOW: - if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) + if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || + IMAGE_INSTANCE_DIRTYP (childii)) redisplay_output_subwindow (w, child, &cdb, &cdga, findex, 0, 0, 0); break; @@ -1435,6 +1481,7 @@ abort (); } } + IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0; } }