bool drm_mode_destroy_blob(int fd, struct drm_mode *mode) { int ret = 0; if (mode->blob_id) { ret = drmModeDestroyPropertyBlob(fd, mode->blob_id); mode->blob_id = 0; } return (ret == 0); }
void CDRMAtomic::DrmAtomicCommit(int fb_id, int flags, bool rendered, bool videoLayer) { uint32_t blob_id; struct plane *plane; if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET) { if (!AddProperty(m_req, m_connector, "CRTC_ID", m_crtc->crtc->crtc_id)) { return; } if (drmModeCreatePropertyBlob(m_fd, m_mode, sizeof(*m_mode), &blob_id) != 0) { return; } if (!AddProperty(m_req, m_crtc, "MODE_ID", blob_id)) { return; } if (!AddProperty(m_req, m_crtc, "ACTIVE", m_active ? 1 : 0)) { return; } if (!videoLayer) { // disable overlay plane on modeset AddProperty(m_req, m_overlay_plane, "FB_ID", 0); AddProperty(m_req, m_overlay_plane, "CRTC_ID", 0); } } if (videoLayer) plane = m_overlay_plane; else plane = m_primary_plane; if (rendered) { AddProperty(m_req, plane, "FB_ID", fb_id); AddProperty(m_req, plane, "CRTC_ID", m_crtc->crtc->crtc_id); AddProperty(m_req, plane, "SRC_X", 0); AddProperty(m_req, plane, "SRC_Y", 0); AddProperty(m_req, plane, "SRC_W", m_mode->hdisplay << 16); AddProperty(m_req, plane, "SRC_H", m_mode->vdisplay << 16); AddProperty(m_req, plane, "CRTC_X", 0); AddProperty(m_req, plane, "CRTC_Y", 0); AddProperty(m_req, plane, "CRTC_W", m_mode->hdisplay); AddProperty(m_req, plane, "CRTC_H", m_mode->vdisplay); } else if (videoLayer && !CServiceBroker::GetGUI()->GetWindowManager().HasVisibleControls()) { // disable gui plane when video layer is active and gui has no visible controls AddProperty(m_req, plane, "FB_ID", 0); AddProperty(m_req, plane, "CRTC_ID", 0); } auto ret = drmModeAtomicCommit(m_fd, m_req, flags | DRM_MODE_ATOMIC_TEST_ONLY, nullptr); if (ret < 0) { CLog::Log(LOGERROR, "CDRMAtomic::%s - test commit failed: %s", __FUNCTION__, strerror(errno)); } else if (ret == 0) { ret = drmModeAtomicCommit(m_fd, m_req, flags, nullptr); if (ret < 0) { CLog::Log(LOGERROR, "CDRMAtomic::%s - atomic commit failed: %s", __FUNCTION__, strerror(errno)); } } if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET) { if (drmModeDestroyPropertyBlob(m_fd, blob_id) != 0) CLog::Log(LOGERROR, "CDRMAtomic::%s - failed to destroy property blob: %s", __FUNCTION__, strerror(errno)); } drmModeAtomicFree(m_req); m_req = drmModeAtomicAlloc(); }