Bug 103519

Summary: [WK2][EFL][Qt] Pixel alignment is wrong in some cases involving a non-integral content scale
Product: WebKit Reporter: Kenneth Rohde Christiansen <kenneth>
Component: WebKit EFLAssignee: Mikhail Pozdnyakov <mikhail.pozdnyakov>
Status: RESOLVED FIXED    
Severity: Normal CC: abecsi, cmarcelo, dongseong.hwang, gyuyoung.kim, helder.correia, kalyan.kondapally, laszlo.gombos, lucas.de.marchi, menard, mikhail.pozdnyakov, noam, ostap73, rafael.lobo, rakuco, webkit-ews, webkit.review.bot, yael, zeno
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 103105    
Attachments:
Description Flags
patch
none
Patch
none
Patch (work in progress)
none
Testcase
none
Patch (work in progress)
none
Patch
none
Patch
none
Patch noam: review+

Description Kenneth Rohde Christiansen 2012-11-28 06:23:01 PST
Go to google.com (make view smaller if scale == 1), search for something

mouse over the >> to show the info overlay. Now scroll up and down, you will see the overlay element shaking
Comment 1 Kenneth Rohde Christiansen 2012-11-29 07:20:13 PST
The following patch shows that the element definitely shakes:

--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
@@ -441,6 +441,9 @@ void TextureMapperLayer::flushCompositingStateSelf(GraphicsLayerTextureMapper* g
     m_transform.setSize(m_state.size);
     m_transform.setFlattening(!m_state.preserves3D);
     m_transform.setChildrenTransform(m_state.childrenTransform);
+
+    if (m_fixedToViewport)
+        printf("pos %f\n", m_transform.combined().m42());
 }


pos 316.438544
pos 317.167813
pos 316.897082
pos 316.626351
pos 316.355620
pos 316.626351
pos 316.626351
pos 316.355620
pos 317.084889
pos 316.814159
pos 316.543428
pos 316.272697
pos 317.001966
pos 316.731235
pos 316.460504
pos 317.189773
pos 316.648311
pos 316.377580
pos 317.106849
Comment 2 Dongseong Hwang 2012-12-03 02:53:55 PST
Chromium shake the overlay element, too.
I think layout causes this shaking.

However, Coordinated Graphics has another problem. When shaking element, the fixed layer is blurry. Chromium always renders crisp.

