[meta] Enable sub-pixel layout on all platforms
https://bugs.webkit.org/show_bug.cgi?id=85532
Summary [meta] Enable sub-pixel layout on all platforms
Levi Weintraub
Reported 2012-05-03 12:34:35 PDT
bug to track enabling the SUBPIXEL_LAYOUT feature flag on all platforms.
Attachments
Nikolas Zimmermann
Comment 1 2012-06-12 04:52:36 PDT
What's the status of sub pixel support? Can you give us an update Levi?
Levi Weintraub
Comment 2 2012-06-12 10:05:06 PDT
(In reply to comment #1) > What's the status of sub pixel support? Can you give us an update Levi? Sure. Sub-pixel support is in but defaulted to off, behind the ENABLE_SUBPIXEL_LAYOUT flag. Chromium has turned this feature on (you can try it in the Dev channel), and all other ports are encouraged to do so. I plan to follow up with encouraging other ports on webkit-dev when we've promoted this functionality to Chromium's beta or stable channel as that'll mean a lot more eyes have verified this functionality. Do you have any specific questions?
Levi Weintraub
Comment 3 2012-06-13 21:01:02 PDT
(In reply to comment #2) > (In reply to comment #1) > > What's the status of sub pixel support? Can you give us an update Levi? > > Sure. > > Sub-pixel support is in but defaulted to off, behind the ENABLE_SUBPIXEL_LAYOUT flag. Chromium has turned this feature on (you can try it in the Dev channel), and all other ports are encouraged to do so. > > I plan to follow up with encouraging other ports on webkit-dev when we've promoted this functionality to Chromium's beta or stable channel as that'll mean a lot more eyes have verified this functionality. > > Do you have any specific questions? I'd love an update on plans for enabling it in the KDE project ;)
Nikolas Zimmermann
Comment 4 2012-06-14 03:45:01 PDT
(In reply to comment #2) > (In reply to comment #1) > > What's the status of sub pixel support? Can you give us an update Levi? > > Sure. > > Sub-pixel support is in but defaulted to off, behind the ENABLE_SUBPIXEL_LAYOUT flag. Chromium has turned this feature on (you can try it in the Dev channel), and all other ports are encouraged to do so. Excellent, I'll try this on Mac for a while. > I plan to follow up with encouraging other ports on webkit-dev when we've promoted this functionality to Chromium's beta or stable channel as that'll mean a lot more eyes have verified this functionality. > > Do you have any specific questions? Not really, if it can be enabled I'm happy -- we can remove SVG specific FloatPoint/FloatRects in several places, if we could use the frameRect/borderBoxRect for this as example. I'm working on it.
Allan Sandfeld Jensen
Comment 5 2012-06-21 02:25:45 PDT
For your information. I have been testing sub-pixel layout on the Qt platform (to ensure my work on rect-based hit-testing was compatible with sub-pixel types), and it works perfectly with no regression I have noticed.
Nikolas Zimmermann
Comment 6 2012-06-26 07:48:01 PDT
(In reply to comment #3) > I'd love an update on plans for enabling it in the KDE project ;) I'm not working on KDE stuff since half a decade btw, historical reasons for my bugzilla account :-) Anyhow, I've experimented lots with SUBPIXEL_LAYOUT turned on, on Mac. You've done a great job, it's working as-expected for most parts. I've ran into an issue with transforming an absolute positioned <div>, which is aligned on sub-pixel boundaries, like this: <html> <body> <div style="-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px;"></div> </body> </html> If you run this in trunk, you won't see anything, unless you zoom in or out at least once. I've nailed down the problem, but I'm yet unsure on how to fix it properly, so I'd like to share it with you to get your insight: void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { LayoutPoint adjustedPaintOffset = paintOffset + location(); PaintPhase phase = paintInfo.phase; // Check if we need to do anything at all. // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView // paints the root's background. if (!isRoot()) { LayoutRect overflowBox = visualOverflowRect(); flipForWritingMode(overflowBox); overflowBox.inflate(maximalOutlineSize(paintInfo.phase)); overflowBox.moveBy(adjustedPaintOffset); if (!overflowBox.intersects(paintInfo.rect)) return; .... Break on RenderBlock::paint(), at some point: Breakpoint 1, WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2626 2626 LayoutPoint adjustedPaintOffset = paintOffset + location(); (gdb) p showRenderTreeForThis() RenderView 0x109124108 #document 0x10882a600 RenderBlock 0x109125b78 HTML 0x109120380 RenderBody 0x1091266d8 BODY 0x109125ca0 * RenderBlock (positioned) 0x1091271e8 DIV 0x109126400 STYLE=-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px; is reached. 2638 if (!overflowBox.intersects(paintInfo.rect)) (gdb) p overflowBox $39 = { m_location = { m_x = { m_value = 0 }, m_y = { m_value = 0 } }, m_size = { m_width = { m_value = 60 }, m_height = { m_value = 60 } } } p paintInfo.rect $40 = { m_location = { m_x = 1, m_y = 1 }, m_size = { m_width = 8, m_height = 6 } } 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 2638 if (!overflowBox.intersects(paintInfo.rect)) Value returned is $41 = false And here's the problem. The paintInfo.rect has a location of 1x1, and a size of 8x6. So let's examine where the incorrect paintInfo.rect is coming from: (gdb) bt #0 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 Looking at frame #1: #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 3147 // Paint the background. 3148 PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0); 3149 renderer()->paint(paintInfo, paintOffset); (gdb) p damageRect.rect() $51 = (const LayoutRect &) @0x7fff5fbf9908: { m_location = { m_x = { m_value = 30 }, m_y = { m_value = 30 } }, m_size = { m_width = { m_value = 480 }, m_height = { m_value = 360 } } } The pixelSnappedIntRect() produces the x/y=1, width=8, height=6 IntRect. Some more background info: The RenderLayer associated with the <div> has a transform, scale(100). #3 0x000000010279c370 in WebCore::RenderLayer::paintLayer (this=0x1091272b8, rootLayer=0x1091244c8, context=0x7fff5fbfb4c0, paintDirtyRect=@0x7fff5fbfa2d0, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3006 3001 { 3002 GraphicsContextStateSaver stateSaver(*context); 3003 context->concatCTM(transform.toAffineTransform()); 3004 3005 // Now do a paint with the root layer shifted to be us. 3006 paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags); 3007 } 3008 3009 // Restore the clip. 3010 if (parent()) (gdb) p transform $56 = { m_matrix = {{100, 0, 0, 0}, {0, 100, 0, 0}, {0, 0, 1, 0}, {-50, -50, 0, 1}} } (gdb) p paintDirtyRect $58 = (const LayoutRect &) @0x7fff5fbfa2d0: { m_location = { m_x = { m_value = 0 }, m_y = { m_value = 0 } }, m_size = { m_width = { m_value = 48000 }, m_height = { m_value = 36000 } } } The mapping of the paintDirtyRect through the inverse of the transform, produces x/y=30 (aka. 0.5). Now that we know the root of the problem, if you change left/top to 0.4999px, it'll show up as expected, as the paintInfo.rect is now at 0x0, as 0.4999px is pixel-snapped to 0, instead of 1. I'm unsure on how to fix this properly: the intersection between the pixel-snapped paint info rect and the overflow box is lossy, as the overflow box is sub-pixel aware. (gdb) p toRenderBox(renderer())->m_frameRect $61 = { m_location = { m_x = { m_value = -30 }, m_y = { m_value = -30 } }, m_size = { m_width = { m_value = 60 }, m_height = { m_value = 60 } } } As no overflow is involved in my example, visualOverflowRect() == borderBoxRect(), aka. LayoutRect(0, 0, m_frameRect->width(), m_frameRect->height()) (in this example). Sorry for the long post, but I thought I'd give as much information as possible, so we can discuss this easier. Levi, any idea?
Philip Rogers
Comment 7 2012-07-04 11:06:49 PDT
(In reply to comment #6) > (In reply to comment #3) > > I'd love an update on plans for enabling it in the KDE project ;) > I'm not working on KDE stuff since half a decade btw, historical reasons for my bugzilla account :-) > > Anyhow, I've experimented lots with SUBPIXEL_LAYOUT turned on, on Mac. You've done a great job, it's working as-expected for most parts. > > I've ran into an issue with transforming an absolute positioned <div>, which is aligned on sub-pixel boundaries, like this: > > <html> > <body> > <div style="-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px;"></div> > </body> > </html> > > If you run this in trunk, you won't see anything, unless you zoom in or out at least once. > I've nailed down the problem, but I'm yet unsure on how to fix it properly, so I'd like to share it with you to get your insight: > void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) > { > LayoutPoint adjustedPaintOffset = paintOffset + location(); > > PaintPhase phase = paintInfo.phase; > > // Check if we need to do anything at all. > // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView > // paints the root's background. > if (!isRoot()) { > LayoutRect overflowBox = visualOverflowRect(); > flipForWritingMode(overflowBox); > overflowBox.inflate(maximalOutlineSize(paintInfo.phase)); > overflowBox.moveBy(adjustedPaintOffset); > if (!overflowBox.intersects(paintInfo.rect)) > return; > .... > > Break on RenderBlock::paint(), at some point: > Breakpoint 1, WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2626 > 2626 LayoutPoint adjustedPaintOffset = paintOffset + location(); > (gdb) p showRenderTreeForThis() > RenderView 0x109124108 #document 0x10882a600 > RenderBlock 0x109125b78 HTML 0x109120380 > RenderBody 0x1091266d8 BODY 0x109125ca0 > * RenderBlock (positioned) 0x1091271e8 DIV 0x109126400 STYLE=-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px; > > is reached. > > 2638 if (!overflowBox.intersects(paintInfo.rect)) > (gdb) p overflowBox > $39 = { > m_location = { > m_x = { > m_value = 0 > }, > m_y = { > m_value = 0 > } > }, > m_size = { > m_width = { > m_value = 60 > }, > m_height = { > m_value = 60 > } > } > } > > p paintInfo.rect > $40 = { > m_location = { > m_x = 1, > m_y = 1 > }, > m_size = { > m_width = 8, > m_height = 6 > } > } > > 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 > 2638 if (!overflowBox.intersects(paintInfo.rect)) > Value returned is $41 = false > > And here's the problem. The paintInfo.rect has a location of 1x1, and a size of 8x6. > So let's examine where the incorrect paintInfo.rect is coming from: > > (gdb) bt > #0 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 > #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 > > Looking at frame #1: > #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 > 3147 // Paint the background. > 3148 PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0); > 3149 renderer()->paint(paintInfo, paintOffset); > > (gdb) p damageRect.rect() > $51 = (const LayoutRect &) @0x7fff5fbf9908: { > m_location = { > m_x = { > m_value = 30 > }, > m_y = { > m_value = 30 > } > }, > m_size = { > m_width = { > m_value = 480 > }, > m_height = { > m_value = 360 > } > } > } > > The pixelSnappedIntRect() produces the x/y=1, width=8, height=6 IntRect. > > Some more background info: > The RenderLayer associated with the <div> has a transform, scale(100). > #3 0x000000010279c370 in WebCore::RenderLayer::paintLayer (this=0x1091272b8, rootLayer=0x1091244c8, context=0x7fff5fbfb4c0, paintDirtyRect=@0x7fff5fbfa2d0, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3006 > > 3001 { > 3002 GraphicsContextStateSaver stateSaver(*context); > 3003 context->concatCTM(transform.toAffineTransform()); > 3004 > 3005 // Now do a paint with the root layer shifted to be us. > 3006 paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags); > 3007 } > 3008 > 3009 // Restore the clip. > 3010 if (parent()) > > (gdb) p transform > $56 = { > m_matrix = {{100, 0, 0, 0}, {0, 100, 0, 0}, {0, 0, 1, 0}, {-50, -50, 0, 1}} > } > > (gdb) p paintDirtyRect > $58 = (const LayoutRect &) @0x7fff5fbfa2d0: { > m_location = { > m_x = { > m_value = 0 > }, > m_y = { > m_value = 0 > } > }, > m_size = { > m_width = { > m_value = 48000 > }, > m_height = { > m_value = 36000 > } > } > } > > The mapping of the paintDirtyRect through the inverse of the transform, produces x/y=30 (aka. 0.5). > Now that we know the root of the problem, if you change left/top to 0.4999px, it'll show up as expected, as the paintInfo.rect is now at 0x0, as 0.4999px is pixel-snapped to 0, instead of 1. > > I'm unsure on how to fix this properly: the intersection between the pixel-snapped paint info rect and the overflow box is lossy, as the overflow box is sub-pixel aware. > > (gdb) p toRenderBox(renderer())->m_frameRect > $61 = { > m_location = { > m_x = { > m_value = -30 > }, > m_y = { > m_value = -30 > } > }, > m_size = { > m_width = { > m_value = 60 > }, > m_height = { > m_value = 60 > } > } > } > > As no overflow is involved in my example, visualOverflowRect() == borderBoxRect(), aka. LayoutRect(0, 0, m_frameRect->width(), m_frameRect->height()) (in this example). > > Sorry for the long post, but I thought I'd give as much information as possible, so we can discuss this easier. Levi, any idea? Levi, eae: ping? This is somewhat of a blocker for the SVG2.0 work.
Emil A Eklund
Comment 8 2012-07-04 12:19:28 PDT
I'll try to get to this later today or tomorrow, been a busy week. Sorry about the delay.
Levi Weintraub
Comment 9 2012-07-25 14:55:37 PDT
(In reply to comment #7) > (In reply to comment #6) > > (In reply to comment #3) > > > I'd love an update on plans for enabling it in the KDE project ;) > > I'm not working on KDE stuff since half a decade btw, historical reasons for my bugzilla account :-) > > > > Anyhow, I've experimented lots with SUBPIXEL_LAYOUT turned on, on Mac. You've done a great job, it's working as-expected for most parts. > > > > I've ran into an issue with transforming an absolute positioned <div>, which is aligned on sub-pixel boundaries, like this: > > > > <html> > > <body> > > <div style="-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px;"></div> > > </body> > > </html> > > > > If you run this in trunk, you won't see anything, unless you zoom in or out at least once. > > I've nailed down the problem, but I'm yet unsure on how to fix it properly, so I'd like to share it with you to get your insight: > > void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) > > { > > LayoutPoint adjustedPaintOffset = paintOffset + location(); > > > > PaintPhase phase = paintInfo.phase; > > > > // Check if we need to do anything at all. > > // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView > > // paints the root's background. > > if (!isRoot()) { > > LayoutRect overflowBox = visualOverflowRect(); > > flipForWritingMode(overflowBox); > > overflowBox.inflate(maximalOutlineSize(paintInfo.phase)); > > overflowBox.moveBy(adjustedPaintOffset); > > if (!overflowBox.intersects(paintInfo.rect)) > > return; > > .... > > > > Break on RenderBlock::paint(), at some point: > > Breakpoint 1, WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2626 > > 2626 LayoutPoint adjustedPaintOffset = paintOffset + location(); > > (gdb) p showRenderTreeForThis() > > RenderView 0x109124108 #document 0x10882a600 > > RenderBlock 0x109125b78 HTML 0x109120380 > > RenderBody 0x1091266d8 BODY 0x109125ca0 > > * RenderBlock (positioned) 0x1091271e8 DIV 0x109126400 STYLE=-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px; > > > > is reached. > > > > 2638 if (!overflowBox.intersects(paintInfo.rect)) > > (gdb) p overflowBox > > $39 = { > > m_location = { > > m_x = { > > m_value = 0 > > }, > > m_y = { > > m_value = 0 > > } > > }, > > m_size = { > > m_width = { > > m_value = 60 > > }, > > m_height = { > > m_value = 60 > > } > > } > > } > > > > p paintInfo.rect > > $40 = { > > m_location = { > > m_x = 1, > > m_y = 1 > > }, > > m_size = { > > m_width = 8, > > m_height = 6 > > } > > } > > > > 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 > > 2638 if (!overflowBox.intersects(paintInfo.rect)) > > Value returned is $41 = false > > > > And here's the problem. The paintInfo.rect has a location of 1x1, and a size of 8x6. > > So let's examine where the incorrect paintInfo.rect is coming from: > > > > (gdb) bt > > #0 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638 > > #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 > > > > Looking at frame #1: > > #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149 > > 3147 // Paint the background. > > 3148 PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0); > > 3149 renderer()->paint(paintInfo, paintOffset); > > > > (gdb) p damageRect.rect() > > $51 = (const LayoutRect &) @0x7fff5fbf9908: { > > m_location = { > > m_x = { > > m_value = 30 > > }, > > m_y = { > > m_value = 30 > > } > > }, > > m_size = { > > m_width = { > > m_value = 480 > > }, > > m_height = { > > m_value = 360 > > } > > } > > } > > > > The pixelSnappedIntRect() produces the x/y=1, width=8, height=6 IntRect. > > > > Some more background info: > > The RenderLayer associated with the <div> has a transform, scale(100). > > #3 0x000000010279c370 in WebCore::RenderLayer::paintLayer (this=0x1091272b8, rootLayer=0x1091244c8, context=0x7fff5fbfb4c0, paintDirtyRect=@0x7fff5fbfa2d0, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3006 > > > > 3001 { > > 3002 GraphicsContextStateSaver stateSaver(*context); > > 3003 context->concatCTM(transform.toAffineTransform()); > > 3004 > > 3005 // Now do a paint with the root layer shifted to be us. > > 3006 paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags); > > 3007 } > > 3008 > > 3009 // Restore the clip. > > 3010 if (parent()) > > > > (gdb) p transform > > $56 = { > > m_matrix = {{100, 0, 0, 0}, {0, 100, 0, 0}, {0, 0, 1, 0}, {-50, -50, 0, 1}} > > } > > > > (gdb) p paintDirtyRect > > $58 = (const LayoutRect &) @0x7fff5fbfa2d0: { > > m_location = { > > m_x = { > > m_value = 0 > > }, > > m_y = { > > m_value = 0 > > } > > }, > > m_size = { > > m_width = { > > m_value = 48000 > > }, > > m_height = { > > m_value = 36000 > > } > > } > > } > > > > The mapping of the paintDirtyRect through the inverse of the transform, produces x/y=30 (aka. 0.5). > > Now that we know the root of the problem, if you change left/top to 0.4999px, it'll show up as expected, as the paintInfo.rect is now at 0x0, as 0.4999px is pixel-snapped to 0, instead of 1. > > > > I'm unsure on how to fix this properly: the intersection between the pixel-snapped paint info rect and the overflow box is lossy, as the overflow box is sub-pixel aware. > > > > (gdb) p toRenderBox(renderer())->m_frameRect > > $61 = { > > m_location = { > > m_x = { > > m_value = -30 > > }, > > m_y = { > > m_value = -30 > > } > > }, > > m_size = { > > m_width = { > > m_value = 60 > > }, > > m_height = { > > m_value = 60 > > } > > } > > } > > > > As no overflow is involved in my example, visualOverflowRect() == borderBoxRect(), aka. LayoutRect(0, 0, m_frameRect->width(), m_frameRect->height()) (in this example). > > > > Sorry for the long post, but I thought I'd give as much information as possible, so we can discuss this easier. Levi, any idea? > > > Levi, eae: ping? This is somewhat of a blocker for the SVG2.0 work. Apologies for the slow response -- I've been away on vacation. This is yet another issue that is solved by the patch on https://bugs.webkit.org/show_bug.cgi?id=89238. I've been trying rather unsuccessfully to get a review (and have been out of town) if one of you have a chance to take a look.
Chris Drackett
Comment 10 2012-07-31 19:01:55 PDT
does this ticket cover adding subpixel support to "normal" css properties (border-size, box-shadow, margin, etc.)
Emil A Eklund
Comment 11 2012-08-01 16:11:52 PDT
(In reply to comment #10) > does this ticket cover adding subpixel support to "normal" css properties (border-size, box-shadow, margin, etc.) This bug is about enabling the subpixel support for platforms other than chromium. See https://trac.webkit.org/wiki/LayoutUnit for details about what that entails.
Nikolas Zimmermann
Comment 12 2012-08-22 06:40:25 PDT
(In reply to comment #9) > Apologies for the slow response -- I've been away on vacation. This is yet another issue that is solved by the patch on https://bugs.webkit.org/show_bug.cgi?id=89238. I've been trying rather unsuccessfully to get a review (and have been out of town) if one of you have a chance to take a look. Oh, does that mean it's fixed now? Going to retry w/o my workarounds then.
Levi Weintraub
Comment 13 2012-08-22 07:37:37 PDT
(In reply to comment #12) > Oh, does that mean it's fixed now? Going to retry w/o my workarounds then. Let me know if there continues to be an issue.
Note You need to log in before you can comment on or make changes to this bug.