Bug 492300 - kwin_wayland misplaces Firefox subsurface
Summary: kwin_wayland misplaces Firefox subsurface
Status: RESOLVED DOWNSTREAM
Alias: None
Product: kwin
Classification: Plasma
Component: wayland-generic (show other bugs)
Version: master
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-08-28 06:28 UTC by derp
Modified: 2024-09-19 16:27 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Firefox in overview (81.29 KB, image/png)
2024-08-28 06:28 UTC, derp
Details
second variant of the bug (775.52 KB, image/png)
2024-08-28 07:16 UTC, derp
Details
second variant of the bug #2 (1.71 MB, image/png)
2024-08-28 07:17 UTC, derp
Details

Note You need to log in before you can comment on or make changes to this bug.
Description derp 2024-08-28 06:28:23 UTC
Created attachment 173023 [details]
Firefox in overview

BACKGROUND

Firefox has support for wl_subsurface, which has not received much updates over last 3 years.
At the time it was decided to let Firefox perform it's own compositing on Wayland instead, because system compositors were not good enough.
As compositors improved in that time, this feature is getting relevant again because it's the only way to use power-efficient video overlays, otherwise Firefox force composites everything on it's own.
The switch is gfx.webrender.compositor.force-enabled, unforunately it's heavily gated and hardcoded to be ignored unless the build is marked as Firefox Nightly.

It may be possible to bring this feature back to life after testing, fixes and convincing upstream it's important because of power efficiency.


SUMMARY

KWin can randomly misplace part of the Firefox window while the proper place becomes transparent, I can't seem to replicate that on mutter.
I also find it a little strange that even if the issue is proved to be on Firefox side, KWin doesn't intersect the subsurface with parent surface, which should eliminate it from view completely? Instead it creates this weird effect seen in the overview.

STEPS TO REPRODUCE
1.  Install Firefox nightly, go to about:config, gfx.webrender.compositor.force-enabled change to true
2. Open some website like YouTube
3. Resize the window multiple times, use F11 multiple times etc.

OBSERVED RESULT

Ultimately the window will bug out after some time, subsurface will be misplaced and it's proper place becomes transparent instead.
In the overview you can see that the subsurface is rendered outside of window borders(the blue border once you focus the window)

EXPECTED RESULT

No bugs

SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Fedora 40, KDE 
KDE Plasma Version:  6.1
KDE Frameworks Version: 6.5.0
Qt Version: 6.7.2
KWIN: 6.1.80/git master

ADDITIONAL INFORMATION
Comment 1 derp 2024-08-28 06:30:56 UTC
Surface hierarchy at the time of the screenshot:

Buffers                                                                                                                                                                         
    - wl_buffer@47 shm, width: 32, height: 32, format: 0                                                                                                                        
    - wl_buffer@61 shm, width: 1, height: 1, format: 0, active: wl_surface@55                                                                                                   
    - wl_buffer@64 shm, width: 64, height: 64, format: 0, active: wl_surface@23                                                                                                 
    - wl_buffer@45 shm, width: 64, height: 64, format: 0                                                                                                                        
    - wl_buffer@69 shm, width: 64, height: 64, format: 0                                                                                                                        
    - wl_buffer@68 shm, width: 64, height: 64, format: 0                                                                                                                        
    - wl_buffer@180 shm, width: 64, height: 64, format: 0                                                                                                                       
    - wl_buffer@192 shm, width: 64, height: 64, format: 0                                                                                                                       
    - wl_buffer@294 shm, width: 64, height: 64, format: 0                                                                                                                       
    - wl_buffer@170 shm, width: 64, height: 64, format: 0                                                                                                                       
    - wl_buffer@375 shm, width: 64, height: 64, format: 0                                                                                                                       
    - wl_buffer@1062 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@135                                                                          
    - wl_buffer@1397 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1321                                                                         
    - wl_buffer@1399 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1407 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1326 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1211                                                                         
    - wl_buffer@1439 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1384                                                                         
    - wl_buffer@1441 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1194                                                                         
    - wl_buffer@1443 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1435 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1328                                                                         
    - wl_buffer@1431 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@549 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                   
    - wl_buffer@1286 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1172 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1192                                                                         
    - wl_buffer@1083 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1329 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1333 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1190 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1323 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1390 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1458 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@421                                                                          
    - wl_buffer@1460 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1231                                                                         
    - wl_buffer@1462 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1464 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@438                                                                          
    - wl_buffer@1466 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1298                                                                         
    - wl_buffer@1468 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1470 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1405                                                                         
    - wl_buffer@1472 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1372 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                      - wl_buffer@1372 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1403 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@132                                                                          
    - wl_buffer@1236 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1199 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1491 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1419 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1240 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1300                                                                         
    - wl_buffer@1447 linux-dmabuf, width: 1024, height: 512, format: 875713089, active: wl_surface@1278                                                                         
    - wl_buffer@1411 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1393 linux-dmabuf, width: 1024, height: 512, format: 875713089                                                                                                  
    - wl_buffer@1345 shm, width: 2880, height: 1800, format: 0, active: wl_surface@51                                                                                           
