Commit graph

481 commits

Author SHA1 Message Date
Roman Gilg
20205f93f7 Save Compositor state in single variable
Summary:
Replace the several internal state booleans of Compositor with a single
enum to register the current state of the compositor. We register four
states of starting, started, stopping and stopped.

The goal is to replace the several different conditionals when starting
and stopping the compositor with a single well defined flow.

There are currently still some ugly conditionals and some replaced ones
might need some more work.

Test Plan: Manually in X and Wayland. Relevant auto tests pass.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D22277
2019-07-04 22:52:05 +02:00
Roman Gilg
09cfc2c0b4 Remove composite reset timer
Summary:
To streamline Compositor code more remove the composite reset timer. The two
times it was used we can either use a singleshot timer instead or connect the
call to a different signal in the X11 backend.

Long term goal is to have a well structured init of the Compositor such that
we can call directly instead.

Test Plan: Manually in X and Wayland nested session.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D22270
2019-07-04 19:15:36 +02:00
Roman Gilg
8c047613c5 Partly remove Compositor restart functionality
Summary:
This removes the restart function of the Compositor class and renames the
internal reinitialize function.

Instead of the restart function reinitialize can be called. Reading again
the settings in this case is fine, since it is done rarely. This reduces
the code complexity.

Test Plan: Manually on Wayland and X. 100% autotests pass.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: davidedmundson, zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D22225
2019-07-04 15:31:40 +02:00
Roman Gilg
ba6daecb4f Remove compositing initialized check
Summary:
The check is used to limit settings reload. But we can afford to reload
settings in case the compositing gets toggled since this happens rarely.

Removing the check reduces code complexity.

Test Plan: Manually in X and Wayland.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D22220
2019-07-04 14:49:10 +02:00
Roman Gilg
cc801a4518 Use new slot syntax in Compositor class
Summary:
As a preparation for further changes clean up the Compositor
class. First step is to use the new slot syntax and rename
some of the slots.

Includes some other minor code style improvements to the class
as well.

Test Plan: Manually in X and Wayland nested session.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: davidedmundson, zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D22218
2019-07-04 14:22:04 +02:00
Roman Gilg
ead1b34563 KSelectionOwner usage in ApplicationX11 and Compositor classes
Summary:
Declare it in the source file for internal usage of ApplicationX11 and
Compositor classes. Additionally use modern style connect and do other
code style updates.

Test Plan: Manually in X session and Wayland windowed.

Reviewers: #kwin, zzag

Subscribers: davidedmundson, sbergeron, zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D21655
2019-06-27 18:08:12 +02:00
Roman Gilg
994fafa912 Move non-Compositor functions out of composite.cpp source file
Summary:
Compositing today is ubiquitous. There is no reason to keep compositing
specific functions of Toplevel, Client and Workspace classes in the
composite.cpp source file. Instead let these definitions be separated.

Test Plan: Compiles

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Maniphest Tasks: T11071

Differential Revision: https://phabricator.kde.org/D21654
2019-06-22 12:02:54 +02:00
Vlad Zagorodniy
fd20c59ada Make Compositor::finish more generic
Summary:
KWin is not only an X11 compositing window manager, but also a Wayland
compositor. The Compositor class is used in both cases so in general it
would be nice to keep it as much as possible generic.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D19879
2019-04-24 00:02:40 +03:00
Vlad Zagorodniy
0db071c218 Move Unmanaged-specific hack away from Toplevel::setupCompositing
Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D20590
2019-04-16 10:12:30 +03:00
Vlad Zagorodniy
10fdf2a220 Discard Deleted before Scene is destroyed
Summary:
Deleted has lifetime bounded to effects and scene.

We can't discard Deleted before EffectsHandler is destroyed because
effects that referenced it may call unrefWindow.

On the other hand, the fact that Deleted may outlive scene doesn't
make sense because Deleted exist purely for animation purposes and
nothing more.

This change arranges lifetime of Deleted so it's more reasonable.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18914
2019-03-04 23:24:42 +02:00
Vlad Zagorodniy
a039f3ba80 [wayland] Send correct current time in the frame callback
Summary:
Currently, each frame callback sent by KWin has the current time in
nanoseconds, but the protocol spec states that we have to send the time
in milliseconds. This is the reason why animations that are driven by
frame callbacks are too fast.

In addition to that, m_timeSinceStart isn't actually "time since start,"
it's rather accumulated duration of all painting cycles. If there is
something to draw and it takes quite a while to compose the scene, maybe
m_timeSinceStart will be close enough to the current time. So, it has
been replaced with QElapsedTimer, this makes the current time correct
and also simplifies code a little bit.

Test Plan: The triangle in weston-subsurfaces no longer spins very fast.

Reviewers: #kwin, romangg

Reviewed By: #kwin, romangg

Subscribers: romangg, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18656
2019-02-26 12:03:57 +02:00
Martin Flöser
cbbe94d769 Restrict available supported compositors based on first initialized one
Summary:
On Wayland we cannot switch from OpenGL to QPainter compositor as this
would break any running OpenGL application. KWin registers it's
EGLDisplay to Wayland and without OpenGL this doesn't make sense any
more. We are not able to render OpenGL buffers in the QPainter
compositor.

While it's theoretically possible to switch from QPainter to OpenGL it
doesn't make any sense for the same reason. Any running OpenGL
application would be using llvmpipe and could not be switched to proper
OpenGL.

This change stores the selected compositing type in Platform and the
implementations can use it to restrict the supported compositors. On X11
we don't need this, all other Platforms implement the restriction. Thus
it's no longer possible to switch the backends at runtime.

