Changeset 206945 in webkit


Ignore:
Timestamp:
Oct 7, 2016, 5:20:05 PM (9 years ago)
Author:
Simon Fraser
Message:

[WK1 Mac] Fix repaints of fixed-background elements in layer-backed WebViews
https://bugs.webkit.org/show_bug.cgi?id=163154
rdar://problem/28674216

Reviewed by Tim Horton.

r55159 added code to counteract AppKit's adjustment of dirty regions during scrolling,
by offsetting the dirty rect in -setNeedsDisplayInRect: if the call happens during
the NSViewBoundsDidChangeNotification handling.

However, AppKit only does dirty region adjustment in the code path that blits ("copy
on scroll"), so r55159 produces incorrect behavior in, for example, layer-backed views.

Fix by overriding -[NSClipView _canCopyOnScrollForDeltaX:deltaY:] to know if a single
scroll is going to blit, and only do adjustments in -setNeedsDisplayInRect: if it is.

  • WebView/WebClipView.h:
  • WebView/WebClipView.mm:

(-[WebClipView _immediateScrollToPoint:]):
(-[WebClipView _canCopyOnScrollForDeltaX:deltaY:]):
(-[WebClipView currentScrollIsBlit]):

  • WebView/WebHTMLView.mm:

(-[WebHTMLView setNeedsDisplayInRect:]):
(-[WebHTMLView drawRect:]):

Location:
trunk/Source/WebKit/mac
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/mac/ChangeLog

    r206867 r206945  
     12016-10-07  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [WK1 Mac] Fix repaints of fixed-background elements in layer-backed WebViews
     4        https://bugs.webkit.org/show_bug.cgi?id=163154
     5        rdar://problem/28674216
     6
     7        Reviewed by Tim Horton.
     8       
     9        r55159 added code to counteract AppKit's adjustment of dirty regions during scrolling,
     10        by offsetting the dirty rect in -setNeedsDisplayInRect: if the call happens during
     11        the NSViewBoundsDidChangeNotification handling.
     12       
     13        However, AppKit only does dirty region adjustment in the code path that blits ("copy
     14        on scroll"), so r55159 produces incorrect behavior in, for example, layer-backed views.
     15       
     16        Fix by overriding -[NSClipView _canCopyOnScrollForDeltaX:deltaY:] to know if a single
     17        scroll is going to blit, and only do adjustments in -setNeedsDisplayInRect: if it is.
     18
     19        * WebView/WebClipView.h:
     20        * WebView/WebClipView.mm:
     21        (-[WebClipView _immediateScrollToPoint:]):
     22        (-[WebClipView _canCopyOnScrollForDeltaX:deltaY:]):
     23        (-[WebClipView currentScrollIsBlit]):
     24        * WebView/WebHTMLView.mm:
     25        (-[WebHTMLView setNeedsDisplayInRect:]):
     26        (-[WebHTMLView drawRect:]):
     27
    1282016-10-06  Youenn Fablet  <youenn@apple.com>
    229
  • trunk/Source/WebKit/mac/WebView/WebClipView.h

    r165676 r206945  
    3535    BOOL _haveAdditionalClip;
    3636    BOOL _isScrolling;
     37    BOOL _currentScrollIsBlit;
    3738    NSRect _additionalClip;
    3839}
    3940
     41- (BOOL)currentScrollIsBlit;
    4042- (void)setAdditionalClip:(NSRect)additionalClip;
    4143- (void)resetAdditionalClip;
  • trunk/Source/WebKit/mac/WebView/WebClipView.mm

    r181587 r206945  
    5151@interface NSClipView (WebNSClipViewDetails)
    5252- (void)_immediateScrollToPoint:(NSPoint)newOrigin;
     53- (BOOL)_canCopyOnScrollForDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY;
    5354@end
    5455
     
    105106{
    106107    _isScrolling = YES;
     108    _currentScrollIsBlit = NO;
    107109
    108110    [[self window] _disableDelayedWindowDisplay];
     
    125127
    126128    _isScrolling = NO;
     129}
     130
     131- (BOOL)_canCopyOnScrollForDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY
     132{
     133    _currentScrollIsBlit = [super _canCopyOnScrollForDeltaX:deltaX deltaY:deltaY];
     134    return _currentScrollIsBlit;
     135}
     136
     137- (BOOL)currentScrollIsBlit
     138{
     139    return _currentScrollIsBlit;
    127140}
    128141
  • trunk/Source/WebKit/mac/WebView/WebHTMLView.mm

    r206917 r206945  
    41114111#endif
    41124112
     4113static BOOL currentScrollIsBlit(NSView *clipView)
     4114{
     4115#if PLATFORM(MAC)
     4116    return [clipView isKindOfClass:[WebClipView class]] && [(WebClipView *)clipView currentScrollIsBlit];
     4117#else
     4118    return NO;
     4119#endif
     4120}
     4121
     4122// FIXME: this entire function could be #ifdeffed out on iOS. The below workaround is AppKit-specific.
    41134123- (void)setNeedsDisplayInRect:(NSRect)invalidRect
    41144124{
    4115     if (_private->inScrollPositionChanged) {
     4125    if (_private->inScrollPositionChanged && currentScrollIsBlit([self superview])) {
    41164126        // When scrolling, the dirty regions are adjusted for the scroll only
    41174127        // after NSViewBoundsDidChangeNotification is sent. Translate the invalid
     
    42284238    const float cWastedSpaceThreshold = 0.75f;
    42294239    BOOL useUnionedRect = (count <= 1) || (count > cRectThreshold);
    4230     if (!useUnionedRect) { 
     4240    if (!useUnionedRect) {
    42314241        // Attempt to guess whether or not we should use the unioned rect or the individual rects.
    42324242        // We do this by computing the percentage of "wasted space" in the union.  If that wasted space
Note: See TracChangeset for help on using the changeset viewer.