Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform api merge #2962

Merged
merged 112 commits into from
Oct 18, 2023
Merged

Platform api merge #2962

merged 112 commits into from
Oct 18, 2023

Conversation

RAOF
Copy link
Contributor

@RAOF RAOF commented Jun 9, 2023

Rework the graphics platform API to support multiple features:

  • Support loading multiple different display backends, combining them all into a single logical set of displays.
  • Support loading multiple rendering platforms, allowing different displays to be composited on different GPUs.

Probing & construction are reworked so that a each DisplayPlatform and RenderingPlatform instance is associated with a single hardware device - so systems with multiple GPUs get a DisplayPlatform instance per GPU and a RenderingPlatform instance per GPU.

Because rendering and display (and client buffer allocation) are linked, there's a selection dance that occurs:

  • First, we probe the DisplayPlatforms, on the assumption that whatever display hardware is there is there.
  • Then, we probe the RenderingPlatforms, giving a list of the display platforms selected.

This selects the set of platforms loaded.

Since each output can be driven by a different DisplayPlatform there is a subsequent probing phase in the DefaultDisplayBufferCompositorFactory. Here, the best rendering platform for the specific output is selected from the set of loaded platforms.

An additional constraint is the_buffer_allocator - the renderer needs to be able to import the buffers allocated by the clients.

Currently, the RenderingPlatform that supplies the_buffer_allocator is chosen arbitrarily. In future, all loaded RenderingPlatforms could be used instead, to provide the full range of client buffer allocation options (although care will be needed to ensure that a mir::Buffer can be imported as a texture on all active RenderingPlatforms).

The various interfaces and how they relate to the rest of Mir:

  • GLRenderingProvider: This is the primary (rendering) interface between the platforms and the rest of Mir.
    • It provides the way to construct a gl::OutputSurface for a display - an interface which provides a GL context and a commit() -> Framebuffer method to get a handle to submit for display.
    • It provides as_texture(Buffer) to take a mir::Buffer and return something implementing gl::Texture, for use in the Renderer.
  • DisplayBuffer: This loses its GL-context-providing function, and instead takes a Framebuffer to put on screen

@RAOF RAOF marked this pull request as draft June 9, 2023 08:10
@codecov
Copy link

codecov bot commented Jun 20, 2023

Codecov Report

Merging #2962 (926748e) into main (effa154) will decrease coverage by 1.80%.
The diff coverage is 37.57%.

@@            Coverage Diff             @@
##             main    #2962      +/-   ##
==========================================
- Coverage   77.67%   75.88%   -1.80%     
==========================================
  Files        1056     1058       +2     
  Lines       73473    74132     +659     
==========================================
- Hits        57071    56252     -819     
- Misses      16402    17880    +1478     
Files Coverage Δ
include/platform/mir/graphics/buffer.h 100.00% <ø> (ø)
include/platform/mir/graphics/display.h 100.00% <ø> (ø)
include/platform/mir/graphics/display_buffer.h 100.00% <ø> (ø)
...atform/mir/graphics/display_configuration_policy.h 100.00% <ø> (ø)
include/platform/mir/graphics/dmabuf_buffer.h 100.00% <ø> (ø)
include/platform/mir/graphics/egl_extensions.h 90.90% <ø> (ø)
...e/platform/mir/graphics/graphic_buffer_allocator.h 100.00% <ø> (ø)
include/platform/mir/renderer/gl/gl_surface.h 100.00% <100.00%> (ø)
include/renderer/mir/renderer/renderer.h 100.00% <ø> (ø)
include/renderer/mir/renderer/renderer_factory.h 100.00% <ø> (ø)
... and 102 more

... and 30 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick browse turned up a few "housekeeping" issues:

  • Header comments don't match current practice
  • We need to bump at least one ABI (mirplatform) and probably mirrender & mirserver too
  • Not all the files added are included in the build

include/core/mir/geometry/forward.h Outdated Show resolved Hide resolved
include/platform/mir/graphics/display.h Show resolved Hide resolved
include/platform/mir/renderer/gl/gl_surface.h Outdated Show resolved Hide resolved
include/platform/mir/renderer/gl/gl_surface.h Outdated Show resolved Hide resolved
Comment on lines 223 to 229

MIR_PLATFORM_2.13 {
global:
extern "C++" {
mir::graphics::DRMFormat::from_mir_format*;
};
} MIR_PLATFORM_2.11;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. We don't need a new stanza (even if the name were correct)

We have an ABI break, not additional APIs

Comment on lines 15 to 16
*
* Authored by: Christopher James Halse Rogers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*
* Authored by: Christopher James Halse Rogers