Outputs                                                                                                                                                                         
    - wl_output@16, scale: 2                                                                                                                                                    
Seats                                                                                                                                                                           
    - wl_seat@19                                                                                                                                                                
       - wl_pointer@18, entered: <nil object>, x: 804.84, y: 117.29, buttons held: 0                                                                                            
       - wl_keyboard@27, entered: <nil object>, keys held: 0                                                                                                                    
    - wl_seat@34                                                                                                                                                                
       - wl_keyboard@41, entered: <nil object>, keys held: 0                                                                                                                    
Surfaces                                                                                                                                                                        
    - wl_surface@20, role: <unknown>                                                                                                                                            
    - wl_surface@23, role: wl_pointer@18                                                                                                                                        
            buffers: wl_buffer@64, total: 314                                                                                                                                   
            active buffer: wl_buffer@64, scale: 2                                                                                                                               
            outputs: wl_output@16                                                                                                                                               
    - wl_surface@51, role: xdg_toplevel@53 of xdg_surface@52                                                                                                                    
            buffers: wl_buffer@1345, total: 443                                                                                                                                 
            active buffer: wl_buffer@1345, scale: 2, frames: 401/402                                                                                                            
            outputs: wl_output@16                                                                                                                                               
            app_id: firefox-nightly, title: Firefox Nightly                                                                                                                     
            geom: x=0 y=0 w=1440 h=900, current: w=1440 h=900                                                                                                                   
            current states: fullscreen, suspended                                                                                                                               
       - wl_surface@55, role: wl_subsurface@56                                                                                                                                  
               buffers: wl_buffer@61, total: 1                                                                                                                                  
               active buffer: wl_buffer@61, frames: 395/396                                                                                                                     
               outputs: wl_output@16                                                                                                                                            
               desync: true, x: 0, y: 0                                                                                                                                         
          - wl_surface@438, role: wl_subsurface@419                                                                                                                             
                  buffers: wl_buffer@1464, total: 832                                                                                                                           
                  active buffer: wl_buffer@1464, frames: 5796/5798                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 0, y: 84                                                                                                                                    
          - wl_surface@132, role: wl_subsurface@396                                                                                                                             
                  buffers: wl_buffer@1403, total: 761                                                                                                                           
                  active buffer: wl_buffer@1403, frames: 5138/5140                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 0, y: 340                                                                                                                                   
          - wl_surface@135, role: wl_subsurface@406                                                                                                                             
                  buffers: wl_buffer@1062, total: 748                                                                                                                           
                  active buffer: wl_buffer@1062, frames: 5136/5138                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 512, y: 340                                                                                                                                                   outputs: wl_output@16                                                                                                                                         
          - wl_surface@421, role: wl_subsurface@81                                                                                                                              
                  buffers: wl_buffer@1458, total: 748                                                                                                                           
                  active buffer: wl_buffer@1458, frames: 5117/5119                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 512, y: 84                                                                                                                                  
          - wl_surface@1321, role: wl_subsurface@1334                                                                                                                           
                  buffers: wl_buffer@1397, total: 55                                                                                                                            
                  active buffer: wl_buffer@1397, frames: 1208/1210                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 1024, y: 596                                                                                                                                
          - wl_surface@1328, role: wl_subsurface@1274                                                                                                                           
                  buffers: wl_buffer@1435, total: 55                                                                                                                            
                  active buffer: wl_buffer@1435, frames: 1207/1209                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 512, y: 596                                                                                                                                 
          - wl_surface@1278, role: wl_subsurface@1244                                                                                                                           
                  buffers: wl_buffer@1447, total: 55                                                                                                                            
                  active buffer: wl_buffer@1447, frames: 1204/1206                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 1024, y: 84                                                                                                                                 
          - wl_surface@1211, role: wl_subsurface@1376                                                                                                                           
                  buffers: wl_buffer@1326, total: 55                                                                                                                            
                  active buffer: wl_buffer@1326, frames: 1198/1200                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 1024, y: 340                                                                                                                                
          - wl_surface@1300, role: wl_subsurface@489                                                                                                                            
                  buffers: wl_buffer@1240, total: 55                                                                                                                            
                  active buffer: wl_buffer@1240, frames: 1193/1195                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 1024, y: 852                                                                                                                                
          - wl_surface@1192, role: wl_subsurface@78                                                                                                                             
                  buffers: wl_buffer@1172, total: 55                                                                                                                            
                  active buffer: wl_buffer@1172, frames: 1192/1194                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 512, y: 852                                                                                                                                 
          - wl_surface@1384, role: wl_subsurface@1415                                                                                                                           
                  buffers: wl_buffer@1439, total: 55                                                                                                                            
                  active buffer: wl_buffer@1439, frames: 1187/1189                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 0, y: 852                                                                                                                                   
          - wl_surface@1194, role: wl_subsurface@1337                                                                                                                           
                  buffers: wl_buffer@1441, total: 55                                                                                                                            
                  active buffer: wl_buffer@1441, frames: 1182/1184                                                                                                              
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 0, y: 596                                                                                                                                   
          - wl_surface@1405, role: wl_subsurface@1487                                                                                                                           
                  buffers: wl_buffer@1470, total: 87                                                                                                                            
                  active buffer: wl_buffer@1470, frames: 257/258                                                                                                                
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 1024, y: 0                                                                                                                                  
          - wl_surface@1231, role: wl_subsurface@1478                                                                                                                           
                  buffers: wl_buffer@1460, total: 87                                                                                                                            
                  active buffer: wl_buffer@1460, frames: 257/258                                                                                                                
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 512, y: 0                                                                                                                                   
          - wl_surface@1298, role: wl_subsurface@1482                                                                                                                           
                  buffers: wl_buffer@1466, total: 87                                                                                                                            
                  active buffer: wl_buffer@1466, frames: 257/258                                                                                                                
                  outputs: wl_output@16                                                                                                                                         
                  desync: false, x: 0, y: 0                                                                                                                                     
    - wl_surface@65, role: <unknown>                                                                                                                                            
    - wl_surface@60, role: <unknown>                                                                                                                                            
    - wl_surface@67, role: <unknown>                                                                                                                                            
    - wl_surface@58, role: <unknown>                                                                                                                                            
    - wl_surface@123, role: <unknown>                                                                                                                                           
    - wl_surface@337, role: <unknown>                                                                                                                                           
    - wl_surface@411, role: <unknown>                                                                                                                                           
    - wl_surface@903, role: <unknown>                                                                                                                                           
