[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / utils / DMAHeapBufferObject.cpp
blobad05aa8290ac8ab7bb1528aa6d087f1c04a73866
1 /*
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.
7 */
9 #include "DMAHeapBufferObject.h"
11 #include "ServiceBroker.h"
12 #include "utils/BufferObjectFactory.h"
13 #include "utils/log.h"
15 #include <array>
17 #include <drm_fourcc.h>
18 #include <fcntl.h>
19 #include <linux/dma-heap.h>
20 #include <sys/ioctl.h>
21 #include <sys/mman.h>
22 #include <unistd.h>
24 namespace
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;
35 } // namespace
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);
47 if (fd < 0)
49 CLog::Log(LOGDEBUG, "CDMAHeapBufferObject::{} unable to open {}: {}", __FUNCTION__, path,
50 strerror(errno));
51 continue;
54 close(fd);
55 DMA_HEAP_PATH = path;
56 break;
59 if (!DMA_HEAP_PATH)
60 return;
62 CLog::Log(LOGDEBUG, "CDMAHeapBufferObject::{} - using {}", __FUNCTION__, DMA_HEAP_PATH);
64 CBufferObjectFactory::RegisterBufferObject(CDMAHeapBufferObject::Create);
67 CDMAHeapBufferObject::~CDMAHeapBufferObject()
69 ReleaseMemory();
70 DestroyBufferObject();
72 close(m_dmaheapfd);
73 m_dmaheapfd = -1;
76 bool CDMAHeapBufferObject::CreateBufferObject(uint32_t format, uint32_t width, uint32_t height)
78 if (m_fd >= 0)
79 return true;
81 uint32_t bpp{1};
83 switch (format)
85 case DRM_FORMAT_ARGB8888:
86 bpp = 4;
87 break;
88 case DRM_FORMAT_ARGB1555:
89 case DRM_FORMAT_RGB565:
90 bpp = 2;
91 break;
92 default:
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)
103 m_size = size;
105 if (m_dmaheapfd < 0)
107 m_dmaheapfd = open(DMA_HEAP_PATH, O_RDWR);
108 if (m_dmaheapfd < 0)
110 CLog::LogF(LOGERROR, "failed to open {}:", DMA_HEAP_PATH, strerror(errno));
111 return false;
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);
121 if (ret < 0)
123 CLog::Log(LOGERROR, "CDMAHeapBufferObject::{} - ioctl DMA_HEAP_IOCTL_ALLOC failed, errno={}",
124 __FUNCTION__, strerror(errno));
125 return false;
128 m_fd = allocData.fd;
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);
135 return false;
138 return true;
141 void CDMAHeapBufferObject::DestroyBufferObject()
143 if (m_fd < 0)
144 return;
146 int ret = close(m_fd);
147 if (ret < 0)
148 CLog::Log(LOGERROR, "CDMAHeapBufferObject::{} - close failed, errno={}", __FUNCTION__,
149 strerror(errno));
151 m_fd = -1;
152 m_stride = 0;
153 m_size = 0;
156 uint8_t* CDMAHeapBufferObject::GetMemory()
158 if (m_fd < 0)
159 return nullptr;
161 if (m_map)
163 CLog::Log(LOGDEBUG, "CDMAHeapBufferObject::{} - already mapped fd={} map={}", __FUNCTION__,
164 m_fd, fmt::ptr(m_map));
165 return 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__,
172 strerror(errno));
173 return nullptr;
176 return m_map;
179 void CDMAHeapBufferObject::ReleaseMemory()
181 if (!m_map)
182 return;
184 int ret = munmap(m_map, m_size);
185 if (ret < 0)
186 CLog::Log(LOGERROR, "CDMAHeapBufferObject::{} - munmap failed, errno={}", __FUNCTION__,
187 strerror(errno));
189 m_map = nullptr;