@@ -37,12 +37,17 @@ add_library(
egl_helper.cpp
quirks.cpp
quirks.h
kms_framebuffer.h
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds the header, but not the implementation. Is it needed?

src/platforms/gbm-kms/server/kms/kms_framebuffer.cpp Outdated Show resolved Hide resolved
src/platforms/gbm-kms/server/kms/kms_framebuffer.cpp Outdated Show resolved Hide resolved
@AlanGriffiths
Copy link
Contributor

AlanGriffiths commented Jun 27, 2023

I tried this with DisplayLink:

gdb --ex run --args miriway-shell --driver-quirks=allow:driver:evdi

It crashed...

Thread 112 "llvmpipe-2" received signal SIGBUS, Bus error.
[Switching to Thread 0x7fffa57fa6c0 (LWP 12778)]
0x00007fffc264b0c2 in util_memset32 (n=64, ui=0, s=0x7fff4dcd3200) at ../src/util/u_memset.h:35
Downloading source file /usr/src/mesa-23.0.2-1ubuntu1/build/../src/util/u_memset.h
35         __asm__ volatile("rep\n\t"                                                                   
(gdb) bt
#0  0x00007fffc264b0c2 in util_memset32 (n=64, ui=0, s=0x7fff4dcd3200) at ../src/util/u_memset.h:35
#1  util_fill_rect
    (dst=0x7fff4dcd3200 <error: Cannot access memory at address 0x7fff4dcd3200>, format=format@entry=PIPE_FORMAT_B8G8R8X8_UNORM, dst_stride=dst_stride@entry=7680, dst_x=dst_x@entry=0, dst_y=dst_y@entry=64, width=width@entry=64, height=64, uc=0x7fffa57f92e0) at ../src/gallium/auxiliary/util/u_surface.c:144
#2  0x00007fffc264b425 in util_fill_box
    (dst=<optimised out>, format=format@entry=PIPE_FORMAT_B8G8R8X8_UNORM, stride=7680, layer_stride=0, x=0, y=64, z=0, width=64, height=64, depth=1, uc=0x7fffa57f92e0)
    at ../src/gallium/auxiliary/util/u_surface.c:184
#3  0x00007fffc26fffb4 in lp_rast_clear_color (task=0x555555ad2ff8, arg=...)
    at ../src/gallium/drivers/llvmpipe/lp_rast.c:162
#4  0x00007fffc2700e35 in blit_rasterize_bin (bin=<optimised out>, task=<optimised out>)
    at ../src/gallium/drivers/llvmpipe/lp_rast.c:943
#5  rasterize_bin (y=<optimised out>, x=<optimised out>, bin=<optimised out>, task=0x555555ad2ff8)
    at ../src/gallium/drivers/llvmpipe/lp_rast.c:995
#6  rasterize_scene (task=task@entry=0x555555ad2ff8, scene=0x7fffa007e568)
    at ../src/gallium/drivers/llvmpipe/lp_rast.c:1065
#7  0x00007fffc2700f4b in thread_function (init_data=init_data@entry=0x555555ad2ff8)
    at ../src/gallium/drivers/llvmpipe/lp_rast.c:1200
#8  0x00007fffc2111e2b in impl_thrd_routine (p=<optimised out>) at ../src/c11/impl/threads_posix.c:67
#9  0x00007ffff768f18a in start_thread (arg=<optimised out>) at ./nptl/pthread_create.c:444
#10 0x00007ffff771dbd0 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

miriway.log

Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of files that have been commented out in CMakeLists.txt that remain in the source tree. If the intention were to remove them, I'd expect the CMakeLists.txt entry and the file to be gone.

Is the intention to restore and fix them?

tests/unit-tests/compositor/CMakeLists.txt Outdated Show resolved Hide resolved
${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp
# ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The corresponding file hasn't been deleted. What is the intent?

tests/unit-tests/platforms/x11/CMakeLists.txt Show resolved Hide resolved
tests/unit-tests/renderers/gl/CMakeLists.txt Outdated Show resolved Hide resolved
@AlanGriffiths
Copy link
Contributor

It would be good to rebase on origin/main: then we'll get a convenient Miriway branch to experiment with

@AlanGriffiths
Copy link
Contributor

@RAOF as you are away, I've rebased this on main to fix CI (and also to get a Miriway branch)

@AlanGriffiths
Copy link
Contributor

I don't think this breaks anything, but I've not yet been able to coax my hardware into doing anything that doesn't work on main

@Saviq
Copy link
Collaborator

Saviq commented Jul 24, 2023

I don't think this breaks anything, but I've not yet been able to coax my hardware into doing anything that doesn't work on main

I'll try something out in the lab… maybe render on Intel where Nvidia has the output, or the other way around.

@RAOF
Copy link
Contributor Author

RAOF commented Jul 25, 2023

I don't think this breaks anything, but I've not yet been able to coax my hardware into doing anything that doesn't work on main

I think this should now work on DisplayLink? If not, I'd be interested in logs!

@AlanGriffiths
Copy link
Contributor

AlanGriffiths commented Jul 25, 2023

I think this should now work on DisplayLink? If not, I'd be interested in logs!

Closer, but it dies as follows:

mir-shell.log

Thread 69 "llvmpipe-2" received signal SIGBUS, Bus error.
[Switching to Thread 0x7fffc0ff96c0 (LWP 9509)]
0x00007ffff581d756 in ?? ()
(gdb) bt
#0  0x00007ffff581d756 in  ()
#1  0x0000000000000000 in  ()
(gdb) info threads
  Id   Target Id                                          Frame 
  1    Thread 0x7ffff6952200 (LWP 9418) "miral-shell"     __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555564a4958)
    at ./nptl/futex-internal.c:57
  2    Thread 0x7ffff694e6c0 (LWP 9428) "miral-shell-ust" syscall ()
    at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
  3    Thread 0x7ffff614d6c0 (LWP 9429) "miral-shell-ust" syscall ()
    at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
  4    Thread 0x7ffff56ab6c0 (LWP 9430) "pool-spawner"    syscall ()
    at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
  5    Thread 0x7fffeffff6c0 (LWP 9431) "gmain"           0x00007ffff770fd7f in __GI___poll (
    fds=0x55555572bd70, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
  6    Thread 0x7ffff4eaa6c0 (LWP 9432) "gdbus"           0x00007ffff770fd7f in __GI___poll (
    fds=0x7fffe0000b90, nfds=2, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
  53   Thread 0x7fffc37fe6c0 (LWP 9490) "miral-s:disk$0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555557be4e8)
    at ./nptl/futex-internal.c:57
  54   Thread 0x7fffecffe6c0 (LWP 9491) "miral-shel:sh0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555557a6ea8)
    at ./nptl/futex-internal.c:57
  55   Thread 0x7fffe61ff6c0 (LWP 9492) "miral-shel:sh1"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555557a6ea8)
    at ./nptl/futex-internal.c:57
  56   Thread 0x7fffe59fe6c0 (LWP 9493) "miral-shel:sh2"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555557a6ea8)
    at ./nptl/futex-internal.c:57
  61   Thread 0x7fffe51fd6c0 (LWP 9499) "miral-:traceq0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x55555595e8c0)
    at ./nptl/futex-internal.c:57
  62   Thread 0x7fffc3fff6c0 (LWP 9500) "miral-sh:gdrv0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555555919d18)
    at ./nptl/futex-internal.c:57
  63   Thread 0x7fffd8dff6c0 (LWP 9503) "miral-:traceq0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x55555594fb90)
    at ./nptl/futex-internal.c:57
  64   Thread 0x7fffe49fc6c0 (LWP 9504) "miral-sh:gdrv0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555559c6c88)
    at ./nptl/futex-internal.c:57
  65   Thread 0x7fffc2ffd6c0 (LWP 9505) "miral-:traceq0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555559b9880)
    at ./nptl/futex-internal.c:57
  66   Thread 0x7fffc27fc6c0 (LWP 9506) "miral-sh:gdrv0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555558b87f8)
    at ./nptl/futex-internal.c:57
  67   Thread 0x7fffc1ffb6c0 (LWP 9507) "llvmpipe-0"      0x00007ffff581d75c in ?? ()
  68   Thread 0x7fffc17fa6c0 (LWP 9508) "llvmpipe-1"      0x00007ffff581d756 in ?? ()
* 69   Thread 0x7fffc0ff96c0 (LWP 9509) "llvmpipe-2"      0x00007ffff581d756 in ?? ()
  70   Thread 0x7fff9ffff6c0 (LWP 9510) "llvmpipe-3"      0x00007ffff581d756 in ?? ()
  71   Thread 0x7fff9f7fe6c0 (LWP 9511) "miral-shell"     __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555555a401f0)
    at ./nptl/futex-internal.c:57
  72   Thread 0x7fff9effd6c0 (LWP 9512) "miral-shell"     __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555555a401f0)
    at ./nptl/futex-internal.c:57
