2 * Copyright (C) 2005-2020 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "DMAHeapBufferObject.h"
11 #include "ServiceBroker.h"
12 #include "utils/BufferObjectFactory.h"
13 #include "utils/log.h"
17 #include <drm_fourcc.h>
19 #include <linux/dma-heap.h>
20 #include <sys/ioctl.h>
27 std::array
<const char*, 3> DMA_HEAP_PATHS
= {
28 "/dev/dma_heap/reserved",
29 "/dev/dma_heap/linux,cma",
30 "/dev/dma_heap/system",
33 static const char* DMA_HEAP_PATH
;
37 std::unique_ptr
<CBufferObject
> CDMAHeapBufferObject::Create()
39 return std::make_unique
<CDMAHeapBufferObject
>();
42 void CDMAHeapBufferObject::Register()
44 for (auto path
: DMA_HEAP_PATHS
)
46 int fd
= open(path
, O_RDWR
);
49 CLog::Log(LOGDEBUG
, "CDMAHeapBufferObject::{} unable to open {}: {}", __FUNCTION__
, path
,
62 CLog::Log(LOGDEBUG
, "CDMAHeapBufferObject::{} - using {}", __FUNCTION__
, DMA_HEAP_PATH
);
64 CBufferObjectFactory::RegisterBufferObject(CDMAHeapBufferObject::Create
);
67 CDMAHeapBufferObject::~CDMAHeapBufferObject()
70 DestroyBufferObject();
76 bool CDMAHeapBufferObject::CreateBufferObject(uint32_t format
, uint32_t width
, uint32_t height
)
85 case DRM_FORMAT_ARGB8888
:
88 case DRM_FORMAT_ARGB1555
:
89 case DRM_FORMAT_RGB565
:
93 throw std::runtime_error("CDMAHeapBufferObject: pixel format not implemented");
96 m_stride
= width
* bpp
;
98 return CreateBufferObject(width
* height
* bpp
);
101 bool CDMAHeapBufferObject::CreateBufferObject(uint64_t size
)
107 m_dmaheapfd
= open(DMA_HEAP_PATH
, O_RDWR
);
110 CLog::LogF(LOGERROR
, "failed to open {}:", DMA_HEAP_PATH
, strerror(errno
));
115 struct dma_heap_allocation_data allocData
{};
116 allocData
.len
= m_size
;
117 allocData
.fd_flags
= (O_CLOEXEC
| O_RDWR
);
118 allocData
.heap_flags
= 0;
120 int ret
= ioctl(m_dmaheapfd
, DMA_HEAP_IOCTL_ALLOC
, &allocData
);
123 CLog::Log(LOGERROR
, "CDMAHeapBufferObject::{} - ioctl DMA_HEAP_IOCTL_ALLOC failed, errno={}",
124 __FUNCTION__
, strerror(errno
));
129 m_size
= allocData
.len
;
131 if (m_fd
< 0 || m_size
<= 0)
133 CLog::Log(LOGERROR
, "CDMAHeapBufferObject::{} - invalid allocation data: fd={} len={}",
134 __FUNCTION__
, m_fd
, m_size
);
141 void CDMAHeapBufferObject::DestroyBufferObject()
146 int ret
= close(m_fd
);
148 CLog::Log(LOGERROR
, "CDMAHeapBufferObject::{} - close failed, errno={}", __FUNCTION__
,
156 uint8_t* CDMAHeapBufferObject::GetMemory()
163 CLog::Log(LOGDEBUG
, "CDMAHeapBufferObject::{} - already mapped fd={} map={}", __FUNCTION__
,
164 m_fd
, fmt::ptr(m_map
));
168 m_map
= static_cast<uint8_t*>(mmap(nullptr, m_size
, PROT_WRITE
, MAP_SHARED
, m_fd
, 0));
169 if (m_map
== MAP_FAILED
)
171 CLog::Log(LOGERROR
, "CDMAHeapBufferObject::{} - mmap failed, errno={}", __FUNCTION__
,
179 void CDMAHeapBufferObject::ReleaseMemory()
184 int ret
= munmap(m_map
, m_size
);
186 CLog::Log(LOGERROR
, "CDMAHeapBufferObject::{} - munmap failed, errno={}", __FUNCTION__
,