diff --git a/debian/control b/debian/control index a05b93b6888..e8350992dc3 100644 --- a/debian/control +++ b/debian/control @@ -77,7 +77,7 @@ Description: Display server for Ubuntu - server library . Contains the shared library needed by server applications for Mir. -Package: libmirplatform28 +Package: libmirplatform29 Section: libs Architecture: linux-any Multi-Arch: same @@ -140,7 +140,7 @@ Section: libdevel Architecture: linux-any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} -Depends: libmirplatform28 (= ${binary:Version}), +Depends: libmirplatform29 (= ${binary:Version}), libmircommon-dev (= ${binary:Version}), libboost-program-options-dev, ${misc:Depends}, diff --git a/debian/libmirplatform28.install b/debian/libmirplatform28.install deleted file mode 100644 index 8b2aeef1ca8..00000000000 --- a/debian/libmirplatform28.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libmirplatform.so.28 diff --git a/debian/libmirplatform29.install b/debian/libmirplatform29.install new file mode 100644 index 00000000000..aae6fdb0e79 --- /dev/null +++ b/debian/libmirplatform29.install @@ -0,0 +1 @@ +usr/lib/*/libmirplatform.so.29 diff --git a/include/platform/mir/graphics/drm_formats.h b/include/platform/mir/graphics/drm_formats.h index 9344ec9c7d7..55af23d1992 100644 --- a/include/platform/mir/graphics/drm_formats.h +++ b/include/platform/mir/graphics/drm_formats.h @@ -27,34 +27,47 @@ namespace mir::graphics class DRMFormat { public: - struct RGBComponentInfo + struct FormatInfo; + class Info { - uint32_t red_bits; - uint32_t green_bits; - uint32_t blue_bits; - std::optional alpha_bits; - }; + public: + struct RGBComponentInfo + { + uint32_t red_bits; + uint32_t green_bits; + uint32_t blue_bits; + std::optional alpha_bits; + }; - // This could be constexpr, at the cost of moving a bunch of implementation into the header - explicit DRMFormat(uint32_t fourcc_format); + auto opaque_equivalent() const -> std::optional; + auto alpha_equivalent() const -> std::optional; - auto name() const -> char const*; + bool has_alpha() const; - auto opaque_equivalent() const -> std::optional const; - auto alpha_equivalent() const -> std::optional const; + auto components() const -> std::optional const&; + private: + friend class DRMFormat; + Info(FormatInfo const* info); - bool has_alpha() const; + FormatInfo const* info; + }; - auto components() const -> std::optional const&; + constexpr explicit DRMFormat(uint32_t fourcc_format) + : fourcc{fourcc_format} + { + } + + auto name() const -> char const*; + + auto info() const -> std::optional; operator uint32_t() const; auto as_mir_format() const -> std::optional; static auto from_mir_format(MirPixelFormat format) -> DRMFormat; - struct FormatInfo; private: - FormatInfo const* info; + uint32_t fourcc; }; auto drm_modifier_to_string(uint64_t modifier) -> std::string; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 498724de7ce..a05ca99d99e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ # We need MIRPLATFORM_ABI in both libmirplatform and the platform implementations. -set(MIRPLATFORM_ABI 28) +set(MIRPLATFORM_ABI 29) set(MIRAL_VERSION_MAJOR 5) set(MIRAL_VERSION_MINOR 1) diff --git a/src/platform/graphics/drm_formats.cpp b/src/platform/graphics/drm_formats.cpp index b8d7553c2d4..42f549d7426 100644 --- a/src/platform/graphics/drm_formats.cpp +++ b/src/platform/graphics/drm_formats.cpp @@ -15,6 +15,7 @@ */ #include "mir/graphics/drm_formats.h" +#include "mir/synchronised.h" #include "mir_toolkit/common.h" #include @@ -22,8 +23,11 @@ #include #include #include +#include #include +#include "mir/log.h" + #ifdef MIR_HAVE_DRM_GET_MODIFIER_NAME #include #endif @@ -67,9 +71,9 @@ struct mg::DRMFormat::FormatInfo { uint32_t format; bool has_alpha; - uint32_t opaque_equivalent; - uint32_t alpha_equivalent; - std::optional components; + std::optional opaque_equivalent; + std::optional alpha_equivalent; + std::optional components; }; namespace @@ -80,7 +84,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XRGB4444, DRM_FORMAT_ARGB4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, {} }, }, @@ -89,7 +93,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XBGR4444, DRM_FORMAT_ABGR4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, {} }, }, @@ -98,7 +102,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_RGBX4444, DRM_FORMAT_RGBA4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, {} }, }, @@ -107,7 +111,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_BGRX4444, DRM_FORMAT_BGRA4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, {} }, }, @@ -116,7 +120,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XRGB4444, DRM_FORMAT_ARGB4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, 4 }, }, @@ -125,7 +129,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XBGR4444, DRM_FORMAT_ABGR4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, 4 }, }, @@ -134,7 +138,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_RGBX4444, DRM_FORMAT_RGBA4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, 4 }, }, @@ -143,7 +147,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_BGRX4444, DRM_FORMAT_BGRA4444, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 4, 4, 4, 4 }, }, @@ -152,7 +156,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XRGB1555, DRM_FORMAT_ARGB1555, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, {} }, }, @@ -161,7 +165,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XBGR1555, DRM_FORMAT_ABGR1555, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, {} }, }, @@ -170,7 +174,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_RGBX5551, DRM_FORMAT_RGBA5551, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, {} }, }, @@ -179,7 +183,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_BGRX5551, DRM_FORMAT_BGRA5551, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, {} }, }, @@ -188,7 +192,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XRGB1555, DRM_FORMAT_ARGB1555, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, 1 }, }, @@ -197,7 +201,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XBGR1555, DRM_FORMAT_ABGR1555, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, 1 }, }, @@ -206,7 +210,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_RGBX5551, DRM_FORMAT_RGBA5551, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, 1 }, }, @@ -215,7 +219,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_BGRX5551, DRM_FORMAT_BGRA5551, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 5, 5, 5, 1 }, }, @@ -223,8 +227,8 @@ constexpr std::array const formats = { DRM_FORMAT_RGB565, false, DRM_FORMAT_RGB565, - DRM_FORMAT_INVALID, - mg::DRMFormat::RGBComponentInfo{ + {}, + mg::DRMFormat::Info::RGBComponentInfo{ 5, 6, 5, {} }, }, @@ -232,8 +236,8 @@ constexpr std::array const formats = { DRM_FORMAT_BGR565, false, DRM_FORMAT_BGR565, - DRM_FORMAT_INVALID, - mg::DRMFormat::RGBComponentInfo{ + {}, + mg::DRMFormat::Info::RGBComponentInfo{ 5, 6, 5, {} }, }, @@ -241,8 +245,8 @@ constexpr std::array const formats = { DRM_FORMAT_RGB888, false, DRM_FORMAT_RGB888, - DRM_FORMAT_INVALID, - mg::DRMFormat::RGBComponentInfo{ + {}, + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -250,8 +254,8 @@ constexpr std::array const formats = { DRM_FORMAT_BGR888, false, DRM_FORMAT_BGR888, - DRM_FORMAT_INVALID, - mg::DRMFormat::RGBComponentInfo{ + {}, + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -260,7 +264,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -269,7 +273,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -278,7 +282,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_RGBX8888, DRM_FORMAT_RGBA8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -287,7 +291,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_BGRX8888, DRM_FORMAT_BGRA8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, {} }, }, @@ -296,7 +300,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, 8 }, }, @@ -305,7 +309,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, 8 }, }, @@ -314,7 +318,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_RGBX8888, DRM_FORMAT_RGBA8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, 8 }, }, @@ -323,7 +327,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_BGRX8888, DRM_FORMAT_BGRA8888, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 8, 8, 8, 8 }, }, @@ -332,7 +336,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, {} }, }, @@ -341,7 +345,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_XBGR2101010, DRM_FORMAT_ABGR2101010, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, {} }, }, @@ -350,7 +354,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_RGBX1010102, DRM_FORMAT_RGBA1010102, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, {} }, }, @@ -359,7 +363,7 @@ constexpr std::array const formats = { false, DRM_FORMAT_BGRX1010102, DRM_FORMAT_BGRA1010102, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, {} }, }, @@ -368,7 +372,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, 2 }, }, @@ -377,7 +381,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_XBGR2101010, DRM_FORMAT_ABGR2101010, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, 2 }, }, @@ -386,7 +390,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_RGBX1010102, DRM_FORMAT_RGBA1010102, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, 2 }, }, @@ -395,7 +399,7 @@ constexpr std::array const formats = { true, DRM_FORMAT_BGRX1010102, DRM_FORMAT_BGRA1010102, - mg::DRMFormat::RGBComponentInfo{ + mg::DRMFormat::Info::RGBComponentInfo{ 10, 10, 10, 2 }, }, @@ -442,68 +446,65 @@ constexpr auto maybe_info_for_format(uint32_t fourcc_format) -> mg::DRMFormat::F } } - -constexpr auto info_for_format(uint32_t fourcc_format) -> mg::DRMFormat::FormatInfo const& -{ - auto const info = maybe_info_for_format(fourcc_format); - - if (info) - { - return *info; - } - BOOST_THROW_EXCEPTION(( - std::runtime_error{ - std::string{"Unsupported DRM format: "} + mg::drm_format_to_string(fourcc_format)})); } +auto mg::DRMFormat::name() const -> const char* +{ + return drm_format_to_string(fourcc); } -mg::DRMFormat::DRMFormat(uint32_t fourcc_format) - : info{&info_for_format(fourcc_format)} +auto mg::DRMFormat::Info::opaque_equivalent() const -> std::optional { + return info->opaque_equivalent.transform([](auto const& fourcc) { return DRMFormat{fourcc};}); } -auto mg::DRMFormat::name() const -> const char* +auto mg::DRMFormat::Info::alpha_equivalent() const -> std::optional { - return drm_format_to_string(info->format); + return info->alpha_equivalent.transform([](auto const& fourcc) { return DRMFormat{fourcc};}); } -auto mg::DRMFormat::opaque_equivalent() const -> const std::optional +bool mg::DRMFormat::Info::has_alpha() const { - if (info->opaque_equivalent != DRM_FORMAT_INVALID) - { - return DRMFormat{info->opaque_equivalent}; - } - return {}; + return info->has_alpha; } -auto mg::DRMFormat::alpha_equivalent() const -> const std::optional +auto mg::DRMFormat::Info::components() const -> std::optional const& { - if (info->alpha_equivalent != DRM_FORMAT_INVALID) - { - return DRMFormat{info->alpha_equivalent}; - } - return {}; + return info->components; } -bool mg::DRMFormat::has_alpha() const +mg::DRMFormat::Info::Info(FormatInfo const* info) + : info{info} { - return info->has_alpha; } -auto mg::DRMFormat::components() const -> std::optional const& +auto mg::DRMFormat::info() const -> std::optional { - return info->components; + if (auto info = maybe_info_for_format(fourcc)) + { + return Info(info); + } + + // Actually, we probably want `std::flat_set`, but no libstdc++ support yet. + static Synchronised> unknown_formats_guard; + auto unknown_formats = unknown_formats_guard.lock(); + if (!unknown_formats->contains(fourcc)) + { + mir::log_warning( + "Detailed info for format %s missing; please report this to https://github.com/canonical/mir/issues/new so this can be added", name()); + unknown_formats->insert(fourcc); + } + return std::nullopt; } mg::DRMFormat::operator uint32_t() const { - return info->format; + return fourcc; } auto mg::DRMFormat::as_mir_format() const -> std::optional { - switch (info->format) + switch (fourcc) { case DRM_FORMAT_ARGB8888: return mir_pixel_format_argb_8888; diff --git a/src/platform/graphics/linux_dmabuf.cpp b/src/platform/graphics/linux_dmabuf.cpp index d28b53903d2..9eea3a8bb4a 100644 --- a/src/platform/graphics/linux_dmabuf.cpp +++ b/src/platform/graphics/linux_dmabuf.cpp @@ -944,6 +944,14 @@ class DMABufTex : public mg::gl::Texture std::shared_ptr const egl_delegate; }; +namespace +{ +auto format_has_known_alpha(mg::DRMFormat format) -> std::optional +{ + return format.info().transform([](auto const& info) { return info.has_alpha(); }); +} +} + class DmabufTexBuffer : public mg::BufferBasic, public mg::DMABufBuffer @@ -965,7 +973,7 @@ class DmabufTexBuffer : on_consumed{std::move(on_consumed)}, on_release{std::move(on_release)}, size_{dma_buf.size()}, - has_alpha{dma_buf.format().has_alpha()}, + has_alpha{format_has_known_alpha(dma_buf.format()).value_or(true)}, // Has-alpha is the safe default for unknown formats planes_{dma_buf.planes()}, modifier_{dma_buf.modifier()}, format_{dma_buf.format()} diff --git a/src/platform/symbols.map b/src/platform/symbols.map index 80961be7627..6cc7ac3e89c 100644 --- a/src/platform/symbols.map +++ b/src/platform/symbols.map @@ -1,4 +1,4 @@ -MIR_PLATFORM_2.17 { +MIR_PLATFORM_2.18 { global: extern "C++" { mir::graphics::AtomicFrame::increment*; @@ -10,14 +10,15 @@ MIR_PLATFORM_2.17 { mir::graphics::DMABufEGLProvider::DMABufEGLProvider*; mir::graphics::DMABufEGLProvider::as_texture*; mir::graphics::DRMFormat::DRMFormat*; - mir::graphics::DRMFormat::alpha_equivalent*; + mir::graphics::DRMFormat::Info::alpha_equivalent*; mir::graphics::DRMFormat::as_mir_format*; - mir::graphics::DRMFormat::components*; + mir::graphics::DRMFormat::Info::components*; mir::graphics::DRMFormat::from_mir_format*; - mir::graphics::DRMFormat::has_alpha*; + mir::graphics::DRMFormat::Info::has_alpha*; mir::graphics::DRMFormat::name*; - mir::graphics::DRMFormat::opaque_equivalent*; + mir::graphics::DRMFormat::Info::opaque_equivalent*; mir::graphics::DRMFormat::operator?unsigned?int*; /* Is actually operator uint32_t(), but 🤷 */ + mir::graphics::DRMFormat::info*; mir::graphics::DisplayConfiguration::operator*; mir::graphics::DisplayConfiguration::valid*; mir::graphics::DisplayConfigurationOutput::extents*; diff --git a/src/platforms/gbm-kms/server/buffer_allocator.cpp b/src/platforms/gbm-kms/server/buffer_allocator.cpp index 4b4156c3725..be849f41205 100644 --- a/src/platforms/gbm-kms/server/buffer_allocator.cpp +++ b/src/platforms/gbm-kms/server/buffer_allocator.cpp @@ -350,14 +350,18 @@ class GBMOutputSurface : public mg::gl::OutputSurface static auto egl_config_for_format(EGLDisplay dpy, mg::GLConfig const& config, mg::DRMFormat format) -> std::optional { - mg::DRMFormat::RGBComponentInfo const default_components = { 8, 8, 8, 0}; + mg::DRMFormat::Info::RGBComponentInfo const default_components = { 8, 8, 8, 0}; + auto const components = + format.info().transform([](auto info) { return info.components(); }) + .value_or(default_components) // optional> -> optional + .value_or(default_components); // optional -> Components EGLint const config_attr[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, static_cast(format.components().value_or(default_components).red_bits), - EGL_GREEN_SIZE, static_cast(format.components().value_or(default_components).green_bits), - EGL_BLUE_SIZE, static_cast(format.components().value_or(default_components).blue_bits), - EGL_ALPHA_SIZE, static_cast(format.components().value_or(default_components).alpha_bits.value_or(0)), + EGL_RED_SIZE, static_cast(components.red_bits), + EGL_GREEN_SIZE, static_cast(components.green_bits), + EGL_BLUE_SIZE, static_cast(components.blue_bits), + EGL_ALPHA_SIZE, static_cast(components.alpha_bits.value_or(0)), EGL_DEPTH_SIZE, config.depth_buffer_bits(), EGL_STENCIL_SIZE, config.stencil_buffer_bits(), EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, @@ -405,11 +409,22 @@ class GBMOutputSurface : public mg::gl::OutputSurface auto alternate_format = [&]() -> std::optional { - if (format.has_alpha()) + if (auto info = format.info()) { - return format.opaque_equivalent(); + if (info->has_alpha()) + { + return info->opaque_equivalent(); + } + else + { + return info->alpha_equivalent(); + } + } + else + { + // If we don't know about the format, we can't find alternatives + return {}; } - return format.alpha_equivalent(); }(); if (alternate_format) diff --git a/src/server/scene/basic_surface.cpp b/src/server/scene/basic_surface.cpp index a58e54e40aa..2af9f2ce2bf 100644 --- a/src/server/scene/basic_surface.cpp +++ b/src/server/scene/basic_surface.cpp @@ -729,7 +729,9 @@ class SurfaceSnapshot : public mg::Renderable { return transformation_; } bool shaped() const override - { return entry->pixel_format().has_alpha(); } + { + return entry->pixel_format().info().transform([](auto info) { return info.has_alpha();}).value_or(true); + } mg::Renderable::ID id() const override { return id_; }