--Type <RET> for more, q to quit, c to continue without paging--c
  73   Thread 0x7fff9e7fc6c0 (LWP 9513) "miral-shell"     __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555555a401f0)
    at ./nptl/futex-internal.c:57
  74   Thread 0x7fff9dffb6c0 (LWP 9514) "miral-shell"     __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555555a401f0)
    at ./nptl/futex-internal.c:57
  75   Thread 0x7fff9d7fa6c0 (LWP 9515) "miral-s:disk$0"  __futex_abstimed_wait_common64 (private=0, 
    cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555557c9f08)
    at ./nptl/futex-internal.c:57

@RAOF
Copy link
Contributor Author

RAOF commented Jul 27, 2023

I think this should now work on DisplayLink? If not, I'd be interested in logs!

Closer, but it dies as follows:

mir-shell.log

I think you might be testing the wrong code? Unless my local branch has gone screwy, this code does not contain the string “Detected single-GPU DisplayBuffer. Rendering will be sent directly to output”, which appears in your log?

@AlanGriffiths
Copy link
Contributor

I think you might be testing the wrong code? Unless my local branch has gone screwy, this code does not contain the string “Detected single-GPU DisplayBuffer. Rendering will be sent directly to output”, which appears in your log?

Even simpler: uploading the wrong log:
miral-app.log

@Saviq
Copy link
Collaborator

Saviq commented Jul 27, 2023

I tried this out remotely on a device with the following connectors:

├───Driver: i915 (Intel Graphics) version 1.6.0 (20201103)
├───Connectors
│   ├───Connector 0
│   │   ├───Type: eDP
│   │   ├───Status: connected
│   ├───Connector 1
│   │   ├───Type: DisplayPort
│   │   ├───Status: disconnected
│   ├───Connector 2
│   │   ├───Type: HDMI-A
│   │   ├───Status: disconnected
│   ├───Connector 3
│   │   ├───Type: DisplayPort
│   │   ├───Status: disconnected
│   ├───Connector 4
│   │   ├───Type: HDMI-A
│   │   ├───Status: disconnected
│   └───Connector 5
│       ├───Type: HDMI-A
│       ├───Status: disconnected
├───Driver: nvidia-drm (NVIDIA DRM driver) version 0.0.0 (20160202)
├───Connectors
│   ├───Connector 0
│   │   ├───Type: DisplayPort
│   │   ├───Status: disconnected
│   ├───Connector 1
│   │   ├───Type: DisplayPort
│   │   ├───Status: disconnected
│   └───Connector 2
│       ├───Type: HDMI-A
│       ├───Status: disconnected

Smoke tests are happy on both rendering platforms:

