Bug 93094

Summary: Protocol: colored buffer
Product: Wayland Reporter: phizh <phizhed>
Component: waylandAssignee: Wayland bug list <wayland-bugs>
Status: RESOLVED WONTFIX QA Contact:
Severity: enhancement    
Priority: medium    
Version: unspecified   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description phizh 2015-11-24 18:07:23 UTC
Create a simple X application, fill color to empty window, then change the window size - the color is redrawn. Chaotic drive the cursor and see the CPU load. The same situation with empty windows when using toolkits - frequent redrawing.

I propose to create a wayland protocol extension, which you can get the colored wl_buffer desired size and then work with him as with the original wl_buffer. The compositor is anyway responsible for the rendering of client buffers and nothing prevents to fill a buffer the color chosen by the client.

So, we have 5 full-screen clients who want to fill their surfaces is black color. Assume that the screen resolution 1920x1080, format argb8888. Each client will create a shared memory file is size 1920*1080*4 = 8294400 B ~= 8 MB. Because clients 5, the total cost 35 MB of memory.

However, using this protocol extension would expend a total memory of 8 MB. In addition, the compositor can fill the buffer using a variety of optimizations - the scope for compositor developers.
Comment 1 phizh 2015-11-24 18:12:19 UTC
* the total cost 40 MB of memory

not enough sleep :)
Comment 2 Daniel Stone 2015-11-24 20:52:14 UTC
I understand the rationale, but I don't think having five fullscreen solid-colour surfaces is a particularly realistic usecase ... do you have any rationale behind this?

Also, this will have no actual impact on cursor movement.
Comment 3 Pekka Paalanen 2015-11-25 07:20:52 UTC
I don't understand why moving the cursor would cause CPU load. We need a lot more information about the implementations involved to reply to that. It sounds like something (the application?) is redrawing or posting damage when there is none.

But you talk about an X application. Is this CPU usage issue specific to Xwayland?

Now, assuming you use case is valid...

For a solid color buffer, we could add what you propose, but there is already protocol to do the equivalent and consuming just one pixel of storage: allocate a 1x1 wl_buffer, e.g. from wl_shm, and paint the one pixel with the color you want. When attaching it to a wl_surface, use wl_viewport to scale that one pixel up to any size you want.

The extension for wl_viewport is not stable yet, but should be quite soon. You can follow it in bug #83918.

If this is really about Xwayland, it seems you have three separate issues filed here:
- the CPU consumption with Xwayland
- Wayland protocol for solid color buffers
- making Xwayland use the solid color buffers (if even possible)

Is this correct?


Btw. it is allowed to attach the same wl_buffer to several wl_surfaces at the same time, but there is a caveat: bug #75303
Comment 4 phizh 2015-11-25 19:19:51 UTC
> I don't understand why moving the cursor would cause CPU load. We need a lot
> more information about the implementations involved to reply to that. It
> sounds like something (the application?) is redrawing or posting damage when
> there is none.
Press down mouse click the corner of the window and slow or chaotic move the cursor, thereby causing frequent redraws when you resize the window and load CPU. I understand that this is a problem of optimization toolkits. But even demos from weston's have similar problems. Resizing window: +1 width or height, +1, +1, +1, +1...... => redrawing background, redrawing, redrawing, redrawing..... http://cgit.freedesktop.org/wayland/weston/tree/clients/editor.c#n721


The reality is that _each_ program fills color to shm, and I want that the programs to use is _already filled shm_.

To do this, and need a unified standard in the role of the protocol, to save more, more and more memory. Laptops 12" with 4K displays are not uncommon, and if you add another connection to an external monitor... A dozen running apps with one theme (and same colors) and the resulting inefficient use of memory for storage of colors and the load when redrawing this.

> But you talk about an X application. Is this CPU usage issue specific to
> Xwayland?
Specific for wayland, X's, Xwayland and gtk, qt, winforms..... - everywhere.
Comment 5 Pekka Paalanen 2015-11-26 07:44:16 UTC
Oh you were talking about continuously resizing the window! Sorry, I didn't get that.

Yes, resizing a window is a very heavy operation, not only causing repaints and content relayouts, but often also buffer reallocations. This is because windows practically always have content that is not a single solid color, which actually requires a full repaint when resized. If you don't want the incurred system load, you have to go back to outline resizing instead of using the modern live resizing. Another option is to have the compositor just scale the old image and signal the size change to the app only when the mouse button has been released. Both alternate resizing methods can be implemented in a compositor without any protocol changes.

I do not think it makes any sense to try to optimize resizing for a solid color surface, because really, what's the use case?

That said, and as I already pointed, there is a way to avoid redrawing huge shm buffers all the time when all you got is a solid color: use 1x1 buffer and wl_viewport. The protocol spec has been written, and Weston has an implementation. It's just that there is no Weston demo that would only draw a solid color surface, because it would be useless.

If windows do not have identical content, there is no memory you could save by de-duplication, because nothing is duplicated.

Getting a pre-filled shm buffer and then "work with him as with the original wl_buffer" saves nothing, because every such buffers needs to be a new instance and painted to the pre-fill color, because the app would be drawing its own thing into that buffer. There is nothing to be gained, and if the compositor were to hand out pre-filled buffers, the compositor would take the performance hit across the whole desktop rather than just the one application.

It is more heavy to copy a buffer from another, than to fill one with a color.
Comment 6 phizh 2015-11-28 19:01:33 UTC
Perhaps, between us is another misunderstanding. When using wl_viewport and wl_buffer 1x1 composer resizes to MxN. When live resizing is happening scale and crop - fills pixels are already a compositor, not a client. And, as I understand it, the compositor makes each time at the beginning of resizing window. That's not what I want.



// get_colored_buffer(color, width, height, stride, format);

/*
Create a wl_buffer - cheap operation. The filling of the shared memory file - expensive operation.
What does the composer when he is asked the colored buffer: if he has no shared memory file with the required color, he creates it. If the file is empty, then fills it to the necessary length ("stride * height"). If the file is not empty, appends to the end of the required number of pixels ("stride * height - shared_memory_file_length"). Then creates a wl_buffer, and gives it to the client;
*/

So, now step by step:
1. "CLIENT_1" asks the compositor "get_colored_buffer(0xFF880000, 100, 100, 400, XRGB8888)";
2. Compositor creates a shared memory file "FILE_1" of length 40_000 and fills it to the 40_000 red (because 0xFF880000) pixels in the pixel format XRGB8888. Creates a wl_buffer from "FILE_1", and gives it wl_buffer to the "CLIENT_1";
3. "CLIENT_2" asks the compositor "get_colored_buffer(0xFF880000, 100, 100, 400, XRGB8888)";
4. The composer creates a wl_buffer from "FILE_1", and gives it wl_buffer to the "CLIENT_2";
5. "CLIENT_1" asks the compositor "get_colored_buffer(0xFF880000, 200, 100, 800, XRGB8888)";
6. The compositor appends to a "FILE_1" 40_000 pixels. The length of the "FILE_1" now is 80_000. Creates a wl_buffer from "FILE_1", and gives it wl_buffer to the "CLIENT_1";
7. "CLIENT_1" asks the compositor "get_colored_buffer(0xFF880000, 10, 10, 40, XRGB8888)";
8. The composer creates a wl_buffer from "FILE_1", and gives it wl_buffer to the "CLIENT_1";


This leads to memory savings. Toolkit's in the future will be less CPU load when resizing window, because they no longer have to manually fill color. Qt application will use the same colored shared memory file, as GTK apps.
Comment 7 Pekka Paalanen 2015-11-29 11:24:47 UTC
(In reply to phizh from comment #6)
> Perhaps, between us is another misunderstanding. When using wl_viewport and
> wl_buffer 1x1 composer resizes to MxN. When live resizing is happening scale
> and crop - fills pixels are already a compositor, not a client. And, as I
> understand it, the compositor makes each time at the beginning of resizing
> window. That's not what I want.

With wl_viewport, the compositor does *not* create any kind of buffer of size NxM. During compositor repaint, it will just fill the given size with the given color in the final framebuffer, which is the cheapest possible operation. There is no memory reserved for the NxM image at all.

Why is that not what you want?

Do you want to do something with the buffer in the client *after* it has been filled with the given color? If so, what do you want to do?
Comment 8 phizh 2015-11-29 13:34:22 UTC
(In reply to Pekka Paalanen from comment #7)
> With wl_viewport, the compositor does *not* create any kind of buffer of
> size NxM. During compositor repaint, it will just fill the given size with
> the given color in the final framebuffer, which is the cheapest possible
> operation. There is no memory reserved for the NxM image at all.
> 
> Why is that not what you want?
> 
> Do you want to do something with the buffer in the client *after* it has
> been filled with the given color? If so, what do you want to do?

>> in the final framebuffer, which is the cheapest possible operation

My goal is to slow resize the window, filled in one color, and have a 0% CPU load. Not understanding the way it works from the inside, I was trying to think optimization based on API abstractions like wl_buffer and wl_shm_pool. Now we have to wait wl_viewport support from toolkits..
Comment 9 Pekka Paalanen 2015-11-30 12:52:41 UTC
I do not think toolkits will ever bother optimizing for the case of an empty window. There is just no use for it.

Besides, if the window has resizing handles or any decorations, it may not be empty: the window decorations might be drawn in the same buffer (the default on Gnome and Gtk+ AFAIK). This prevents sharing the buffer storage, and disallows the use of the wl_viewport trick.

Closing as wontfix.

If you want near zero CPU-usage for window resizing, you'll get that with a compositor that implements either outline or GL-texture-scaled resizing instead of live resizing, regardless of window content. That could actually have a use.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.