Bug 264954 - Controlling layer size through scaling contexts is inconsistent when there are child layers.
Summary: Controlling layer size through scaling contexts is inconsistent when there ar...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Compositing (show other bugs)
Version: Safari 15
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-11-16 07:55 PST by Onne Gorter
Modified: 2023-11-23 07:56 PST (History)
2 users (show)

See Also:


Attachments
Small testcase. Zoom with +/-. Toggle content layer with spacebar. (4.88 KB, text/html)
2023-11-16 07:55 PST, Onne Gorter
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Onne Gorter 2023-11-16 07:55:48 PST
Created attachment 468619 [details]
Small testcase. Zoom with +/-. Toggle content layer with spacebar.

We use a zooming setup, and to keep things sharp, do:
1. a global transform to zoom in or out (adding will-change: transform)
2. zoom content layers to match the size they are displayed at (adding will-change: transform)
3. zoom an inner layer back down to not distort actual content (no will-change)
4. actual content

Which works great normally. Element 1 becomes a transformation layer, element 2 becomes a layer backed by the appropriate amount of pixels. As users zoom, we sometimes switch the size and scale of that layer.

Until the content contains layers itself (backdrop filters, or simply will-change: transform set), then element 3 becomes a layer on its own, and it's amount of backing pixels is insufficient, making everything blurry.

This is unexpected and inconsistent. This setup works in all other browsers. (It works also in Firefox, though it doesn't use layers like this.)


I suspect that in Safari 14 this setup works, but I cannot test this, it used to work. In Safari 15.6  and Safari 16 that element 3 becoming a layer is unavoidable.

One workaround is to use `zoom: X` instead of `transform: scale(X)` for 3, except that texts don't behave the same at all zoom levels.

See the attachment for a minimal setup. If you turn on "Show Compositing Borders" in the inspector layer panel, you can see what is happening.
Comment 1 Simon Fraser (smfr) 2023-11-16 13:51:20 PST
I think this is bug 27684 ?
Comment 2 Onne Gorter 2023-11-17 00:54:58 PST
It could be that any fix to https://bugs.webkit.org/show_bug.cgi?id=27684 fixes our situation as well.


Basically, you'd expect a layer from this:

  <div style="transform: translateZ(0.1px) scale(4); transform-origin: 0 0;">Blurry</div>

To get a backing buffer that is 4 * width x 4 * height, which it does on Chrome, but not on Safari.


But the case for this report is different. There is a correctly sized and scaled layer with backing buffer. But the moment a child layer appears, an implicit layer is created. While:
- That implicit layer is not necessary, as it can merge with the layer of its direct parent. Instead, now it turns that parent layer from one with a backing buffer, to one that is just a transformation layer.
- And, to add insult to injury, that implicit layer has a badly sized backing buffer. Likely because of that scale bug, though, technically, we scale that layer down, so maybe, despite that bug, it does get the right size, just not a suitable size.


Note that because of this, for our editor at http://framer.com, can only be used for "simpler" documents. The moment clients use things with layers, zooming in makes everything look blurry and unusable. I cannot test older version of Safari, but I strongly suspect the problem was introduced in Safari 15.6.
Comment 3 Radar WebKit Bug Importer 2023-11-23 07:56:12 PST
<rdar://problem/118748860>