Skip to content

Commit

Permalink
Sneak DisplaySink in and try to use the GBM path ( doesn't work :( )
Browse files Browse the repository at this point in the history
  • Loading branch information
tarek-y-ismail committed Sep 13, 2024
1 parent e8e7ec7 commit eeec45a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 22 deletions.
2 changes: 1 addition & 1 deletion include/platform/mir/graphics/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ class DmaBufDisplayAllocator : public DisplayAllocator
{
};

virtual auto framebuffer_for(std::shared_ptr<DMABufBuffer> buffer)
virtual auto framebuffer_for(mir::graphics::DisplaySink& sink, std::shared_ptr<DMABufBuffer> buffer)
-> std::unique_ptr<Framebuffer> = 0;
};

Expand Down
53 changes: 36 additions & 17 deletions src/platforms/atomic-kms/server/kms/display_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,22 +343,27 @@ void mga::DisplaySink::set_next_image(std::unique_ptr<Framebuffer> content)
}
}

auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr<DMABufBuffer> buffer) -> std::unique_ptr<Framebuffer>
auto mga::DmaBufDisplayAllocator::framebuffer_for(mg::DisplaySink& sink, std::shared_ptr<DMABufBuffer> buffer) -> std::unique_ptr<Framebuffer>
{
DisplaySink* ds = dynamic_cast<DisplaySink*>(&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",
Expand All @@ -367,22 +372,36 @@ auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr<DMABufBuffer>
/* 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<uint32_t>(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<uint32_t>{
new uint32_t{0},
[drm_fd = drm_fd()](uint32_t* fb_id)
Expand All @@ -401,8 +420,8 @@ auto mga::DmaBufDisplayAllocator::framebuffer_for(std::shared_ptr<DMABufBuffer>
height.as_uint32_t(),
pixel_format,
gem_handles,
pitches,
offsets,
(uint32_t*)pitches,
(uint32_t*)offsets,
modifiers,
fb_id.get(),
0);
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/atomic-kms/server/kms/display_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class DmaBufDisplayAllocator : public graphics::DmaBufDisplayAllocator
{
}

virtual auto framebuffer_for(std::shared_ptr<DMABufBuffer> buffer) -> std::unique_ptr<Framebuffer> override;
virtual auto framebuffer_for(mir::graphics::DisplaySink& sink, std::shared_ptr<DMABufBuffer> buffer) -> std::unique_ptr<Framebuffer> override;

auto drm_fd() -> mir::Fd const
{
Expand Down
7 changes: 4 additions & 3 deletions src/platforms/gbm-kms/server/buffer_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,25 +561,26 @@ 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}
{
}

auto buffer_to_framebuffer(std::shared_ptr<Buffer> buffer) -> std::unique_ptr<Framebuffer> override
{
if(auto dma_buf = std::dynamic_pointer_cast<mir::graphics::DMABufBuffer>(buffer))
{
return allocator->framebuffer_for(dma_buf);
return allocator->framebuffer_for(sink, dma_buf);
}

return {};
}

private:
DmaBufDisplayAllocator* allocator;
mg::DisplaySink& sink;
};

return std::make_unique<FooFramebufferProvider>(allocator);
return std::make_unique<FooFramebufferProvider>(allocator, sink);
}

// TODO: Make this not a null implementation, so bypass/overlays can work again
Expand Down

0 comments on commit eeec45a

Please sign in to comment.