From 35695642d513759fabcdf5dc568661cfa5ceb03b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 23 Jun 2024 19:03:35 -0500 Subject: [PATCH] Use the first available plane that meets the zpos requirement Planes seem to be listed in descending order of capabilities with later planes sometimes lacking scaling capabilities, which is the case with vs-drm on the TH1520. --- app/streaming/video/ffmpeg-renderers/drm.cpp | 49 +++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 9de05052..1fa8f61b 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -445,13 +445,43 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params) return DIRECT_RENDERING_INIT_FAILED; } + // Find the active plane (if any) on this CRTC with the highest zpos. + // We'll need to use a plane with a equal or greater zpos to be visible. + uint64_t maxActiveZpos = 0; + for (uint32_t i = 0; i < planeRes->count_planes; i++) { + drmModePlane* plane = drmModeGetPlane(m_DrmFd, planeRes->planes[i]); + if (plane != nullptr) { + if (plane->crtc_id == m_CrtcId) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Plane %u is active on CRTC %u", + plane->plane_id, + m_CrtcId); + + drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_DrmFd, planeRes->planes[i], DRM_MODE_OBJECT_PLANE); + if (props != nullptr) { + // Only consider primary and overlay planes as valid render targets + uint64_t type; + if (getPropertyByName(props, "type", &type) && (type == DRM_PLANE_TYPE_PRIMARY || type == DRM_PLANE_TYPE_OVERLAY)) { + uint64_t zPos; + if (getPropertyByName(props, "zpos", &zPos) && zPos > maxActiveZpos) { + maxActiveZpos = zPos; + } + } + + drmModeFreeObjectProperties(props); + } + } + + drmModeFreePlane(plane); + } + } + // Find a plane with the required format to render on // // FIXME: We should check the actual DRM format in a real AVFrame rather // than just assuming it will be a certain hardcoded type like NV12 based // on the chosen video format. - uint64_t maxZpos = 0; - for (uint32_t i = 0; i < planeRes->count_planes; i++) { + for (uint32_t i = 0; i < planeRes->count_planes && !m_PlaneId; i++) { drmModePlane* plane = drmModeGetPlane(m_DrmFd, planeRes->planes[i]); if (plane != nullptr) { // If the plane can't be used on our CRTC, don't consider it further @@ -494,27 +524,24 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params) drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_DrmFd, planeRes->planes[i], DRM_MODE_OBJECT_PLANE); if (props != nullptr) { uint64_t type; - uint64_t zPos = 0; + uint64_t zPos; // Only consider primary and overlay planes as valid render targets if (!getPropertyByName(props, "type", &type) || (type != DRM_PLANE_TYPE_PRIMARY && type != DRM_PLANE_TYPE_OVERLAY)) { drmModeFreePlane(plane); } // If this plane has a zpos property and it's lower (further from user) than - // the previous plane we found, avoid this plane in favor of the closer one. + // the highest active plane we found, avoid this plane. It won't be visible. // // Note: zpos is not a required property, but if any plane has it, all planes must. - else if (getPropertyByName(props, "zpos", &zPos) && m_PlaneId && zPos < maxZpos) { + else if (getPropertyByName(props, "zpos", &zPos) && zPos < maxActiveZpos) { drmModeFreePlane(plane); } else { - // This plane is a better match than what we had previously! - m_PlaneId = plane->plane_id; - maxZpos = zPos; + SDL_assert(!m_PlaneId); + SDL_assert(!m_Plane); - if (m_Plane) { - drmModeFreePlane(m_Plane); - } + m_PlaneId = plane->plane_id; m_Plane = plane; }