[Webkit-unassigned] [Bug 85532] [meta] Enable sub-pixel layout on all platforms

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Wed Jul 4 11:06:49 PDT 2012


https://bugs.webkit.org/show_bug.cgi?id=85532


Philip Rogers <pdr at google.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pdr at google.com




--- Comment #7 from Philip Rogers <pdr at google.com>  2012-07-04 11:06:49 PST ---
(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.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list