It looks like images are drawn into iOS as if the backing store is a retina backing store, which means images get interpolated. This is a problem for many Web PlatformTests, like css/css-writing-modes/text-indent-vrl-016.xht, though there are many, many more (at least 90?). These tests show an image which is big and white with a precisely sized green square at some location/size, and compare it to a green div at a particular place. On macOS, the green part of the image matches the div exactly, but on iOS, the contents of the image seem to be antialiased, which means the green square is fuzzy, causing a reftest failure. Screenshots attached.
Created attachment 394061 [details] iOS screenshot of the corner of the green square inside the big image
Created attachment 394062 [details] macOS screenshot of the corner of the green square inside the big image
Created attachment 394063 [details] macOS screenshot of the corner of the green square inside the big image
For some reason the macOS image isn't as crisp as it actually is on my screen. I don't know why. It shows a perfectly hard edge on macOS.
(In reply to Myles C. Maxfield from comment #4) > For some reason the macOS image isn't as crisp as it actually is on my > screen. I don't know why. It shows a perfectly hard edge on macOS. *the macOS image I attached to this bug
(lldb) p adjustedDestRect (WebCore::FloatRect) $0 = { m_location = (m_x = 0, m_y = 0) m_size = (m_width = 160, m_height = 320) } (lldb) p CGContextGetCTM(context) error: <user expression 1>:1:1: 'CGContextGetCTM' has unknown return type; cast the call to its declared return type CGContextGetCTM(context) ^~~~~~~~~~~~~~~~~~~~~~~~ (lldb) p (CGAffineTransform)CGContextGetCTM(context) (CGAffineTransform) $1 = (a = 2, b = 0, c = 0, d = 2, tx = 714, ty = 544) (lldb) p (CGAffineTransform)CGContextGetBaseCTM(context) (CGAffineTransform) $2 = (a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) (lldb) po subImage.get() <CGImage 0x7f895213a2f0> (IP) <<CGColorSpace 0x7f8952139d00> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)> width = 160, height = 320, bpc = 8, bpp = 32, row bytes = 640 kCGImageAlphaLast | 0 (default byte order) | kCGImagePixelFormatPacked is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes
It looks like the 2x2 scale is coming from: frame #3: 0x0000000103ff4231 WebKit`WebKit::RemoteLayerBackingStore::drawInContext(this=0x0000000141b5f1f0, context=0x0000000141bb52b8, backImage=0x0000000000000000) at RemoteLayerBackingStore.mm:344:13 frame #4: 0x0000000103ff38f2 WebKit`WebKit::RemoteLayerBackingStore::display(this=0x0000000141b5f1f0) at RemoteLayerBackingStore.mm:283:13 frame #5: 0x0000000104decf2d WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x0000000141b63b70, context=0x0000000141b902f0, transaction=0x00007ffeeca34030) at PlatformCALayerRemote.cpp:180:102 frame #6: 0x0000000104ded1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x0000000141b637a0, context=0x0000000141b902f0, transaction=0x00007ffeeca34030) at PlatformCALayerRemote.cpp:202:15 frame #7: 0x0000000104ded1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x0000000141b53c00, context=0x0000000141b902f0, transaction=0x00007ffeeca34030) at PlatformCALayerRemote.cpp:202:15 frame #8: 0x0000000104ded1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x0000000141b631e8, context=0x0000000141b902f0, transaction=0x00007ffeeca34030) at PlatformCALayerRemote.cpp:202:15 frame #9: 0x0000000104ded1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x0000000141b63000, context=0x0000000141b902f0, transaction=0x00007ffeeca34030) at PlatformCALayerRemote.cpp:202:15 frame #10: 0x00000001049977e7 WebKit`WebKit::RemoteLayerTreeContext::buildTransaction(this=0x0000000141b902f0, transaction=0x00007ffeeca34030, rootLayer=0x0000000141b63000) at RemoteLayerTreeContext.mm:158:21 frame #11: 0x0000000103b26e48 WebKit`WebKit::RemoteLayerTreeDrawingArea::updateRendering(this=0x0000000141b65000) at RemoteLayerTreeDrawingArea.mm:363:31 ... frame #17: 0x0000000103b2bd8e WebKit`WebCore::Timer::fired(this=0x0000000141b65080) at Timer.h:126:9
The drawing has this backtrace: ... frame #30: 0x000000043cb4dc84 WebCore`WebCore::RenderLayer::paintLayerContents(this=0x000000045e15e5c0, context=0x000000045e1bdae0, paintingInfo=0x00007ffeecba0010, paintFlags=(m_storage = 96)) at RenderLayer.cpp:4716:13 frame #31: 0x000000043cb91529 WebCore`WebCore::RenderLayerBacking::paintIntoLayer(this=0x00007ffeecba00f8, layer=0x000000045e15e5c0, paintFlags=(m_storage = 96))::$_5::operator()(WebCore::RenderLayer&, WTF::OptionSet<WebCore::RenderLayer::PaintLayerFlag>) const at RenderLayerBacking.cpp:2910:19 frame #32: 0x000000043cb90ddf WebCore`WebCore::RenderLayerBacking::paintIntoLayer(this=0x000000045e1f1540, graphicsLayer=0x000000045e159000, context=0x000000045e1bdae0, paintDirtyRect=0x00007ffeecba02e0, paintBehavior=(m_storage = 0), eventRegionContext=0x0000000000000000) at RenderLayerBacking.cpp:2927:5 frame #33: 0x000000043cb927df WebCore`WebCore::RenderLayerBacking::paintContents(this=0x000000045e1f1540, graphicsLayer=0x000000045e159000, context=0x000000045e1bdae0, clip=0x00007ffeecba0360, layerPaintBehavior=0) at RenderLayerBacking.cpp:3135:9 frame #34: 0x000000043c63e064 WebCore`WebCore::GraphicsLayer::paintGraphicsLayerContents(this=0x000000045e159000, context=0x000000045e1bdae0, clip=0x00007ffeecba0708, layerPaintBehavior=0) at GraphicsLayer.cpp:516:14 frame #35: 0x000000043c6bf495 WebCore`WebCore::GraphicsLayerCA::platformCALayerPaintContents(this=0x000000045e159000, (null)=0x000000045e15b200, context=0x000000045e1bdae0, clip=0x00007ffeecba0708, layerPaintBehavior=0) at GraphicsLayerCA.cpp:1717:5 frame #36: 0x000000043a862df2 WebCore`WebCore::PlatformCALayer::drawLayerContents(graphicsContext=0x000000045e1bdae0, platformCALayer=0x000000045e15b200, dirtyRects=0x00007ffeecba06f8, layerPaintBehavior=0) at PlatformCALayerCocoa.mm:1217:28 frame #37: 0x000000043c6dd52b WebCore`WebCore::TileGrid::platformCALayerPaintContents(this=0x000000046a9df000, platformCALayer=0x000000045e1dfb70, context=0x000000045e1bdae0, (null)=0x00007ffeecba0918, layerPaintBehavior=0) at TileGrid.cpp:733:9 frame #38: 0x00000004208633b1 WebKit`WebKit::RemoteLayerBackingStore::drawInContext(this=0x000000045e1678b8, context=0x000000045e1bdae0, backImage=0x0000000000000000) at RemoteLayerBackingStore.mm:353:27 frame #39: 0x00000004208628f2 WebKit`WebKit::RemoteLayerBackingStore::display(this=0x000000045e1678b8) at RemoteLayerBackingStore.mm:283:13 frame #40: 0x000000042165bf2d WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x000000045e1dfb70, context=0x000000045e1982f0, transaction=0x00007ffeecba14c0) at PlatformCALayerRemote.cpp:180:102 frame #41: 0x000000042165c1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x000000045e1df7a0, context=0x000000045e1982f0, transaction=0x00007ffeecba14c0) at PlatformCALayerRemote.cpp:202:15 frame #42: 0x000000042165c1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x000000045e15b200, context=0x000000045e1982f0, transaction=0x00007ffeecba14c0) at PlatformCALayerRemote.cpp:202:15 frame #43: 0x000000042165c1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x000000045e1df5b8, context=0x000000045e1982f0, transaction=0x00007ffeecba14c0) at PlatformCALayerRemote.cpp:202:15 frame #44: 0x000000042165c1d4 WebKit`WebKit::PlatformCALayerRemote::recursiveBuildTransaction(this=0x000000045e16b000, context=0x000000045e1982f0, transaction=0x00007ffeecba14c0) at PlatformCALayerRemote.cpp:202:15 frame #45: 0x00000004212067e7 WebKit`WebKit::RemoteLayerTreeContext::buildTransaction(this=0x000000045e1982f0, transaction=0x00007ffeecba14c0, rootLayer=0x000000045e16b000) at RemoteLayerTreeContext.mm:158:21 frame #46: 0x0000000420395e48 WebKit`WebKit::RemoteLayerTreeDrawingArea::updateRendering(this=0x000000045e16d000) at RemoteLayerTreeDrawingArea.mm:363:31 ...
So it looks like the source of the "2" is RemoteLayerBackingStore::m_scale.
Looks like this is getting set from WebCore::Page::m_deviceScaleFactor
We generally try to run tests at 1x, but we don't have support on iOS: void PlatformWebView::changeWindowScaleIfNeeded(float) { // Retina only surface. }
See also this code in TestController.cpp: // Generally, the tests should default to running at 1x. updateWindowScaleForTest() will adjust the scale to // something else for specific tests that need to run at a different window scale. m_mainWebView->changeWindowScaleIfNeeded(1);
Also, in GraphicsContext::drawNativeImage(): #if PLATFORM(IOS_FAMILY) bool wasAntialiased = CGContextGetShouldAntialias(context); // Anti-aliasing is on by default on the iPhone. Need to turn it off when drawing images. CGContextSetShouldAntialias(context, false); // Align to pixel boundaries adjustedDestRect = roundToDevicePixels(adjustedDestRect); #endif
_page->setIntrinsicDeviceScaleFactor(WebCore::screenScaleFactor([UIScreen mainScreen]));
Created attachment 394126 [details] PoC patch If you apply the attached patch, at least one of the failing WPT tests starts passing. I have no idea, though, whether this is a good patch, or an incomplete one.
These are the tests this bug should fix: imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vrl-016.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vrl-014.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vrl-012.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vrl-010.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vlr-017.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vlr-015.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vlr-013.xht imported/w3c/web-platform-tests/css/css-writing-modes/text-indent-vlr-011.xht imported/w3c/web-platform-tests/css/css-writing-modes/percent-padding-vrl-004.xht imported/w3c/web-platform-tests/css/css-writing-modes/percent-padding-vrl-002.xht imported/w3c/web-platform-tests/css/css-writing-modes/percent-padding-vlr-005.xht imported/w3c/web-platform-tests/css/css-writing-modes/percent-padding-vlr-003.xht imported/w3c/web-platform-tests/css/css-writing-modes/padding-vrl-004.xht imported/w3c/web-platform-tests/css/css-writing-modes/padding-vlr-005.xht imported/w3c/web-platform-tests/css/css-writing-modes/overconstrained-rel-pos-ltr-top-bottom-vlr-003.xht imported/w3c/web-platform-tests/css/css-writing-modes/overconstrained-rel-pos-ltr-left-right-vlr-005.xht imported/w3c/web-platform-tests/css/css-writing-modes/normal-flow-overconstrained-vlr-003.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vrl-016.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vrl-014.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vrl-012.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vrl-010.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vlr-017.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vlr-015.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vlr-013.xht imported/w3c/web-platform-tests/css/css-writing-modes/clip-rect-vlr-011.xht imported/w3c/web-platform-tests/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht imported/w3c/web-platform-tests/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht imported/w3c/web-platform-tests/css/css-writing-modes/border-vrl-006.xht imported/w3c/web-platform-tests/css/css-writing-modes/border-vlr-007.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-226.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-218.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-210.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-202.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-194.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-186.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-178.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-170.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-162.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-146.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-138.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-130.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-122.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-114.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-106.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-096.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-090.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-084.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-078.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-072.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-066.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-060.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-054.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-048.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-042.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-036.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-030.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-024.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-018.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-012.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-147.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht imported/w3c/web-platform-tests/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht
<rdar://problem/60704836>