WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
47016
[chromium] GPU compositor cannot handle large layers
https://bugs.webkit.org/show_bug.cgi?id=47016
Summary
[chromium] GPU compositor cannot handle large layers
Adrienne Walker
Reported
2010-10-01 13:59:05 PDT
This corresponds to
http://code.google.com/p/chromium/issues/detail?id=48019
. From the original bug: "There's a limit to the maxium texture size that GPUs can handle and therefore there's currently a hard limit to how large layers can be (it's set to 4Kx4K). A proper solution would be to implement tiled layers to be more friendly with vram usage."
Attachments
Patch
(10.20 KB, patch)
2010-10-01 14:07 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(23.03 KB, patch)
2010-10-05 16:42 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(20.74 KB, patch)
2010-10-06 10:48 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(20.88 KB, patch)
2010-10-07 09:33 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(17.19 KB, patch)
2010-10-07 16:54 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(16.84 KB, patch)
2010-10-07 21:57 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(16.69 KB, patch)
2010-10-10 09:56 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(16.58 KB, patch)
2010-10-12 09:19 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(16.72 KB, patch)
2010-10-13 15:04 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Patch
(17.75 KB, patch)
2010-10-13 17:16 PDT
,
Adrienne Walker
no flags
Details
Formatted Diff
Diff
Show Obsolete
(9)
View All
Add attachment
proposed patch, testcase, etc.
Adrienne Walker
Comment 1
2010-10-01 14:07:16 PDT
Created
attachment 69516
[details]
Patch
Vangelis Kokkevis
Comment 2
2010-10-01 15:46:50 PDT
Comment on
attachment 69516
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=69516&action=review
Looks good, other than the couple of comments.
> WebCore/ChangeLog:9 > + large are not drawn, as before.
nit but for clarity you might want to make the distinction between layers that are transformed in 3D and those that appear flat on the page (instead of 2D and 3D layers).
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:183 > + m_skipsDraw = true;
4 space indent
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:190 > + const IntSize layerPos(position().x() - m_bounds.width() / 2,
position() is not necessarily the center point of the layer as other matrices get layered on on it. The center of the layer is always the translation component of the drawTransform()
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:200 > + m_largeLayerDrawRect = drawRect;
It took me a bit of time to decipher the transformation logic here. Adding some inline comments describing what each rect and pos really is and in which space, would really help a lot.
Vangelis Kokkevis
Comment 3
2010-10-01 16:19:13 PDT
I also wonder whether we can split some of this code into its own function so that we can use it for large images which end up in an ImageLayerChromium (a derived class).
Adrienne Walker
Comment 4
2010-10-01 16:32:28 PDT
(In reply to
comment #3
)
> I also wonder whether we can split some of this code into its own function so that we can use it for large images which end up in an ImageLayerChromium (a derived class).
That's reasonable. I will just go ahead and update ImageLayerChromium with this same change while I'm at it.
Adrienne Walker
Comment 5
2010-10-05 16:42:48 PDT
Created
attachment 69865
[details]
Patch
Adrienne Walker
Comment 6
2010-10-05 16:46:59 PDT
(In reply to
comment #5
)
> Created an attachment (id=69865) [details] > Patch
Addressed the above feedback. Abstracted the transform logic into its own function. Updated ImageLayerChromium to just use the ContentLayerChromium logic for creating partial textures. Added a test with a large (500x20000) image to test this. Additionally, after some thought, given that large layers will need to reallocate pixels every time the content rect changes during scrolling, the canvas and pixel data is cached and reused if it is the same size.
James Robinson
Comment 7
2010-10-05 16:47:16 PDT
Comment on
attachment 69865
[details]
Patch For a .dumpAsText() or .layerTreeAsText() test there should be no expected .png, just the layer output (as a .txt). Do you need to specify both .dumpAsText() and .layerTreeAsText()?
James Robinson
Comment 8
2010-10-05 16:48:22 PDT
Whoops, I totally misinterpreted the purpose of the image. My bad!
James Robinson
Comment 9
2010-10-05 16:48:39 PDT
Comment on
attachment 69865
[details]
Patch Resetting enne's flags
Adrienne Walker
Comment 10
2010-10-05 16:54:20 PDT
(In reply to
comment #9
)
> (From update of
attachment 69865
[details]
) > Resetting enne's flags
Per an in-person conversation with jamesr, I am going to look into seeing if there's some way to create an image layer without checking in a PNG.
Adrienne Walker
Comment 11
2010-10-06 10:48:36 PDT
Created
attachment 69957
[details]
Patch
Adrienne Walker
Comment 12
2010-10-06 10:52:37 PDT
(In reply to
comment #11
)
> Created an attachment (id=69957) [details] > Patch
Image file removed. The image src is now programmatically generated from a canvas.
Adrienne Walker
Comment 13
2010-10-07 09:33:06 PDT
Created
attachment 70097
[details]
Patch
Adrienne Walker
Comment 14
2010-10-07 09:37:17 PDT
(In reply to
comment #13
)
> Created an attachment (id=70097) [details] > Patch
This last patch is just a tiny addition of a sanity check for the case where clipping against the content rect still yields a texture that is too large. I'd like to land this patch today if possible, given that I'm out on vacation Friday through Monday. If it's at all possible, could I get a review today?
Vangelis Kokkevis
Comment 15
2010-10-07 12:57:03 PDT
Comment on
attachment 70097
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=70097&action=review
Looks good overall. Some comments are inline. Also, while I like the improvement done with caching the update bitmaps so that they can be reused I feel that that change should go on a separate CL as it's orthogonal to the large layer stuff.
> LayoutTests/compositing/tiling/huge-layer-img.html:22 > + var context = canvas.getContext('2d');
Might be better to try to achieve the same effect with absolutely positioned <div> elements with a background color style property. I'm worried that <canvas> adds an unnecessary unknown to the test.
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:204 > IntRect dirtyRect(m_dirtyRect);
Since m_dirtyRect isn't used by the large layers, setting the dirtyRect to m_dirtyRect should be done for small layers only for clarity.
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:353 > + m_largeLayerDrawRect.width() / 2);
Since largeLayers only kick in if their draw transform is identity or translation, we can completely throw out the drawTransform and do: TransformationMatrix transform; transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y())
> WebCore/platform/graphics/chromium/ImageLayerChromium.cpp:81 > + // image to a canvas, as the pixel contents can't be uploaded directly.
canvas -> bitmap (it's only a "canvas" in the skia case)
Adrienne Walker
Comment 16
2010-10-07 13:15:20 PDT
Thanks for the quick review. (In reply to
comment #15
)
> (From update of
attachment 70097
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=70097&action=review
> > Looks good overall. Some comments are inline. Also, while I like the improvement done with caching the update bitmaps so that they can be reused I feel that that change should go on a separate CL as it's orthogonal to the large layer stuff.
That's reasonable. No need for this patch to be overly complex. I'll cherry-pick that change out into another patch and file a bug once this has landed.
> > LayoutTests/compositing/tiling/huge-layer-img.html:22 > > + var context = canvas.getContext('2d'); > > Might be better to try to achieve the same effect with absolutely positioned <div> elements with a background color style property. I'm worried that <canvas> adds an unnecessary unknown to the test.
This is a test for ImageLayerChromium. The huge-layer.html page already does exactly what you specify. I changed this test to use canvas to satisfy jamesr's request above that I not commit a large binary image. I could use a data URL, but that seemed less flexible for somebody else modifying the test in the future. Is that preferable to canvas?
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:204 > > IntRect dirtyRect(m_dirtyRect); > > Since m_dirtyRect isn't used by the large layers, setting the dirtyRect to m_dirtyRect should be done for small layers only for clarity.
I'll clean this up.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:353 > > + m_largeLayerDrawRect.width() / 2); > > Since largeLayers only kick in if their draw transform is identity or translation, we can completely throw out the drawTransform and do: > TransformationMatrix transform; > transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y())
Ah, that's a much more elegant way to express that.
> > WebCore/platform/graphics/chromium/ImageLayerChromium.cpp:81 > > + // image to a canvas, as the pixel contents can't be uploaded directly. > > canvas -> bitmap (it's only a "canvas" in the skia case)
Quite right.
Adrienne Walker
Comment 17
2010-10-07 13:51:25 PDT
(In reply to
comment #16
)
> > > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:353 > > > + m_largeLayerDrawRect.width() / 2); > > > > Since largeLayers only kick in if their draw transform is identity or translation, we can completely throw out the drawTransform and do: > > TransformationMatrix transform; > > transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y()) > > Ah, that's a much more elegant way to express that.
Actually, what about the original z-component? Are we not still using depth buffers?
Adrienne Walker
Comment 18
2010-10-07 16:54:20 PDT
Created
attachment 70173
[details]
Patch
Adrienne Walker
Comment 19
2010-10-07 16:56:02 PDT
(In reply to
comment #18
)
> Created an attachment (id=70173) [details] > Patch
Removed the caching of update bitmaps. After an in-person discussion with Vangelis, I left the re-use of the drawTransform (as the z-component of the translation may not be non-zero) and the use of canvas (as using a data URL would likely be larger on disk than using a PNG in the first place).
Adrienne Walker
Comment 20
2010-10-07 21:57:22 PDT
Created
attachment 70201
[details]
Patch
Adrienne Walker
Comment 21
2010-10-07 21:57:45 PDT
(In reply to
comment #20
)
> Created an attachment (id=70201) [details] > Patch
Rebaseling against ToT.
James Robinson
Comment 22
2010-10-08 16:44:16 PDT
Comment on
attachment 70201
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=70201&action=review
Needs a touch more cleanup.
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:130 > + , m_allocatedTextureSize(0, 0) > + , m_skipsDraw(false) > + , m_largeLayerDrawRect(0, 0, 0, 0) > + , m_largeLayerDirtyRect(0, 0, 0, 0)
The default constructor should do the right thing for all of these except for m_skipsDraw. No need to list them out.
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:149 > +bool ContentLayerChromium::largeLayer() const
This function name isn't very clear - it actually looks more like a getter for some large layer member variable. Maybe something like requiresClippedUpdateRect() or something?
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:155 > +void ContentLayerChromium::calculateLargeLayerViewRect(IntRect* dirtyRect, > + IntRect* drawRect) const
nit: don't line wrap this WebKit typically uses reference parameters for out params
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:164 > + // 1) The minimal texture space rectangle to be uploaded, returned in > + // dirtyRect. > + // 2) The content rect-relative rectangle to draw this texture in, returned > + // in drawRect.
nit: this is over-wrapped. There's not a firm column limit in WebKit but this would be more readable if (1) and (2) were each only on one line.
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:175 > + const IntSize layerPos(transform.m41() - m_bounds.width() / 2, > + transform.m42() - m_bounds.height() / 2); > + // Transform the contentRect into the space of the layer. > + IntRect contentRectInLayerSpace(IntPoint(0, 0) - layerPos, > + contentRect.size());
I don't fully grok the math here, but it seems like the negation in contentRectInLayerSpace's initialization could be done in the layerPos calculation and that layerPos is really an IntPoint and not an IntSize. Or in other words something like: const IntPoint layerPos(m_bounds.width() - transform.m41() / 2, m_bounds.height() - transform.m42() / 2); IntRect contentRectInLayerSpace(layerPos, contentRect.size());
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:375 > + transform.setM41(m_largeLayerDrawRect.center().x()); > + transform.setM42(m_largeLayerDrawRect.center().y());
is this just doing a translate? If so please use the appropriate translate() function on TransformationMatrix to be clearer
> WebCore/platform/graphics/chromium/ContentLayerChromium.h:95 > + bool largeLayer() const; > + void calculateLargeLayerViewRect(IntRect* dirtyRect, > + IntRect* drawRect) const; > > unsigned m_contentsTexture; > IntSize m_allocatedTextureSize; > bool m_skipsDraw; > - > + IntRect m_largeLayerDrawRect; > + IntRect m_largeLayerDirtyRect;
It looks like the newly added functions/members should all be private: except for largeLayer()
Adrienne Walker
Comment 23
2010-10-10 09:56:44 PDT
Created
attachment 70407
[details]
Patch
Adrienne Walker
Comment 24
2010-10-10 10:03:03 PDT
(In reply to
comment #22
)
> (From update of
attachment 70201
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=70201&action=review
> > Needs a touch more cleanup.
Thanks for the review. I appreciate all the nits, as I'm still learning WebKit style.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:130 > > + , m_allocatedTextureSize(0, 0) > > + , m_skipsDraw(false) > > + , m_largeLayerDrawRect(0, 0, 0, 0) > > + , m_largeLayerDirtyRect(0, 0, 0, 0) > > The default constructor should do the right thing for all of these except for m_skipsDraw. No need to list them out.
The default constructor is "IntRect() {}" so far as I can tell, so I've left these initializations.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:149 > > +bool ContentLayerChromium::largeLayer() const > > This function name isn't very clear - it actually looks more like a getter for some large layer member variable. Maybe something like requiresClippedUpdateRect() or something?
Good suggestion.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:155 > > +void ContentLayerChromium::calculateLargeLayerViewRect(IntRect* dirtyRect, > > + IntRect* drawRect) const > > nit: don't line wrap this > > WebKit typically uses reference parameters for out params
Done.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:164 > > + // 1) The minimal texture space rectangle to be uploaded, returned in > > + // dirtyRect. > > + // 2) The content rect-relative rectangle to draw this texture in, returned > > + // in drawRect. > > nit: this is over-wrapped. There's not a firm column limit in WebKit but this would be more readable if (1) and (2) were each only on one line.
Done.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:175 > > + const IntSize layerPos(transform.m41() - m_bounds.width() / 2, > > + transform.m42() - m_bounds.height() / 2); > > + // Transform the contentRect into the space of the layer. > > + IntRect contentRectInLayerSpace(IntPoint(0, 0) - layerPos, > > + contentRect.size()); > > I don't fully grok the math here, but it seems like the negation in contentRectInLayerSpace's initialization could be done in the layerPos calculation and that layerPos is really an IntPoint and not an IntSize.
It's really more of a relative position than an absolute one, which is why I used IntSize originally. I've changed it as you suggested.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:375 > > + transform.setM41(m_largeLayerDrawRect.center().x()); > > + transform.setM42(m_largeLayerDrawRect.center().y()); > > is this just doing a translate? If so please use the appropriate translate() function on TransformationMatrix to be clearer
It's a translate, but preserving the z-coordinate. I've modified this to call translate3d now.
> > WebCore/platform/graphics/chromium/ContentLayerChromium.h:95 > > + bool largeLayer() const; > > + void calculateLargeLayerViewRect(IntRect* dirtyRect, > > + IntRect* drawRect) const; > > > > unsigned m_contentsTexture; > > IntSize m_allocatedTextureSize; > > bool m_skipsDraw; > > - > > + IntRect m_largeLayerDrawRect; > > + IntRect m_largeLayerDirtyRect; > > It looks like the newly added functions/members should all be private: except for largeLayer()
Good catch. I had originally intended to use them in ImageLayerChromium, but I found a simpler solution that didn't require that.
James Robinson
Comment 25
2010-10-11 13:02:02 PDT
> > > > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:130 > > > + , m_allocatedTextureSize(0, 0) > > > + , m_skipsDraw(false) > > > + , m_largeLayerDrawRect(0, 0, 0, 0) > > > + , m_largeLayerDirtyRect(0, 0, 0, 0) > > > > The default constructor should do the right thing for all of these except for m_skipsDraw. No need to list them out. > > The default constructor is "IntRect() {}" so far as I can tell, so I've left these initializations.
True, but IntRect has two members of type IntPoint and IntSize, both of which have default constructors that zero-initialize. It's one of the nice properties of the WebCore geometric primitives.
James Robinson
Comment 26
2010-10-11 13:08:20 PDT
Comment on
attachment 70407
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=70407&action=review
R=me
> WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:130 > + , m_allocatedTextureSize(0, 0) > + , m_skipsDraw(false) > + , m_largeLayerDrawRect(0, 0, 0, 0) > + , m_largeLayerDirtyRect(0, 0, 0, 0)
nit: IntSize and IntRect zero-initialize by default.
Adrienne Walker
Comment 27
2010-10-12 09:19:56 PDT
Created
attachment 70535
[details]
Patch
Adrienne Walker
Comment 28
2010-10-12 09:26:21 PDT
(In reply to
comment #26
)
> (From update of
attachment 70407
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=70407&action=review
> > R=me > > > WebCore/platform/graphics/chromium/ContentLayerChromium.cpp:130 > > + , m_allocatedTextureSize(0, 0) > > + , m_skipsDraw(false) > > + , m_largeLayerDrawRect(0, 0, 0, 0) > > + , m_largeLayerDirtyRect(0, 0, 0, 0) > > nit: IntSize and IntRect zero-initialize by default.
Oh, you're quite right. Since I'm not a committer yet, I uploaded another patch with that change.
WebKit Commit Bot
Comment 29
2010-10-12 09:45:04 PDT
Comment on
attachment 70535
[details]
Patch Rejecting patch 70535 from commit-queue. Failed to run "['./WebKitTools/Scripts/webkit-patch', '--status-host=queues.webkit.org', 'build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']" exit_code: 2 Last 500 characters of output: k All tests successful. Files=14, Tests=304, 1 wallclock secs ( 0.72 cusr + 0.17 csys = 0.89 CPU) Running build-dumprendertree Compiling Java tests make: Nothing to be done for `default'. Running tests from /Projects/CommitQueue/LayoutTests Testing 21536 test cases. compositing/tiling/huge-layer-img.html -> failed Exiting early after 1 failures. 984 tests run. 38.60s total testing time 983 test cases (99%) succeeded 1 test case (<1%) had incorrect layout 1 test case (<1%) had stderr output Full output:
http://queues.webkit.org/results/4370024
Adrienne Walker
Comment 30
2010-10-13 15:04:30 PDT
Created
attachment 70669
[details]
Patch
Adrienne Walker
Comment 31
2010-10-13 15:08:31 PDT
(In reply to
comment #30
)
> Created an attachment (id=70669) [details] > Patch
As it turns out, the compositing directory isn't run at all on chromium and I missed that fact while grepping through test expectations. So, no need for platform-specific expectations at this point. The new -expected.txt file is from mac and it passes there.
James Robinson
Comment 32
2010-10-13 15:49:18 PDT
Comment on
attachment 70669
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=70669&action=review
Still looks good, just need some expectations tweaks.
> LayoutTests/compositing/tiling/huge-layer-img-expected.txt:1 > +The yellow box should be large enough to scroll off the bottom. There should be a red box on the first page and a blue box near the bottom of the yellow box. This tests that we can support very large composited image layers.
If this is a mac-specific expectation and other platforms produce a different result, then it really should go into platform/mac If we have the chromium results why not check them in as well? We're working on enabling those on the bots and will have to check in expectations at some point one way or the other.
Adrienne Walker
Comment 33
2010-10-13 17:16:37 PDT
Created
attachment 70688
[details]
Patch
James Robinson
Comment 34
2010-10-13 17:19:31 PDT
Comment on
attachment 70688
[details]
Patch Cool. Could you file a bug about the layer sizes/offsets being slightly different?
Adrienne Walker
Comment 35
2010-10-13 17:27:51 PDT
(In reply to
comment #34
)
> (From update of
attachment 70688
[details]
) > Cool. Could you file a bug about the layer sizes/offsets being slightly different?
https://bugs.webkit.org/show_bug.cgi?id=47638
WebKit Commit Bot
Comment 36
2010-10-14 00:18:46 PDT
Comment on
attachment 70688
[details]
Patch Clearing flags on attachment: 70688 Committed
r69747
: <
http://trac.webkit.org/changeset/69747
>
WebKit Commit Bot
Comment 37
2010-10-14 00:18:53 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug