Changeset 18704 in webkit
- Timestamp:
- Jan 9, 2007, 5:50:25 AM (19 years ago)
- Location:
- trunk/WebKit
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKit/ChangeLog
r18694 r18704 1 2007-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 1 13 2007-01-08 Anders Carlsson <acarlsson@apple.com> 2 14 -
trunk/WebKit/Misc/WebNSWindowExtras.h
r14379 r18704 30 30 31 31 @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 display34 // too often, which can cause performance problems with CoreGraphics' coalesced updates35 // 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 displayed39 // 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 are43 // no more runloop timers/sources for that mode.44 + (void)_webkit_displayThrottledWindows;45 46 32 // centers "visually", putting 1/3 of the remaining space above, and 2/3 below 47 33 - (void)centerOverMainWindow; -
trunk/WebKit/Misc/WebNSWindowExtras.m
r15781 r18704 29 29 #import "WebNSWindowExtras.h" 30 30 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 @end61 62 @interface NSWindow (AppKitSecretsIKnow)63 - (void)_postWindowNeedsDisplay;64 @end65 66 31 @implementation NSWindow (WebExtras) 67 68 + (void)_webkit_enableWindowDisplayThrottle69 {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 immediately104 [displayInfo->window _postWindowNeedsDisplay];105 cancelPendingWindowDisplay(displayInfo);106 free(displayInfo);107 }108 109 + (void)_webkit_displayThrottledWindows110 {111 if (!throttlingWindowDisplay)112 return;113 114 // Force all throttle timers to fire by running the runloop in WebKitDisplayThrottleRunLoopMode until there are115 // 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_disableWindowDisplayThrottle120 {121 if (!throttlingWindowDisplay)122 return;123 124 // Clear throttlingWindowDisplay first so that the displays triggered by disableWindowDisplayThrottleApplierFunction()125 // go through the normal NSWindow display path126 throttlingWindowDisplay = NO;127 128 // Display any windows that have pending displays129 CFDictionaryApplyFunction(windowDisplayInfoDictionary, disableWindowDisplayThrottleApplierFunction, NULL);130 131 CFRelease(windowDisplayInfoDictionary);132 windowDisplayInfoDictionary = NULL;133 }134 32 135 33 - (void)centerOverMainWindow … … 153 51 154 52 @end 155 156 @implementation NSWindow (WebExtrasInternal)157 158 // Returns the old method implementation159 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 > 0165 oldIMP = method_setImplementation(method, newImplementation);166 #else167 oldIMP = method->method_imp;168 method->method_imp = newImplementation;169 #endif170 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 window176 // 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 window193 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 exist223 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 display240 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 display245 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 updates249 displayInfo->displayTimer = [[NSTimer timerWithTimeInterval:(DISPLAY_REFRESH_INTERVAL - timeSinceLastDisplay)250 target:window251 selector:@selector(_webkit_doPendingPostWindowNeedsDisplay:)252 userInfo:nil253 repeats:NO] retain];254 255 // The NSWindow autodisplay mechanism is documented to only work for NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, and NSModalPanelRunLoopMode256 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 can262 // force all window throttle timers to fire by running in just that mode263 [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 *)timer284 {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 implementations295 // of -_postWindowNeedsDisplay296 [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 329 329 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 330 330 331 // Window display is throttled to 60 frames per second if WebKitThrottleWindowDisplayPreferenceKey332 // is set to YES. The window display throttle is OFF by default for compatibility with Mac OS X333 // 10.4.6.334 if ([defaults boolForKey:WebKitThrottleWindowDisplayPreferenceKey])335 [NSWindow _webkit_enableWindowDisplayThrottle];336 337 331 // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set 338 332 // 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 71 71 72 72 73 // Window display is throttled to 60 frames per second if WebKitThrottleWindowDisplayPreferenceKey74 // is set to YES. The window display throttle is OFF by default for compatibility with Mac OS X75 // 10.4.6.76 #define WebKitThrottleWindowDisplayPreferenceKey @"WebKitThrottleWindowDisplay"77 78 73 // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set 79 74 // 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.