$ sudo MIR_SERVER_PLATFORM_RENDERING_LIBS=mir:gbm-kms mir-test-tools.smoke-test 2>&1 | grep -e Selected -e complete
[2023-07-27 10:46:44.449371] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:46:44.467482] <information> mirserver: Selected rendering driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/renderD128)
[2023-07-27 10:46:44.592297] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
[2023-07-27 10:46:48.516116] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:46:48.534346] <information> mirserver: Selected rendering driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/renderD128)
[2023-07-27 10:46:48.658923] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
[2023-07-27 10:46:52.516437] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:46:52.535108] <information> mirserver: Selected rendering driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/renderD128)
[2023-07-27 10:46:52.659337] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
I: Smoke testing complete with returncode 0
$ sudo MIR_SERVER_PLATFORM_RENDERING_LIBS=mir:eglstream-kms mir-test-tools.smoke-test 2>&1 | grep -e Selected -e complete
[2023-07-27 10:47:22.883179] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:22.906715] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card1)
[2023-07-27 10:47:22.912079] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:23.074824] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
[2023-07-27 10:47:27.033291] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:27.057053] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card1)
[2023-07-27 10:47:27.062046] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:27.227748] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
[2023-07-27 10:47:31.166640] <information> mirserver: Selected display driver: mir:gbm-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:31.189489] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card1)
[2023-07-27 10:47:31.194295] <information> mirserver: Selected rendering driver: mir:eglstream-kms (version 2.14.1) for device ((null): /dev/dri/card0)
[2023-07-27 10:47:31.349014] <information> mirserver: Selected input driver: mir:evdev-input (version: 2.14.1)
I: Smoke testing complete with returncode 0

Running manually I was able to run Frame under both renderers, but had to manually match the renderer used by glmark2-es2-wayland, not sure if that's by design? Otherwise I ended up with either:

[build] use-vbo=false:[destroyed object]: error 4: Client requested unsupported format/modifier combination DRM_FORMAT_ARGB8888/NVIDIA:BLOCK_LINEAR_2D,HEIGHT=4,KIND=6,GEN=2,SECTO

Or reverting to llvmpipe, if Frame rendered on Nvidia but glmark2 didn't have access to Nvidia userspace.

At one point, trying to VNC, I ended up with ScreenShooter errors, but can't reproduce now:

[2023-07-27 10:43:46.228290] < - ERROR - > BasicScreenShooter: failed to capture screen: /root/parts/mir/src/src/server/compositor/basic_screen_shooter.cpp(95): Throw in function void mir::compositor::BasicScreenShooter::Self::OneShotBufferDisplayProvider::set_next_buffer(std::shared_ptr<mir::renderer::software::WriteMappableBuffer>)
Dynamic exception type: boost::wrapexcept<std::logic_error>
std::exception::what: Attempt to set next buffer with a buffer already pending

@Saviq
Copy link
Collaborator

Saviq commented Jul 27, 2023

What's suspect, is that the Intel GPU ends up with higher scores to Nvidia on glmark2:

=======================================================
    glmark2 2021.02
=======================================================
    OpenGL Information
    GL_VENDOR:     Intel
    GL_RENDERER:   Mesa Intel(R) UHD Graphics (CML GT2)
    GL_VERSION:    OpenGL ES 3.2 Mesa 22.2.5
=======================================================
[build] use-vbo=false: FPS: 420 FrameTime: 2.381 ms
[build] use-vbo=true: FPS: 453 FrameTime: 2.208 ms
[texture] texture-filter=nearest:^C FPS: 472 FrameTime: 2.119 ms
=======================================================
                                  glmark2 Score: 448 
=======================================================
=======================================================
    glmark2 2021.02
=======================================================
    OpenGL Information
    GL_VENDOR:     NVIDIA Corporation
    GL_RENDERER:   Quadro T2000 with Max-Q Design/PCIe/SSE2
    GL_VERSION:    OpenGL ES 3.2 NVIDIA 525.125.06
=======================================================
[build] use-vbo=false: FPS: 334 FrameTime: 2.994 ms
[build] use-vbo=true: FPS: 348 FrameTime: 2.874 ms
[texture] texture-filter=nearest:^C FPS: 393 FrameTime: 2.545 ms
=======================================================
                                  glmark2 Score: 358 
=======================================================

This is a 4K display, though.

Weston scores slightly higher, too:

=======================================================
    glmark2 2021.02                                                                            
=======================================================
    OpenGL Information                                                                         
    GL_VENDOR:     Intel                                                                       
    GL_RENDERER:   Mesa Intel(R) UHD Graphics (CML GT2)
    GL_VERSION:    OpenGL ES 3.2 Mesa 22.2.5-0ubuntu0.1~22.04.3
=======================================================
[build] use-vbo=false: FPS: 467 FrameTime: 2.141 ms
[build] use-vbo=true: FPS: 480 FrameTime: 2.083 ms
[texture] texture-filter=nearest:^C FPS: 465 FrameTime: 2.151 ms
=======================================================
                                  glmark2 Score: 470 
=======================================================

@RAOF
Copy link
Contributor Author

RAOF commented Jul 28, 2023

Argh, EGL context handling.

Let's give that a try on DisplayLink!

@AlanGriffiths
Copy link
Contributor

AlanGriffiths commented Jul 28, 2023

This now starts up on evdi, but there are issues with the display configuration:

