Bug 54133 - [chromium] Replace tiler data structure with something smarter
Summary: [chromium] Replace tiler data structure with something smarter
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Adrienne Walker
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-09 12:19 PST by Adrienne Walker
Modified: 2011-03-10 14:47 PST (History)
5 users (show)

See Also:


Attachments
Patch (27.63 KB, patch)
2011-02-22 15:51 PST, Adrienne Walker
no flags Details | Formatted Diff | Diff
Patch (18.19 KB, patch)
2011-03-10 13:11 PST, Adrienne Walker
kbr: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adrienne Walker 2011-02-09 12:19:14 PST
Currently, Chromium's tiled compositor uses a logical 2D array to hold all the tiles in a page, where their position is implicit based on their location in the array.  If the page size is large, this is inefficient.  At extremely large page sizes, this becomes impossible due to integer arithmetic overflow.

This needs to be changed to something that uses less memory and is more efficient when resizing.  Even just storing position explicitly and having a flat list of "visible" tiles might be just as reasonable.
Comment 1 Adrienne Walker 2011-02-22 15:51:08 PST
Created attachment 83403 [details]
Patch
Comment 2 Kenneth Russell 2011-02-23 11:44:48 PST
Comment on attachment 83403 [details]
Patch

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

Looks good overall. A couple of minor comments/questions and one small must-fix bug.

> Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:206
>      for (size_t i = 0; i < m_tiles.size(); ++i) {
> -        if (m_tiles[i])
> -            m_unusedTiles.append(m_tiles[i].release());
> +        m_unusedTiles.append(m_tiles[i].release());
>      }

No braces for one-line bodies.

> Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:223
> +    // To avoid an O(n^2) check for tile existence via tileAt, keep a flag
> +    // vector indexed by tile location marking all the tiles we've seen already.

Wouldn't it be better to just bite the bullet and use a HashMap whose keys are the (i,j) pairs of ints and whose values are Tile*'s?

> Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:497
> +    m_tiler->m_tiles[m_idx].release();

This leaks memory! You probably meant to call clear(), but you shouldn't need to do this at all -- the resize() call after the swap() should take care of destroying the last OwnPtr<Tile> and therefore its referent.
Comment 3 Adrienne Walker 2011-02-23 11:52:58 PST
(In reply to comment #2)
> (From update of attachment 83403 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=83403&action=review
> 
> Looks good overall. A couple of minor comments/questions and one small must-fix bug.
> 
> > Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:206
> >      for (size_t i = 0; i < m_tiles.size(); ++i) {
> > -        if (m_tiles[i])
> > -            m_unusedTiles.append(m_tiles[i].release());
> > +        m_unusedTiles.append(m_tiles[i].release());
> >      }
> 
> No braces for one-line bodies.

Oh, quite right.  I'm sad that check-webkit-style didn't yell at me first.

> > Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:223
> > +    // To avoid an O(n^2) check for tile existence via tileAt, keep a flag
> > +    // vector indexed by tile location marking all the tiles we've seen already.
> 
> Wouldn't it be better to just bite the bullet and use a HashMap whose keys are the (i,j) pairs of ints and whose values are Tile*'s?

That's a good suggestion.  It'd probably clean up this code quite a bit, so I'll look into that.

> > Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp:497
> > +    m_tiler->m_tiles[m_idx].release();
> 
> This leaks memory! You probably meant to call clear(), but you shouldn't need to do this at all -- the resize() call after the swap() should take care of destroying the last OwnPtr<Tile> and therefore its referent.

Ack! You're quite right.  Thanks for catching that.
Comment 4 Adrienne Walker 2011-02-24 09:53:19 PST
Re: HashMap.  It's definitely the right data structure to use and the code is a lot cleaner for it.  However, as it turns out, HashMap is incompatible with OwnPtr as a value type (because there's no copy constructor on an OwnPtr).

The easiest, but most terrible solution is to leak/adopt the memory manually in LayerTilerChromium when adding and removing from the HashMap, but it subverts the whole reason for using OwnPtr in the first place.

A better approach might be creating an OwnPtrHashMap.  abarth proposed this last year, but it didn't materialize.  I think it also might be possible to add some additional template parameters to HashMap to allow for the storing of raw pointers in the underlying implementation but use PassOwnPtr at the HashMap API boundary to ensure that no memory leaks.

This looks like a not terribly small yak to shave, so I will likely punt on this patch temporarily.
Comment 5 Kenneth Russell 2011-02-24 09:56:08 PST
(In reply to comment #4)
> Re: HashMap.  It's definitely the right data structure to use and the code is a lot cleaner for it.  However, as it turns out, HashMap is incompatible with OwnPtr as a value type (because there's no copy constructor on an OwnPtr).
> 
> The easiest, but most terrible solution is to leak/adopt the memory manually in LayerTilerChromium when adding and removing from the HashMap, but it subverts the whole reason for using OwnPtr in the first place.
> 
> A better approach might be creating an OwnPtrHashMap.  abarth proposed this last year, but it didn't materialize.  I think it also might be possible to add some additional template parameters to HashMap to allow for the storing of raw pointers in the underlying implementation but use PassOwnPtr at the HashMap API boundary to ensure that no memory leaks.
> 
> This looks like a not terribly small yak to shave, so I will likely punt on this patch temporarily.

I assume you mean you'll go ahead with using a list and then potentially upgrade to a hash map in the future? I don't mean to derail this patch.
Comment 6 Adrienne Walker 2011-03-10 13:11:58 PST
Created attachment 85383 [details]
Patch
Comment 7 Kenneth Russell 2011-03-10 14:03:33 PST
Comment on attachment 85383 [details]
Patch

This looks much better. Thanks for cleaning it up and researching how best to use a map for the tiles.
Comment 8 Adrienne Walker 2011-03-10 14:47:50 PST
Committed r80767: <http://trac.webkit.org/changeset/80767>