Hi,

I've noticed that uploading data from shared client memory buffers to textures hurts performance really bad in kwin. Sometimes, it takes about 40ms to attach a client buffer to a texture. Since most compositors don't take any precautions of uploading the buffer data asynchronously, you may also experience this problem with weston, sway, etc.

One way to prevent stalling the compositor is to apply the committed state after updating the texture. In other words, when a surface is committed, you enqueue the pending state and kick off an upload job on a different thread. Once the upload job has completed, remove the cached state from the queue and (depending on if it's a synchronized sub-surface) apply it. This solution has a lot in common with how the linux-explicit-synchronization protocol should be ideally implemented.

Another way to address this issue is to use PBOs. Even though they drastically improve the performance, the resulting upload times are still too high (at least that is the case on my machine).

The tricky thing about the queue-based solution is that every shared memory client buffer will have to have its own texture and therefore there must be some way to indicate the buffer damage. At the moment, if a client feeds the compositor with shared memory client buffers, all those buffers will be attached to a single texture and therefore the surface damage is sort of (but not really) equivalent to the buffer damage.

Given that the wl_surface object has a method with a name of damage_buffer, I should clarify what I mean by "surface damage" and "buffer damage". A surface damage indicates the area of the surface that has changed between two consecutive commits. A buffer damage is the area of the buffer that has changed since last time it was used. To get more detailed explanation of the difference between the surface damage and the buffer damage, please refer to the EGL_KHR_partial_update spec.

wl_surface_damage() and wl_surface_damage_buffer() specify the surface damage.

The compositor could keep the last N surface damages and then accumulate them to get the buffer damage, but it's a heuristic, it doesn't always produce the right results... It would be great if the wl_buffer interface had a method to specify the buffer damage, e.g.

    wl_buffer_damage(buffer, ... buffer_damage); <-- this one
    wl_surface_attach(surface, buffer, 0, 0);
    wl_surface_damage(surface, ... surface_damage);
    wl_surface_commit(surface);

The buffer damage and the surface damage are not the same and there is no **strong** connection between the two, for example, if the buffer damage is empty, it doesn't imply that the surface damage is also empty (and vice versa). It can be the case if the client has pre-rendered N buffers and simply cycles between them.

What is your opinion about buffer damage? Do you think it makes sense or are there alternatives that don't require changing the core wayland protocols?

Cheers,
Vlad
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to