8>< ---------------------------------------------------
layouts:
  default:                         # the current layout
    cards:
    # a list of cards (currently matched by card-id)

    - card-id: 0
      eDP-1:
        # This output supports the following modes: [email protected]
        #
        # Uncomment the following to enforce the selected configuration.
        # Or amend as desired.
        #
        state: enabled	# {enabled, disabled}, defaults to enabled
        mode: [email protected]	# Defaults to preferred mode
        position: [0, 0]	# Defaults to [0, 0]
        orientation: normal	# {normal, left, right, inverted}, defaults to normal
        scale: 1
        group: 0	# Outputs with the same non-zero value are treated as a single display

      DisplayPort-1:
        # (disconnected)

      HDMI-A-1:
        # (disconnected)

      DisplayPort-2:
        # (disconnected)

      HDMI-A-2:
        # (disconnected)

      DVI-I-1:
        # This output supports the following modes: [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected]
        #
        # Uncomment the following to enforce the selected configuration.
        # Or amend as desired.
        #
        state: enabled	# {enabled, disabled}, defaults to enabled
        mode: [email protected]	# Defaults to preferred mode
        position: [0, 0]	# Defaults to [0, 0]
        orientation: normal	# {normal, left, right, inverted}, defaults to normal
        scale: 1
        group: 0	# Outputs with the same non-zero value are treated as a single display

      DVI-I-1:
        # This output supports the following modes: [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected],
        # [email protected], [email protected], [email protected], [email protected], [email protected]
        #
        # Uncomment the following to enforce the selected configuration.
        # Or amend as desired.
        #
        state: enabled	# {enabled, disabled}, defaults to enabled
        mode: [email protected]	# Defaults to preferred mode
        position: [0, 0]	# Defaults to [0, 0]
        orientation: normal	# {normal, left, right, inverted}, defaults to normal
        scale: 1
        group: 0	# Outputs with the same non-zero value are treated as a single display

      DVI-I-1:
        # (disconnected)

      DVI-I-1:
        # (disconnected)
8>< ---------------------------------------------------

Both the external monitors are being named DVI-I-1, and I'm not sure why they are under card-id: 0

[update]

Looking elsewhere in the log I see:

[2023-07-28 11:08:13.676145] <information> gbm-kms: DRM device details:
[2023-07-28 11:08:13.676174] <information> gbm-kms: /dev/dri/card1: using driver evdi [Extensible Virtual Display Interface] (version: 1.13.1 driver date: 20230324)
[2023-07-28 11:08:13.676562] <information> gbm-kms: 	Output: DVI-I-1 (connected)
...
[2023-07-28 11:08:13.694036] <information> gbm-kms: DRM device details:
[2023-07-28 11:08:13.694099] <information> gbm-kms: /dev/dri/card2: using driver evdi [Extensible Virtual Display Interface] (version: 1.13.1 driver date: 20230324)
[2023-07-28 11:08:13.694530] <information> gbm-kms: 	Output: DVI-I-2 (connected)

So these evdi devices are being reported inconsistently.

[update 1]

And getting miriway to generate a .display config doesn't show them:

~$ cat .config/miriway-shell.display
layouts:
# keys here are layout labels (used for atomically switching between them).
# The yaml anchor 'the_default' is used to alias the 'default' label

  default:
    cards:
    # a list of cards (currently matched by card-id)

    - card-id: 0
      eDP-1:
        # This output supports the following modes: [email protected]
        #
        # Uncomment the following to enforce the selected configuration.
        # Or amend as desired.
        #
        state: enabled	# {enabled, disabled}, defaults to enabled
        mode: [email protected]	# Defaults to preferred mode
        position: [0, 0]	# Defaults to [0, 0]
        orientation: normal	# {normal, left, right, inverted}, defaults to normal
        scale: 1
        group: 0	# Outputs with the same non-zero value are treated as a single display

      DisplayPort-1:
        # (disconnected)

      HDMI-A-1:
        # (disconnected)

      DisplayPort-2:
        # (disconnected)

      HDMI-A-2:
        # (disconnected)

  side_by_side:
    cards:
    # a list of cards (currently matched by card-id)

    - card-id: 0
      eDP-1:
        # This output supports the following modes: [email protected]
        #
        # Uncomment the following to enforce the selected configuration.
        # Or amend as desired.
        #
        state: enabled	# {enabled, disabled}, defaults to enabled
        mode: [email protected]	# Defaults to preferred mode
        position: [0, 0]	# Defaults to [0, 0]
        orientation: normal	# {normal, left, right, inverted}, defaults to normal
        scale: 1
        group: 0	# Outputs with the same non-zero value are treated as a single display

      DisplayPort-1:
        # (disconnected)

      HDMI-A-1:
        # (disconnected)

      DisplayPort-2:
        # (disconnected)

      HDMI-A-2:
        # (disconnected)

@Saviq Saviq marked this pull request as ready for review July 31, 2023 11:04
@Saviq Saviq marked this pull request as draft July 31, 2023 11:04
@AlanGriffiths
Copy link
Contributor

I see this when running on my hybrid system - seems Mir doesn't like its Nvidia support:

$ grep eglstream: miriway.log 
[2023-07-31 14:24:28.552752] <information> eglstream: EGLDevice found but unsuitable. Missing extension EGL_KHR_stream_consumer_gltexture
[2023-07-31 14:24:28.552771] <information> eglstream: EGLDevice found but unsuitable. Missing extension EGL_NV_stream_attrib
[2023-07-31 14:24:28.561428] < - debug - > eglstream: Failed to initialise EGL: EGL_NOT_INITIALIZED (0x3001)
[2023-07-31 14:24:28.561465] < - debug - > eglstream: Failed to find kernel device for EGLDevice: Failed to determine DRM device node path from EGLDevice: EGL_BAD_PARAMETER (0x300c)
[2023-07-31 14:24:28.561475] < - debug - > eglstream: EGLDeviceEXTs found, but none are suitable for Mir

