1. 28 Jan, 2021 2 commits
  2. 24 Jan, 2021 1 commit
  3. 07 Jan, 2021 1 commit
  4. 06 Jan, 2021 3 commits
    • Vlad Zahorodnii's avatar
      Introduce RenderLoop · b8a70e62
      Vlad Zahorodnii authored
      At the moment, our frame scheduling infrastructure is still heavily
      based on Xinerama-style rendering. Specifically, we assume that painting
      is driven by a single timer, etc.
      This change introduces a new type - RenderLoop. Its main purpose is to
      drive compositing on a specific output, or in case of X11, on the
      overlay window.
      With RenderLoop, compositing is synchronized to vblank events. It
      exposes the last and the next estimated presentation timestamp. The
      expected presentation timestamp can be used by effects to ensure that
      animations are synchronized with the upcoming vblank event.
      On Wayland, every outputs has its own render loop. On X11, per screen
      rendering is not possible, therefore the platform exposes the render
      loop for the overlay window. Ideally, the Scene has to expose the
      RenderLoop, but as the first step towards better compositing scheduling
      it's good as is for the time being.
      The RenderLoop tries to minimize the latency by delaying compositing as
      close as possible to the next vblank event. One tricky thing about it is
      that if compositing is too close to the next vblank event, animations
      may become a little bit choppy. However, increasing the latency reduces
      the choppiness.
      Given that, there is no any "silver bullet" solution for the choppiness
      issue, a new option has been added in the Compositing KCM to specify the
      amount of latency. By default, it's "Medium," but if a user is not
      satisfied with the upstream default, they can tweak it.
    • Vlad Zahorodnii's avatar
      Drop flag to indicate if swap buffers is blocking · 7a3fa88f
      Vlad Zahorodnii authored
      We want the new compositing timing algorithm to be invariant regarding
      whether glXSwapBuffers() or eglSwapBuffers() block.
    • Vlad Zahorodnii's avatar
      Swap buffers after finishing a compositing cycle · 0ceff5fd
      Vlad Zahorodnii authored
      The compositing timing algorithm assumes that glXSwapBuffers() and
      eglSwapBuffers() block. While this was true long time ago with NVIDIA
      drivers, nowadays, it's not the case. The NVIDIA driver queues
      several buffers in advance and if the application runs out of them,
      it will block. With Mesa driver, swapping buffer was never blocking.
      This change makes the render backends swap buffers right after ending
      a compositing cycle. This may potentially block, but it shouldn't be
      an issue with modern drivers. In case it gets proven, we can move
      glXSwapBuffers() and eglSwapBuffers() in a separate thread.
      Note that this change breaks the compositing timing algorithm, but
      it's already sort of broken with Mesa drivers.
  5. 14 Dec, 2020 1 commit
  6. 11 Dec, 2020 1 commit
  7. 10 Dec, 2020 1 commit
    • Vlad Zahorodnii's avatar
      Provide expected presentation time to effects · 9f2cb0ae
      Vlad Zahorodnii authored
      Effects are given the interval between two consecutive frames. The main
      flaw of this approach is that if the Compositor transitions from the idle
      state to "active" state, i.e. when there is something to repaint,
      effects may see a very large interval between the last painted frame and
      the current. In order to address this issue, the Scene invalidates the
      timer that is used to measure time between consecutive frames before the
      Compositor is about to become idle.
      While this works perfectly fine with Xinerama-style rendering, with per
      screen rendering, determining whether the compositor is about to idle is
      rather a tedious task mostly because a single output can't be used for
      the test.
      Furthermore, since the Compositor schedules pointless repaints just to
      ensure that it's idle, it might take several attempts to figure out
      whether the scene timer must be invalidated if you use (true) per screen
      Ideally, all effects should use a timeline helper that is aware of the
      underlying render loop and its timings. However, this option is off the
      table because it will involve a lot of work to implement it.
      Alternative and much simpler option is to pass the expected presentation
      time to effects rather than time between consecutive frames. This means
      that effects are responsible for determining how much animation timelines
      have to be advanced. Typically, an effect would have to store the
      presentation timestamp provided in either prePaint{Screen,Window} and
      use it in the subsequent prePaint{Screen,Window} call to estimate the
      amount of time passed between the next and the last frames.
      Unfortunately, this is an API incompatible change. However, it shouldn't
      take a lot of work to port third-party binary effects, which don't use the
      AnimationEffect class, to the new API. On the bright side, we no longer
      need to be concerned about the Compositor getting idle.
      We do still try to determine whether the Compositor is about to idle,
      primarily, because the OpenGL render backend swaps buffers on present,
      but that will change with the ongoing compositing timing rework.
  8. 02 Dec, 2020 1 commit
  9. 28 Nov, 2020 1 commit
  10. 27 Nov, 2020 1 commit
  11. 12 Nov, 2020 2 commits
  12. 11 Nov, 2020 1 commit
    • Vlad Zahorodnii's avatar
      Refactor how per screen rendering is handled · 755dd81e
      Vlad Zahorodnii authored
      In order to allow per screen rendering, we need the Compositor to be
      able to drive rendering on each screen. Currently, it's not possible
      because Scene::paint() paints all screen.
      With this change, the Compositor will be able to ask the Scene to paint
      only a screen with the specific id.
  13. 03 Nov, 2020 1 commit
    • David Edmundson's avatar
      Drop QGraphicsView classes in PaintData · 3d43f8ad
      David Edmundson authored and Vlad Zahorodnii's avatar Vlad Zahorodnii committed
      QGraphicsRotation and Scale are QObject wrappers. It's not useful in
      data structures where we're creating mulitple of these every frame. It's
      large enough to appear in hotspot as taking over 1% of a regular frame.
      We don't even use the QGraphicsRotation mapping inside scene for a
      reason, so it's not giving us much.
      It's technically an API break in libkwineffects. Pragamatically no-one
      would use these. We also lose QGraphicsScale's origin, but we never
      exposed this in PaintData's public header.
  14. 02 Nov, 2020 2 commits
  15. 30 Oct, 2020 2 commits
    • Vlad Zahorodnii's avatar
      Report partial updates on all outputs · d5203c79
      Vlad Zahorodnii authored
      Previously, we couldn't do it because repaints weren't tracked per each
    • Vlad Zahorodnii's avatar
      Store repaint regions per individual screen · 74391e25
      Vlad Zahorodnii authored
      AnimationEffect schedules repaints in postPaintWindow() and performs
      cleanup in preScreenPaint(). With the X11-style rendering, this doesn't
      have any issues, scheduled repaints will be reset during the next
      compositing cycle.
      But with per screen rendering, we might hit the following case
          - Paint screen 0
          - Reset scheduled repaints
          - AnimationEffect::prePaintScreen(): update the timeline
          - AnimationEffect::postPaintScreen(): schedule a repaint
          - Paint screen 1
          - Reset scheduled repaints
          - AnimationEffect::prePaintScreen(): destroy the animation
          - AnimationEffect::postPaintScreen(): no repaint is scheduled
          - Return to the event loop
      In this scenario, the repaint region scheduled by AnimationEffect will
      be lost when compositing is performed on screen 1.
      There is no any other way to fix this issue but maintain repaint regions
      per each individual screen if per screen rendering is enabled.
      BUG: 428439
  16. 28 Oct, 2020 1 commit
    • Vlad Zahorodnii's avatar
      scenes/opengl: Use GL_CLAMP_TO_EDGE wrap mode with sw cursor · e5b2fca4
      Vlad Zahorodnii authored
      We use the GL_LINEAR magnification filter. This means that GL_REPEAT
      wrap mode cannot be used for the software cursor because sampling texels
      beyond the right texture edge is the same as sampling texels on the
      left edge. This may produce undesired visual artifacts.
  17. 27 Oct, 2020 1 commit
    • Vlad Zahorodnii's avatar
      platform/drm: Fix clipped HiDPI hardware cursors · c8eeefbd
      Vlad Zahorodnii authored
      If an output is rotated, we will compute a transform matrix for the
      cursor plane to rotate its contents.
      In order to compute that matrix we need the rect of the cursor in the
      device-independent pixels, the scale factor and the output transform.
      The problem is that we provide a rect of the cursor in the native
      pixels. This may result in the cursor being partially or fully clipped.
      CCBUG: 424589
  18. 26 Oct, 2020 2 commits
    • Vlad Zahorodnii's avatar
      Clip software cursors · 4a0128ca
      Vlad Zahorodnii authored
      If you play some video and the software cursor doesn't hover it, then
      the shadow cast by the cursor will be getting darker and darker with
      every frame.
      The main reason for that is that kwin paints the software cursor even
      if the rect behind it hasn't been damaged or repainted.
    • Vlad Zahorodnii's avatar
      Mark the cursor as rendered after performing compositing · 9b09f039
      Vlad Zahorodnii authored
      If a cursor animation is driven purely by frame callbacks and kwin
      uses hardware cursors, the cpu usage may spike to 100%.
      This change addresses that issue by sending frame callbacks after a
      compositing cycle has been performed.
  19. 25 Oct, 2020 1 commit
  20. 19 Oct, 2020 1 commit
    • Vlad Zahorodnii's avatar
      screencast: Use fences to avoid stalling the graphics pipeline · 9c20df50
      Vlad Zahorodnii authored
      Currently, we use glFinish() to ensure that stream consumers don't see
      corrupted or rather incomplete buffers. This is a serious issue because
      glFinish() not only prevents the gpu from processing new GL commands,
      but it also blocks the compositor.
      This change addresses the blocking issue by using native fences. With
      the proposed change, after finishing recording a frame, a fence is
      inserted in the command stream. When the native fence is signaled, the
      pending pipewire buffer will be enqueued.
      If the EGL_ANDROID_native_fence_sync extension is not supported, we'll
      fall back to using glFinish().
  21. 13 Oct, 2020 1 commit
  22. 17 Sep, 2020 1 commit
  23. 09 Sep, 2020 1 commit
  24. 19 Aug, 2020 1 commit
    • Aleix Pol Gonzalez's avatar
      Implement EGL_KHR_partial_update and EGL_EXT_swap_buffers_with_damage · eeeac049
      Aleix Pol Gonzalez authored and Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez committed
      Notify the driver about the parts of the screen that will be repainted.
      In some cases this can be benefitial. This is especially useful on lima
      and panfrost devices (e.g. pinephone, pinebook, pinebook pro).
      Test Plan:
      Tested on a pinebook pro with a late mesa version.
      Basically I implemented it, then it didn't work and I fixed it.
      Maybe next step we want to look into our damage algorithm.
  25. 07 Aug, 2020 2 commits
    • Vlad Zahorodnii's avatar
      Prettify license headers · 4ce853e8
      Vlad Zahorodnii authored
    • Vlad Zahorodnii's avatar
      Switch to SPDX license markers · 1fb9f6f1
      Vlad Zahorodnii authored
      The main advantage of SPDX license identifiers over the traditional
      license headers is that it's more difficult to overlook inappropriate
      licenses for kwin, for example GPL 3. We also don't have to copy a
      lot of boilerplate text.
      In order to create this change, I ran licensedigger -r -c from the
      toplevel source directory.
  26. 05 Aug, 2020 1 commit
  27. 31 Jul, 2020 1 commit
  28. 28 Jul, 2020 1 commit
  29. 23 Jul, 2020 1 commit
  30. 15 May, 2020 1 commit
  31. 04 May, 2020 2 commits
    • Vlad Zahorodnii's avatar
      [scene] Generate window quads for sub-surfaces · f2c8981f
      Vlad Zahorodnii authored
      No window quads are generated for sub-surfaces right now. This leads to
      issues with effects that operate on window quads, e.g. magic lamp and
      wobbly windows. Furthermore, the OpenGL scene needs window quads to
      properly clip windows during the rendering process.
      The best way to render sub-surfaces would be with a little help from a
      scene graph. Contrary to GNOME, KDE hasn't developed any scene graph
      implementation that we could use in kwin. As a short term solution, this
      change adjusts the scene to generate window quads.
      Window quads are generated as we traverse the current window pixmap tree
      in the depth-first search manner. In order to match a list of quads with
      a particular WindowPixmap, we assign an id to each quad.
      BUG: 387313
      FIXED-IN: 5.19.0
      Differential Revision: https://phabricator.kde.org/D29131
    • Vlad Zahorodnii's avatar
      [scene] Build window pixmap trees before starting rendering · e4b598ca
      Vlad Zahorodnii authored
      In order to generate window quads for sub-surfaces, we need a valid
      window pixmap tree. The problem is that the window pixmap tree is
      created too late in the rendering process. This change adjusts the
      scene so it creates window pixmap trees before buildQuads().
      Differential Revision: https://phabricator.kde.org/D29131