Test Plan:
Adjusted tests run, no runtime test as gui doesn't support
switching to QPainter anyway.

Reviewers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D19084
2019-02-22 16:59:08 +01:00
Roman Gilg
06f64d5e56 [autotests] Sub-surface resize test
Summary:
Adds an autotest to show that KWin fails an assertion when a client tries to
resize a sub-surface.

Since it is the first autotest dealing with sub-surfaces explicitly additional
autotest helpers are introduced to allow that.

We also add a new signal in Compositor to spy on to know when the buffer swap
has been completed.

Test Plan:
Test fails as expected:
```
QFATAL : KWin::BufferSizeChangeTest::testShmBufferSizeChangeOnSubSurface() ASSERT: "image.size() == m_size" in file /home/roman/dev/kde/src/kde/workspace/kwin/platformsupport/scenes/opengl/abstract_egl_backend.cpp, line 394
FAIL!  : KWin::BufferSizeChangeTest::testShmBufferSizeChangeOnSubSurface() Received a fatal error.
   Loc: [Unknown file(0)]
Totals: 4 passed, 1 failed, 0 skipped, 0 blacklisted, 367ms
********* Finished testing of KWin::BufferSizeChangeTest *********
```

Reviewers: #kwin, zzag

Subscribers: zzag, graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18452
2019-02-21 23:33:32 +01:00
Vlad Zagorodniy
50041fd5f9 Merge branch 'Plasma/5.15' 2019-02-20 15:11:48 +02:00
Vlad Zagorodniy
9a68cbd9b1 Don't destroy DecorationRenderer in setup/finish compositing
Summary:
Currently, KWin/Wayland crashes when the compositor is reinitialized.
The reason for that is ShellClient's DecorationRenderer gets destroyed
when the scene is already gone, thus there is no current OpenGL context.
Client works around that issue by destroying scene-specific DecorationRender
in finishCompositing. Such a workaround could be applied to ShellClient
as well, but it would make code more confusing because DecoratedClientImpl
also tries to destroy DecorationRenderer.

A better approach would be to notify DecoratedClientImpl that
compositing is about to be finished, so it can destroy the decoration
renderer when the scene is still alive. This not only fixes the
previously mentioned issue in ShellClient, but also makes code a little
bit tidier.

Test Plan:
Start Plasma on Wayland session, change any compositor settings (e.g.
animation speed).

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18921
2019-02-20 15:09:37 +02:00
Vlad Zagorodniy
d167935157 Add addToplevel and removeToplevel to Scene
Summary:
Code that destroys all scene windows when finishing compositing is not
readable. E.g. can you tell what this piece of code is doing without
looking into the source code of Scene::windowClosed?

    foreach (Client * c, Workspace::self()->clientList())
        m_scene->windowClosed(c, NULL);

This change intoduces removeToplevel(as well its counterpart) method to
the Scene class. The name of the new method much better describes what
we're doing.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18210
2019-02-14 14:43:11 +02:00
Erik Kurzinger
f294e7a035 Call frameRendered for undamaged Wayland surfaces
Currently, if a Wayland surface registers a frame callback but does
not send a damage event, the callback will not be serviced even after
KWin has completed a compositing cycle and is therefore ready to
render a new frame for the surface. Since some clients, including any
using NVIDIA's Wayland EGL implementation, wait for frame events
before preparing each frame this behavior can result in hangs if a
compositing cycle occurs between registering the frame callback and
sending the damage event.

Instead, in accordance with the Wayland specification, frame callbacks
should be serviced (via KWayland::Server::SurfaceInterface::frameRendered)
for all visible windows - not just those damaged since the last
compositing cycle.
2019-01-29 12:38:42 -08:00
Martin Flöser
c2c92fab51 Ensure the Compositor does not start during termination
Summary:
The SceneOpenGLES test was starting to randomly crash on my system. On
investigation I observed that there was a graphics reset ("Attempting to
reset compositing.") which triggered a delayed restart of the
compositor. This even was only processed while waiting for XWayland to
terminate. Which resulted in a crash in KWin::getXServerVersion as the
xcb connection broke.

It makes no sense to setup the compositor again during application
shutdown. Thus the dtors set a flag that they are terminating the
application and Compositor::setup is checking for it.

Test Plan: Test no longer crashes, although it goes through the crashing path

Reviewers: #kwin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18015
2019-01-12 07:36:55 +01:00
Vlad Zagorodniy
295138145c Make sure that effect windows outlive effects
Summary:
Compositing is suspended/finished in a very hard way fashion, effect
windows are destroyed without notifying effects about it.

AnimationEffect tries gracefully release deleted windows, but because
in some cases(like when suspending compositing) a deleted window can
be already destroyed, a segmentation fault can happen.

This change adjusts the order in which effect windows and effects are
destroyed, so AnimationEffect (and other effects) cannot access dangling
pointers.

BUG: 400788
FIXED-IN: 5.15.0

Reviewers: #kwin, graesslin

Reviewed By: #kwin, graesslin

Subscribers: graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D17311
2018-12-02 19:59:53 +02:00
Vlad Zagorodniy
89001b1a5a Don't detach list of damaged windows when sending 'done' events
Summary: Most likely, someone forgot to add `qAsConst`.

Reviewers: #kwin, broulik

Reviewed By: broulik

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D13830
2018-07-02 12:48:22 +03:00
Rohan Garg
3e37f896e3 Simplify compositing setup code
Summary: We can get rid of the superfluous if/else ladder.

Reviewers: kwin

Subscribers: #kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D10393
2018-02-08 20:12:01 +01:00
Martin Flöser
53f6a337bf Force Software QtQuick rendering when starting with QPainter compositor
Summary:
If KWin/Wayland starts up with the QPainter compositor we force software
rendering in QtQuick. It doesn't make sense to try to use the OpenGL
renderer as that normally just results in an abort when trying to create
the QOpenGLContext.

Test Plan:
Run KWin with KWIN_COMPOSE=Q, tried to quick tile a window and
used Alt+Tab. Worked fine, didn't crash anymore.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D8663
2017-11-05 11:09:04 +01:00
Martin Flöser
8f4b6a8973 Drop the explicit fallback to XRender
Summary:
With the new try of all compositor types supported there is an automatic
fallback from OpenGL to XRender/QPainter in case OpenGL setup failed.
So there is no need to invoke a method to do just that.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D8364
2017-10-19 18:26:57 +02:00
Martin Flöser
729bfd04a0 Try all supported Compositor Types of the current Platform
Summary:
The Compositor now tries to create a Scene not just once but every
type supported by the Platform till it finds one which works. The user's
configuration is only used as a preferred hint and tried first if the
platform supports it.

This brings as an advantage that on platforms such as framebuffer the
user does not need to specify which compositor to use: KWin uses QPainter
automatically.

Also we don't need to do the "translation" from XRender to QPainter any
more. XRender is not supported by any platform using QPainter, so the
user configuration is ignored anyway.

BUG: 350159
FIXED-IN: 5.12.0

Test Plan: Run on framebuffer, verified debug output.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D8363
2017-10-19 18:26:33 +02:00
Martin Flöser
7ef8409157 Move X11-only specific part of EffectsHandlerImpl to x11 platform plugin
Summary:
The Platform API is extended by a call to create the EffectsHandler. In
X11 standalone Platform a new EffectsHandlerImplX11 is added which
contains the X11 only parts of the EffectsHandler, such as grabbing the
X keyboard and the X11 mouse interception window.

The EffectsHandlerImpl gains some virtual methods for the parts which
are now done in the X11 specific implementation. In return we get rid of
lots of if-else structures checking for the operation mode.

Test Plan: Only compile tested.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7955
2017-10-16 16:54:17 +02:00
Martin Flöser
8ae37c420b Move SceneOpenGL into a dedicated plugin
Summary:
Unfortunately a rather large change which required more refactoring than
initially expected. The main problem was that some parts needed to go
into platformsupport so that the platform plugins can link them. Due to
the rather monolithic nature of scene_opengl.h a few changes were
required:
* SceneOpenGL::Texture -> SceneOpenGLTexture
* SceneOpenGL::TexturePrivate -> SceneOpenGLTexturePrivate
* texture based code into dedicated files
* SwapProfiler code into dedicated files
* SwapProfiler only used in x11 variants
* Safety checks for OpenGL scene moved into the new plugin
* signal declared in SceneOpenGL moved to Scene, so that we don't need
to include SceneOpenGL in composite

Test Plan: Nested OpenGL compositor works

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7740
2017-09-30 13:12:10 +02:00
Martin Flöser
e8664f83b9 Only call xcb_flush in performCompositing if we have an X11 connection
Summary: Otherwise KWin crashes when operating without XWayland support.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7892
2017-09-21 18:11:19 +02:00
Martin Flöser
01ddbe7d75 Make AbstractEglBackend a QObject
Summary:
Several of the subclasses are already derived from QObject.

The main reason is that the class should be moved out of KWin core in
order to move the OpenGL scene into a plugin. As Compositor calls into
the AbstractEglBackend to unbind the wayland display this creates a
problem which is easily solved by turning the AbstractEglBackend into a
QObject and connect to the signal emitted by the Compositor.

Test Plan: Compiles

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7669
2017-09-07 19:25:28 +02:00
Martin Flöser
2892fad5b6 Do not hard runtime depend on X11 in composite startup
Summary:
The compositor needs to claim the X11 compositor selection and redirect
the X11 windows. This of course only makes sense when having X11 support.

This change refactors the code so that if X11 support is missing the code
is not executed, but as soon as X11 support comes available the selection
gets claimed.

Also if the connection goes away the selection is deleted, though it
might be that this does not work as KSelectionOwner might call into xcb
and cause a crash. This needs to be tested once we start supporting
XWayland going away.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7504
2017-09-01 18:05:22 +02:00
Martin Flöser
535b107969 Move QPainter compositor into plugin
This change is similar to D7232 and moves the scene_qpainter into a
dedicated plugin. Compared to the XRender case it's more complicated as
the platform plugins need to implement a platform specific backend.

The base implementation for this part used to be in scene_qpainter. As
the idea is to completly move it away from KWin core it would be point
less to still have the backend definition in KWin core, but it cannot
be in the scene plugin as otherwise all platforms need to link the
plugin.

To solve this a new platformsupport subdirectory is added which contains
the scene platform backend as a static library. For the OpenGL scene such
a static library will also be required.

Test Plan: SceneQPainter test still passes, nested compositor still works

Reviewers: #kwin, #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7259
2017-09-01 17:44:49 +02:00
Martin Flöser
054d923411 Move SceneXRender into a plugin
Summary:
First step for loading the compositor Scenes through plugins. The general
idea is that we currently needlessly pull in all the Scenes although only
one will be used.

E.g. on X11 we pull in QPainter, although they are not compatible. On
Wayland we pull in XRender although they are not compatible.

Furthermore our current Scene creation strategy is not really fault
tolerant and can create situations where we don't get a compositor. E.g
on fbdev backend the default settings won't work as it does not support
OpenGL.

Long term I want to tackle those conceptional problems together:
we try to load all plugins supported by the current platform till we have
a scene which works. Thus on Wayland we don't end up in a situation where
we don't have a working compositor because the configuration is bad.

To make this possible the switch statement in the Scene needs to go and
needs to be replaced by a for loop iterating over all the available
scenes on the platform. If we go there it makes sense to replace it
directly with a plugin based approach.

So this is a change which tackles the problem by first introducing the
plugin loading. The xrender based scene (as it's the most simple one)
is moved into a plugin. It is first tried to find a scene plugin and only
if there is none the existing code is used.

Test Plan: Tested all scenes

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7232
2017-09-01 17:42:28 +02:00
Martin Flöser
12cb1c108e Port Compositor::deleteUnusedSupportProperties away from global x11 connection
Was already using the connection exposed by KWin::Application for parts
of the code. This makes the whole code use the KWin::Application code.
2017-08-23 11:51:18 +02:00
Martin Flöser
a65b2c062c Move event filtering for overlay window into an X11EventFilter
Summary:
The OverlayWindowX11 also inherits from X11EventFilter and performs
the filtering itself.

Test Plan: Compiles, not yet tested as I'm on Wayland

Reviewers: #kwin, #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7197
2017-08-12 11:32:53 +02:00
Martin Flöser
630514d52a Remove roundtrip to XServer from Workspace::xStackingOrder
Introduce a method Workspace::markXStackingOrderAsDirty

Summary:
This method replaces the calls x_stacking_dirty = true in the code base
allowing for further refactoring of that functionality.

Remove roundtrip to XServer from Workspace::xStackingOrder

The method xStackingOrder is only used during a Compositor paint pass.
If the stacking order had changed, the method updated the stacking order
from X by performing a sync XQueryTree. With other words we had a round
trip to the X server directly in the paint pass.

This change rearchitectures this area by making better use of xcb. When
we notice that the stacking order changed and an XQueryTree is needed,
we directly send out the request. When xStackingOrder is finally called,
which normally happens a few milliseconds later, the reply is retreived.
In the worst case it still blocks, but in most cases the roundtrip is
gone.

If the stacking order changed again before accessing xStackingOrder the
running request is cancelled and a new request is issued. So whenever we
get into xStackingOrder it will have the current state.

The updating of the xStackingOrder is moved into a dedicated method and
xStackingOrder invokes it through a const_cast instead of operating on
mutable variables.

Test Plan: Normal system usage, no issues

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D6323
2017-07-01 08:21:51 +02:00
Luboš Luňák
af9f81700f fix uninitialized variable
Accessed later if e.g. compositing is suspended or not possible at startup.
2017-04-14 15:03:27 +02:00
Martin Gräßlin
ec2d862d4e Port Compositor::windowRepaintsPending to use std::any_of
Summary:
While investigating a repaint issue I had a hard time to work with the
code and decided to change it to a more modern variant.

Instead of duplicating the same logic for each of the lists it's now
moved into a dedicated templated method which used std::any_of. Which is
exactly the algorithm we need: if there is any window with a non empty
repaints region it should return true.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D3397
2016-11-25 07:37:28 +01:00
Antonio Larrosa
19147f5f85 [platformx/x11] Add a freeze protection against OpenGL
Summary:
With nouveau driver it can happen that KWin gets frozen when first trying
to render with OpenGL. This results in a freeze of the complete desktop
as the compositor is non functional.

Our OpenGL breakage detection is only able to detect crashes, but not
freezes. This change improves it by also added a freeze protection.

In the PreInit stage a thread is started with a QTimer of 15 sec. If the
timer fires, qFatal is triggered to terminate KWin. This can only happen
if the creation of the OpenGL compositor takes longer than said 15 sec.

In the PostInit stage the timer gets deleted and the thread stopeed
again.

Thus if a freeze is detected the OpenGL unsafe protection is written into
the config. KWin aborts and gets restarted by DrKonqui. The new KWin
instance will no longer try to activate the freezing OpenGL as the
protection is set.

If KWin doesn't freeze the protection is removed from the config as
we are used to.

Check for freezes for the first n frames, not just the first

This patch changes the freeze detection code to detect freezes in the
first 30 frames (by default, users can change that with the
KWIN_MAX_FRAMES_TESTED environment variable). This detects
successfully the freezes associated to nouveau drivers
in https://bugzilla.suse.com/show_bug.cgi?id=1005323

Reviewers: davidedmundson, #plasma, #kwin, graesslin

Reviewed By: #plasma, #kwin, graesslin

Subscribers: luebking, graesslin, kwin, plasma-devel, davidedmundson

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D3132
2016-10-25 09:51:23 +02:00
Martin Gräßlin
01ee957c49 Call setupCompositing on internal clients on startup of Compositor
This fixes a regression found in TestSceneQPainter for restarting the
Compositor. The internal clients were never added to the Scene.

We cannot just call setupCompositing because there is a phase during
startup where setupCompositing already passes but the Compositor is not
yet fully initialized. Thus it could happen that it's called twice which
makes the Scene assert.

To solve that setupCompositing and finishCompositing are now overriden
in ShellClient and track whether they successfully called
setupCompositing.
2016-08-19 12:33:59 +02:00
Martin Gräßlin
facca93606 Also finishCompositing for Wayland windows in Compositor::finish
We should be able to restart the Compositor also on Wayland.

As the Compositor might be terminated after Workspace we need to
ensure to not call into Workspace while doing finishCompositing.

Reviewed-By: bshah
2016-08-19 09:18:30 +02:00
Martin Gräßlin
996ee34e14 Remove the unredirect fullscreen windows functionality
Summary:
Rational: unredirect fullscreen windows is a weird beast. It's intended
to make fullscreen windows "faster" by not compositing that screen. But
that doesn't really work as KWin jumps out of that condition pretty
quickly. E.g. whenever a tooltip window is shown. KWin itself has a
better functionality by supporting to block compositing completely.
The complete code was full of hacks around it to try to ensure that
things don't break.

Overall unredirect fullscreen has always been the odd one. We had it
because a compositor needs to have it, but it never got truly integrated.
E.g. effects don't interact with it properly so that some things randomly
work, others don't. Will it trigger the screenedge, probably yes, but
will it show the highlight: properly no.

By removing the functionality we finally acknowledge that this mode is
not maintained and has not been maintained for years and that we do not
intend to support it better in future. Over the years we tried to make
it more and more hidden: it's disabled for Intel GPUs, because it used
to crash KWin. It's marked as an "expert" option, etc.

It's clearly something we tried to hide from the user that it exists.

For Wayland the whole unredirect infrastructure doesn't make sense
either. There is no such thing as "unredirecting". We might make use
of passing buffers directly to the underlying stack, but that will be
done automatically when we know it can be done, not by some magic is
this a window of specific size.

Test Plan:
Compiles, cannot really test as I am an Intel user who never
had that working.

Reviewers: #kwin, #plasma, #vdg

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D2180
2016-08-04 14:48:35 +02:00
Martin Gräßlin
3308f35984 Handle restart of Compositor Scene correctly for Wayland client
Summary:
This change ensures that KWin doesn't crash in the QPainter scene if
the compositor gets restarted and if there are Wayland clients.

BUG: 365471

Test Plan:
Test case added to scene qpainter which triggers a restart
of the Compositor with a window being shown. Verifies that rendering
is correct afterwards.

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2185
2016-07-21 08:11:32 +02:00
Martin Gräßlin
9d7ef58b2b Support restarting the OpenGL compositor on Wayland
Summary:
KWin needs to support restarting the OpenGL compositor in case of a
graphics reset event.

On Wayland the tricky part is that the applications should not notice
this. Most importantly KWin cannot just destroy the EGLDisplay and create
a new one. But this is how a restart works: the complete compositor gets
torn down and recreated - including the EGLDisplay.

This change moves ownership of the EGLDisplay to the Platform.
The AbstractEglBackend subclasses query the Platform whether there is
already an EGLDisplay. Only if there is no EGLDisplay the EGLDisplay is
created and only if no EGLDisplay is registered with Wayland the bind
is performed.

Another change is regarding the destruction: the AbstractEglDisplay does
no longer unbind the Wayland display and does no longer destroy the
EGLDisplay. The EGLDisplay is destroyed by the Platform - so very late
on application exit. The Wayland display is unbound when the Compositor
terminates.

Test Plan:
Limited testing with the added auto-test. This one needs to
be extended to fully verify that OpenGL applications continue to work.
But this requires build.kde.org to support OpenGL on Wayland.

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2202
2016-07-20 14:08:23 +02:00
Martin Gräßlin
f27dceda2c Disable the locked screen check in Compositor::windowRepaintsPending
This is responsible for plasmashell freezing when screen is locked.

The change itself was not wrong, but we first need to enable the
infrastructure to "fake" rendering when screen is locked/disabled, etc.
2016-07-19 08:14:40 +02:00
Martin Gräßlin
a35ffa93d7 Use hiddenInternal() for a ShellClient which got unmapped
Summary:
So far when a ShellClient got unmapped ready_for_painting was set to
false. That is the ShellClient was treated in the same way as a not
yet shown window. It was completely excluded from painting, a close
animation impossible.

This change makes use of the functionality available in
Client::hiddenInternal(). The window is considered as hidden, thus
still excluded from e.g. getting input events, but could be rendered
any time as we still have a previous window pixmap (if referenced).
This allows to have it considered in the rendering pass, but effects
still cannot make use of it as that state is not yet exposed to the
effects.

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2083
2016-07-13 10:45:10 +02:00
Martin Gräßlin
3c6dff75d5 Stop composite timer when Workspace gets destroyed
On Wayland tear down the Workspace gets destroyed before the Compositor
gets destroyed. If the timer fires in that area, the Compositor would
crash. It's not possible to start the timer if the Workspace is
destroyed, thus it should also be stoped on Workspace destroy.

Reviewed-By: Bhushan Shah
2016-06-29 08:34:10 +02:00
Martin Gräßlin
7c822fadee Move the OpenGL unsafe check into the Platform
Summary:
A new virtual method createOpenGLSafePoint is added to Platform.
This is invoked through the Compositor with a PreInit and a PostInit
argument pre and post creating the SceneOpenGL.

The Platform plugin can implement this and use it for detecting whether
creating the OpenGL compositor on this platform crashed in the past.
Thus it's the base for the openGLIsBroken platform check.

The x11 standalone plugin is the first to implement this functionality
using the previous code which was designed for X11.

This also means that a crash of the OpenGL compositor during init on
Wayland won't result in OpenGL being disabled.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1582
2016-05-17 14:29:29 +02:00
Martin Gräßlin
48e69b77d9 If glx is not available try to create egl backend
Summary:
So far the OpenGL is unsafe check functionality in Compositor disabled
OpenGL compositing if glx is not available and we are in standalone X11
mode.

This is technically no longer correct for quite some time. Just because
GLX is not available doesn't mean that OpenGL doesn't work. We have an
EGL backend. So let's try to use that if glx is not available.

This change removes the check completely from Compositor. Instead the
standalone x11 plugin checks whether glx is available prior to createing
the glx backend. If not available it falls through to the egl backend.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1581
2016-05-17 14:25:33 +02:00
Martin Gräßlin
d15d3a5ff1 Provide functionality of CompositingPrefs through Platform
Summary:
CompositingPrefs is only relevant for X11 standalone. It had some
"hacks" to make it not block Compositing on Wayland. Thus it was in
its current form not really useful.

Now all the functionality is provided through Platform with a default
implementation which is sensible for Wayland platforms.

The X11 standalone platform implements the new methods with the
Wayland checks removed.

In addition all calls to CompositingPrefs now go through the platform
directly and CompositingPrefs is completely dropped.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1576
2016-05-17 13:59:52 +02:00
Martin Gräßlin
c45942a70c Move requiresCompositing from Application to Platform
Summary:
This change reduces the windowing system specific code pathes. Instead
of checking whether we are on X11 or Wayland to decide whether
compositing is required, we just ask the Platform.

The default is true, only x11 standalone allows to not require
compositing.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1575
2016-05-17 13:59:32 +02:00
Martin Gräßlin
56331942f3 Bind sending frameRendered to whether we have a Wayland Server not to operation mode
Summary:
This ensures that frameRendered is also sent if we start a Wayland Server
on X11.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1597
2016-05-13 10:05:38 +02:00
Martin Gräßlin
1845881fbf Don't call xcb_damage_subtract for Wayland windows
Summary:
Instead of checking the operation mode for X11, we check whether the
damage_handle is created. This fixes a bad damage warning for Wayland
windows in kwin_x11.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1490
2016-05-02 15:54:27 +02:00
Martin Gräßlin
a0919d6c4d Only create damage_handle for Toplevel's without a Wayland Surface
Summary:
If the Toplevel has a Wayland Surface we don't want an X11 damage
handle. Ideally we would just check for the Surface and get rid of
the operation mode check. But setupCompositing is called for Xwayland
clients before the surface is set.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1486
2016-05-02 15:53:22 +02:00
Martin Gräßlin
bfa31d48cd Only destroy damage_handle if a damage_handle got created
Summary:
Instead of binding to the OperationMode whether the damage_handle
should be destroyed, we bind it to whether damage_handle got created.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1483
2016-05-02 15:52:39 +02:00
Martin Gräßlin
e64450c807 Merge branch 'Plasma/5.6' 2016-04-26 13:13:17 +02:00
Martin Gräßlin
4ef07494bd Don't check for waylandServer() when accessing the platform in Compositor
Summary: Less diversions between X11 and Wayland.

Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1415
2016-04-15 15:21:49 +02:00
Martin Gräßlin
df2c26e3d9 Only start Xwayland server if Compositor created a Scene
So far if the Scene creation failed kwin_wayland went into a shutdown,
but didn't succeed because the thread to start Xwayland was already
running: it froze.

This change introduces a new signal in Compositor: sceneCreated. The
startup of Xwayland is bound to this signal. If it gets fired KWin can
startup Xwayland. If it does not get fired, KWin terminates correctly.
2016-04-14 08:51:16 +02:00
Martin Gräßlin
d31e9e88b4 Rename abstract_backend.(h|cpp) to platform.(h|cpp)
Reviewers: #plasma

Subscribers: plasma-devel

Projects: #plasma

Differential Revision: https://phabricator.kde.org/D1340
2016-04-07 16:18:12 +02:00
Martin Gräßlin
10632f09ca Rename AbstractBackend to Platform 2016-04-07 16:18:12 +02:00
Martin Gräßlin
146af48f22 waylandServer()->backend() replaced by kwinApp()->platform() 2016-04-07 15:00:11 +02:00
Martin Gräßlin
757523a324 Use kwinApp()->config() instead of KSharedConfig::openConfig()
That way all over kwin we can inject a custom config in the autotests.
2016-01-29 11:24:18 +01:00
Thomas Lübking
87795eef2a Actually keep the expandedGeometry alive
... until the effects handled the deletion

BUG: 318322
BUG: 320892
BUG: 344359
REVIEW: 126323

FIXED-IN: 5.6
2016-01-15 01:37:51 +01:00
Michael Pyne
4957c18a44 Widen int to qint64 before multiplication, not after.
Noted by Coverity, CID 1334968.
2015-12-27 21:56:09 -05:00
Bhushan Shah
e5518dffe2 [wayland] Add some restrictions for lockscreen
When screen is locked,

- No window other then screenlocker or inputmethods gets rendered
- Only screenlocker gets keyboard events
- Only screenlocker and inputmethods get mouse events

Things that are not secured/tested are :

- Touch events
- Global shortcuts for screenlocker
- Fallback/emergency screen not yet working

REVIEW: 126015
2015-11-16 16:16:20 +05:30
Martin Gräßlin
240e7ba337 [wayland] Emit signal before x11 connection gets destroyed
Used in Compositor to destroy the cm_selection. This would crash
otherwise as it calls into xcb after Xwayland is destroyed.
2015-11-12 15:13:42 +01:00
Martin Gräßlin
f75e53af60 [wayland] Ensure to not call into x11 on Compositor tear-down
During Compositor tear down Xwayland is already destroyed. Thus it
doesn't make sense to try to delete the support properties: either
it freezes in xcb or it crashes because the connection is null.

At the same time we also ensure that the connection internally is
reset to null. Note: the one in kwinglobals.h caches and could cause
use-after-free errors. Any tear-down code must be migrated to
kwinApp()->x11Connection().
2015-11-10 13:54:26 +01:00
Nick Shaforostoff
3a8d7d866a optimize string operations
-use qstringliteral only when necessary (i.e. not in concat or comparison)
-use qbytearray instead of qstring when dealing with latin1 input and output (glplatform)
-use qstringref to extract numbers from strings (glplatform)
-define qt_use_qstringbuilder to optimize all string concatenations
-anidata: use ctor init lists, add windowType member initialization

REVIEW: 125933
2015-11-05 14:14:06 +00:00
Martin Gräßlin
004b928c8d Core uses runtime checks for whether we are on OpenGLES 2015-11-03 09:29:31 +01:00
Martin Gräßlin
95a99d337a Move s_haveResizeEffect from Client to AbstractClient 2015-10-26 09:21:36 +01:00
Martin Gräßlin
d24411b9ac Don't perform Compositor::setCompositeTimer during startup
The check whether Workspace is created is not sufficient. There's a
time when Workspace is already created but Compositor not ready yet
and where we can hit this code path.
2015-10-20 11:41:04 +02:00
Thomas Lübking
d04645266c enforce update on re-redirection
REVIEW: 125039
BUG: 342881
FIXED-IN: 5.5
2015-09-29 23:02:41 +02:00
Martin Gräßlin
679da47235 [wayland] Don't run Compositor loop if all outputs are disabled
This ensures that the Compositor doesn't perform compositing and doesn't
run the compositing timer if e.g. all outputs are dpms disabled. Thus
we don't render any more, don't trigger wakeups and block applications
from rendering if they properly implement the frame rendered callback.
2015-09-10 14:31:46 +02:00
Martin Gräßlin
3139dcd3b9 Drop cmakedefine HAVE_WAYLAND
Now a required build dependency.
2015-08-12 11:39:20 +02:00
Martin Gräßlin
bc45c61eeb [wayland] Not visible windows should not trigger a repaint
When going through the pending repaints we need to ensure that
an unmapped Wayland client doesn't keep us in a repaint loop.
2015-07-17 20:39:57 +02:00
Martin Gräßlin
72635101f0 [wayland] Improve creation of KWayland::Server::PlasmaWindowInterface
The creation of PlasmaWindowInterface is moved from WaylandServer into
AbstractClient. This allows the sub classes to better control when to
create/destroy the Client.

For creation it's bound to becoming visible - that is Windows which are
only created but never shown are not announced at all.

For Client it's destroyed with the normal tear-down of a Client, for
ShellClient it's destroyed on unmapped (which also means a new one
will be created again in case of another mapping of the surface).

As a side effect, this works around the problem that ShellClients do not
yet get destroyed for QtWayland's menus (needs further investigation).
2015-07-09 09:10:33 +02:00
Martin Gräßlin
86e0fc4dde [wayland] Ensure internal clients can trigger compositor repaints 2015-06-06 17:43:13 +02:00
Martin Gräßlin
48272a0de8 Ensure Compositor can tear down without a Workspace
It's possible that the Workspace doesn't get created at all (e.g.
Xwayland failed to start). In that case we must ensure to not call into
Workspace calls during tear down.
2015-05-27 09:13:33 +02:00
Thomas Lübking
e42c874859 Merge branch 'Plasma/5.3' 2015-05-17 22:23:27 +02:00
Thomas Lübking
e6176ffc02 fix CM reselection
only return early if we cannot create a
selectionwatcher, otherwise the claiming
code turns unreachable after the creation
of cm_selection

BUG: 347813
REVIEW: 123826
2015-05-17 22:13:25 +02:00
Martin Gräßlin
d60c377890 [wayland] Introduce a ShellClient
The ShellClient is a Toplevel subclass for a
KWayland::Server::ShellSurfaceInterface. It gets created when a new
ShellSurfaceInterface is created and destoryed when it gets unmapped.

So far the usage is still rather limited. The ShellClient is opened
at position (0/0). While it's possible to pass pointer events to it,
it's not yet possible to activate it, so no keyboard focus.
2015-05-08 12:43:44 +02:00
Martin Gräßlin
2afaa60dc5 [wayland] A backend can mark whether it is ready
Replaces the functionality of the WaylandBackend and makes it available
to all backends by providing the functionality directly in
AbstractBackend. By default a backend is not ready and the implementation
must call setReady(true) to indicate that setup has finished
successfully. The compositor won't start till the backend indicates that
it is ready.
2015-05-05 19:05:31 +02:00
Martin Gräßlin
72db1e63a3 [wayland] Move backend implementations into a backends/<name> directory
The aim is to be able to create a plugin for each of the backends.
The following directories are created:
* backends/drm
* backends/fbdev
* backends/wayland
* backends/x11
2015-05-05 13:05:37 +02:00
Martin Gräßlin
49f58059c6 [wayland] Backends are no longer singletons
They are installed in the WaylandServer, thus we don't need an explicit
singleton accessor. If we need to differentiate we can cast.
2015-03-23 14:29:07 +01:00
Martin Gräßlin
6bf44b7db4 [wayland] Add an X11 output backend
This new backend allows to start a kwin_wayland server nested on an
X-Server by using a normal X11 window as output. This allows testing
kwin_wayland without needing to start another Wayland server first.

The behavior is triggered by using new command line arguments:
--windowed
--x11-display=<:0>

With optional --width and --height arguments.

In this mode the WaylandBackend is not created at all.

So far the backend is not fully integrated yet and only the QPainter
backend supports this mode.
2015-03-20 14:08:53 +01:00
Martin Gräßlin
862bb95ffb [wayland] Do not start composite timer if Workspace is not ready yet
Could cause a race during startup resulting in crash.
2015-03-18 16:27:22 +01:00
Martin Gräßlin
fafa22d0c6 [wayland] Invoke frame rendered callback on damaged windows
Introduces a new time counter on Compositor to indicate the elapsed
time sine the compositor started.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
659c416879 [wayland] Handle damage events from SurfaceInterface
On Wayland we get the damage from the SurfaceInterface instead of
using a damage handle. This change ensures that the damage handle
interaction is only used on platform X11, while on Wayland we get
the damage from the SurfaceInterface directly.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
50ef02fa1b [wayland] Start Compositor and Scene before Workspace
For Xwayland we need to have the Scene (and EglDisplay) created prior
to starting Xwayland and having X11. This requires creating the
Compositor before creating Workspace and starting Xwayland.

To support this the startup of Compositor is split into two parts:
prior and after Workspace creation.

The change might also be interesting for the kwin_x11 case as it could
result in the compositor being up in a quicker way.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
659ff1c732 [wayland] Don't check whether GLX is available
We won't use it, so let's not check for it.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
58d79e2da4 Compositor: connect to configChanged emitted by Options instead of Workspace
Removes dependency to Workspace in ctor.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
147af71f8a Drop Workspace dependency from Scene
Only used for one connect which can also be done outside of Scene.
Subclasses got the singleton pointer and just passed to the parent.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
7c3197b1eb Use new ctors for KXMessages and KSelectionOwner
Allows to pass the connection and rootWindow and doesn't depend on
QX11Info.
2015-03-17 10:20:19 +01:00
Martin Gräßlin
c383d6074c Replace QX11Info::appScreen() with KWin::Application::x11ScreenNumber()
No need to go through QX11Info for information we have.
2015-03-17 09:44:53 +01:00
Fredrik Höglund
38f1945c6c Use swap events to drive repaints
Don't start the composite timer at the end of performPaint() when a
buffer swap is pending and vsync is enabled.  Instead set
m_composeAtSwapCompletion to true so performPaint() gets called again
as soon as the swap completes.

This makes the repaint cycle look like this:

    scene->paint()
    SwapBuffers()
    Process events
          ·
          ·
    Swap completes
    Fetch and reset damage (if applicable)
    scene->paint()
    SwapBuffers()
    Process events
          ·
          ·
    Swap completes
    ...

This results in a noticeable improvement in animation smoothness with
drivers that support GLX_INTEL_swap_event, since we're now able to
consistently render at the monitor refresh rate.
2015-01-06 07:51:50 +01:00
Daniel Pastushchak
0d997b1093 Introduce categorized logging for kwin core
Done by Daniel Pastushchak for KDE during GCI-2014.
2014-12-05 14:27:15 +01:00
Martin Gräßlin
f78ff8eaa5 Do not emit DecorationSettings::alphaChannelSupportedChanged on tear down
The Compositor is destroyed before the Client and Decorations are
destroyed on shutdown. This meant the Decorations reacted needlessly
on the alpha channel supported. E.g. Aurorae recreated the Decoration
and most likely crashed in Qt.

With this change the signal gets disconnected and the Decorations
just don't do anything.
2014-12-03 13:10:35 +01:00
Martin Gräßlin
c2e53b9a2f Merge branch 'kdecorations2'
Conflicts:
	effects.cpp
	paintredirector.cpp
2014-12-02 08:38:10 +01:00
Martin Gräßlin
bf4ba54647 Remove displayWidth and displayHeight from the compositor
Instead of getting size from displayWidth() and displayHeight() use
the information we have from Screens. This means there is only one
place to have the information and by that we can ensure that all
components use the same data to rely on. displayWidth/displayHeight
seem to provide the wrong information when unplugging an output
without disabling the output. This results in rendering artefacts.
But KWin::Screens has the correct information available.
2014-11-27 09:00:19 +01:00
Martin Gräßlin
21dca7ac14 Keep a QPointer<DecoratedClientImpl> in Client
This allows to remove the internal access to the DecoratedClientPrivate
in the KDecoration API.
2014-10-21 07:46:44 +02:00
Martin Gräßlin
e32da9d9e0 Merge branch 'master' into kdecorations2
Conflicts:
	CMakeLists.txt
	paintredirector.cpp
	scene_opengl.h
	scene_qpainter.h
	scene_xrender.h
2014-10-20 16:04:52 +02:00
Fredrik Höglund
32e9de1e23 Refactor the swap completion interface
Move the buffer-swap-pending state from the compositing backends to
the Compositor class. The Compositor is the only class that needs to
access the state, and this way it to do it without calling through
a chain of virtual functions. This commit adds two new functions to
Compositor; aboutToSwapBuffers() and bufferSwapComplete(). The
backends call these functions to set and reset the buffer-swap-pending
state.

This commit also renames a number of functions and variables to make
their meaning clear.

The act of promoting the contents of the back buffer to become the
contents of the front buffer is referred to as posting the buffer,
presenting the buffer, or swapping the buffers; rendering the buffer
is what paintScreen() does.
2014-09-18 20:21:20 +02:00