27#include <Gfx/Graph/interop/EglDmaBufImport.hpp>
29#include <ossia/detail/dylib_loader.hpp>
32#include <QOpenGLContext>
33#include <QOpenGLExtraFunctions>
53 static constexpr uint32_t GBM_BO_USE_SCANOUT_v = 1u << 0;
55 static constexpr uint32_t GBM_BO_USE_RENDERING_v = (1u << 2);
56 static constexpr uint32_t GBM_BO_USE_LINEAR_v = (1u << 4);
60 static constexpr uint32_t DRM_FORMAT_ARGB8888_v = 0x34325241u;
61 static constexpr uint32_t DRM_FORMAT_ABGR8888_v = 0x34324241u;
62 static constexpr uint32_t DRM_FORMAT_XRGB8888_v = 0x34325258u;
63 static constexpr uint64_t DRM_FORMAT_MOD_LINEAR_v = 0ULL;
65 using FN_gbm_create_device = gbm_device* (*)(
int fd);
66 using FN_gbm_device_destroy = void (*)(gbm_device* gbm);
67 using FN_gbm_bo_create
68 = gbm_bo* (*)(gbm_device*, uint32_t w, uint32_t h, uint32_t fmt,
70 using FN_gbm_bo_create_with_modifiers2
71 = gbm_bo* (*)(gbm_device*, uint32_t w, uint32_t h, uint32_t fmt,
72 const uint64_t* mods,
unsigned int count, uint32_t flags);
73 using FN_gbm_bo_get_fd = int (*)(gbm_bo*);
74 using FN_gbm_bo_get_stride = uint32_t (*)(gbm_bo*);
75 using FN_gbm_bo_get_offset = uint32_t (*)(gbm_bo*,
int plane);
76 using FN_gbm_bo_get_modifier = uint64_t (*)(gbm_bo*);
77 using FN_gbm_bo_get_plane_count = int (*)(gbm_bo*);
78 using FN_gbm_bo_destroy = void (*)(gbm_bo*);
80 std::optional<ossia::dylib_loader> m_lib;
81 FN_gbm_create_device m_create_device{};
82 FN_gbm_device_destroy m_device_destroy{};
83 FN_gbm_bo_create m_bo_create{};
84 FN_gbm_bo_create_with_modifiers2 m_bo_create_with_modifiers2{};
85 FN_gbm_bo_get_fd m_bo_get_fd{};
86 FN_gbm_bo_get_stride m_bo_get_stride{};
87 FN_gbm_bo_get_offset m_bo_get_offset{};
88 FN_gbm_bo_get_modifier m_bo_get_modifier{};
89 FN_gbm_bo_get_plane_count m_bo_get_plane_count{};
90 FN_gbm_bo_destroy m_bo_destroy{};
93 gbm_device* m_device{
nullptr};
98 static bool isAvailable() noexcept
102 ossia::dylib_loader probe(
103 std::vector<std::string_view>{
"libgbm.so.1",
"libgbm.so"});
104 if(!probe.symbol<FN_gbm_create_device>(
"gbm_create_device"))
113 return ::access(
"/dev/dri/renderD128", R_OK | W_OK) == 0;
121 std::vector<std::string_view>{
"libgbm.so.1",
"libgbm.so"});
129 = m_lib->symbol<FN_gbm_create_device>(
"gbm_create_device");
131 = m_lib->symbol<FN_gbm_device_destroy>(
"gbm_device_destroy");
132 m_bo_create = m_lib->symbol<FN_gbm_bo_create>(
"gbm_bo_create");
134 m_bo_create_with_modifiers2
135 = m_lib->symbol<FN_gbm_bo_create_with_modifiers2>(
136 "gbm_bo_create_with_modifiers2");
137 m_bo_get_fd = m_lib->symbol<FN_gbm_bo_get_fd>(
"gbm_bo_get_fd");
139 = m_lib->symbol<FN_gbm_bo_get_stride>(
"gbm_bo_get_stride");
141 = m_lib->symbol<FN_gbm_bo_get_offset>(
"gbm_bo_get_offset");
143 = m_lib->symbol<FN_gbm_bo_get_modifier>(
"gbm_bo_get_modifier");
144 m_bo_get_plane_count = m_lib->symbol<FN_gbm_bo_get_plane_count>(
145 "gbm_bo_get_plane_count");
146 m_bo_destroy = m_lib->symbol<FN_gbm_bo_destroy>(
"gbm_bo_destroy");
148 if(!m_create_device || !m_device_destroy || !m_bo_create
149 || !m_bo_get_fd || !m_bo_get_stride || !m_bo_destroy)
156 m_drmFd = ::open(
"/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
159 qWarning() <<
"EglDmaBufExport: failed to open /dev/dri/renderD128";
163 m_device = m_create_device(m_drmFd);
166 qWarning() <<
"EglDmaBufExport: gbm_create_device failed";
174 void shutdown() noexcept
176 if(m_device && m_device_destroy)
177 m_device_destroy(m_device);
197 uint32_t drm_fourcc{};
198 EglDmaBufImporter::PlaneImport plane{};
199 unsigned int glTexture{0};
207 bool allocSlotGbmOnly(
208 Slot& out, uint32_t w, uint32_t h, uint32_t drm_fourcc,
209 uint32_t extraFlags = 0) noexcept
214 out.drm_fourcc = drm_fourcc;
219 const uint64_t mods[] = {DRM_FORMAT_MOD_LINEAR_v};
221 = GBM_BO_USE_RENDERING_v | GBM_BO_USE_LINEAR_v | extraFlags;
222 if(m_bo_create_with_modifiers2)
224 out.bo = m_bo_create_with_modifiers2(
225 m_device, w, h, drm_fourcc, mods,
226 sizeof(mods) /
sizeof(mods[0]), flags);
232 out.bo = m_bo_create(m_device, w, h, drm_fourcc, flags);
241 out.bo = m_bo_create(
242 m_device, w, h, drm_fourcc, GBM_BO_USE_LINEAR_v | extraFlags);
246 qWarning() <<
"EglDmaBufExport: gbm_bo_create failed";
250 out.fd = m_bo_get_fd(out.bo);
251 out.stride = m_bo_get_stride(out.bo);
252 out.offset = m_bo_get_offset ? m_bo_get_offset(out.bo, 0) : 0;
254 = m_bo_get_modifier ? m_bo_get_modifier(out.bo) : 0ULL;
255 out.size = std::size_t(out.stride) * std::size_t(h);
259 qWarning() <<
"EglDmaBufExport: gbm_bo_get_fd returned -1";
261 m_bo_destroy(out.bo);
277 Slot& out, uint32_t w, uint32_t h, uint32_t drm_fourcc,
278 EglDmaBufImporter& importer, uint32_t extraFlags = 0) noexcept
280 if(!allocSlotGbmOnly(out, w, h, drm_fourcc, extraFlags))
286 out.glTexture = createLinearClampGlTexture2D();
287 if(out.glTexture == 0)
289 qWarning() <<
"EglDmaBufExport: failed to create GL texture";
293 m_bo_destroy(out.bo);
300 if(!importer.importPlane(
301 out.plane, out.glTexture, out.fd, out.modifier, out.offset,
302 out.stride, drm_fourcc,
int(w),
int(h)))
304 qWarning() <<
"EglDmaBufExport: importer.importPlane failed";
305 if(
auto* ctx = QOpenGLContext::currentContext(); ctx)
306 ctx->extraFunctions()->glDeleteTextures(1, &out.glTexture);
311 m_bo_destroy(out.bo);
321 void destroySlotGbmOnly(Slot& s)
noexcept
328 if(s.bo && m_bo_destroy)
333 void destroySlot(Slot& s, EglDmaBufImporter& importer)
noexcept
336 importer.cleanupPlane(s.plane);
339 if(
auto* ctx = QOpenGLContext::currentContext(); ctx)
340 ctx->extraFunctions()->glDeleteTextures(1, &s.glTexture);
351 if(s.bo && m_bo_destroy)
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11