mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-24 09:05:06 +03:00
cam: drm: Avoid importing the same dmabuf multiple times
When creating a DRM frame buffer, the dmabufs for the planes are imported as GEM objects. For multi-planar formats, all planes may use the same dmabuf, which results in multiple imports. This doesn't cause any issue at import time, as DRM detects this situation and returns the same GEM object. However, when destroying the frame buffer, the same GEM object ends up being closed multiple times, which generates an error. Fix this by avoiding multiple imports of the same dmabuf for the same frame buffer. While the issue may theoretically occur with identical dmabufs for different frame buffers, this is quite unlikely and is thus not addressed. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
71dad75373
commit
dd8b6a2cc9
2 changed files with 18 additions and 13 deletions
|
@ -283,9 +283,9 @@ FrameBuffer::FrameBuffer(Device *dev)
|
|||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
for (FrameBuffer::Plane &plane : planes_) {
|
||||
for (const auto &plane : planes_) {
|
||||
struct drm_gem_close gem_close = {
|
||||
.handle = plane.handle,
|
||||
.handle = plane.second.handle,
|
||||
.pad = 0,
|
||||
};
|
||||
int ret;
|
||||
|
@ -605,22 +605,27 @@ std::unique_ptr<FrameBuffer> Device::createFrameBuffer(
|
|||
int ret;
|
||||
|
||||
const std::vector<libcamera::FrameBuffer::Plane> &planes = buffer.planes();
|
||||
fb->planes_.reserve(planes.size());
|
||||
|
||||
unsigned int i = 0;
|
||||
for (const libcamera::FrameBuffer::Plane &plane : planes) {
|
||||
int fd = plane.fd.fd();
|
||||
uint32_t handle;
|
||||
|
||||
ret = drmPrimeFDToHandle(fd_, plane.fd.fd(), &handle);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
std::cerr
|
||||
<< "Unable to import framebuffer dmabuf: "
|
||||
<< strerror(-ret) << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
auto iter = fb->planes_.find(fd);
|
||||
if (iter == fb->planes_.end()) {
|
||||
ret = drmPrimeFDToHandle(fd_, plane.fd.fd(), &handle);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
std::cerr
|
||||
<< "Unable to import framebuffer dmabuf: "
|
||||
<< strerror(-ret) << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fb->planes_.push_back({ handle });
|
||||
fb->planes_[fd] = { handle };
|
||||
} else {
|
||||
handle = iter->second.handle;
|
||||
}
|
||||
|
||||
handles[i] = handle;
|
||||
offsets[i] = plane.offset;
|
||||
|
|
|
@ -242,7 +242,7 @@ private:
|
|||
|
||||
FrameBuffer(Device *dev);
|
||||
|
||||
std::vector<Plane> planes_;
|
||||
std::map<int, Plane> planes_;
|
||||
};
|
||||
|
||||
class AtomicRequest
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue