Bug 66488 - [chromium] Leaking SkBitmaps for background images
Summary: [chromium] Leaking SkBitmaps for background images
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: John Bates
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-18 11:16 PDT by Tony Gentilcore
Modified: 2011-08-26 05:43 PDT (History)
12 users (show)

See Also:


Attachments
Patch (22.79 KB, patch)
2011-08-24 15:22 PDT, John Bates
no flags Details | Formatted Diff | Diff
Patch (24.22 KB, patch)
2011-08-24 17:10 PDT, John Bates
no flags Details | Formatted Diff | Diff
Patch (24.26 KB, patch)
2011-08-24 18:46 PDT, John Bates
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tony Gentilcore 2011-08-18 11:16:45 PDT
It appears that images used as background images will never be collected for the lifetime of a renderer.

One problem is that NativeImageSkia is a SkBitmap, but SkBitmap's dtor isn't virtual. So we leak fields like the m_resizedImage SkBitmap.

However, just making SkBitmaps dtor virtual doesn't seem to fix the problem. There is something else going on w/ the assignment operator or copy constructors that I am still trying to figure out. Any other set of eyes on this would be appreciated.
Comment 1 John Bates 2011-08-18 11:30:28 PDT
Hey Tony,

Just FYI, I have a CL in flight that touches this code.
https://bugs.webkit.org/show_bug.cgi?id=65587

From what I know about Skia's object model, deriving from their classes is going to be problematic in many ways. Ie: memset(this, 0, sizeof(*this)) and assignment is memcpy(... sizeof(*this)). Since sizeof(*this) can include bits of the derived members, it's failtastic.

I think we need to find out who creates and destroys the NativeImageSkia objects and refactor that code so that NativeImageSkia has a SkBitmap member instead of deriving from it.
Comment 2 Tony Gentilcore 2011-08-18 12:03:34 PDT
> I think we need to find out who creates and destroys the NativeImageSkia objects and refactor that code so that NativeImageSkia has a SkBitmap member instead of deriving from it.

Hi John,

Yeah, that seems like the right approach. Since this ends up being a pretty noticeable leak, I was hoping there would be an easier way to patch this, but it looks like an involved refactor instead.

Since you are pretty familiar with this area, do you want to pick this up?

-Tony
Comment 3 John Bates 2011-08-19 14:35:10 PDT
(In reply to comment #2)
> > I think we need to find out who creates and destroys the NativeImageSkia objects and refactor that code so that NativeImageSkia has a SkBitmap member instead of deriving from it.
> 
> Hi John,
> 
> Yeah, that seems like the right approach. Since this ends up being a pretty noticeable leak, I was hoping there would be an easier way to patch this, but it looks like an involved refactor instead.
> 
> Since you are pretty familiar with this area, do you want to pick this up?

No problem, I'll look into it once I get my other patch landed. Did you gather any more clues about where the leak was occurring?

> 
> -Tony
Comment 4 John Bates 2011-08-24 15:13:39 PDT
SkBitmap can't have virtuals unless it's refactored to not do the memcpy(sizeof) tricks, since that clobbers the vtable. The symptoms I saw were things like crashes in the NativeImageSkia destructor (because it probably was a copy, and should have been a plain SkBitmap vtable).

Patch coming shortly to make SkBitmap a member...
Comment 5 John Bates 2011-08-24 15:22:31 PDT
Created attachment 105081 [details]
Patch
Comment 6 WebKit Review Bot 2011-08-24 16:03:27 PDT
Comment on attachment 105081 [details]
Patch

Attachment 105081 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/9509030
Comment 7 John Bates 2011-08-24 17:10:31 PDT
Created attachment 105099 [details]
Patch
Comment 8 Stephen White 2011-08-24 18:16:06 PDT
Comment on attachment 105099 [details]
Patch

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

Looks good.  r=me

> Source/WebCore/platform/graphics/skia/NativeImageSkia.h:67
> +    SkBitmap& bitmap() { return m_image; }

I'm not a fan of returning a non-const reference (although that's not webkit coding style or anything, just personal preference).  Out of curiosity, how many call sites break with only the const ref variant available?

> Source/WebCore/platform/graphics/skia/PatternSkia.cpp:62
> +    const NativeImageSkia* bm = m_tileImage->nativeImageForCurrentFrame();

Nit:  Might make sense to rename "bm" to "image" now that it's a NativeImageSkia and not a bitmap.
Comment 9 John Bates 2011-08-24 18:45:03 PDT
Comment on attachment 105099 [details]
Patch

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

New patch next...

>> Source/WebCore/platform/graphics/skia/NativeImageSkia.h:67
>> +    SkBitmap& bitmap() { return m_image; }
> 
> I'm not a fan of returning a non-const reference (although that's not webkit coding style or anything, just personal preference).  Out of curiosity, how many call sites break with only the const ref variant available?

There are a few calls in ImageDecoderSkia.cpp (reset, copyTo, setConfig, allocPixels, setIsOpaque). The non-const ref is just trying to mimic the original is-a behavior. I can't say I'm a fan either. It's just that the alternative of wrapping all the used SkBitmap methods seems too difficult to maintain.

>> Source/WebCore/platform/graphics/skia/PatternSkia.cpp:62
>> +    const NativeImageSkia* bm = m_tileImage->nativeImageForCurrentFrame();
> 
> Nit:  Might make sense to rename "bm" to "image" now that it's a NativeImageSkia and not a bitmap.

Done.
Comment 10 John Bates 2011-08-24 18:46:41 PDT
Created attachment 105116 [details]
Patch
Comment 11 Mike Reed 2011-08-25 06:28:22 PDT
works for me
Comment 12 Stephen White 2011-08-25 08:24:31 PDT
Comment on attachment 105099 [details]
Patch

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

>>> Source/WebCore/platform/graphics/skia/NativeImageSkia.h:67
>>> +    SkBitmap& bitmap() { return m_image; }
>> 
>> I'm not a fan of returning a non-const reference (although that's not webkit coding style or anything, just personal preference).  Out of curiosity, how many call sites break with only the const ref variant available?
> 
> There are a few calls in ImageDecoderSkia.cpp (reset, copyTo, setConfig, allocPixels, setIsOpaque). The non-const ref is just trying to mimic the original is-a behavior. I can't say I'm a fan either. It's just that the alternative of wrapping all the used SkBitmap methods seems too difficult to maintain.

One option would be to return a non-const pointer instead of ref.  That makes it marginally clearer that it may be modified.
Comment 13 Stephen White 2011-08-25 08:25:06 PDT
Comment on attachment 105116 [details]
Patch

Looks good.  r=me
Comment 14 WebKit Review Bot 2011-08-25 09:42:30 PDT
Comment on attachment 105116 [details]
Patch

Clearing flags on attachment: 105116

Committed r93792: <http://trac.webkit.org/changeset/93792>
Comment 15 WebKit Review Bot 2011-08-25 09:42:35 PDT
All reviewed patches have been landed.  Closing bug.
Comment 16 John Bates 2011-08-25 16:19:19 PDT
> One option would be to return a non-const pointer instead of ref.  That makes it marginally clearer that it may be modified.

I was thinking that would send the message that you can hold on to the pointer. With a reference, you'd usually have to deliberately deref into a pointer if you wanted to hold onto it.