Merge pull request #26148 from ksooo/fix-secondstotimestring-warning
[xbmc.git] / xbmc / utils / DumbBufferObject.cpp
blob51e518a0c5a6522b955f958f6151c6aa7121e705
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 "DumbBufferObject.h"
11 #include "ServiceBroker.h"
12 #include "utils/BufferObjectFactory.h"
13 #include "utils/log.h"
14 #include "windowing/gbm/WinSystemGbm.h"
15 #include "windowing/gbm/WinSystemGbmEGLContext.h"
17 #include <drm_fourcc.h>
18 #include <fcntl.h>
19 #include <sys/mman.h>
20 #include <unistd.h>
22 #include "PlatformDefs.h"
24 using namespace KODI::WINDOWING::GBM;
26 std::unique_ptr<CBufferObject> CDumbBufferObject::Create()
28 return std::make_unique<CDumbBufferObject>();
31 void CDumbBufferObject::Register()
33 CBufferObjectFactory::RegisterBufferObject(CDumbBufferObject::Create);
36 CDumbBufferObject::CDumbBufferObject()
38 auto winSystem = static_cast<CWinSystemGbmEGLContext*>(CServiceBroker::GetWinSystem());
40 m_device = winSystem->GetDrm()->GetFileDescriptor();
43 CDumbBufferObject::~CDumbBufferObject()
45 ReleaseMemory();
46 DestroyBufferObject();
49 bool CDumbBufferObject::CreateBufferObject(uint32_t format, uint32_t width, uint32_t height)
51 if (m_fd >= 0)
52 return true;
54 uint32_t bpp;
56 switch (format)
58 case DRM_FORMAT_ARGB1555:
59 case DRM_FORMAT_RGB565:
60 bpp = 16;
61 break;
62 case DRM_FORMAT_ARGB8888:
63 bpp = 32;
64 break;
65 default:
66 throw std::runtime_error("CDumbBufferObject: pixel format not implemented");
69 struct drm_mode_create_dumb create_dumb{};
70 create_dumb.height = height;
71 create_dumb.width = width;
72 create_dumb.bpp = bpp;
74 int ret = drmIoctl(m_device, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
75 if (ret < 0)
77 CLog::Log(LOGERROR, "CDumbBufferObject::{} - ioctl DRM_IOCTL_MODE_CREATE_DUMB failed, errno={}",
78 __FUNCTION__, strerror(errno));
79 return false;
82 m_size = create_dumb.size;
83 m_stride = create_dumb.pitch;
85 ret = drmPrimeHandleToFD(m_device, create_dumb.handle, 0, &m_fd);
86 if (ret < 0)
88 CLog::Log(LOGERROR, "CDumbBufferObject::{} - failed to get fd from prime handle, errno={}",
89 __FUNCTION__, strerror(errno));
90 return false;
93 return true;
96 void CDumbBufferObject::DestroyBufferObject()
98 if (m_fd < 0)
99 return;
101 int ret = close(m_fd);
102 if (ret < 0)
103 CLog::Log(LOGERROR, "CDumbBufferObject::{} - close failed, errno={}", __FUNCTION__,
104 strerror(errno));
106 m_fd = -1;
107 m_stride = 0;
108 m_size = 0;
111 uint8_t* CDumbBufferObject::GetMemory()
113 if (m_fd < 0)
114 return nullptr;
116 if (m_map)
118 CLog::Log(LOGDEBUG, "CDumbBufferObject::{} - already mapped fd={} map={}", __FUNCTION__, m_fd,
119 fmt::ptr(m_map));
120 return m_map;
123 uint32_t handle;
124 int ret = drmPrimeFDToHandle(m_device, m_fd, &handle);
125 if (ret < 0)
127 CLog::Log(LOGERROR, "CDumbBufferObject::{} - failed to get handle from prime fd, errno={}",
128 __FUNCTION__, strerror(errno));
129 return nullptr;
132 struct drm_mode_map_dumb map_dumb{};
133 map_dumb.handle = handle;
135 ret = drmIoctl(m_device, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
136 if (ret < 0)
138 CLog::Log(LOGERROR, "CDumbBufferObject::{} - ioctl DRM_IOCTL_MODE_MAP_DUMB failed, errno={}",
139 __FUNCTION__, strerror(errno));
140 return nullptr;
143 m_offset = map_dumb.offset;
145 m_map = static_cast<uint8_t*>(mmap(nullptr, m_size, PROT_WRITE, MAP_SHARED, m_device, m_offset));
146 if (m_map == MAP_FAILED)
148 CLog::Log(LOGERROR, "CDumbBufferObject::{} - mmap failed, errno={}", __FUNCTION__,
149 strerror(errno));
150 return nullptr;
153 return m_map;
156 void CDumbBufferObject::ReleaseMemory()
158 if (!m_map)
159 return;
161 int ret = munmap(m_map, m_size);
162 if (ret < 0)
163 CLog::Log(LOGERROR, "CDumbBufferObject::{} - munmap failed, errno={}", __FUNCTION__,
164 strerror(errno));
166 m_map = nullptr;
167 m_offset = 0;