Changeset 18704 in webkit


Ignore:
Timestamp:
Jan 9, 2007, 5:50:25 AM (19 years ago)
Author:
mjs
Message:

Reviewed by Darin.


  • remove window display throttling code; no longer used
  • Misc/WebNSWindowExtras.h:
  • Misc/WebNSWindowExtras.m:
  • WebView/WebFrameView.mm: (-[WebFrameView initWithFrame:]):
  • WebView/WebPreferenceKeysPrivate.h:
Location:
trunk/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit/ChangeLog

    r18694 r18704  
     12007-01-09  Maciej Stachowiak  <mjs@apple.com>
     2
     3        Reviewed by Darin.
     4       
     5        - remove window display throttling code; no longer used
     6
     7        * Misc/WebNSWindowExtras.h:
     8        * Misc/WebNSWindowExtras.m:
     9        * WebView/WebFrameView.mm:
     10        (-[WebFrameView initWithFrame:]):
     11        * WebView/WebPreferenceKeysPrivate.h:
     12
    1132007-01-08  Anders Carlsson  <acarlsson@apple.com>
    214
  • trunk/WebKit/Misc/WebNSWindowExtras.h

    r14379 r18704  
    3030
    3131@interface NSWindow (WebExtras)
    32 // Throttles the NSWindow autodisplay mechanism to a maximum of 60 frames per second.
    33 // This ensures that dynamically updated web content does not cause the window to display
    34 // too often, which can cause performance problems with CoreGraphics' coalesced updates
    35 // feature.  See <http://developer.apple.com/technotes/tn2005/tn2133.html>.
    36 + (void)_webkit_enableWindowDisplayThrottle;
    37 
    38 // Disables NSWindow display throttling.  Any windows with pending displays will be displayed
    39 // immediately when window throttling is disabled.
    40 + (void)_webkit_disableWindowDisplayThrottle;
    41 
    42 // Force all throttle timers to fire by running the runloop in WebKitDisplayThrottleRunLoopMode until there are
    43 // no more runloop timers/sources for that mode.
    44 + (void)_webkit_displayThrottledWindows;
    45 
    4632// centers "visually", putting 1/3 of the remaining space above, and 2/3 below
    4733- (void)centerOverMainWindow;
  • trunk/WebKit/Misc/WebNSWindowExtras.m

    r15781 r18704  
    2929#import "WebNSWindowExtras.h"
    3030
    31 #import "WebKitLogging.h"
    32 #import <JavaScriptCore/Assertions.h>
    33 #import <objc/objc-runtime.h>
    34 
    35 #define DISPLAY_REFRESH_INTERVAL (1.0 / 60.0)
    36 
    37 static NSString *WebKitDisplayThrottleRunLoopMode = @"WebKitDisplayThrottleRunLoopMode";
    38 
    39 static BOOL throttlingWindowDisplay;
    40 static CFMutableDictionaryRef windowDisplayInfoDictionary;
    41 static IMP oldNSWindowPostWindowNeedsDisplayIMP;
    42 static IMP oldNSWindowDeallocIMP;
    43 static IMP oldNSWindowFinalizeIMP;
    44 
    45 typedef struct {
    46     NSWindow *window;
    47     CFTimeInterval lastDisplayTime;
    48     NSTimer *displayTimer;
    49 } WindowDisplayInfo;
    50 
    51 @interface NSWindow (WebExtrasInternal)
    52 static IMP swizzleInstanceMethod(Class class, SEL selector, IMP newImplementation);
    53 static void replacementPostWindowNeedsDisplay(id self, SEL cmd);
    54 static void replacementDealloc(id self, SEL cmd);
    55 static void replacementFinalize(id self, SEL cmd);
    56 static WindowDisplayInfo *getWindowDisplayInfo(NSWindow *window);
    57 static BOOL requestWindowDisplay(NSWindow *window);
    58 static void cancelPendingWindowDisplay(WindowDisplayInfo *displayInfo);
    59 - (void)_webkit_doPendingPostWindowNeedsDisplay:(NSTimer *)timer;
    60 @end
    61 
    62 @interface NSWindow (AppKitSecretsIKnow)
    63 - (void)_postWindowNeedsDisplay;
    64 @end
    65 
    6631@implementation NSWindow (WebExtras)
    67 
    68 + (void)_webkit_enableWindowDisplayThrottle
    69 {
    70     if (throttlingWindowDisplay)
    71         return;
    72    
    73     static BOOL installedWindowThrottle = NO;
    74     if (!installedWindowThrottle) {       
    75         // Override -[NSWindow _postWindowNeedsDisplay]
    76         ASSERT(!oldNSWindowPostWindowNeedsDisplayIMP);
    77         oldNSWindowPostWindowNeedsDisplayIMP = swizzleInstanceMethod(self, @selector(_postWindowNeedsDisplay), (IMP)replacementPostWindowNeedsDisplay);
    78         ASSERT(oldNSWindowPostWindowNeedsDisplayIMP);
    79        
    80         // Override -[NSWindow dealloc]
    81         ASSERT(!oldNSWindowDeallocIMP);
    82         oldNSWindowDeallocIMP = swizzleInstanceMethod(self, @selector(dealloc), (IMP)replacementDealloc);
    83         ASSERT(oldNSWindowDeallocIMP);
    84 
    85         // Override -[NSWindow finalize]
    86         ASSERT(!oldNSWindowFinalizeIMP);
    87         oldNSWindowFinalizeIMP = swizzleInstanceMethod(self, @selector(finalize), (IMP)replacementFinalize);
    88         ASSERT(oldNSWindowFinalizeIMP);
    89 
    90         installedWindowThrottle = YES;
    91     }
    92 
    93     windowDisplayInfoDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    94     ASSERT(windowDisplayInfoDictionary);
    95 
    96     throttlingWindowDisplay = YES;
    97 }
    98 
    99 static void disableWindowDisplayThrottleApplierFunction(const void *key, const void *value, void *context)
    100 {
    101     WindowDisplayInfo *displayInfo = (WindowDisplayInfo *)value;
    102    
    103     // Display immediately
    104     [displayInfo->window _postWindowNeedsDisplay];
    105     cancelPendingWindowDisplay(displayInfo);
    106     free(displayInfo);
    107 }
    108 
    109 + (void)_webkit_displayThrottledWindows
    110 {
    111     if (!throttlingWindowDisplay)
    112         return;
    113 
    114     // Force all throttle timers to fire by running the runloop in WebKitDisplayThrottleRunLoopMode until there are
    115     // no more runloop timers/sources for that mode.
    116     while (CFRunLoopRunInMode((CFStringRef)WebKitDisplayThrottleRunLoopMode, 1.0 / DISPLAY_REFRESH_INTERVAL, true) == kCFRunLoopRunHandledSource) {}
    117 }
    118 
    119 + (void)_webkit_disableWindowDisplayThrottle
    120 {
    121     if (!throttlingWindowDisplay)
    122         return;
    123 
    124     // Clear throttlingWindowDisplay first so that the displays triggered by disableWindowDisplayThrottleApplierFunction()
    125     // go through the normal NSWindow display path
    126     throttlingWindowDisplay = NO;
    127    
    128     // Display any windows that have pending displays
    129     CFDictionaryApplyFunction(windowDisplayInfoDictionary, disableWindowDisplayThrottleApplierFunction, NULL);
    130    
    131     CFRelease(windowDisplayInfoDictionary);
    132     windowDisplayInfoDictionary = NULL;
    133 }
    13432
    13533- (void)centerOverMainWindow
     
    15351
    15452@end
    155 
    156 @implementation NSWindow (WebExtrasInternal)
    157 
    158 // Returns the old method implementation
    159 static IMP swizzleInstanceMethod(Class class, SEL selector, IMP newImplementation)
    160 {
    161     Method method = class_getInstanceMethod(class, selector);
    162     ASSERT(method);
    163     IMP oldIMP;
    164 #if defined(OBJC_API_VERSION) && OBJC_API_VERSION > 0
    165     oldIMP = method_setImplementation(method, newImplementation);
    166 #else
    167     oldIMP = method->method_imp;
    168     method->method_imp = newImplementation;
    169 #endif
    170     return oldIMP;
    171 }
    172 
    173 static void replacementPostWindowNeedsDisplay(id self, SEL cmd)
    174 {
    175     // Call the original NSWindow method implementation if window throttling is disabled, or the window
    176     // is currently being deallocated.
    177     if (!throttlingWindowDisplay || ((NSWindow *)self)->_wFlags.windowDying) {
    178         oldNSWindowPostWindowNeedsDisplayIMP(self, cmd);
    179         return;
    180     }
    181        
    182     // Do not call into -[NSWindow _postWindowNeedsDisplay] if requestWindowDisplay() returns NO.  In that case, requestWindowDisplay()
    183     // will schedule a timer to display at the appropriate time.
    184     if (requestWindowDisplay(self))
    185         oldNSWindowPostWindowNeedsDisplayIMP(self, cmd);
    186 }
    187 
    188 static void clearWindowDisplayInfo(id self)
    189 {
    190     ASSERT(throttlingWindowDisplay);
    191    
    192     // Remove WindowDisplayInfo for this window
    193     WindowDisplayInfo *displayInfo = (WindowDisplayInfo *)CFDictionaryGetValue(windowDisplayInfoDictionary, self);
    194     if (displayInfo) {
    195         cancelPendingWindowDisplay(displayInfo);
    196         free(displayInfo);
    197         CFDictionaryRemoveValue(windowDisplayInfoDictionary, self);
    198     }
    199 }
    200 
    201 static void replacementDealloc(id self, SEL cmd)
    202 {
    203     if (throttlingWindowDisplay)
    204         clearWindowDisplayInfo(self);
    205 
    206     oldNSWindowDeallocIMP(self, cmd);
    207 }
    208 
    209 static void replacementFinalize(id self, SEL cmd)
    210 {
    211     if (throttlingWindowDisplay)
    212         clearWindowDisplayInfo(self);
    213 
    214     oldNSWindowFinalizeIMP(self, cmd);
    215 }
    216 
    217 static WindowDisplayInfo *getWindowDisplayInfo(NSWindow *window)
    218 {
    219     ASSERT(throttlingWindowDisplay);
    220     ASSERT(windowDisplayInfoDictionary);
    221    
    222     // Get the WindowDisplayInfo for this window, or create it if it does not exist
    223     WindowDisplayInfo *displayInfo = (WindowDisplayInfo *)CFDictionaryGetValue(windowDisplayInfoDictionary, window);
    224     if (!displayInfo) {
    225         displayInfo = (WindowDisplayInfo *)malloc(sizeof(WindowDisplayInfo));
    226         displayInfo->window = window;
    227         displayInfo->lastDisplayTime = 0;
    228         displayInfo->displayTimer = nil;
    229         CFDictionarySetValue(windowDisplayInfoDictionary, window, displayInfo);
    230     }
    231    
    232     return displayInfo;
    233 }
    234 
    235 static BOOL requestWindowDisplay(NSWindow *window)
    236 {
    237     ASSERT(throttlingWindowDisplay);
    238 
    239     // Defer display if there is already a pending display
    240     WindowDisplayInfo *displayInfo = getWindowDisplayInfo(window);
    241     if (displayInfo->displayTimer)
    242         return NO;
    243        
    244     // Defer display if it hasn't been at least DISPLAY_REFRESH_INTERVAL seconds since the last display
    245     CFTimeInterval now = CFAbsoluteTimeGetCurrent();
    246     CFTimeInterval timeSinceLastDisplay = now - displayInfo->lastDisplayTime;
    247     if (timeSinceLastDisplay < DISPLAY_REFRESH_INTERVAL) {
    248         // Redisplay soon -- if we redisplay too quickly, we'll block due to pending CG coalesced updates
    249         displayInfo->displayTimer = [[NSTimer timerWithTimeInterval:(DISPLAY_REFRESH_INTERVAL - timeSinceLastDisplay)
    250                                                              target:window
    251                                                            selector:@selector(_webkit_doPendingPostWindowNeedsDisplay:)
    252                                                            userInfo:nil
    253                                                             repeats:NO] retain];
    254        
    255         // The NSWindow autodisplay mechanism is documented to only work for NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, and NSModalPanelRunLoopMode
    256         NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    257         [runLoop addTimer:displayInfo->displayTimer forMode:NSDefaultRunLoopMode];
    258         [runLoop addTimer:displayInfo->displayTimer forMode:NSEventTrackingRunLoopMode];
    259         [runLoop addTimer:displayInfo->displayTimer forMode:NSModalPanelRunLoopMode];
    260        
    261         // Schedule the timer in WebKitDisplayThrottleRunLoopMode so that +_webkit_displayThrottledWindows can
    262         // force all window throttle timers to fire by running in just that mode
    263         [runLoop addTimer:displayInfo->displayTimer forMode:WebKitDisplayThrottleRunLoopMode];
    264        
    265         return NO;
    266     }
    267 
    268     // Allow the display: there is no pending display, and it's been long enough to display again.
    269     displayInfo->lastDisplayTime = now;
    270     return YES;
    271 }
    272 
    273 static void cancelPendingWindowDisplay(WindowDisplayInfo *displayInfo)
    274 {
    275     if (!displayInfo->displayTimer)
    276         return;
    277 
    278     [displayInfo->displayTimer invalidate];
    279     [displayInfo->displayTimer release];
    280     displayInfo->displayTimer = nil;
    281 }
    282 
    283 - (void)_webkit_doPendingPostWindowNeedsDisplay:(NSTimer *)timer
    284 {
    285     WindowDisplayInfo *displayInfo = getWindowDisplayInfo(self);
    286     ASSERT(timer == displayInfo->displayTimer);
    287     ASSERT(throttlingWindowDisplay);
    288    
    289     // Clear displayInfo->displayTimer first because requestWindowDisplay() will not allow a display if the timer is non-nil.
    290     // However, we must wait to invalidate timer because it may have the last reference to this window.
    291     NSTimer *oldDisplayTimer = displayInfo->displayTimer;
    292     displayInfo->displayTimer = nil;
    293    
    294     // Don't call directly into oldNSWindowPostWindowNeedsDisplayIMP because we don't want to bypass subclass implementations
    295     // of -_postWindowNeedsDisplay
    296     [self _postWindowNeedsDisplay];
    297    
    298     // Finally, invalidate the firing display timer.
    299     [oldDisplayTimer invalidate];
    300     [oldDisplayTimer release];
    301 }
    302 
    303 @end
  • trunk/WebKit/WebView/WebFrameView.mm

    r18541 r18704  
    329329        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    330330       
    331         // Window display is throttled to 60 frames per second if WebKitThrottleWindowDisplayPreferenceKey
    332         // is set to YES.  The window display throttle is OFF by default for compatibility with Mac OS X
    333         // 10.4.6.
    334         if ([defaults boolForKey:WebKitThrottleWindowDisplayPreferenceKey])
    335             [NSWindow _webkit_enableWindowDisplayThrottle];
    336        
    337331        // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set
    338332        // to NO, or has no value.  For compatibility with Mac OS X 10.4.6, deferred updates are OFF by
  • trunk/WebKit/WebView/WebPreferenceKeysPrivate.h

    r17255 r18704  
    7171
    7272
    73 // Window display is throttled to 60 frames per second if WebKitThrottleWindowDisplayPreferenceKey
    74 // is set to YES.  The window display throttle is OFF by default for compatibility with Mac OS X
    75 // 10.4.6.
    76 #define WebKitThrottleWindowDisplayPreferenceKey @"WebKitThrottleWindowDisplay"
    77 
    7873// CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set
    7974// to NO, or has no value.  For compatibility with Mac OS X 10.4.6, deferred updates are OFF by
Note: See TracChangeset for help on using the changeset viewer.