Viewports                                                                                                                                                                       
    - wp_viewport@420, surface: wl_surface@438, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                     
    - wp_viewport@394, surface: wl_surface@132, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                     
    - wp_viewport@113, surface: wl_surface@421, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                     
    - wp_viewport@77, surface: wl_surface@135, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                      
    - wp_viewport@1182, surface: wl_surface@1300, source: x=0.000000 y=0.000000 w=832.000000 h=95.000000, dest: w=416 h=48                                                      
    - wp_viewport@1341, surface: wl_surface@1278, source: x=0.000000 y=0.000000 w=832.000000 h=512.000000, dest: w=416 h=256                                                    
    - wp_viewport@1413, surface: wl_surface@1328, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                   
    - wp_viewport@1421, surface: wl_surface@1211, source: x=0.000000 y=0.000000 w=832.000000 h=512.000000, dest: w=416 h=256                                                    
    - wp_viewport@1316, surface: wl_surface@1194, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                   
    - wp_viewport@1310, surface: wl_surface@1192, source: x=0.000000 y=0.000000 w=1024.000000 h=95.000000, dest: w=512 h=48                                                     
    - wp_viewport@1151, surface: wl_surface@1321, source: x=0.000000 y=0.000000 w=832.000000 h=512.000000, dest: w=416 h=256                                                    
    - wp_viewport@1359, surface: wl_surface@1384, source: x=0.000000 y=0.000000 w=1024.000000 h=95.000000, dest: w=512 h=48                                                     
    - wp_viewport@1499, surface: wl_surface@1298, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                   
    - wp_viewport@1455, surface: wl_surface@1231, source: x=0.000000 y=0.000000 w=1024.000000 h=512.000000, dest: w=512 h=256                                                   
    - wp_viewport@1484, surface: wl_surface@1405, source: x=0.000000 y=0.000000 w=832.000000 h=512.000000, dest: w=416 h=256
