Subject: Re: 23/NS: redraws according to mouse-face are slow

From: Adrian Robert <[email-masked]>
Date: Tue, 5 May 2009 17:36:31 +0700

On May 5, 2009, at 10:37 AM, David Reitter wrote:

> On May 4, 2009, at 9:53 PM, Chong Yidong wrote:
>
>> I see.  It seems ns_draw_glyph_string is a lot more expensive that
>> x_draw_glyph_string.  The show_mouse_face function assumes that the
>> *_draw_glyph_string operation is relatively cheap, which is why it's
>> called inside a loop.
>>
>> My guess is that the problem lies in the calls to ns_focus and
>> ns_unfocus in ns_draw_glyph_string.
>
> Right - but we still need them, at least for clipping.
> That said, because of the clipping, calls to ns_focus may be more  
> expensive than desirable. We have multiple calls to  
> ns_draw_glyph_string, often more than one for each row, but we only  
> need one clipping for the whole frame.  So, ideally we'd call  
> ns_focus outside the loops that call ns_draw_glyph_string, but the  
> architecture won't allow that.
>
>>> If we wrap the code in show_mouse_face in NS[Dis|En]ableScreen, the
>>> problem goes away for me (and it's not just delayed).  Same for the
>>> header-line/overlay issues I reported in #2530.
>>
>> If possible, we should minimize the amount of platform-dependent code
>> inside xdisp.c.  Could you experiment with putting these calls  
>> somewhere
>> in nsterm.m, say surrounding the calls to note_mouse_highlight?
>>
>> Also, could it be ns_update_begin and ns_update_end that you want to
>> call, instead of NSDisableScreen and NSEnableScreen?
>
> Yes, sure, this variant works well, and it takes care of the ugly  
> flicker as well.
> (However, when moving the mouse over a piece of text with (common)  
> mouse-face property, we shouldn't need to redraw in the first  
> place, and that should be addressed at some point, perhaps after  
> 23.1.)

That ns_update_begin() acheives the same effect suggests that perhaps  
the core mouse face code should do this (through the RIF).   
ns_draw_glyph_string() is not slow for any other operations, despite  
the fact that it is called with the same granularity (same-face-glyph- 
run) everywhere, likely because the update_begin()/end() batching is  
used.

(And yes, thanks for tracking this David!)

-Adrian