Fix image decoding to separately decode image meta data from actual image bits. I
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Dec 2004 22:34:31 +0000 (22:34 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Dec 2004 22:34:31 +0000 (22:34 +0000)
incorrectly consolidated decode of meta data and image bits resulting in a huge
performance regression.

Double size of WebCore cache on lower end machines.  On the PLT run on machines with
256MB of memory, too many images were being evicted, causing a re-decode on the PLT.
Upping the lower limit of the cache size ensure that no images are evicted (this
goes hand-in-hand with the change to the minimum object size from 32K to 40K).

        Reviewed by Ken.

        * WebCoreSupport.subproj/WebImageData.h:
        * WebCoreSupport.subproj/WebImageData.m:
        (+[WebImageData initialize]):
        (-[WebImageData _commonTermination]):
        (-[WebImageData _invalidateImages]):
        (-[WebImageData _invalidateImageProperties]):
        (-[WebImageData imageAtIndex:]):
        (-[WebImageData propertiesAtIndex:]):
        (-[WebImageData _cacheImages:allImages:]):
        (-[WebImageData decodeData:isComplete:callback:]):
        (-[WebImageData incrementalLoadWithBytes:length:complete:callback:]):
        * WebView.subproj/WebPreferences.m:
        (+[WebPreferences initialize]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8257 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebImageData.h
WebKit/WebCoreSupport.subproj/WebImageData.m
WebKit/WebView.subproj/WebPreferences.m

index ccff928a19c788e6818a76abc3ee0df51481f420..53289bf2c6167481aed5e3e8e33c3b85bcd599eb 100644 (file)
@@ -1,3 +1,30 @@
+2004-12-20  Richard Williamson   <rjw@apple.com>
+
+       Fix image decoding to separately decode image meta data from actual image bits.  I
+       incorrectly consolidated decode of meta data and image bits resulting in a huge
+       performance regression.
+
+       Double size of WebCore cache on lower end machines.  On the PLT run on machines with
+       256MB of memory, too many images were being evicted, causing a re-decode on the PLT.
+       Upping the lower limit of the cache size ensure that no images are evicted (this
+       goes hand-in-hand with the change to the minimum object size from 32K to 40K).
+
+        Reviewed by Ken.
+
+        * WebCoreSupport.subproj/WebImageData.h:
+        * WebCoreSupport.subproj/WebImageData.m:
+        (+[WebImageData initialize]):
+        (-[WebImageData _commonTermination]):
+        (-[WebImageData _invalidateImages]):
+        (-[WebImageData _invalidateImageProperties]):
+        (-[WebImageData imageAtIndex:]):
+        (-[WebImageData propertiesAtIndex:]):
+        (-[WebImageData _cacheImages:allImages:]):
+        (-[WebImageData decodeData:isComplete:callback:]):
+        (-[WebImageData incrementalLoadWithBytes:length:complete:callback:]):
+        * WebView.subproj/WebPreferences.m:
+        (+[WebPreferences initialize]):
+
 2004-12-20  Richard Williamson   <rjw@apple.com>
 
        Fixed build problem caused by change to ImageIO API.
index 2e0508a323769e30f431898c555fe89be00e0cb5..6ce0b579f1818fb7b265ea03c558d1ef6596326c 100644 (file)
@@ -14,6 +14,7 @@
 {
     size_t imagesSize;
     CGImageRef *images;
+    size_t imagePropertiesSize;
     CFDictionaryRef *imageProperties;
     CGImageSourceRef imageSource;
 
@@ -34,8 +35,6 @@
     
     id _PDFDoc;
     BOOL isPDF;
-    
-    BOOL imageDataUpdated;
 }
 
 - (size_t)numberOfImages;
index ad8edbde8a44d71dc6ce867ad2e43f8afa0aaaef..b506fb82a5d937d5eec5aed5cac855f8f529b129 100644 (file)
@@ -30,6 +30,7 @@ static CFDictionaryRef imageSourceOptions;
 @interface WebImageData (WebInternal)
 - (void)_commonTermination;
 - (void)_invalidateImages;
+- (void)_invalidateImageProperties;
 - (int)_repetitionCount;
 - (float)_frameDuration;
 - (void)_stopAnimation;
@@ -38,7 +39,7 @@ static CFDictionaryRef imageSourceOptions;
 -(void)_createPDFWithData:(NSData *)data;
 - (CGPDFDocumentRef)_PDFDocumentRef;
 - (BOOL)_PDFDrawFromRect:(NSRect)srcRect toRect:(NSRect)dstRect operation:(CGCompositeOperation)op alpha:(float)alpha flipped:(BOOL)flipped context:(CGContextRef)context;
-- (void)_createImages;
+- (void)_cacheImages:(size_t)optionalIndex allImages:(BOOL)allImages;
 @end
 
 
@@ -46,7 +47,11 @@ static CFDictionaryRef imageSourceOptions;
 
 + (void)initialize
 {
-    [WebImageRendererFactory setShouldUseThreadedDecoding:(WebNumberOfCPUs() >= 2 ? YES : NO)];
+    // Currently threaded decoding doesn't play well with the WebCore cache.  Until
+    // those issues are resolved threaded decoding is OFF by default, even on dual CPU
+    // machines.
+    //[WebImageRendererFactory setShouldUseThreadedDecoding:(WebNumberOfCPUs() >= 2 ? YES : NO)];
+    [WebImageRendererFactory setShouldUseThreadedDecoding:NO];
 }
 
 - init
@@ -76,6 +81,7 @@ static CFDictionaryRef imageSourceOptions;
     ASSERT (!frameTimer);
     
     [self _invalidateImages];
+    [self _invalidateImageProperties];
         
     if (imageSource)
         CFRelease (imageSource); 
@@ -133,17 +139,24 @@ static CFDictionaryRef imageSourceOptions;
         for (i = 0; i < imagesSize; i++) {
             if (images[i])
                 CFRelease (images[i]);
-
-            if (imageProperties[i])
-                CFRelease (imageProperties[i]);
         }
         free (images);
         images = 0;
-        free (imageProperties);
-        imageProperties = 0;
     }
 }
 
