Bug 103796 - [chromium] ImageDecodingStore should cache partially decoded images
Summary: [chromium] ImageDecodingStore should cache partially decoded images
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Images (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Hin-Chung Lam
URL:
Keywords:
: 104311 (view as bug list)
Depends on:
Blocks: 99790
  Show dependency treegraph
 
Reported: 2012-11-30 18:14 PST by Hin-Chung Lam
Modified: 2012-12-10 22:16 PST (History)
11 users (show)

See Also:


Attachments
Patch (42.92 KB, patch)
2012-12-05 00:05 PST, Hin-Chung Lam
no flags Details | Formatted Diff | Diff
Patch (43.63 KB, patch)
2012-12-07 15:27 PST, Hin-Chung Lam
no flags Details | Formatted Diff | Diff
Patch for landing (43.63 KB, patch)
2012-12-07 18:14 PST, Hin-Chung Lam
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Hin-Chung Lam 2012-11-30 18:14:07 PST
Current implementation does not cache partially decoded images. The result is that when an image is partially decoded, the bitmap and corresponding ImageDecoder is deleted. The means any subsequent decoding will have to start from scratch.

Redoing image decoding many times is very expensive and should be avoided. The solution to this is to cache partially decoded bitmap together with the ImageDecoder.
Comment 1 Hin-Chung Lam 2012-12-05 00:05:00 PST
Created attachment 177684 [details]
Patch
Comment 2 Hin-Chung Lam 2012-12-05 00:12:11 PST
Comment on attachment 177684 [details]
Patch

The seems big but if you focus on ImageDecodingStore and ImageFrameGenerator the others are just test and changes to mock modules.

ImageDecodingStore

Added logic to handle incomplete cache entries.

ImageFrameGenerator

Added logic to resume decoding using a cached decoder. The change has some code move involved to share code with decoding starting from scratch.
Comment 3 Hin-Chung Lam 2012-12-05 14:29:18 PST
Woohoo! Tested this with Chrome and it works with large JPEG files too, which means this incomplete image caching is working.
Comment 4 Hin-Chung Lam 2012-12-07 11:38:34 PST
nduca, senorblanco: have time to have a look? As we have discussed we'll change the resampling algorithm later so it's now in it's own function and easy to swap out.
Comment 5 Stephen White 2012-12-07 12:14:32 PST
Comment on attachment 177684 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=177684&action=review

Please fix the anonymous bool.  The rest are nits and suggestions, which you can heed or ignore at your whim.

> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:80
> +bool ImageDecodingStore::lockCache(const ImageFrameGenerator* generator, const SkISize& scaledSize, bool cacheMustBeComplete, const ScaledImageFragment** cachedImage, ImageDecoder** decoder)

For cacheMustBeComplete:  "Prefer enums to bools on function parameters if callers are likely to be passing constants, since named constants are easier to read at the call site."

> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:82
>      CacheEntry* cacheEntry = 0;

Maybe ASSERT(cachedImage) here?  Seems to be non-optional outparam.  (I'd actually keep it as the actual return value, since only decoder seems to be optional, but that's just personal style.)

> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:103
> +    if (decoder)
> +        *decoder = cacheEntry->cachedDecoder();

(Suggestion)  Would it make sense to have this function return a cacheEntry instead, so the caller could just get the decoder from it?  Or would that expose too much implementation to the caller?

> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:152
> +    OwnPtr<ImageDecoder> trash;

Does this really need to live to end of function scope?  (I'm guessing yes, just making sure.)

> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:168
> +        cacheEntry->overwriteCachedImage(newImage);
> +        newCachedImage = cacheEntry->cachedImage();
> +
> +        // Image is complete then decoder is not needed.
> +        if (cacheEntry->cachedImage()->isComplete())
> +            trash = cacheEntry->releaseCachedDecoder();

(Suggestion) It seems like the only place you releaseCachedDecoder() is right after calling overwriteCachedImage().  If that's always going to be true, perhaps you should just have overwriteCachedImage() release the decoder itself if isComplete() is true?
Comment 6 Hin-Chung Lam 2012-12-07 15:27:13 PST
Created attachment 178292 [details]
Patch
Comment 7 Hin-Chung Lam 2012-12-07 15:27:19 PST
Comment on attachment 177684 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=177684&action=review

>> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:80
>> +bool ImageDecodingStore::lockCache(const ImageFrameGenerator* generator, const SkISize& scaledSize, bool cacheMustBeComplete, const ScaledImageFragment** cachedImage, ImageDecoder** decoder)
> 
> For cacheMustBeComplete:  "Prefer enums to bools on function parameters if callers are likely to be passing constants, since named constants are easier to read at the call site."

Okay.

>> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:82
>>      CacheEntry* cacheEntry = 0;
> 
> Maybe ASSERT(cachedImage) here?  Seems to be non-optional outparam.  (I'd actually keep it as the actual return value, since only decoder seems to be optional, but that's just personal style.)

Done.

>> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:103
>> +        *decoder = cacheEntry->cachedDecoder();
> 
> (Suggestion)  Would it make sense to have this function return a cacheEntry instead, so the caller could just get the decoder from it?  Or would that expose too much implementation to the caller?

I want to keep CacheEntry internal to ImageDecodingStore.

>> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:152
>> +    OwnPtr<ImageDecoder> trash;
> 
> Does this really need to live to end of function scope?  (I'm guessing yes, just making sure.)

Yes so that deleting the object doesn't live inside the lock.

>> Source/WebCore/platform/graphics/chromium/ImageDecodingStore.cpp:168
>> +            trash = cacheEntry->releaseCachedDecoder();
> 
> (Suggestion) It seems like the only place you releaseCachedDecoder() is right after calling overwriteCachedImage().  If that's always going to be true, perhaps you should just have overwriteCachedImage() release the decoder itself if isComplete() is true?

Good idea, will do.
Comment 8 Stephen White 2012-12-07 16:36:31 PST
Comment on attachment 178292 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=178292&action=review

OK.  The logic still seems a bit complex, but perhaps that can be cleaned up later.  r=me

> Source/WebCore/platform/graphics/chromium/ImageFrameGenerator.cpp:191
> +            *decoder = m_imageDecoderFactory->create().leakPtr();

I wonder if this function (and others) should take an OwnPtr<ImageDecoder>* instead?  Then you wouldn't have to call leakPtr() here.
Comment 9 Hin-Chung Lam 2012-12-07 18:13:21 PST
(In reply to comment #8)
> (From update of attachment 178292 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=178292&action=review
> 
> OK.  The logic still seems a bit complex, but perhaps that can be cleaned up later.  r=me
> 
> > Source/WebCore/platform/graphics/chromium/ImageFrameGenerator.cpp:191
> > +            *decoder = m_imageDecoderFactory->create().leakPtr();
> 

ImageDecodingStore is pretty close to complete and concise. There will be some more work in ImageFrameGenerator later.

> I wonder if this function (and others) should take an OwnPtr<ImageDecoder>* instead?  Then you wouldn't have to call leakPtr() here.

One caller doesn't transfer ownership hence it's a ** parameter.
Comment 10 Hin-Chung Lam 2012-12-07 18:14:31 PST
Created attachment 178317 [details]
Patch for landing
Comment 11 WebKit Review Bot 2012-12-07 19:01:15 PST
Comment on attachment 178317 [details]
Patch for landing

Clearing flags on attachment: 178317

Committed r137008: <http://trac.webkit.org/changeset/137008>
Comment 12 WebKit Review Bot 2012-12-07 19:01:20 PST
All reviewed patches have been landed.  Closing bug.
Comment 13 Min Qin 2012-12-10 22:16:33 PST
*** Bug 104311 has been marked as a duplicate of this bug. ***