1. 14 Jul, 2020 1 commit
  2. 07 Jul, 2020 3 commits
  3. 25 Jun, 2020 2 commits
  4. 17 Mar, 2020 1 commit
  5. 20 Dec, 2019 5 commits
  6. 17 Dec, 2019 2 commits
  7. 03 Dec, 2019 1 commit
  8. 28 Nov, 2019 1 commit
    • Olivier Fourdan's avatar
      xwayland: Add buffer release callback · 77658741
      Olivier Fourdan authored
      
      
      The API `wl_buffer_add_listener` is misleading in the sense that there
      can be only one `wl_buffer` release callback, and trying to add a new
      listener when once is already in place will lead to a protocol error.
      
      The Xwayland EGL backends may need to set up their own `wl_buffer`
      release listener, meaning that there is no way to our own `wl_buffer`
      release callback.
      
      To avoid the problem, add our own callback API to be notified when the
      `wl_buffer` associated with an `xwl_pixmap` is released, triggered from
      the different `xwl_pixmap` implementations.
      
      Also update the Present code to use the new buffer release callback API.
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      Reviewed-by: Michel Dänzer's avatarMichel Dänzer <mdaenzer@redhat.com>
      77658741
  9. 12 Oct, 2019 1 commit
  10. 13 Mar, 2019 1 commit
  11. 09 Jan, 2019 1 commit
    • Olivier Fourdan's avatar
      xwayland: handle case without any crtc · e8295c50
      Olivier Fourdan authored
      Xwayland creates and destroys the CRTC along with the Wayland outputs,
      so there is possibly a case where the number of CRTC drops to 0.
      
      However, `xwl_present_get_crtc()` always return `crtcs[0]` which is
      invalid when `numCrtcs` is 0.
      
      That leads to crash if a client queries the Present capabilities when
      there is no CRTC, the backtrace looks like:
      
        #0  raise() from libc.so
        #1  abort() from libc.so
        #2  OsAbort() at utils.c:1350
        #3  AbortServer() at log.c:879
        #4  FatalError() at log.c:1017
        #5  OsSigHandler() at osinit.c:156
        #6  OsSigHandler() at osinit.c:110
        #7  <signal handler called>
        #8  main_arena() from libc.so
        #9  proc_present_query_capabilities() at present_request.c:236
        #10 Dispatch() at dispatch.c:478
        #11
      
       dix_main() at main.c:276
      
      To avoid returning an invalid pointer (`crtcs[0]`) in that case, simply
      check for `numCrtcs` being 0 and return `NULL` in that case.
      
      Thanks to Michel Dänzer <michel.daenzer@amd.com> for pointing this as a
      possible cause of the crash.
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      Reviewed-by: Michel Dänzer's avatarMichel Dänzer <michel.daenzer@amd.com>
      Bugzilla: https://bugzilla.redhat.com/1609181
      e8295c50
  12. 19 Nov, 2018 4 commits
    • Michel Dänzer's avatar
      xwayland: Don't take buffer release queue into account for frame timer · e6cd1c9b
      Michel Dänzer authored
      The buffer release queue has two kinds of entries:
      
      * Pending async flips.
      * Completed flips waiting for their buffer to be released by the Wayland
        compositor.
      
      xwl_present_timer_callback neither completes async flips nor releases
      buffers, so the timer isn't needed for the buffer release queue.
      e6cd1c9b
    • Michel Dänzer's avatar
      xwayland: Don't need xwl_window anymore in xwl_present_queue_vblank · f5416153
      Michel Dänzer authored
      Fixes issue #12. Presumably the problem was that Present operations on
      unmapped windows were executed immediately instead of only when reaching
      the target MSC.
      f5416153
    • Michel Dänzer's avatar
      xwayland: Add xwl_present_unrealize_window · 8c953857
      Michel Dänzer authored
      When a window is unrealized, a pending frame callback may never be
      called, which could result in repeatedly freezing until the frame timer
      fires after a second.
      
      Fixes these symptoms when switching from fullscreen to windowed mode in
      sauerbraten.
      8c953857
    • Michel Dänzer's avatar
      xwayland: Replace xwl_window::present_window with ::present_flipped · 6b016d58
      Michel Dänzer authored
      There's no need to keep track of the window which last performed a
      Present flip. This fixes crashes due to the assertion in
      xwl_present_flips_stop failing. Fixes issue #10.
      
      The damage generated by a flip only needs to be ignored once, then
      xwl_window::present_flipped can be cleared. This may fix freezing in
      the (hypothetical) scenario where Present flips are performed on a
      window, followed by other drawing requests using the window as the
      destination, but nothing triggering xwl_present_flips_stop. The damage
      from the latter drawing requests would continue being ignored.
      6b016d58
  13. 25 Oct, 2018 3 commits
    • Michel Dänzer's avatar
      xwayland: Complete "synchronous" Present flips from xwl_present_msc_bump · ace551d8
      Michel Dänzer authored
      Completing them from xwl_present_sync_callback had at least two issues:
      
      * It was before the MSC was incremented in xwl_present_frame_callback,
        so the MSC value in the completion event could be lower than the
        target specified by the client. This could cause hangs with the Mesa
        Vulkan drivers.
      * It allowed clients to run at a frame-rate higher than the Wayland
        compositor's frame-rate, wasting energy on generating frames which
        were never displayed. This isn't expected to happen unless the client
        specified PresentOptionAsync (in which case flips are still completed
        from xwl_present_sync_callback, allowing higher frame-rates).
      
      v2:
      * Make xwl_present_has_events return true when there's a pending
        "synchronous" flip, so those complete after at most ~1 second even if
        the Wayland server doesn't send a frame event.
      
      Bugzilla: https://bugs.freedesktop.org/106713
      ace551d8
    • Michel Dänzer's avatar
      xwayland: Rename xwl_present_events_notify to xwl_present_msc_bump · 2bfc46d4
      Michel Dänzer authored
      And consolidate more code from xwl_present_timer_callback and
      xwl_present_frame_callback in it.
      2bfc46d4
    • Michel Dänzer's avatar
      xwayland: Use xwl_present_reset_timer in xwl_present_timer_callback · 5e8b9a3a
      Michel Dänzer authored
      Apart from simplifying the code, this should also prevent a condition
      (which might only be possible with the following fix) reported in
      wayland/weston#115 (comment 52467):
      
      1. xwl_present_timer_callback indirectly calls xwl_present_reset_timer
         -> xwl_present_free_timer
      2. xwl_present_timer_callback then returns a non-0 value, so DoTimer
         calls TimerSet with the old xwl_present_window->frame_timer pointer
         which was freed in step 1 => use after free
      
      Calling xwl_present_reset_timer explicitly passes NULL to TimerSet if
      step 1 freed xwl_present_window->frame_timer, and it will allocate a new
      one.
      5e8b9a3a
  14. 24 Oct, 2018 1 commit
  15. 18 Oct, 2018 1 commit
  16. 10 Sep, 2018 1 commit
    • Olivier Fourdan's avatar
      xwayland: Remove xwl_present_window from privates on cleanup · 3f31f569
      Olivier Fourdan authored
      Xwayland's `xwl_destroy_window()` invokes `xwl_present_cleanup()`
      before the common `DestroyWindow()`.
      
      But then `DestroyWindow()` calls `present_destroy_window()` which will
      possibly end up in `xwl_present_abort_vblank()` which will try to access
      data that was previously freed by `xwl_present_cleanup()`:
      
        Invalid read of size 8
           at 0x434184: xwl_present_abort_vblank (xwayland-present.c:378)
           by 0x53785B: present_wnmd_abort_vblank (present_wnmd.c:651)
           by 0x53695A: present_free_window_vblank (present_screen.c:87)
           by 0x53695A: present_destroy_window (present_screen.c:152)
           by 0x42A90D: xwl_destroy_window (xwayland.c:653)
           by 0x584298: compDestroyWindow (compwindow.c:613)
           by 0x53CEE3: damageDestroyWindow (damage.c:1570)
           by 0x4F1BB8: DbeDestroyWindow (dbe.c:1326)
           by 0x46F7F6: FreeWindowResources (window.c:1031)
           by 0x472847: DeleteWindow (window.c:1099)
           by 0x46B54C: doFreeResource (resource.c:880)
           by 0x46C706: FreeClientResources (resource.c:1146)
           by 0x446ADE: CloseDownClient (dispatch.c:3473)
         Address 0x182abde0 is 80 bytes inside a block of size 112 free'd
           at 0x4C2FDAC: free (vg_replace_malloc.c:530)
           by 0x42A937: xwl_destroy_window (xwayland.c:647)
           by 0x584298: compDestroyWindow (compwindow.c:613)
           by 0x53CEE3: damageDestroyWindow (damage.c:1570)
           by 0x4F1BB8: DbeDestroyWindow (dbe.c:1326)
           by 0x46F7F6: FreeWindowResources (window.c:1031)
           by 0x472847: DeleteWindow (window.c:1099)
           by 0x46B54C: doFreeResource (resource.c:880)
           by 0x46C706: FreeClientResources (resource.c:1146)
           by 0x446ADE: CloseDownClient (dispatch.c:3473)
           by 0x446DA5: ProcKillClient (dispatch.c:3279)
           by 0x4476AF: Dispatch (dispatch.c:479)
         Block was alloc'd at
           at 0x4C30B06: calloc (vg_replace_malloc.c:711)
           by 0x433F46: xwl_present_window_get_priv (xwayland-present.c:54)
           by 0x434228: xwl_present_get_crtc (xwayland-present.c:302)
           by 0x539728: proc_present_query_capabilities (present_request.c:227)
           by 0x4476AF: Dispatch (dispatch.c:479)
           by 0x44B5B5: dix_main (main.c:276)
           by 0x75F611A: (below main) (libc-start.c:308)
      
      This is because `xwl_present_cleanup()` frees the memory but does not
      remove it from the window's privates, and `xwl_present_abort_vblank()`
      will still find it and hence try to access that freed memory...
      
      Remove `xwl_present_window` from window's privates on cleanup so that no
      other function can find and reuse that data once it's freed.
      
      Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1616269
      
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      3f31f569
  17. 21 Jun, 2018 3 commits
    • Olivier Fourdan's avatar
      xwayland: simplify xwl_glamor_pixmap_get_wl_buffer() · 79235905
      Olivier Fourdan authored
      
      
      When retrieving the Wayland buffer from a pixmap, if the buffer already
      exists, the GBM backend will return that existing buffer.
      
      However, as seen with the Present issues, if the call had previously
      passed a wrong size, that buffer will remain at the wrong size for as
      long as the buffer exists, which is error prone.
      
      Considering that the width/height passed to get_wl_buffer() is always the
      actual pixmap  drawable size, and considering that the EGLStream backend
      makes no use of the size either, there is really no point in passing the
      width/height around.
      
      Simplify the xwl_glamor_pixmap_get_wl_buffer() and EGL backends API by
      removing the pixmap size, and use the drawable size instead.
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      79235905
    • Olivier Fourdan's avatar
      xwayland: check for EGLStream backend explicitly · 5d843f69
      Olivier Fourdan authored
      
      
      Now that we have separate backends for EGLStream and GBM, we can
      explicitly check for the EGLStream backend to disable present support
      in that case.
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      Reviewed-by: Emil Velikov's avatarEmil Velikov <emil.velikov@collabora.com>
      5d843f69
    • Olivier Fourdan's avatar
      xwayland: refactor EGL backends for wayland registry · d7185a84
      Olivier Fourdan authored
      
      
      To be able to check for availability of the Wayland interfaces required
      to run a given EGL backend (either GBM or EGLStream for now), we need
      to have each backend structures and vfuncs in place before we enter the
      Wayland registry dance.
      
      That basically means that we should init all backends at first, connect
      to the Wayland compositor and query the available interfaces and then
      decide which backend is available and should be used (or none if either
      the Wayland interfaces or the EGL extensions are not available).
      
      For this purpose, hold an egl_backend struct for each backend we are to
      consider prior to connect to the Wayland display so that, when we get to
      query the Wayland interfaces, everything is in place for each backend to
      handle the various Wayland interfaces.
      
      Eventually, when we need to chose which EGL backend to use for glamor,
      the available Wayland interfaces and EGL extensions available are all
      known to Xwayland.
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      Reviewed-by: Emil Velikov's avatarEmil Velikov <emil.velikov@collabora.com>
      d7185a84
  18. 11 Jun, 2018 1 commit
  19. 08 May, 2018 1 commit
  20. 07 May, 2018 1 commit
  21. 30 Apr, 2018 1 commit
  22. 24 Apr, 2018 1 commit
    • Lyude Paul's avatar
      xwayland: Add glamor egl_backend for EGLStreams · 54ac0971
      Lyude Paul authored
      
      
      This adds initial support for displaying Xwayland applications through
      the use of EGLStreams and nvidia's custom wayland protocol by adding
      another egl_backend driver. This also adds some additional egl_backend
      hooks that are required to make things work properly.
      
      EGLStreams work a lot differently then the traditional way of handling
      buffers with wayland. Unfortunately, there are also a LOT of various
      pitfalls baked into it's design that need to be explained.
      
      This has a very large and unfortunate implication: direct rendering is,
      for the time being at least, impossible to do through EGLStreams. The
      main reason being that the EGLStream spec mandates that we lose the
      entire color buffer contents with each eglSwapBuffers(), which goes
      against X's requirement of not losing data with pixmaps.  no way to use
      an allocated EGLSurface as the storage for glamor rendering like we do
      with GBM, we have to rely on blitting each pixmap to it's respective
      EGLSurface producer each frame. In order to pull this off, we add two
      different additional egl_backend hooks that GBM opts out of
      implementing:
      
      - egl_backend.allow_commits for holding off displaying any EGLStream
        backed pixmaps until the point where it's stream is completely
        initialized and ready for use
      - egl_backend.post_damage for blitting the content of the EGLStream
        surface producer before Xwayland actually damages and commits the
        wl_surface to the screen.
      
      The other big pitfall here is that using nvidia's wayland-eglstreams
      helper library is also not possible for the most part. All of it's API
      for creating and destroying streams rely on being able to perform a
      roundtrip in order to bring each stream to completion since the wayland
      compositor must perform it's job of connecting a consumer to each
      EGLstream. Because Xwayland has to potentially handle both responding to
      the wayland compositor and it's own X clients, the situation of the
      wayland compositor being one of our X clients must be considered. If we
      perform a roundtrip with the Wayland compositor, it's possible that the
      wayland compositor might currently be connected to us as an X client and
      thus hang while both Xwayland and the wayland compositor await responses
      from eachother. To avoid this, we work directly with the wayland
      protocol and use wl_display_sync() events along with release() events to
      set up and destroy EGLStreams asynchronously alongside handling X
      clients.
      
      Additionally, since setting up EGLStreams is not an atomic operation we
      have to take into consideration the fact that an EGLStream can
      potentially be created in response to a window resize, then immediately
      deleted due to another pending window resize in the same X client's
      pending reqests before Xwayland hits the part of it's event loop where
      we read from the wayland compositor. To make this even more painful, we
      also have to take into consideration that since EGLStreams are not
      atomic that it's possible we could delete wayland resources for an
      EGLStream before the compositor even finishes using them and thus run
      into errors. So, we use quite a bit of tracking logic to keep EGLStream
      objects alive until we know the compositor isn't using them (even if
      this means the stream outlives the pixmap it backed).
      
      While the default backend for glamor remains GBM, this patch exists for
      users who have had to deal with the reprecussion of their GPU
      manufacturers ignoring the advice of upstream and the standardization of
      GBM across most major GPU manufacturers. It is not intended to be a
      final solution to the GBM debate, but merely a baindaid so our users
      don't have to suffer from the consequences of companies avoiding working
      upstream. New drivers are strongly encouraged not to use this as a
      backend, and use GBM like everyone else. We even spit this out as an
      error from Xwayland when using the eglstream backend.
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      Acked-by: Daniel Stone's avatarDaniel Stone <daniels@collabora.com>
      Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
      54ac0971
  23. 19 Apr, 2018 1 commit
  24. 18 Apr, 2018 1 commit
    • Olivier Fourdan's avatar
      xwayland: avoid using freed xwl_window on unrealize · 8b8f9007
      Olivier Fourdan authored
      xwl_unrealize_window() would use freed xwl_window which can lead to
      various memory corruption and crashes, as reported by valgrind:
      
       Invalid read of size 8
          at 0x42C802: xwl_present_cleanup (xwayland-present.c:84)
          by 0x42BA67: xwl_unrealize_window (xwayland.c:601)
          by 0x541EE9: compUnrealizeWindow (compwindow.c:285)
          by 0x57E1FA: UnrealizeTree (window.c:2816)
          by 0x581189: UnmapWindow (window.c:2874)
          by 0x54EB26: ProcUnmapWindow (dispatch.c:879)
          by 0x554B7D: Dispatch (dispatch.c:479)
          by 0x558BE5: dix_main (main.c:276)
          by 0x7C4B1BA: (below main) (libc-start.c:308)
        Address 0xf520f60 is 96 bytes inside a block of size 184 free'd
          at 0x4C2EDAC: free (vg_replace_malloc.c:530)
          by 0x42B9FB: xwl_unrealize_window (xwayland.c:624)
          by 0x541EE9: compUnrealizeWindow (compwindow.c:285)
          by 0x57E1FA: UnrealizeTree (window.c:2816)
          by 0x581189: UnmapWindow (window.c:2874)
          by 0x54EB26: ProcUnmapWindow (dispatch.c:879)
          by 0x554B7D: Dispatch (dispatch.c:479)
          by 0x558BE5: dix_main (main.c:276)
          by 0x7C4B1BA: (below main) (libc-start.c:308)
        Block was alloc'd at
          at 0x4C2FB06: calloc (vg_replace_malloc.c:711)
          by 0x42B307: xwl_realize_window (xwayland.c:488)
          by 0x541E59: compRealizeWindow (compwindow.c:268)
          by 0x57DA40: RealizeTree (window.c:2617)
          by 0x580B28: MapWindow (window.c:2694)
          by 0x54EA2A: ProcMapWindow (dispatch.c:845)
          by 0x554B7D: Dispatch (dispatch.c:479)
          by 0x558BE5: dix_main (main.c:276)
          by 0x7C4B1BA: (below main) (libc-start.c:308)
      
      This is because UnrealizeTree() traverses the tree from top to bottom,
      which invalidates the assumption that if the Window doesn't feature an
      xwl_window on its own, it's the xwl_window of its first ancestor with
      one.
      
      This reverts commit 82df2ce3
      
      Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
      Signed-off-by: default avatarOlivier Fourdan <ofourdan@redhat.com>
      8b8f9007
  25. 28 Mar, 2018 1 commit