Bug 174632 - [GTK] Completely garbled display in Transifex in accelerated compositing mode
Summary: [GTK] Completely garbled display in Transifex in accelerated compositing mode
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Miguel Gomez
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-18 08:52 PDT by gautier
Modified: 2017-08-27 11:12 PDT (History)
5 users (show)

See Also:


Attachments
Transifex home garbled screenshot (211.65 KB, image/png)
2017-07-18 08:52 PDT, gautier
no flags Details
Patch (2.46 KB, patch)
2017-08-24 05:42 PDT, Miguel Gomez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description gautier 2017-07-18 08:52:40 PDT
Created attachment 315797 [details]
Transifex home garbled screenshot

Similarly to https://bugs.webkit.org/show_bug.cgi?id=168964 (by which I am affected too), the website transifex.com is completely garbled (see attached screenshot).

I am testing with webkit 2.16.5 on epiphany browser 3.22.7 as well as eolie browser latest master.

No changes when using LIBGL_ALWAYS_SOFTWARE=1 envvar.

### Environment
- PC: Lenovo Yoga 2 13
- Eolie version: 0.9-27-g7b8cfb5
- Gnome shell 3.22.2 (gtk+ 3.22)
- Running on X11
- Operating system: Linux sessifet 4.9.0-1-amd64 #1 SMP Debian 4.9.6-3 (2017-01-28) x86_64 GNU/Linux
- lspci -v
...
00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 09) (prog-if 00 [VGA controller])
	Subsystem: Lenovo Haswell-ULT Integrated Graphics Controller
	Flags: bus master, fast devsel, latency 0, IRQ 43
	Memory at b0000000 (64-bit, non-prefetchable) [size=4M]
	Memory at a0000000 (64-bit, prefetchable) [size=256M]
	I/O ports at 4000 [size=64]
	[virtual] Expansion ROM at 000c0000 [disabled] [size=128K]
	Capabilities: <access denied>
	Kernel driver in use: i915
	Kernel modules: i915
Comment 1 Michael Catanzaro 2017-07-19 19:39:46 PDT
If you need a workaround, you can use the environment variable WEBKIT_DISABLE_COMPOSITING_MODE=1.

Miguel, since I'm afraid you've become our expert on AC mode, any chance you'll have time to look into this? It looks exactly like the breakage that sometimes occurs on YouTube when exiting fullscreen mode.
Comment 2 Miguel Gomez 2017-07-20 05:38:44 PDT
(In reply to Michael Catanzaro from comment #1)
> If you need a workaround, you can use the environment variable
> WEBKIT_DISABLE_COMPOSITING_MODE=1.
> 
> Miguel, since I'm afraid you've become our expert on AC mode, any chance
> you'll have time to look into this? It looks exactly like the breakage that
> sometimes occurs on YouTube when exiting fullscreen mode.

I'm going on holidays but I'll give it a look when I'm back.
This looks like the pixman limitation problem again. Like https://bugs.webkit.org/show_bug.cgi?id=169094 for example. I'm not sure whether the fix for that is included in 2.16.5, but I'll check it.
Comment 3 Salil 2017-08-10 08:39:00 PDT
export WEBKIT_DISABLE_COMPOSITING_MODE=1
did not help the garbled display issue, for me.
Comment 4 Miguel Gomez 2017-08-16 03:08:02 PDT
I'm able to reproduce this with minibrowser and current ToT, but it doesn't happen when AC is disabled using WEBKIT_DISABLE_COMPOSITING_MODE=1.

Anyway, seems that the tiles are mixed somehow. This is usually a consequence of the cairo state corruption, so my bet is that something like that is happening. I'll dig into it.
Comment 5 Miguel Gomez 2017-08-17 08:44:31 PDT
The problem seems to be caused because of one of the svg images used in the page (home-cloud-visual.svg). For some reason that I haven't found yet, it can't be rendered properly, and it's also affecting the rendering of the rest of the page. I tried replacing that image with another and then the rendering works properly then.
Comment 6 Miguel Gomez 2017-08-22 02:19:48 PDT
(In reply to Miguel Gomez from comment #5)
> The problem seems to be caused because of one of the svg images used in the
> page (home-cloud-visual.svg). For some reason that I haven't found yet, it
> can't be rendered properly, and it's also affecting the rendering of the
> rest of the page. I tried replacing that image with another and then the
> rendering works properly then.

I've being debugging the rendering of the image for a while. I've checked that the sizes used are not that big to cause the pixman overflow, so it has to be other issue. I suspect it can be related to what happened in https://bugs.webkit.org/show_bug.cgi?id=126124, which is a problem with cairo and clipping areas. While the bug was fixed (using a workaround), there seems to be a persistent problem in cairo with the clipping (see https://bugs.freedesktop.org/show_bug.cgi?id=100722).

What I think is happening is that during the sequence of cairo commands to render the image, the clipping problem gets triggered, and this screws the commands results after that. I'm trying to isolate the concrete command that breaks the rendering, but there are *a lot* of them and it's not easy to find the concrete point when the rendering starts to get wrong. I'll keep working on it.
Comment 7 Miguel Gomez 2017-08-24 05:23:27 PDT
wow this was an extensive debug with an unexpected end.

So, when rendering the problematic svg image, drawing commands are being issued to the GrapgicsContext that are in the end sent to cairo.
The problematic command here is GraphicsContext::clipToImageBuffer, which is supposed to apply the content as an imageBuffer a mask for clipping the drawings after that. This is not supported in cairo. What is supported is rendering a surface content with an image mask. So what's done here is:

- save the current context status
- change the rendering target to a temporal one and save the image mask
- render to the temporal target
- when the context status is restored, render the temporal target contents into the original target using the saved image mask

In order to support these steps, there's a stack that stores context data every time the context is saved, and restores it when the context is restored. This is handled by PlatformContextCairo::save() and PlatformContextCairo::restore(). The image mask that has to be applied on restore() is also saved in that stack.

And here comes the funny thing. That stack is a WTF::Vector. As the vector grows there's a moment when it will move its contents to a bigger memory space. This move will use a constructor copy if available to move the stored data. But the class used to store the data in the stack has a copy constructor that doesn't copy the image mask. This causes that when the Vector reaches a concrete size and the items are moved, all the image masks stored there are lost.

Then, as there are no image masks to apply, restore doesn't change the rendering target from the temporal one to the original, which causes that nothing gets rendered.
Comment 8 Miguel Gomez 2017-08-24 05:42:54 PDT
Created attachment 318982 [details]
Patch
Comment 9 Michael Catanzaro 2017-08-24 09:32:28 PDT
Comment on attachment 318982 [details]
Patch

Wow. Please add to https://trac.webkit.org/wiki/WebKitGTK/2.18.x when landing.
Comment 10 WebKit Commit Bot 2017-08-25 01:10:40 PDT
Comment on attachment 318982 [details]
Patch

Clearing flags on attachment: 318982

Committed r221183: <http://trac.webkit.org/changeset/221183>
Comment 11 WebKit Commit Bot 2017-08-25 01:10:42 PDT
All reviewed patches have been landed.  Closing bug.
Comment 12 gautier 2017-08-27 11:12:18 PDT
Wow, tremendous investigation Miguel, thanks and good job! Wouldn't expect this bug to be that severe :).