+- (void)_invalidateImageProperties
+{
+    size_t i;
+    for (i = 0; i < imagePropertiesSize; i++) {
+       if (imageProperties[i])
+           CFRelease (imageProperties[i]);
+    }
+    free (imageProperties);
+    imageProperties = 0;
+    imagePropertiesSize = 0;
+}
+
 - (CFDictionaryRef)_imageSourceOptions
 {
     if (!imageSourceOptions) {
@@ -180,51 +193,73 @@ static CFDictionaryRef imageSourceOptions;
            
 - (CGImageRef)imageAtIndex:(size_t)index
 {
-    if (imageDataUpdated) {
-       imageDataUpdated = NO;
-       [self _createImages];
-    }
-
-    if (index >= imagesSize)
+    if (index >= [self numberOfImages])
         return 0;
 
+    if (!images || images[index] == 0){
+       [self _cacheImages:index allImages:NO];
+    }
+    
     return images[index];
 }
 
 - (CFDictionaryRef)propertiesAtIndex:(size_t)index
 {
-    if (imageDataUpdated) {
-       imageDataUpdated = NO;
-       [self _createImages];
+    size_t num = [self numberOfImages];
+    
+    // Number of images changed!
+    if (imagePropertiesSize && num > imagePropertiesSize) {
+        // Clear cache.
+       [self _invalidateImageProperties];
     }
-
-    if (index >= imagesSize)
-        return 0;
-
-    return imageProperties[index];
+    
+    if (imageProperties == 0 && num) {
+        imageProperties = (CFDictionaryRef *)malloc (num * sizeof(CFDictionaryRef));
+        size_t i;
+        for (i = 0; i < num; i++) {
+            imageProperties[i] = CGImageSourceGetPropertiesAtIndex (imageSource, i, 0);
+            if (imageProperties[i])
+                CFRetain (imageProperties[i]);
+        }
+        imagePropertiesSize = num;
+    }
+    
+    if (index < num) {
+        // If image properties are nil, try to get them again.  May have attempted to
+        // get them before enough data was available in the header.
+        if (imageProperties[index] == 0) {
+            imageProperties[index] = CGImageSourceGetPropertiesAtIndex (imageSource, index, 0);
+            if (imageProperties[index])
+                CFRetain (imageProperties[index]);
+        }
+        
+        return imageProperties[index];
+    }
+        
+    return 0;
 }
 
-- (void)_createImages
+- (void)_cacheImages:(size_t)optionalIndex allImages:(BOOL)allImages
 {
     size_t i;
 
-    [self _invalidateImages];
-    
     imagesSize = [self numberOfImages];
-    for (i = 0; i < imagesSize; i++) {
+    size_t from, to;
+    
+    if (allImages) {
+       from = 0;
+       to = imagesSize;
+    }
+    else {
+       from = optionalIndex;
+       to = optionalIndex+1;
+    }
+    for (i = from; i < to; i++) {
         if (!images) {
             images = (CGImageRef *)calloc (imagesSize, sizeof(CGImageRef *));
         }
-            
-        images[i] = CGImageSourceCreateImageAtIndex (imageSource, i, [self _imageSourceOptions]);
 
-        if (!imageProperties) {
-            imageProperties = (CFDictionaryRef *)malloc (imagesSize * sizeof(CFDictionaryRef));
-        }
-        
-        imageProperties[i] = CGImageSourceGetPropertiesAtIndex (imageSource, i, 0);
-        if (imageProperties[i])
-            CFRetain (imageProperties[i]);
+        images[i] = CGImageSourceCreateImageAtIndex (imageSource, i, [self _imageSourceOptions]);
     }
 }
 
@@ -241,7 +276,8 @@ static CFDictionaryRef imageSourceOptions;
     else {
         // The work of decoding is actually triggered by image creation.
         CGImageSourceUpdateData (imageSource, data, isComplete);
-        [self _createImages];
+       [self _invalidateImages];
+        [self _cacheImages:0 allImages:YES];
     }
         
     [decodeLock unlock];
@@ -289,8 +325,8 @@ static CFDictionaryRef imageSourceOptions;
             }
         }
         else {
+           [self _invalidateImages];
             CGImageSourceUpdateData (imageSource, data, isComplete);
-           imageDataUpdated = YES;
         }
     }
     
index 752c8440dc8645085425f35f30010ec2ded5a79c..783f3ce6d0e9454ada8213269a0092bfee54063e 100644 (file)
@@ -185,7 +185,7 @@ NS_ENDHANDLER
         @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
         @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
         @"4",                           WebKitPageCacheSizePreferenceKey,
-        @"4194304",                     WebKitObjectCacheSizePreferenceKey,
+        @"8388608",                     WebKitObjectCacheSizePreferenceKey,
         [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
         @"",                            WebKitUserStyleSheetLocationPreferenceKey,
         [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,