Comment 2 derp 2024-08-28 06:54:19 UTC
WAYLAND_DEBUG=1 ./firefox may be used to print Wayland calls, and the suspicious API calls that Firefox uses are (in no specific order):

[3175848.494] {Default Queue}  -> wl_subcompositor#38.get_subsurface(new id wl_subsurface#853, wl_surface#748, wl_surface#55)
[3175848.498] {Default Queue}  -> wl_subsurface#853.place_above(wl_surface#898)
[3175848.503] {Default Queue}  -> wl_subsurface#853.set_position(1435, 86)
[3175848.719] {Default Queue}  -> wl_subsurface#773.destroy()
Comment 3 David Edmundson 2024-08-28 07:11:56 UTC
Is firefox ok when not in the overview?
Comment 4 derp 2024-08-28 07:16:30 UTC
Created attachment 173028 [details]
second variant of the bug

A second "variant" of the bug. Moving cursor over the bugged transparent area results in duplicate visible cursors or sometimes unrelated content from another window.
That suggest, along with damage tracking and buffer aging, that one part of KWin may see the subsurface in it's proper place and the other one does not.
Comment 5 derp 2024-08-28 07:17:47 UTC
Created attachment 173029 [details]
second variant of the bug #2

and the screenshout of bugs happening in transparent area

to above question: no, outside of the overview Firefox is also not OK
Comment 6 Vlad Zahorodnii 2024-08-28 12:54:39 UTC
gfx.webrender.compositor.force-enabled used to have bugs last time I tested it and I won't be surprised if those issues still persist up to this day because the clients often get subsurface wrong way.

> KWin doesn't intersect the subsurface with parent surface

It must not do that, subsurfaces can stick outside their parent surface.
Comment 7 Vlad Zahorodnii 2024-08-28 13:01:01 UTC
The layer compositor option doesn't work for me in Firefox Nightly. Either way, please report this issue to firefox developers.
Comment 8 derp 2024-08-28 13:17:54 UTC
some investigation would be nice, if not for Firefox, at least for the fact that the transparent area renders garbage breaking damage/buffer age tracking. if Firefox really sends wrong data (even though I see nothing suspicious from the surface dump I pasted earlier), new asserts could be added to reject it one way or another
Comment 9 Vlad Zahorodnii 2024-08-28 13:53:24 UTC
> the transparent area renders garbage breaking damage/buffer age tracking

ff sets the opaque region for the main surface (it mainly contains the client side drop shadow). if a subsurface is translucent or not covering that part of the main surface, you're going to see visual artifacts as on one of the screenshots
Comment 10 derp 2024-08-28 14:20:59 UTC
hm, are you saying the corruption would trigger for every app where the application lies about effective opaque region? I think that would make sense, and there's no way to reasonably protect against that without scanning pixels every frame.

that btw. reminded me of another app that lies about opaque regions - Telegram fullscreen viewer of image attachments. it does a direct scanout, but as soon as you press Meta and open the KDE menu, it starts underlaying other windows in unused areas. but this one can't be turned into corruption in any way I can think of, so just a fun fact
Comment 11 David Edmundson 2024-09-19 16:13:33 UTC Comment hidden (spam)
Comment 12 Nate Graham 2024-09-19 16:26:33 UTC Comment hidden (spam)