I think it is related to something like TiledBackingStore::mapToContents.
Comment 3 Kenneth Rohde Christiansen 2012-12-03 03:02:53 PST
(In reply to comment #2)
> Chromium shake the overlay element, too.
> I think layout causes this shaking.
> 
> However, Coordinated Graphics has another problem. When shaking element, the fixed layer is blurry. Chromium always renders crisp.
> 
> I think it is related to something like TiledBackingStore::mapToContents.

Yeah, it seems to map things into non discrete positions making it blurry.
Comment 4 Dongseong Hwang 2012-12-03 03:10:02 PST
(In reply to comment #3)
> (In reply to comment #2)
> > Chromium shake the overlay element, too.
> > I think layout causes this shaking.
> > 
> > However, Coordinated Graphics has another problem. When shaking element, the fixed layer is blurry. Chromium always renders crisp.
> > 
> > I think it is related to something like TiledBackingStore::mapToContents.
> 
> Yeah, it seems to map things into non discrete positions making it blurry.

Do you think what is the scope of this bug?

We need to separate two problems.
1. Shaking layout
2. Blurry fixed layer.

#1 may require to fix layout routine. It seems to be hard.
We can fix #2 by ourselves.
Comment 5 Kenneth Rohde Christiansen 2012-12-03 03:17:34 PST
> Do you think what is the scope of this bug?
> 
> We need to separate two problems.
> 1. Shaking layout
> 2. Blurry fixed layer.
> 
> #1 may require to fix layout routine. It seems to be hard.
> We can fix #2 by ourselves.

We could do that, basically we need to fix both
Comment 6 Mikhail Pozdnyakov 2012-12-04 08:25:17 PST
Created attachment 177490 [details]
patch

Fix for shaking. Blurring is a separate issue and should be addressed separately.
Comment 7 Rafael Brandao 2012-12-04 08:37:40 PST
(In reply to comment #6)
> Created an attachment (id=177490) [details]
> patch
> 
> Fix for shaking. Blurring is a separate issue and should be addressed separately.

This has been changed to fix the blurry tiles when it was scrolled. If that was wrong, I think we should just rollout the patch for bug 103079 and reopen that bug.
Comment 8 Kenneth Rohde Christiansen 2012-12-04 10:47:47 PST
(In reply to comment #7)
> (In reply to comment #6)
> > Created an attachment (id=177490) [details] [details]
> > patch
> > 
> > Fix for shaking. Blurring is a separate issue and should be addressed separately.
> 
> This has been changed to fix the blurry tiles when it was scrolled. If that was wrong, I think we should just rollout the patch for bug 103079 and reopen that bug.

This is not all of that patch. But doing this does mean that the transform used for events and painting AC is slightly different that the one for positioning the content.
Comment 9 Mikhail Pozdnyakov 2012-12-04 11:00:42 PST
(In reply to comment #7)
> (In reply to comment #6)
> > Created an attachment (id=177490) [details] [details]
> > patch
> > 
> > Fix for shaking. Blurring is a separate issue and should be addressed separately.
> 
> This has been changed to fix the blurry tiles when it was scrolled. If that was wrong, I think we should just rollout the patch for bug 103079 and reopen that bug.

Patch has a lot of good things which I would keep, we just need to find good solution to fix blurring issue, including fixed elements
Comment 10 Mikhail Pozdnyakov 2012-12-05 01:33:14 PST
Comment on attachment 177490 [details]
patch

removing the flags yet, as proper fix should also solve blurring issue
Comment 11 Kenneth Rohde Christiansen 2012-12-05 07:39:53 PST
Created attachment 177745 [details]
Patch
Comment 12 Kenneth Rohde Christiansen 2012-12-06 13:12:14 PST
Created attachment 178066 [details]
Patch (work in progress)

This patch shows crisp pixel aligned fixed positioned elements, but with the following test case it can be seen that it sometimes moves one pixel (shaking)
Comment 13 Kenneth Rohde Christiansen 2012-12-06 13:12:35 PST
Created attachment 178067 [details]
Testcase
Comment 14 Kenneth Rohde Christiansen 2012-12-06 13:44:13 PST
(In reply to comment #12)
> Created an attachment (id=178066) [details]
> Patch (work in progress)
> 
> This patch shows crisp pixel aligned fixed positioned elements, but with the following test case it can be seen that it sometimes moves one pixel (shaking)

This relates to our visibleContentsRect which in WebCore doesn't 100% represent where we are (as it is roundedIntRect). We can only fix this properly if we move to scale in WebCore.
Comment 15 Yael 2012-12-06 14:15:42 PST
(In reply to comment #14)
> (In reply to comment #12)
> > Created an attachment (id=178066) [details] [details]
> > Patch (work in progress)
> > 
> > This patch shows crisp pixel aligned fixed positioned elements, but with the following test case it can be seen that it sometimes moves one pixel (shaking)
> 
> This relates to our visibleContentsRect which in WebCore doesn't 100% represent where we are (as it is roundedIntRect). We can only fix this properly if we move to scale in WebCore.

Does Qt have the same problem?
Comment 16 Kenneth Rohde Christiansen 2012-12-06 16:47:33 PST
> Does Qt have the same problem?

Yes. Your adjustment code hides the shaking somehow (but results in some misalignment and blurriness), so turning it off and doing debugging makes it easier to see the issue. I didn't dig into fixing this adjustment code yet.

How big the issue is depends on the exact scale. At some scales it is barely notifiable.
Comment 17 Kenneth Rohde Christiansen 2012-12-06 17:47:14 PST
Created attachment 178123 [details]
Patch (work in progress)

Fixes the temporarily position adjustment to be aligned to device units (comparing using the float version of visibleContentsRect).
Fixed that the layers can be blurry then the page reaches the end of the page.

one-off shaking still there.
Comment 18 Kenneth Rohde Christiansen 2012-12-06 17:51:06 PST
(In reply to comment #17)
> Created an attachment (id=178123) [details]
> Patch (work in progress)
> 
> Fixes the temporarily position adjustment to be aligned to device units (comparing using the float version of visibleContentsRect).
> Fixed that the layers can be blurry then the page reaches the end of the page.
> 
> one-off shaking still there.

With this patch you can go to google.com, search for "hest"
If you use the default EFL window size, the page will be slightly scaled down.

Now hover the mouse over one of the >> signs for one element

Then the fixed position element pops up and if you put the mouse over it and scroll up and down, it stays perfectly and is very crisp :-)

That is quite an improvement on what we had before, even if we have the one-off issue at certain scales.
Comment 19 Dongseong Hwang 2012-12-06 18:12:46 PST
Comment on attachment 178123 [details]
Patch (work in progress)

View in context: https://bugs.webkit.org/attachment.cgi?id=178123&action=review
great work!
However, we will use pageScaleFactor and deviceScaleFactor in WebCore::Page and move GraphicsLayerCA's snapping algorithm to RenderLayerBacking or RenderLayerCompositor in the future.

> Source/WebKit2/UIProcess/PageViewportController.cpp:97
> +    // Unfortunately it doesn't seem to be enough, so just always allow one pixel more.

I think it is because CoordinatedGraphicsLayer::computePixelAlignment replaces a layer, so the layer shifts off by 1 pixel.
I think we can not reproduce this bug before this patch.

> Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:108
> +    computePixelAlignment(adjustedPosition, adjustedSize, adjustedAnchorPoint, pixelAlignmentOffset);

It is better to computePixel during flushing.
computing here causes redundant computing over and over again. for example, setPosition after setSize.

> Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:863
> +    FloatRect alignedBounds = roundedIntRect(scaledBounds);

You're right. I think mac has bug also.
I think we should use something like pixelSnappedIntRect instead of roundedIntRece and enclosingIntRect to preserve size (size change causes TiledBackingStore's work!)
http://trac.webkit.org/wiki/LayoutUnit
Comment 20 Kenneth Rohde Christiansen 2012-12-07 02:43:29 PST
> > Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:108
> > +    computePixelAlignment(adjustedPosition, adjustedSize, adjustedAnchorPoint, pixelAlignmentOffset);
> 
> It is better to computePixel during flushing.
> computing here causes redundant computing over and over again. for example, setPosition after setSize.

Possible yes, but I didn't look into making this performant yet :-)

> 
> > Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:863
> > +    FloatRect alignedBounds = roundedIntRect(scaledBounds);
> 
> You're right. I think mac has bug also.
> I think we should use something like pixelSnappedIntRect instead of roundedIntRece and enclosingIntRect to preserve size (size change causes TiledBackingStore's work!)
> http://trac.webkit.org/wiki/LayoutUnit

I am not sure, because LayoutUnits store the value (float) in an int. So if you apply scale to a rect and then remove it again, then you don't necessarily end up with the same rect, at least not if the values are not int aligned first. Also then we would need to enable sub pixel layouts which we cannot yet due to some blocker bugs (cairo fonts for one)
Comment 21 Kenneth Rohde Christiansen 2012-12-07 07:29:28 PST
Created attachment 178215 [details]
Patch
Comment 22 Early Warning System Bot 2012-12-07 07:40:07 PST
Comment on attachment 178215 [details]
Patch

Attachment 178215 [details] did not pass qt-wk2-ews (qt):
Output: http://queues.webkit.org/results/15175704
Comment 23 Kenneth Rohde Christiansen 2012-12-07 08:01:17 PST
Created attachment 178220 [details]
Patch
Comment 24 Noam Rosenthal 2012-12-07 08:03:52 PST
Comment on attachment 178220 [details]
Patch

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

> Source/WebKit2/UIProcess/PageViewportController.cpp:98
> +    if (!isIntegral(m_effectiveScale)) {

if (modf(m_effectiveScale))
Comment 25 Kenneth Rohde Christiansen 2012-12-07 08:53:02 PST
Created attachment 178223 [details]
Patch
Comment 26 Noam Rosenthal 2012-12-07 10:15:49 PST
Comment on attachment 178223 [details]
Patch

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

> Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:599
> +    // Sets the values.
> +    computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);

Let's rename it then to adjustGeometryForPixelAlignment
Comment 27 Kenneth Rohde Christiansen 2012-12-07 13:06:23 PST
> > +    // Sets the values.
> > +    computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);
> 
> Let's rename it then to adjustGeometryForPixelAlignment

You find that more clear? it modifies its arguments and I am just passing them directly here. The method itself doesn't adjust anything, plus I like using the same naming as in the mac code
Comment 28 Kenneth Rohde Christiansen 2012-12-07 13:13:13 PST
(In reply to comment #27)
> > > +    // Sets the values.
> > > +    computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);
> > 
> > Let's rename it then to adjustGeometryForPixelAlignment
> 
> You find that more clear? it modifies its arguments and I am just passing them directly here. The method itself doesn't adjust anything, plus I like using the same naming as in the mac code

Can be renamed later, if we decide to do so.
Comment 29 Kenneth Rohde Christiansen 2012-12-07 13:17:54 PST
Landed in 136976