8 #include <drm_fourcc.h>
11 #define LOC QString("DRMBuf: ")
15 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"DRM frame: Layers %1 Objects %2")
16 .arg(Desc->nb_layers).arg(Desc->nb_objects));
17 for (
int i = 0; i < Desc->nb_layers; ++i)
19 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Layer %1: Format %2 Planes %3")
20 .arg(i).arg(
fourcc_str(
static_cast<int>(Desc->layers[i].format)))
21 .arg(Desc->layers[i].nb_planes));
22 for (
int j = 0; j < Desc->layers[i].nb_planes; ++j)
24 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
" Plane %1: Index %2 Offset %3 Pitch %4")
25 .arg(j).arg(Desc->layers[i].planes[j].object_index)
26 .arg(Desc->layers[i].planes[j].offset).arg(Desc->layers[i].planes[j].pitch));
29 for (
int i = 0; i < Desc->nb_objects; ++i)
30 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Object: %1 FD %2 Mods 0x%3")
31 .arg(i).arg(Desc->objects[i].fd).arg(Desc->objects[i].format_modifier, 0 , 16));
43 : m_device(std::move(
Device))
45 if (!DRMDesc || DRMDesc->nb_layers < 1)
51 for (
auto i = 0; i < DRMDesc->nb_objects; i++)
53 int ret = drmPrimeFDToHandle(
m_device->GetFD(), DRMDesc->objects[i].fd,
57 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to get GEM handle");
66 std::array<uint64_t,4> modifiers = { 0 };
68 if (DRMDesc->nb_layers == 1)
70 const auto * layer = &DRMDesc->layers[0];
71 for (
int plane = 0; plane < layer->nb_planes; plane++)
73 auto objectidx =
static_cast<size_t>(layer->planes[plane].object_index);
75 if (handle && layer->planes[plane].pitch)
77 handles[
static_cast<size_t>(plane)] = handle;
78 pitches[
static_cast<size_t>(plane)] =
static_cast<uint32_t
>(layer->planes[plane].pitch);
79 offsets[
static_cast<size_t>(plane)] =
static_cast<uint32_t
>(layer->planes[plane].offset);
80 modifiers[
static_cast<size_t>(plane)] = DRMDesc->objects[objectidx].format_modifier;
87 for (
int i = 0; i < DRMDesc->nb_layers; i++)
89 const auto & layer = DRMDesc->layers[i];
90 auto objectidx =
static_cast<size_t>(layer.planes[0].object_index);
92 if (handle && layer.planes[0].pitch)
94 handles[
static_cast<size_t>(i)] = handle;
95 pitches[
static_cast<size_t>(i)] =
static_cast<uint32_t
>(layer.planes[0].pitch);
96 offsets[
static_cast<size_t>(i)] =
static_cast<uint32_t
>(layer.planes[0].offset);
97 modifiers[
static_cast<size_t>(i)] = DRMDesc->objects[objectidx].format_modifier;
102 uint32_t flags = (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID) ? DRM_MODE_FB_MODIFIERS : 0;
103 uint32_t format = DRMDesc->layers[0].format;
106 if (DRMDesc->nb_layers == 2)
113 else if (DRMDesc->nb_layers == 3)
119 if (
auto ret = drmModeAddFB2WithModifiers(
m_device->GetFD(),
static_cast<uint32_t
>(Size.width()),
120 static_cast<uint32_t
>(Size.height()), format,
121 handles.data(), pitches.data(), offsets.data(),
122 modifiers.data(), &
m_fb, flags); ret < 0)
125 if (ret = drmModeAddFB2(
m_device->GetFD(),
static_cast<uint32_t
>(Size.width()),
126 static_cast<uint32_t
>(Size.height()), format,
127 handles.data(), pitches.data(), offsets.data(), &
m_fb, flags); ret < 0)
129 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to create framebuffer (error: %1)").arg(ret));
134 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"New video fb %1").arg(
m_fb));
140 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Deleting video fb %1").arg(
m_fb));
145 for (
size_t i = 0; i < AV_DRM_MAX_PLANES; ++i)