RESOLVED FIXED Bug 95134
[chromium] Support high DPI scroll bar on top level web frame.
https://bugs.webkit.org/show_bug.cgi?id=95134
Summary [chromium] Support high DPI scroll bar on top level web frame.
Robert Flack
Reported 2012-08-27 15:17:28 PDT
Currently the ScrollbarLayerChromium of the top level frame is in a ScrollbarLayerChromium with a regular 1x scale factor regardless of the current content scale factor. The scroll bar should match the content scale of the rest of the browser drawing a high DPI scrollbar when running on a high DPI display.
Attachments
Patch (13.14 KB, patch)
2012-08-27 15:24 PDT, Robert Flack
no flags
Patch (16.65 KB, patch)
2012-09-05 07:45 PDT, Robert Flack
no flags
Patch (16.20 KB, patch)
2012-09-05 10:51 PDT, Robert Flack
no flags
Patch (9.07 KB, patch)
2012-09-06 19:48 PDT, Robert Flack
no flags
Patch (10.29 KB, patch)
2012-09-07 12:59 PDT, Robert Flack
no flags
Patch (11.17 KB, patch)
2012-09-07 14:06 PDT, Robert Flack
no flags
Patch (11.14 KB, patch)
2012-09-11 21:50 PDT, Robert Flack
no flags
Patch (11.45 KB, patch)
2012-09-12 05:38 PDT, Robert Flack
no flags
Patch (13.06 KB, patch)
2012-09-13 11:28 PDT, Robert Flack
no flags
Patch (2.59 KB, patch)
2012-09-18 13:07 PDT, Robert Flack
no flags
Robert Flack
Comment 1 2012-08-27 15:24:17 PDT
Robert Flack
Comment 2 2012-09-05 07:45:55 PDT
WebKit Review Bot
Comment 3 2012-09-05 07:49:26 PDT
Please wait for approval from abarth@webkit.org, dglazkov@chromium.org, fishd@chromium.org, jamesr@chromium.org or tkent@chromium.org before submitting, as this patch contains changes to the Chromium public API. See also https://trac.webkit.org/wiki/ChromiumWebKitAPI.
Dana Jansens
Comment 4 2012-09-05 10:23:14 PDT
Comment on attachment 162243 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162243&action=review As a note for reviewers: Twiz is working on a change (wkb.ug/95094) to set contentsScale on all layers in the tree appropriately, which would eliminate the need for these changes to Frame/FrameView/ScrollingCoordiatorChromium/WebLayer. So I'm not sure that this should land before that change, unless it is at risk for m23. > Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:268 > + IntRect thumbRect = m_geometry->thumbRect(m_scrollbar.get()); Why'd this change to a IntRect? > Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:282 > + // Paint and upload the entire part. I don't feel like this comment is adding much value here. Is there something to explain that the code does not? > Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:293 > + IntRect thumbRect = m_geometry->thumbRect(m_scrollbar.get()); Why switched to IntRect again? > Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:108 > - m_geometry->splitTrack(&m_scrollbar, m_geometry->trackRect(&m_scrollbar), backTrackRect, thumbRect, foreTrackRect); > + WebRect trackRect = m_geometry->trackRect(&m_scrollbar); > + m_geometry->splitTrack(&m_scrollbar, trackRect, backTrackRect, thumbRect, foreTrackRect); no-op change? should this be in the diff? > Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:113 > - OwnPtr<CCTextureDrawQuad> quad = CCTextureDrawQuad::create(sharedQuadState, IntRect(thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height), m_thumbResourceId, premultipledAlpha, uvRect, flipped); > + OwnPtr<CCTextureDrawQuad> quad = CCTextureDrawQuad::create(sharedQuadState, IntRect(thumbRect.x * widthScale, thumbRect.y * heightScale, thumbRect.width * widthScale, thumbRect.height * heightScale), m_thumbResourceId, premultipledAlpha, uvRect, flipped); Style-wise, how about we add some local variables here: thumbContentRect and foreTrackContentRect? These will be the original rects scale()d up by width and height scale. Then we don't have to add multiplications inline here. > Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:155 > - return WebKit::WebSize(m_owner->contentBounds().width(), m_owner->contentBounds().height()); > + return WebKit::WebSize(m_owner->bounds().width(), m_owner->bounds().height()); Who does this change affect, can you justify this one? It seems unrelated to the other changes somehow, is this fixing a separate bug than rendering scale?
Robert Flack
Comment 5 2012-09-05 10:50:10 PDT
Comment on attachment 162243 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162243&action=review >> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:268 >> + IntRect thumbRect = m_geometry->thumbRect(m_scrollbar.get()); > > Why'd this change to a IntRect? Not sure, changing to WebRect. Maybe this came out of merging, or just testing. >> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:282 >> + // Paint and upload the entire part. > > I don't feel like this comment is adding much value here. Is there something to explain that the code does not? Removed. >> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:293 >> + IntRect thumbRect = m_geometry->thumbRect(m_scrollbar.get()); > > Why switched to IntRect again? Changed back. >> Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:108 >> + m_geometry->splitTrack(&m_scrollbar, trackRect, backTrackRect, thumbRect, foreTrackRect); > > no-op change? should this be in the diff? No, this was from testing. Removed. >> Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:113 >> + OwnPtr<CCTextureDrawQuad> quad = CCTextureDrawQuad::create(sharedQuadState, IntRect(thumbRect.x * widthScale, thumbRect.y * heightScale, thumbRect.width * widthScale, thumbRect.height * heightScale), m_thumbResourceId, premultipledAlpha, uvRect, flipped); > > Style-wise, how about we add some local variables here: thumbContentRect and foreTrackContentRect? These will be the original rects scale()d up by width and height scale. Then we don't have to add multiplications inline here. Done. >> Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:155 >> + return WebKit::WebSize(m_owner->bounds().width(), m_owner->bounds().height()); > > Who does this change affect, can you justify this one? It seems unrelated to the other changes somehow, is this fixing a separate bug than rendering scale? splitRect uses the trackRect which comes from WebScrollBar::size to compute the size of the scrollbar components. The size was coming from this class which was giving the pixel size and the resulting calculations were using a combination of pixel size and DIP size which resulted in the incorrect positioning I was originally seeing.
Robert Flack
Comment 6 2012-09-05 10:51:05 PDT
Adrienne Walker
Comment 7 2012-09-05 19:12:20 PDT
Comment on attachment 162285 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162285&action=review > Source/Platform/chromium/public/WebLayer.h:108 > + // Set to apply a scale factor used when painting and drawing this layer's content. Defaults to 1.0. > + virtual void setContentsScale(float) = 0; > + virtual float contentsScale() = 0; > + No no no. I think twiz's change in bug 95094 makes this unnecessary. > Source/WebCore/page/FrameView.cpp:708 > +void FrameView::deviceOrPageScaleFactorChanged() > +{ > + frame()->page()->scrollingCoordinator()->frameViewHorizontalScrollbarLayerDidChange( > + this, layerForHorizontalScrollbar()); > + frame()->page()->scrollingCoordinator()->frameViewVerticalScrollbarLayerDidChange( > + this, layerForVerticalScrollbar()); > +} I think all this is unnecessary too. > Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:285 > + float widthScale = static_cast<float>(contentBounds().width()) / bounds().width(); > + float heightScale = static_cast<float>(contentBounds().height()) / bounds().height(); > + > + scrollbarOrigin.scale(widthScale, heightScale); Can I suggest a helper function to convert an IntRect from layer space into content space? > Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:157 > - return WebKit::WebSize(m_owner->contentBounds().width(), m_owner->contentBounds().height()); > + return WebKit::WebSize(m_owner->bounds().width(), m_owner->bounds().height()); Yeah, this is definitely correct. It only worked before because bounds() == contentBounds() for scrollbar layers.
Robert Flack
Comment 8 2012-09-06 19:48:16 PDT
Robert Flack
Comment 9 2012-09-06 19:59:16 PDT
Comment on attachment 162285 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162285&action=review Thanks for the reviews! >> Source/Platform/chromium/public/WebLayer.h:108 >> + > > No no no. I think twiz's change in bug 95094 makes this unnecessary. Right, I was just waiting on the change to land to remove it :-). >> Source/WebCore/page/FrameView.cpp:708 >> +} > > I think all this is unnecessary too. Done, and other now unnecessary code. >> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:285 >> + scrollbarOrigin.scale(widthScale, heightScale); > > Can I suggest a helper function to convert an IntRect from layer space into content space? Not quite sure exactly what you're proposing. Something on LayerChromium like IntRect LayerChromium::convertToContentSpace(const IntRect&);?
Adrienne Walker
Comment 10 2012-09-07 09:39:23 PDT
Comment on attachment 162285 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162285&action=review The rest of the new patch looks really good. >>> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:285 >>> + scrollbarOrigin.scale(widthScale, heightScale); >> >> Can I suggest a helper function to convert an IntRect from layer space into content space? > > Not quite sure exactly what you're proposing. Something on LayerChromium like IntRect LayerChromium::convertToContentSpace(const IntRect&);? Yeah, exactly something like LayerChromium::layerRectToContentRect(IntRect). Mostly just for readability so that you don't have to parse all the additional scale factors on every x, y, w, h value.
WebKit Review Bot
Comment 11 2012-09-07 10:42:37 PDT
Comment on attachment 162656 [details] Patch Attachment 162656 [details] did not pass chromium-ews (chromium-xvfb): Output: http://queues.webkit.org/results/13785526 New failing tests: compositing/geometry/fixed-position-iframe-composited-page-scale-down.html
Robert Flack
Comment 12 2012-09-07 12:59:06 PDT
Robert Flack
Comment 13 2012-09-07 13:01:41 PDT
(In reply to comment #10) > (From update of attachment 162285 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=162285&action=review > > The rest of the new patch looks really good. > > >>> Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:285 > >>> + scrollbarOrigin.scale(widthScale, heightScale); > >> > >> Can I suggest a helper function to convert an IntRect from layer space into content space? > > > > Not quite sure exactly what you're proposing. Something on LayerChromium like IntRect LayerChromium::convertToContentSpace(const IntRect&);? > > Yeah, exactly something like LayerChromium::layerRectToContentRect(IntRect). Mostly just for readability so that you don't have to parse all the additional scale factors on every x, y, w, h value. Done.
Adrienne Walker
Comment 14 2012-09-07 13:05:06 PDT
Comment on attachment 162849 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162849&action=review > Source/WebCore/platform/graphics/chromium/LayerChromium.h:296 > + IntRect layerRectToContentRect(const IntRect& layerRect); > + How about on CCLayerImpl too?
Robert Flack
Comment 15 2012-09-07 14:06:11 PDT
Robert Flack
Comment 16 2012-09-07 14:08:20 PDT
(In reply to comment #14) > (From update of attachment 162849 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=162849&action=review > > > Source/WebCore/platform/graphics/chromium/LayerChromium.h:296 > > + IntRect layerRectToContentRect(const IntRect& layerRect); > > + > > How about on CCLayerImpl too? Done too.
Dana Jansens
Comment 17 2012-09-07 14:12:34 PDT
Comment on attachment 162863 [details] Patch I am a bit on the fence about this layerRectToContentRect thing. Content space has a different origin than layer space does. It makes sense to scale a rect's size between these two spaces but not its position.
Dana Jansens
Comment 18 2012-09-07 14:53:59 PDT
(In reply to comment #17) > (From update of attachment 162863 [details]) > I am a bit on the fence about this layerRectToContentRect thing. > > Content space has a different origin than layer space does. It makes sense to scale a rect's size between these two spaces but not its position. Sorry, I was out to lunch here completely. This is right as is. We do similar in TLC also: void TiledLayerChromium::setNeedsDisplayRect(const FloatRect& dirtyRect) { float contentsWidthScale = static_cast<float>(contentBounds().width()) / bounds().width(); float contentsHeightScale = static_cast<float>(contentBounds().height()) / bounds().height(); FloatRect scaledDirtyRect(dirtyRect); scaledDirtyRect.scale(contentsWidthScale, contentsHeightScale);
Adrienne Walker
Comment 19 2012-09-07 14:58:48 PDT
Comment on attachment 162863 [details] Patch R=me. Thanks!
WebKit Review Bot
Comment 20 2012-09-07 18:50:34 PDT
Comment on attachment 162863 [details] Patch Attachment 162863 [details] did not pass chromium-ews (chromium-xvfb): Output: http://queues.webkit.org/results/13772968 New failing tests: compositing/geometry/fixed-position-iframe-composited-page-scale-down.html
Robert Flack
Comment 21 2012-09-11 21:50:03 PDT
Robert Flack
Comment 22 2012-09-11 21:56:08 PDT
The failing test compositing/geometry/fixed-position-iframe-composited-page-scale-down.html calls window.internals.settings.setPageScaleFactor(0.5, 0, 0). Trying to draw the scrollbar at a ~0.5 scale factor seems to cause some off by one issues however I'm not sure why we draw the top-level scroll bar differently when the final pixel size in the layout test is the same as at 1x. The latest patch uses rounded sizes and existing FloatRect operations which should be more correct but I think this will still fail the test.
Dana Jansens
Comment 23 2012-09-11 23:11:06 PDT
Comment on attachment 163517 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=163517&action=review > Source/WebCore/platform/graphics/chromium/LayerChromium.cpp:152 > + FloatRect contentRect(layerRect); > + contentRect.scale(widthScale, heightScale); > + return roundedIntRect(contentRect); I feel like this should be an containingIntRect not rounded, so that it always includes the whole layerRect given to the method. I think there's very few cases we want to round, typically we take the containing/contained rect. > Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp:152 > + return IntSize(lroundf(bounds().width() * contentsScale()), lroundf(bounds().height() * contentsScale())); This is the rounding exception, but it's fine here because it's defining the space, not moving between spaces.
WebKit Review Bot
Comment 24 2012-09-11 23:41:18 PDT
Comment on attachment 163517 [details] Patch Attachment 163517 [details] did not pass chromium-ews (chromium-xvfb): Output: http://queues.webkit.org/results/13824567 New failing tests: compositing/geometry/fixed-position-iframe-composited-page-scale-down.html
Robert Flack
Comment 25 2012-09-12 05:38:39 PDT
Robert Flack
Comment 26 2012-09-12 05:52:37 PDT
Comment on attachment 163517 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=163517&action=review I found that the test was failing because the page scale was being applied to the scrollbar contentBounds, which I believe is incorrect. See the ScrollbarLayerChromium constructor in the latest patch where I call setBoundsContainPageScale. Not sure if the constructor is the correct place/way to call a parent class method so please correct me if I got it wrong. Thanks! >> Source/WebCore/platform/graphics/chromium/LayerChromium.cpp:152 >> + return roundedIntRect(contentRect); > > I feel like this should be an containingIntRect not rounded, so that it always includes the whole layerRect given to the method. I think there's very few cases we want to round, typically we take the containing/contained rect. Done.
Dana Jansens
Comment 27 2012-09-12 07:38:16 PDT
(In reply to comment #26) > (From update of attachment 163517 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=163517&action=review > > I found that the test was failing because the page scale was being applied to the scrollbar contentBounds, which I believe is incorrect. See the ScrollbarLayerChromium constructor in the latest patch where I call setBoundsContainPageScale. Not sure if the constructor is the correct place/way to call a parent class method so please correct me if I got it wrong. Thanks! Will this affect only the root scrollbar or others too. What's expected here? I think non-root scrollbars will actually be scaled by page scale (though we should be using overlay scrollbars under pinch anyway). Is it possible to set this flag on the root scrollbar layer from CCLTHImpl?
Robert Flack
Comment 28 2012-09-12 09:08:38 PDT
(In reply to comment #27) > (In reply to comment #26) > > (From update of attachment 163517 [details] [details]) > > View in context: https://bugs.webkit.org/attachment.cgi?id=163517&action=review > > > > I found that the test was failing because the page scale was being applied to the scrollbar contentBounds, which I believe is incorrect. See the ScrollbarLayerChromium constructor in the latest patch where I call setBoundsContainPageScale. Not sure if the constructor is the correct place/way to call a parent class method so please correct me if I got it wrong. Thanks! > > Will this affect only the root scrollbar or others too. What's expected here? I think non-root scrollbars will actually be scaled by page scale (though we should be using overlay scrollbars under pinch anyway). Actually, I think we expect non-root scrollbars to be scaled down by page scale. I've locally run a layout test of page scale 0.5 and the image result of the non-root scrollbar is unaffected by this line, in both cases it is scaled down to half size. > Is it possible to set this flag on the root scrollbar layer from CCLTHImpl? I don't think so, perhaps there's a way between them that I haven't found yet.
Dana Jansens
Comment 29 2012-09-13 00:30:32 PDT
(In reply to comment #28) > (In reply to comment #27) > > (In reply to comment #26) > > > (From update of attachment 163517 [details] [details] [details]) > > > View in context: https://bugs.webkit.org/attachment.cgi?id=163517&action=review > > > > > > I found that the test was failing because the page scale was being applied to the scrollbar contentBounds, which I believe is incorrect. See the ScrollbarLayerChromium constructor in the latest patch where I call setBoundsContainPageScale. Not sure if the constructor is the correct place/way to call a parent class method so please correct me if I got it wrong. Thanks! > > > > Will this affect only the root scrollbar or others too. What's expected here? I think non-root scrollbars will actually be scaled by page scale (though we should be using overlay scrollbars under pinch anyway). > > Actually, I think we expect non-root scrollbars to be scaled down by page scale. I've locally run a layout test of page scale 0.5 and the image result of the non-root scrollbar is unaffected by this line, in both cases it is scaled down to half size. To clarify, this line won't prevent the scrollbar from changing its size, it prevents it from having its contentsScale adjusted by the page scale. So if you pinched in and the scrollbar was 5x as big, you would still get a scrollbar rendered at 1x (or 2x in hi-dpi). If the flag was not set, then the scrollbar would be painted in a bitmap scaled 5x (whether we have resources for that or how it would appear is another issue that I'm not sure about). > > Is it possible to set this flag on the root scrollbar layer from CCLTHImpl? > > I don't think so, perhaps there's a way between them that I haven't found yet.
Adrienne Walker
Comment 30 2012-09-13 10:24:56 PDT
(In reply to comment #28) > (In reply to comment #27) > > > > Is it possible to set this flag on the root scrollbar layer from CCLTHImpl? > > I don't think so, perhaps there's a way between them that I haven't found yet. NCCH has enough information to find the root scrollbar layers and set flags on them. It used to do this in the past to reserve scrollbar textures (see: https://bugs.webkit.org/show_bug.cgi?id=77251). There's no reason you couldn't do something like that and explicitly set the flag you need on them.
Robert Flack
Comment 31 2012-09-13 11:28:34 PDT
Robert Flack
Comment 32 2012-09-13 11:31:08 PDT
(In reply to comment #30) > (In reply to comment #28) > > (In reply to comment #27) > > > > > > Is it possible to set this flag on the root scrollbar layer from CCLTHImpl? > > > > I don't think so, perhaps there's a way between them that I haven't found yet. > > NCCH has enough information to find the root scrollbar layers and set flags on them. It used to do this in the past to reserve scrollbar textures (see: https://bugs.webkit.org/show_bug.cgi?id=77251). There's no reason you couldn't do something like that and explicitly set the flag you need on them. Dana, I misunderstood your comment before, thanks for the clarification. Adrienne, thanks for the example! I've updated the patch.
Dana Jansens
Comment 33 2012-09-13 17:03:46 PDT
I spoke with twiz and enne today about an idea I had to avoid the need to set boundsContainPageScale on this layer at all: basically we only include pageScale in the contentsScale for layers in the subtree of the rootScrollLayer. I think this patch shouldn't worry about that. When the function to set contentsScale on all layers is changed, then the boundsContainPageScale should be removed here though. And hopefully writing this here will remind us all at that time. Cheers!
Robert Flack
Comment 34 2012-09-14 10:41:45 PDT
Ping, are we happy with this patch now?
Adrienne Walker
Comment 35 2012-09-14 13:01:11 PDT
Comment on attachment 163918 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=163918&action=review I like the changes. This code has all moved. Can you create a Chromium bug and rebase your Source/WebCore/platform/graphics/chromium/cc on top of /cc instead? I'll lgtm that. > Source/WebKit/chromium/src/NonCompositedContentHost.cpp:34 > +#include "LayerChromium.h" You can't include or use LayerChromium in NonCompositedContentHost. You have to go through WebContentLayer.
Robert Flack
Comment 36 2012-09-18 13:07:44 PDT
James Robinson
Comment 37 2012-09-18 14:11:48 PDT
Comment on attachment 164610 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=164610&action=review > Source/WebKit/chromium/ChangeLog:8 > + Calls setAppliesPageScale(true) on root scrollbar layers as these are not scaled. can we test this? we have layout tests that cover high-DPI mode and we can use non-mock scrollbars on a given test by calling window.internals.setMockScrollbarsEnabled()
Adrienne Walker
Comment 38 2012-09-18 14:30:24 PDT
Comment on attachment 164610 [details] Patch R=me. Thanks for moving this code here.
Robert Flack
Comment 39 2012-09-19 09:20:27 PDT
(In reply to comment #37) > (From update of attachment 164610 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=164610&action=review > > > Source/WebKit/chromium/ChangeLog:8 > > + Calls setAppliesPageScale(true) on root scrollbar layers as these are not scaled. > > can we test this? we have layout tests that cover high-DPI mode and we can use non-mock scrollbars on a given test by calling window.internals.setMockScrollbarsEnabled() Yes, there is a difference, however it will still be low DPI until after we land http://codereview.chromium.org/10909255/ which we can't land without this fix for page scale.
WebKit Review Bot
Comment 40 2012-09-19 10:57:45 PDT
Comment on attachment 164610 [details] Patch Clearing flags on attachment: 164610 Committed r129023: <http://trac.webkit.org/changeset/129023>
WebKit Review Bot
Comment 41 2012-09-19 10:57:50 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.