Mir

MirResizeEvent's width/height fields are not in sync with the next buffer the client receives

Bug #1288021 reported by Daniel van Vugt
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mir
Triaged
Medium
Unassigned
mir (Ubuntu)
Triaged
Medium
Unassigned

Bug Description

MirResizeEvent's width/height fields are not in sync with the next buffer the client receives.

This is because they represent the latest dimensions of a surface. However, due to compositing and frame scheduling, MirResizeEvent arrives a significant time before the client gets any buffers with the new dimensions. So if the client actually tries to use the width/height provided in MirResizeEvent, it will render incorrectly with ugly artefacts.

Clients should always be using the latest _buffer_ dimensions, and not the latest surface dimensions. As demonstrated in examples/* the latest buffer dimensions are available via:

mir_buffer_usage_software: Use the width/height returned by mir_surface_get_graphics_region().

mir_buffer_usage_hardware: Use the actual buffer dimensions as accurately reported by EGL as soon as you get a new buffer from eglSwapBuffers:

    eglSwapBuffers(egldisplay, eglsurface);

    if (eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, &width) &&
        eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height))
    {
        glViewport(0, 0, width, height);
    }

This is current best practice, and will result in smooth client resizing. Unfortunately it means the width/height fields in the MirResizeEvent structure should be ignored. Perhaps we need to deprecate them, or perhaps we should enhance them to represent buffer dimensions instead...

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Is there any news on this? Does event 2.0 fixes it?

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

No news, maybe.

Fixing this fully would be a significant change, probably in libmirclient logic. We'd need to implement code to replace the underlying buffer a client has _after_ they have been given it by swapping. This can only work if we can detect whether the client has started rendering to the buffer or not. So I don't know.

Simpler solutions might be possible, whereby we just synthesize MirResizeEvent in a way that guarantees it agrees with what's coming in the next SwapBuffers. Come to think of it, since Mir is switching to double buffers in release 0.12, this might just happen by default. So long as you never make the assumption that the new size is available before you SwapBuffers, then the new double buffering in 0.12 might just solve this.

tags: added: resize
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

For a more recent history of this bug causing pain in QtMir/Unity8 see bug 1466510.

Changed in mir:
assignee: nobody → Daniel van Vugt (vanvugt)
summary: - MirResizeEvent's width/height fields are not useful, even dangerous
+ MirResizeEvent's width/height fields are not in sync with the next
+ buffer the client receives
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

When dealing with this issue in Xmir, I came up with another approach -

If you resize your client to the "future" dimensions given in MirResizeEvent then you will have much less resizing lag. Just so long as you also remember to clip (glViewport) your rendering to the buffer dimensions which may be different to the surface dimensions.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

And also remember to keep redrawing new frames until buffer size == surface size.

description: updated
tags: added: xmir
Changed in mir:
assignee: Daniel van Vugt (vanvugt) → nobody
Revision history for this message
Michał Sawicz (saviq) wrote :

Syncing task from Mir.

Changed in mir (Ubuntu):
importance: Undecided → Medium
status: New → Triaged
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.