From eeec45a0edc19edfb171b134e0d7aab541b46203 Mon Sep 17 00:00:00 2001 From: Tarek Ismail Date: Thu, 12 Sep 2024 18:34:51 +0300 Subject: [PATCH] Sneak `DisplaySink` in and try to use the GBM path ( doesn't work :( ) --- include/platform/mir/graphics/platform.h | 2 +- .../atomic-kms/server/kms/display_buffer.cpp | 53 +++++++++++++------ .../atomic-kms/server/kms/display_sink.h | 2 +- .../gbm-kms/server/buffer_allocator.cpp | 7 +-- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/include/platform/mir/graphics/platform.h b/include/platform/mir/graphics/platform.h index 193e3988dc..5e5f709a8c 100644 --- a/include/platform/mir/graphics/platform.h +++ b/include/platform/mir/graphics/platform.h @@ -396,7 +396,7 @@ class DmaBufDisplayAllocator : public DisplayAllocator { }; - virtual auto framebuffer_for(std::shared_ptr buffer) + virtual auto framebuffer_for(mir::graphics::DisplaySink& sink, std::shared_ptr buffer) -> std::unique_ptr = 0; }; diff --git a/src/platforms/atomic-kms/server/kms/display_buffer.cpp b/src/platforms/atomic-kms/server/kms/display_buffer.cpp index d600abbd03..831a79ed5a 100644 --- a/src/platforms/atomic-kms/server/kms/display_buffer.cpp +++ b/src/platforms/atomic-kms/server/kms/display_buffer.cpp @@ -343,22 +343,27 @@ void mga::DisplaySink::set_next_image(std::unique_ptr content) } } -auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr buffer) -> std::unique_ptr +auto mga::DmaBufDisplayAllocator::framebuffer_for(mg::DisplaySink& sink, std::shared_ptr buffer) -> std::unique_ptr { + DisplaySink* ds = dynamic_cast(&sink); + if(!ds) + return {}; + auto plane_descriptors = buffer->planes(); + auto const max_planes = 4zu; assert(plane_descriptors.size() <= 4); auto width = buffer->size().width; auto height = buffer->size().height; auto pixel_format = buffer->format(); - uint32_t gem_handles[4] = {0}; - uint32_t pitches[4] = {0}; - uint32_t offsets[4] = {0}; + int dmabuf_fds[4] = {0}; + int pitches[4] = {0}; + int offsets[4] = {0}; uint64_t modifiers[4] = {}; - std::fill_n(modifiers, 4, 0); + std::fill_n(modifiers, 4, buffer->modifier().value_or(DRM_FORMAT_MOD_NONE)); mir::log_debug( "Buffer format %s", @@ -367,22 +372,36 @@ auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr /* buffer->modifier().value_or(0) */ ); - for (std::size_t i = 0; i < std::min(1zu, plane_descriptors.size()); i++) + for (std::size_t i = 0; i < std::min(max_planes, plane_descriptors.size()); i++) { - uint32_t gem_handle = 0; - int ret = drmPrimeFDToHandle(drm_fd(), plane_descriptors[i].dma_buf, &gem_handle); - if(ret) - { - mir::log_debug("Failed to convert buffer"); - return {}; - } - - gem_handles[i] = gem_handle; + dmabuf_fds[i] = plane_descriptors[i].dma_buf; pitches[i] = plane_descriptors[i].stride; offsets[i] = plane_descriptors[i].offset; } + gbm_import_fd_modifier_data import_data = { + .width = buffer->size().width.as_uint32_t(), + .height = buffer->size().height.as_uint32_t(), + .format = buffer->format(), + .num_fds = static_cast(std::min(plane_descriptors.size(), max_planes)), + .fds = {dmabuf_fds[0], dmabuf_fds[1], dmabuf_fds[2], dmabuf_fds[3]}, + .strides = {pitches[0], pitches[1], pitches[2], pitches[3]}, + .offsets = {offsets[0], pitches[1], pitches[2], pitches[3]}, + .modifier = buffer->modifier().value_or(DRM_FORMAT_MOD_NONE), + }; + struct gbm_bo* gbm_bo = gbm_bo_import(ds->gbm_device().get(), GBM_BO_IMPORT_FD_MODIFIER, (void*)&import_data, GBM_BO_USE_SCANOUT); + + if(!gbm_bo) + { + mir::log_debug("Failed to import buffer"); + return {}; + } + + uint32_t gem_handles[4] = {0}; + for (std::size_t i = 0; i < std::min(max_planes, plane_descriptors.size()); i++) + gem_handles[i] = gbm_bo_get_handle_for_plane(gbm_bo, i).u32; + auto fb_id = std::shared_ptr{ new uint32_t{0}, [drm_fd = drm_fd()](uint32_t* fb_id) @@ -401,8 +420,8 @@ auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr height.as_uint32_t(), pixel_format, gem_handles, - pitches, - offsets, + (uint32_t*)pitches, + (uint32_t*)offsets, modifiers, fb_id.get(), 0); diff --git a/src/platforms/atomic-kms/server/kms/display_sink.h b/src/platforms/atomic-kms/server/kms/display_sink.h index 8f7ce8a2d3..b925dd8783 100644 --- a/src/platforms/atomic-kms/server/kms/display_sink.h +++ b/src/platforms/atomic-kms/server/kms/display_sink.h @@ -58,7 +58,7 @@ class DmaBufDisplayAllocator : public graphics::DmaBufDisplayAllocator { } - virtual auto framebuffer_for(std::shared_ptr buffer) -> std::unique_ptr override; + virtual auto framebuffer_for(mir::graphics::DisplaySink& sink, std::shared_ptr buffer) -> std::unique_ptr override; auto drm_fd() -> mir::Fd const { diff --git a/src/platforms/gbm-kms/server/buffer_allocator.cpp b/src/platforms/gbm-kms/server/buffer_allocator.cpp index cbb7f7c315..5792b216aa 100644 --- a/src/platforms/gbm-kms/server/buffer_allocator.cpp +++ b/src/platforms/gbm-kms/server/buffer_allocator.cpp @@ -561,7 +561,7 @@ auto mgg::GLRenderingProvider::make_framebuffer_provider(DisplaySink& sink) struct FooFramebufferProvider: public FramebufferProvider { public: - FooFramebufferProvider(DmaBufDisplayAllocator* allocator) : allocator{allocator} + FooFramebufferProvider(DmaBufDisplayAllocator* allocator, mg::DisplaySink& sink) : allocator{allocator}, sink{sink} { } @@ -569,7 +569,7 @@ auto mgg::GLRenderingProvider::make_framebuffer_provider(DisplaySink& sink) { if(auto dma_buf = std::dynamic_pointer_cast(buffer)) { - return allocator->framebuffer_for(dma_buf); + return allocator->framebuffer_for(sink, dma_buf); } return {}; @@ -577,9 +577,10 @@ auto mgg::GLRenderingProvider::make_framebuffer_provider(DisplaySink& sink) private: DmaBufDisplayAllocator* allocator; + mg::DisplaySink& sink; }; - return std::make_unique(allocator); + return std::make_unique(allocator, sink); } // TODO: Make this not a null implementation, so bypass/overlays can work again