I assume that means it didn't find an output to render to. And didn't consider it for rendering?

@Saviq
Copy link
Collaborator

Saviq commented Jul 31, 2023

I see this when running on my hybrid system - seems Mir doesn't like its Nvidia support:

$ grep eglstream: miriway.log 
[2023-07-31 14:24:28.552752] <information> eglstream: EGLDevice found but unsuitable. Missing extension EGL_KHR_stream_consumer_gltexture
[2023-07-31 14:24:28.552771] <information> eglstream: EGLDevice found but unsuitable. Missing extension EGL_NV_stream_attrib
[2023-07-31 14:24:28.561428] < - debug - > eglstream: Failed to initialise EGL: EGL_NOT_INITIALIZED (0x3001)
[2023-07-31 14:24:28.561465] < - debug - > eglstream: Failed to find kernel device for EGLDevice: Failed to determine DRM device node path from EGLDevice: EGL_BAD_PARAMETER (0x300c)
[2023-07-31 14:24:28.561475] < - debug - > eglstream: EGLDeviceEXTs found, but none are suitable for Mir

I assume that means it didn't find an output to render to. And didn't consider it for rendering?

What do drm_info or graphics-test-tools.drm-info say? It more sounds like your Nvidia support isn't working? Got the nvidia-drm.modeset=1 bit on the kernel cmdline? Though I found that unnecessary on newer drivers…

@AlanGriffiths
Copy link
Contributor

Got the nvidia-drm.modeset=1 bit on the kernel cmdline

I don't. (It has been a while since I used Nvidia, probably lost along the way)

Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design surrounding RenderingPlatform is much more complex than we currently need. We don't need a RendererInterfaceBase, type tags or associated dynamic type deduction.

I assume this intended as a customization point to support non-gl renderers but without a real usecase we can't be sure this is necessary or sufficient.

*/
}

class RendererInterfaceBase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Words like "Interface" and "Base" scattered around a type hierarchy usually don't add much. And "InterfaceBase" sounds a bit tautological.

