emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: animate incredibly slow compared to 21.3


From: Kim F. Storm
Subject: Re: animate incredibly slow compared to 21.3
Date: Sun, 13 Mar 2005 02:15:22 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Richard Stallman <address@hidden> writes:

>     To make scrolling (even of images or lines of widely different height)
>     reliable, compute-motion would need to pay attention to every display
>     element and parameter, including things like frame-local face properties.
>
>     So either it re-implements the redisplay or it reuses the redisplay.
>
> The display mechanism at C level is already designed to facilitate
> this.  It's just a matter of adapting the higher levels to use it.

I don't understand -- what C level "display mechanism" is designed to
facilitate "this".

> If this was already done for vertical-motion, it can surely be done
> for compute-motion.

I guess so -- but is it really needed?

There are currently 3 uses of compute-motion in the code:

window-buffer-height
mouse-avoidance-point-position
windmove-coordinates-of-position

Stefan already showed how window-buffer-height can be implemented using
count-screen-lines (which uses vertical-motion).

The two others can be replaced by MUCH SIMPLER code using
posn-at-point, like this:

*** avoid.el    23 Aug 2004 00:30:55 +0200      1.37
--- avoid.el    12 Mar 2005 23:54:30 +0100      
***************
*** 138,160 ****
  (defun mouse-avoidance-point-position ()
    "Return the position of point as (FRAME X . Y).
  Analogous to `mouse-position'."
!   (let* ((w (selected-window))
!        (edges (window-inside-edges w))
!        (list
!         (compute-motion (max (window-start w) (point-min))   ; start pos
!                         ;; window-start can be < point-min if the
!                         ;; latter has changed since the last redisplay
!                         '(0 . 0)                             ; start XY
!                         (point)                              ; stop pos
!                         nil                                  ; stop XY: none
!                         nil                                  ; width
!                         (cons (window-hscroll w) 0)          ; 0 may not be 
right?
!                         (selected-window))))
!     ;; compute-motion returns (pos HPOS VPOS prevhpos contin)
      ;; we want:               (frame hpos . vpos)
      (cons (selected-frame)
!         (cons (+ (car edges)       (car (cdr list)))
!               (+ (car (cdr edges)) (car (cdr (cdr list))))))))
  
  ;(defun mouse-avoidance-point-position-test ()
  ;  (interactive)
--- 138,149 ----
  (defun mouse-avoidance-point-position ()
    "Return the position of point as (FRAME X . Y).
  Analogous to `mouse-position'."
!   (let* ((edges (window-inside-edges))
!        (col-row (posn-col-row (posn-at-point))))
      ;; we want:               (frame hpos . vpos)
      (cons (selected-frame)
!         (cons (+ (car edges)       (car col-row))
!               (+ (car (cdr edges)) (cdr col-row))))))
  
  ;(defun mouse-avoidance-point-position-test ()
  ;  (interactive)


*** windmove.el 14 Sep 2004 12:42:20 +0200      1.9
--- windmove.el 13 Mar 2005 00:26:57 +0100      
***************
*** 206,216 ****
  ;; rest.
  ;;
  ;; This work is done by `windmove-reference-loc'.  It can figure out
! ;; the locations of the corners by calling `window-edges', but to
! ;; calculate the frame-based location of point, it calls the workhorse
! ;; function `windmove-coordinates-of-position', which itself calls the
! ;; incredibly hairy builtin `compute-motion'.  There is a good deal of
! ;; black magic in getting all the arguments to this function just right.
  ;;
  ;; The second step is more messy.  Conceptually, it is fairly simple:
  ;; if we know the reference location, and the coordinates of the
--- 206,213 ----
  ;; rest.
  ;;
  ;; This work is done by `windmove-reference-loc'.  It can figure out
! ;; the locations of the corners by calling `window-edges' combined
! ;; with the result of `posn-at-point'.
  ;;
  ;; The second step is more messy.  Conceptually, it is fairly simple:
  ;; if we know the reference location, and the coordinates of the
***************
*** 404,461 ****
         (windmove-constrain-around-range (cdr coord) min-y max-y)))))
  
  
- 
- ;; `windmove-coordinates-of-position' is stolen and modified from the
- ;; Emacs 20 Lisp Reference Manual, section 27.2.5.  It seems to work
- ;; okay, although I am bothered by the fact that tab-offset (the cdr
- ;; of the next-to- last argument) is set to 0.  On the other hand, I
- ;; can't find a single usage of `compute-motion' anywhere that doesn't
- ;; set this component to zero, and I'm too lazy to grovel through the
- ;; C source to figure out what's happening in the background.  there
- ;; also seems to be a good deal of fun in calculating the correct
- ;; width of lines for telling `compute-motion' about; in particular,
- ;; it seems we need to subtract 1 (for the continuation column) from
- ;; the number that `window-width' gives, or continuation lines aren't
- ;; counted correctly.  I haven't seen anyone doing this before,
- ;; though.
- ;;
- ;; Now updated for Emacs 21, based on the Emacs 21 Lisp Reference
- ;; Manual, section 30.2.5.  It is no longer necessary to subtract
- ;; 1 for the usable width of the window.
- ;; TODO: also handle minibuffer case, w/ `minibuffer-prompt-width'.
- (defun windmove-coordinates-of-position (pos)
-   "Return the coordinates of position POS in the current window.
- Return the window-based coodinates in a cons pair: (HPOS . VPOS),
- where HPOS and VPOS are the zero-based x and y components of the
- screen location of POS.
- As an example, if point is in the top left corner of a window, then
- the return value from `windmove-coordinates-of-position' is (0 . 0)
- regardless of the where point is in the buffer and where the window
- is placed in the frame."
-   (let ((big-hairy-result (compute-motion
-                            (window-start)
-                            '(0 . 0)
-                            pos
-                            nil ; (window-width window-height)
-                            nil ; window-width
-                            (cons (window-hscroll)
-                                  0)  ; why zero?
-                            (selected-window))))
-   (cons (nth 1 big-hairy-result)        ; hpos, not vpos as documented
-         (nth 2 big-hairy-result))))     ; vpos, not hpos as documented
- 
- (defun windmove-coordinates-of-window-position (pos &optional window)
-   "Return the coordinates of position POS in WINDOW.
- Return the window-based coodinates in a cons pair: (HPOS . VPOS),
- where HPOS and VPOS are the zero-based x and y components of the
- screen location of POS.  If WINDOW is nil, return the coordinates in
- the currently selected window."
-   (if (null window)
-       (windmove-coordinates-of-position pos)
-     (save-selected-window
-       (select-window window)
-       (windmove-coordinates-of-position pos))))
- 
  ;; This calculates the reference location in the current window: the
  ;; frame-based (x . y) of either point, the top-left, or the
  ;; bottom-right of the window, depending on ARG.
--- 401,406 ----
***************
*** 482,490 ****
         ((= effective-arg 0)
            (windmove-coord-add
               top-left
!              (windmove-coordinates-of-window-position
!               (window-point window)
!               window)))))))
  
  ;; This uses the reference location in the current window (calculated
  ;; by `windmove-reference-loc' above) to find a reference location
--- 427,434 ----
         ((= effective-arg 0)
            (windmove-coord-add
               top-left
!              (posn-col-row
!             (posn-at-point (window-point window) window))))))))
  
  ;; This uses the reference location in the current window (calculated
  ;; by `windmove-reference-loc' above) to find a reference location

>
>     > IMO, compute-motion is too cumbersome to use.
>
> The facility is essential.  The idea of eliminating it makes no sense.

If there are trivial replacements for the existing uses, it's not
"essential".

Actually, these new versions works better with proportional fonts than
the old code using compute-motion.


That leaves the problem sit-for in line-move, but again,
compute-motion doesn't solve the problem, as the information we need
is the result of pos-visible-in-window-p in case point is only
partially visible.  I don't see how compute-motion can give us that
information.

I still fail to see why sit-for is so bad in line-move -- most of the
time it simply means that redisplay happens a little sooner than it
would otherwise do.  Except for the mis-use of next-line in animate,
nobody has complained about bad performance due to this (because
it performs just fine IMO).

> > I don't know of a way to make it simpler to use, but I would be glad
> if it were.

One problem with compute-motion is that for practical use, you often
have to provide a valid "window-start", but that may not be valid
until after redisplay ... so it suffers from similar problems
as using pos-visible-in-window-p in line-move.

>
> (The C-level mechanism has similar complexities in its interface.
> They are simply necessary.)

But at the C-level, the required parameters are readily available, so
it is less complex, that at the Lisp level where you have to use
approximations to the proper values.

I still think we should declare compute-motion obsolete.

Instead, we could fix pos-at-x-y and pos-at-point to not rely on
the display to be up-to-date.

-- 
Kim F. Storm <address@hidden> http://www.cua.dk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]