Ask CG to not parse image metadata
authorpsolanki@apple.com <psolanki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2011 23:24:59 +0000 (23:24 +0000)
committerpsolanki@apple.com <psolanki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2011 23:24:59 +0000 (23:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71029

Reviewed by Simon Fraser.

We don't need CG to parse the image metadata since WebCore never uses it. Passing this
option shaves off time spent under CGImageSourceCopyPropertiesAtIndex. Under Instruments I
saw the time drop from ~75ms to ~25ms when loading http://boston.com/bigpicture and the
first link on that page.

No new tests because no change in functionality.

* platform/graphics/ImageSource.h:
* platform/graphics/cg/ImageSourceCG.cpp:
(WebCore::imageSourceOptions):
(WebCore::ImageSource::isSizeAvailable):
(WebCore::ImageSource::frameSizeAtIndex):
(WebCore::ImageSource::getHotSpot):
(WebCore::ImageSource::repetitionCount):
(WebCore::ImageSource::createFrameAtIndex):
(WebCore::ImageSource::frameDurationAtIndex):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ImageSource.h
Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp

index 1914b11..9dc0c91 100755 (executable)
@@ -1,3 +1,27 @@
+2011-10-27  Pratik Solanki  <psolanki@apple.com>
+
+        Ask CG to not parse image metadata
+        https://bugs.webkit.org/show_bug.cgi?id=71029
+
+        Reviewed by Simon Fraser.
+
+        We don't need CG to parse the image metadata since WebCore never uses it. Passing this
+        option shaves off time spent under CGImageSourceCopyPropertiesAtIndex. Under Instruments I
+        saw the time drop from ~75ms to ~25ms when loading http://boston.com/bigpicture and the
+        first link on that page.
+
+        No new tests because no change in functionality.
+
+        * platform/graphics/ImageSource.h:
+        * platform/graphics/cg/ImageSourceCG.cpp:
+        (WebCore::imageSourceOptions):
+        (WebCore::ImageSource::isSizeAvailable):
+        (WebCore::ImageSource::frameSizeAtIndex):
+        (WebCore::ImageSource::getHotSpot):
+        (WebCore::ImageSource::repetitionCount):
+        (WebCore::ImageSource::createFrameAtIndex):
+        (WebCore::ImageSource::frameDurationAtIndex):
+
 2011-10-27  David Grogan  <dgrogan@chromium.org>
 
         Move eventqueue from Document to ScriptExecutionContext so that it can be accessed from workers
index dcc6755..7ce7e08 100644 (file)
@@ -126,6 +126,13 @@ public:
         GammaAndColorProfileIgnored
     };
 
+#if USE(CG)
+    enum ShouldSkipMetaData {
+        DoNotSkipMetaData,
+        SkipMetaData
+    };
+#endif
+
     ImageSource(AlphaOption alphaOption = AlphaPremultiplied, GammaAndColorProfileOption gammaAndColorProfileOption = GammaAndColorProfileApplied);
     ~ImageSource();
 
index f0776e4..1009843 100644 (file)
@@ -41,6 +41,7 @@ using namespace std;
 namespace WebCore {
 
 const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
+const CFStringRef kCGImageSourceSkipMetaData = CFSTR("kCGImageSourceSkipMetaData");
 
 // kCGImagePropertyGIFUnclampedDelayTime is available in the ImageIO framework headers on some versions
 // of SnowLeopard. It's not possible to detect whether the constant is available so we define our own here
@@ -107,14 +108,15 @@ void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool
         setData(data, allDataReceived);
 }
 
-static CFDictionaryRef imageSourceOptions()
+static CFDictionaryRef imageSourceOptions(ImageSource::ShouldSkipMetaData skipMetaData)
 {
     static CFDictionaryRef options;
 
     if (!options) {
-        const unsigned numOptions = 2;
-        const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32 };
-        const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue };
+        const unsigned numOptions = 3;
+        const CFBooleanRef imageSourceSkipMetaData = (skipMetaData == ImageSource::SkipMetaData) ? kCFBooleanTrue : kCFBooleanFalse;
+        const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetaData };
+        const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetaData };
         options = CFDictionaryCreate(NULL, keys, values, numOptions, 
             &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     }
@@ -172,7 +174,7 @@ bool ImageSource::isSizeAvailable()
 
     // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!
     if (imageSourceStatus >= kCGImageStatusIncomplete) {
-        RetainPtr<CFDictionaryRef> image0Properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
+        RetainPtr<CFDictionaryRef> image0Properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetaData)));
         if (image0Properties) {
             CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelWidth);
             CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelHeight);
@@ -186,7 +188,7 @@ bool ImageSource::isSizeAvailable()
 IntSize ImageSource::frameSizeAtIndex(size_t index) const
 {
     IntSize result;
-    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()));
+    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetaData)));
     if (properties) {
         int w = 0, h = 0;
         CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
@@ -207,7 +209,7 @@ IntSize ImageSource::size() const
 
 bool ImageSource::getHotSpot(IntPoint& hotSpot) const
 {
-    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
+    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetaData)));
     if (!properties)
         return false;
 
@@ -244,7 +246,7 @@ int ImageSource::repetitionCount()
     if (!initialized())
         return result;
 
-    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyProperties(m_decoder, imageSourceOptions()));
+    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyProperties(m_decoder, imageSourceOptions(SkipMetaData)));
     if (properties) {
         CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
         if (gifProperties) {
@@ -272,7 +274,7 @@ CGImageRef ImageSource::createFrameAtIndex(size_t index)
     if (!initialized())
         return 0;
 
-    RetainPtr<CGImageRef> image(AdoptCF, CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions()));
+    RetainPtr<CGImageRef> image(AdoptCF, CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(SkipMetaData)));
     CFStringRef imageUTI = CGImageSourceGetType(m_decoder);
     static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");
     if (!imageUTI || !CFEqual(imageUTI, xbmUTI))
@@ -313,7 +315,7 @@ float ImageSource::frameDurationAtIndex(size_t index)
         return 0;
 
     float duration = 0;
-    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()));
+    RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetaData)));
     if (properties) {
         CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
         if (typeProperties) {