There is only one derived type: GLRenderingProvider, and it is not obvious why that needs an "InterfaceBase". (I realise it is part of the RenderingPlatform::acquire_interface mechanism, but that seems overengineered.)

  • `

Comment on lines 197 to 198
template<typename Interface>
static auto acquire_interface(std::shared_ptr<RenderingPlatform> platform) -> std::shared_ptr<Interface>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like needless complexity: There is only one specialization of this template used:

auto gl_provider = mg::RenderingPlatform::acquire_interface<mg::GLRenderingProvider>(...)

Comment on lines 218 to 235
/**
* Acquire a specific hardware interface
*
* This should perform any runtime checks necessary to verify the requested interface is
* expected to work and return a pointer to an implementation of that interface.
*
* This function is guaranteed to be called with `this` managed by a `shared_ptr`; if
* the returned value needs to share ownership with `this`, calls to std::shared_from_this
* can be expected to work.
*
* \param type_tag [in] An instance of the Tag type for the requested interface.
* Implementations are expected to dynamic_cast<> this to
* discover the specific interface being requested.
* \return A pointer to an implementation of the RenderInterfaceBase-derived
* interface that corresponds to the most-derived type of tag_type.
*/
virtual auto maybe_create_interface(
RendererInterfaceBase::Tag const& type_tag) -> std::shared_ptr<RendererInterfaceBase> = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overly generic: This is only ever called with GLRenderingProvider::Tag{} and the return type is always downcast to shared_ptr<GLRenderingProvider>

@AlanGriffiths
Copy link
Contributor

AlanGriffiths commented Oct 13, 2023

Running on plain gbm-kms there's a failure when connecting or disconnecting an output the leads to a crash. I'll just drop this bt of the initial failure here:

Thread 18 "Mir/Comp" hit Breakpoint 1.12, std::system_error::system_error (this=0x7fffc3ffdb00, 
    __v=12291, __ecat=..., __what="Failed to create EGL window surface")
    at /usr/include/c++/13/system_error:578
578	    system_error(int __v, const error_category& __ecat, const string& __what)
(gdb) bt
#0  std::system_error::system_error
    (this=0x7fffc3ffdb00, __v=12291, __ecat=..., __what="Failed to create EGL window surface")
    at /usr/include/c++/13/system_error:578
#1  0x00007ffff4e798a1 in mir::graphics::egl_error (msg="Failed to create EGL window surface")
    at /home/alan/CLionProjects/mir/include/platform/mir/graphics/egl_error.h:33
#2  0x00007ffff4ec3446 in (anonymous namespace)::GBMOutputSurface::create_renderable
    (dpy=0x5555557c7dc0, share_context=0x555555810e10, format=..., config=warning: RTTI symbol not found for class 'mir::DefaultServerConfiguration::the_gl_config()::{lambda()#1}::operator()() const::NoGLConfig'
..., display=..., size=...)
    at /home/alan/CLionProjects/mir/src/platforms/gbm-kms/server/buffer_allocator.cpp:433
#3  0x00007ffff4ec21cb in (anonymous namespace)::GBMOutputSurface::GBMOutputSurface
    (this=0x7fffbc0f5700, dpy=0x5555557c7dc0, share_context=0x555555810e10, config=warning: RTTI symbol not found for class 'mir::DefaultServerConfiguration::the_gl_config()::{lambda()#1}::operator()() const::NoGLConfig'
..., display=..., format=..., size=...)
    at /home/alan/CLionProjects/mir/src/platforms/gbm-kms/server/buffer_allocator.cpp:271
#4  0x00007ffff4ec40b3 in std::make_unique<(anonymous namespace)::GBMOutputSurface, void* const&, void* const&, mir::graphics::GLConfig const&, mir::graphics::GBMDisplayProvider&, mir::graphics::DRMFormat, mir::geometry::generic::Size<int>&> () at /usr/include/c++/13/bits/unique_ptr.h:1070
#5  0x00007ffff4ec3a92 in mir::graphics::gbm::GLRenderingProvider::surface_for_output
    (this=0x5555559f6310, target=std::shared_ptr<mir::graphics::DisplayInterfaceProvider> (use count 7, weak count 1) = {...}, size=..., config=warning: RTTI symbol not found for class 'mir::DefaultServerConfiguration::the_gl_config()::{lambda()#1}::operator()() const::NoGLConfig'
...)
    at /home/alan/CLionProjects/mir/src/platforms/gbm-kms/server/buffer_allocator.cpp:522
#6  0x00007ffff6e5202d in mir::compositor::DefaultDisplayBufferCompositorFactory::create_compositor_for
    (this=0x5555559f63b0, display_buffer=...)
    at /home/alan/CLionProjects/mir/src/server/compositor/default_display_buffer_compositor_factory.cpp:86
#7  0x00007ffff6e57ca6 in mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}::operator()(mir::graphics::DisplayBuffer&) const (__closure=0x7fffc3ffe0a0, buffer=...)
    at /home/alan/CLionProjects/mir/src/server/compositor/multi_threaded_compositor.cpp:89
#8  0x00007ffff6e5d1a1 in std::__invoke_impl<void, mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}&, mir::graphics::DisplayBuffer&>(std::__invoke_other, mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}&, mir::graphics::DisplayBuffer&) (__f=...) at /usr/include/c++/13/bits/invoke.h:61
#9  0x00007ffff6e5c127 in std::__invoke_r<void, mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}&, mir::graphics::DisplayBuffer&>(mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}&, mir::graphics::DisplayBuffer&) (__fn=...)
    at /usr/include/c++/13/bits/invoke.h:111
#10 0x00007ffff6e5ac9e in std::_Function_handler<void (mir::graphics::DisplayBuffer&), mir::compositor::CompositingFunctor::operator()()::{lambda(mir::graphics::DisplayBuffer&)#1}>::_M_invoke(std::_Any_data const&, mir::graphics::DisplayBuffer&) (__functor=..., __args#0=...)
    at /usr/include/c++/13/bits/std_function.h:290
#11 0x00007ffff4e6af03 in std::function<void (mir::graphics::DisplayBuffer&)>::operator()(mir::graphics::DisplayBuffer&) const (this=0x7fffc3ffe0a0, __args#0=...)
    at /usr/include/c++/13/bits/std_function.h:591
#12 0x00007ffff4e698ef in mir::graphics::gbm::DisplayBuffer::for_each_display_buffer(std::function<void (mir::graphics::DisplayBuffer&)> const&) (this=0x555555a958f0, f=...)
    at /home/alan/CLionProjects/mir/src/platforms/gbm-kms/server/kms/display_buffer.cpp:146
#13 0x00007ffff6e585b5 in mir::compositor::CompositingFunctor::operator() (this=0x555555704850)
    at /home/alan/CLionProjects/mir/src/server/compositor/multi_threaded_compositor.cpp:85
#14 0x00007ffff6e5ea99 in std::__invoke_impl<void, mir::compositor::CompositingFunctor&> (__f=...)
    at /usr/include/c++/13/bits/invoke.h:61
#15 0x00007ffff6e5e90b in std::__invoke<mir::compositor::CompositingFunctor&> (__fn=...)
    at /usr/include/c++/13/bits/invoke.h:96
#16 0x00007ffff6e5e228 in std::reference_wrapper<mir::compositor::CompositingFunctor>::operator()<>() const (this=0x7fffbc25b260) at /usr/include/c++/13/bits/refwrap.h:359
#17 0x00007ffff6e5d6f2 in std::__invoke_impl<void, std::reference_wrapper<mir::compositor::CompositingFunctor>&> (__f=...) at /usr/include/c++/13/bits/invoke.h:61
#18 0x00007ffff6e5c8f0 in std::__invoke_r<void, std::reference_wrapper<mir::compositor::CompositingFunctor>&> (__fn=...) at /usr/include/c++/13/bits/invoke.h:111
#19 0x00007ffff6e5b9ac in std::_Function_handler<void (), std::reference_wrapper<mir::compositor::CompositingFunctor> >::_M_invoke(std::_Any_data const&) (__functor=...)
    at /usr/include/c++/13/bits/std_function.h:290
#20 0x00007ffff779eeea in std::function<void ()>::operator()() const (this=0x7fffbc25b260)
    at /usr/include/c++/13/bits/std_function.h:591
#21 0x00007ffff77b6fef in operator() (__closure=0x7fffbc25b240)
    at /home/alan/CLionProjects/mir/src/common/thread_pool_executor.cpp:266
#22 0x00007ffff77b9642 in std::__invoke_impl<void, (anonymous namespace)::ThreadPool::spawn(std::function<void()>&&)::<lambda()>&>(std::__invoke_other, struct {...} &) (__f=...)
    at /usr/include/c++/13/bits/invoke.h:61
#23 0x00007ffff77b8ee3 in std::__invoke_r<void, (anonymous namespace)::ThreadPool::spawn(std::function<void()>&&)::<lambda()>&>(struct {...} &) (__fn=...) at /usr/include/c++/13/bits/invoke.h:111
#24 0x00007ffff77b855e in std::_Function_handler<void(), (anonymous namespace)::ThreadPool::spawn(std::function<void()>&&)::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...)
    at /usr/include/c++/13/bits/std_function.h:290
#25 0x00007ffff779eeea in std::function<void ()>::operator()() const (this=0x7fffc3ffe2c0)
    at /usr/include/c++/13/bits/std_function.h:591
#26 0x00007ffff77b6b90 in (anonymous namespace)::Worker::work_loop
    (me=0x5555557230f0, shutdown_channel=...)
    at /home/alan/CLionProjects/mir/src/common/thread_pool_executor.cpp:184
#27 0x00007ffff77ba689 in std::__invoke_impl<void, void (*)((anonymous namespace)::Worker*, std::promise<std::atomic<bool>*>&&), (anonymous namespace)::Worker*, std::promise<std::atomic<bool>*> >
    (__f=@0x555555a91b78: 0x7ffff77b6ac1 <(anonymous namespace)::Worker::work_loop((anonymous namespace)::Worker*, std::promise<std::atomic<bool>*>&&)>) at /usr/include/c++/13/bits/invoke.h:61
#28 0x00007ffff77ba5ff in std::__invoke<void (*)((anonymous namespace)::Worker*, std::promise<std::atomic<bool>*>&&), (anonymous namespace)::Worker*, std::promise<std::atomic<bool>*> >
    (__fn=@0x555555a91b78: 0x7ffff77b6ac1 <(anonymous namespace)::Worker::work_loop((anonymous namespace--Type <RET> for more, q to quit, c to continue without paging--q
Quit

Move some destructor instantiations from the header, where there's
a `unique_ptr<IncompleteType>` member, to the implementation where
`IncompleteType` is no longer incomplete.

I'm not sure why this built in CI, nor why it only just *now* fails
for me?
@RAOF
Copy link
Contributor Author

RAOF commented Oct 16, 2023

Of course I can't reproduce this (on Lunar), either with Intel or AMD doing the rendering on my laptop.

That said, at least the backtrace is clearly EGL_BAD_ALLOC in eglCreatePlatformWindowSurface. I wonder what ways that can happen…

Better naming for rendering classes, functions and variables
@RAOF
Copy link
Contributor Author

RAOF commented Oct 16, 2023

Of course I can't reproduce this (on Lunar), either with Intel or AMD doing the rendering on my laptop.

That said, at least the backtrace is clearly EGL_BAD_ALLOC in eglCreatePlatformWindowSurface. I wonder what ways that can happen…

Tracing through Mesa I can't see anything that would return EGL_BAD_ALLOC without a failure of malloc() or a parameter we're passing as nullptr being treated as non-null.

@RAOF
Copy link
Contributor Author

RAOF commented Oct 16, 2023

The design surrounding RenderingPlatform is much more complex than we currently need. We don't need a RendererInterfaceBase, type tags or associated dynamic type deduction.

I assume this intended as a customization point to support non-gl renderers but without a real usecase we can't be sure this is necessary or sufficient.

This is correct: it's an extension point for non-GL renderers.

It can be removed (and re-added later if necessary).

@AlanGriffiths
Copy link
Contributor

I can confirm that 36ccfe8 fixes the plug/unplug problem

…s; and they no longer compile.

While it would be good to have specific tests fail if the features these should test for don't work, we won't miss bugs from not running these
@Saviq
Copy link
Collaborator

Saviq commented Oct 17, 2023

First time I've seen this in CI, but miral-test.WaylandExtensions failed on armhf (in qemu, so…)

https://github.com/MirServer/mir/actions/runs/6532933229/job/17737084346?pr=2962#step:8:9441

[ RUN ] WaylandExtensions.client_sees_default_extensions
# …
[2023-10-16 11:59:01.452160] < -warning- > mirserver: Manually-specified rendering platform mir:stub-graphics does not claim to support this system. Trying anyway...
# …
[2023-10-16 11:59:01.517221] < - ERROR - > : failed to create BasicScreenShooter: ../../../../src/server/compositor/basic_screen_shooter.cpp(218): Throw in function static std::shared_ptr<mir::graphics::GLRenderingProvider> mir::compositor::BasicScreenShooter::select_provider(const std::span<std::shared_ptr<mir::graphics::GLRenderingProvider> >&)
# ...
 qemu: uncaught target signal 11 (Segmentation fault) - core dumped
/<<PKGBUILDDIR>>/tools/detect_fd_leaks.bash: line 84: 42033 Segmentation fault      (core dumped) $@ 2>&1
     42034 Done                    | detect_fd_leaks

AlanGriffiths and others added 8 commits October 17, 2023 09:49
Decoupling writing the display configuration from processing it
# Conflicts:
#	src/miral/display_configuration_option.cpp
#	src/platforms/gbm-kms/server/kms/kms_framebuffer.h
#	src/platforms/gbm-kms/server/surfaceless_egl_context.h
Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do it!

@AlanGriffiths AlanGriffiths added this pull request to the merge queue Oct 18, 2023
Merged via the queue into main with commit 1d57c1d Oct 18, 2023
32 of 33 checks passed
@AlanGriffiths AlanGriffiths deleted the platform-API-merge branch October 18, 2023 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants