/* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "libdrm_macros.h" #include "drm/drm_fourcc.h" #include "drm_dpps_mgr_imp.h" #define __CLASS__ "DRMDppsManagerImp" namespace sde_drm { static DRMDppsManagerImp dpps_mgr; static DRMDppsManagerDummyImp dpps_dummy_mgr; DRMDppsManagerIntf* GetDppsManagerIntf() { #if (defined(__ANDROID__)) return &dpps_mgr; #else return &dpps_dummy_mgr; #endif } DRMDppsManagerImp::~DRMDppsManagerImp() { /* clean up the ION buffers for LTM */ DeInitLtmBuffers(); conn_id_ = -1; crtc_id_ = -1; drm_fd_ = -1; } int DRMDppsManagerImp::GetDrmResources(drmModeRes* res) { int enc_id = -1; drmModeConnector *conn = NULL; drmModeEncoder *enc = NULL; drmModeCrtc *crtc = NULL; if (drm_fd_ < 0 ) { DRM_LOGE("Invalid drm_fd_ %d", drm_fd_); return -EINVAL; } for (auto i = 0; i < res->count_connectors; i++) { conn = drmModeGetConnector(drm_fd_, res->connectors[i]); if (conn && conn->connector_type == DRM_MODE_CONNECTOR_DSI && conn->count_modes && conn->connection == DRM_MODE_CONNECTED) { DRM_LOGI("Found connector %d", conn->connector_id); conn_id_ = conn->connector_id; break; } drmModeFreeConnector(conn); conn = NULL; } if (conn_id_ < 0 || !conn) { DRM_LOGE("Cannot find valid connector"); conn_id_ = -1; return -EINVAL; } for (auto i = 0; i < conn->count_encoders; i++) { enc = drmModeGetEncoder(drm_fd_, conn->encoders[i]); if (enc && enc->encoder_type == DRM_MODE_ENCODER_DSI) { DRM_LOGI("Found encoder %d", enc->encoder_id); enc_id = enc->encoder_id; break; } drmModeFreeEncoder(enc); enc = NULL; } if (enc_id < 0 || !enc) { DRM_LOGE("Cannot find valid encoder"); drmModeFreeConnector(conn); conn = NULL; res = NULL; conn_id_ = -1; return -EINVAL; } for (auto i = 0; i < res->count_crtcs; i++) { if (enc->possible_crtcs & (1 << i)) { crtc = drmModeGetCrtc(drm_fd_, res->crtcs[i]); if (crtc) { DRM_LOGI("Found crtc %d", crtc->crtc_id); crtc_id_ = crtc->crtc_id; break; } drmModeFreeCrtc(crtc); crtc = NULL; } } if (crtc_id_ < 0 || !crtc) { DRM_LOGE("Cannot find valid crtc"); drmModeFreeEncoder(enc); drmModeFreeConnector(conn); enc = NULL; conn = NULL; conn_id_ = -1; crtc_id_ = -1; return -EINVAL; } return 0; } int DRMDppsManagerImp::InitCrtcProps() { if (drm_fd_ < 0 || crtc_id_ < 0) { DRM_LOGE("Invalid drm_fd_ %d or crtc_id_ %d", drm_fd_, crtc_id_); return -EINVAL; } drmModeObjectProperties *props = drmModeObjectGetProperties(drm_fd_, crtc_id_, DRM_MODE_OBJECT_CRTC); if (!props || !props->props || !props->prop_values) { drmModeFreeObjectProperties(props); return -EINVAL; } for (uint32_t j = 0; j < props->count_props; j++) { drmModePropertyRes *info = drmModeGetProperty(drm_fd_, props->props[j]); if (!info) { continue; } std::string property_name(info->name); DRMProperty prop_enum = prop_mgr_.GetPropertyEnum(property_name); if (prop_enum == DRMProperty::INVALID) { DRM_LOGD("DRMProperty %s missing from global property mapping", info->name); drmModeFreeProperty(info); continue; } prop_mgr_.SetPropertyId(prop_enum, info->prop_id); drmModeFreeProperty(info); } drmModeFreeObjectProperties(props); return 0; } int DRMDppsManagerImp::InitConnProps() { if (drm_fd_ < 0 || conn_id_ < 0) { DRM_LOGE("Invalid drm_fd_ %d or conn_id_ %d", drm_fd_, conn_id_); return -EINVAL; } drmModeObjectProperties *props = drmModeObjectGetProperties(drm_fd_, conn_id_, DRM_MODE_OBJECT_CONNECTOR); if (!props || !props->props || !props->prop_values) { drmModeFreeObjectProperties(props); return -EINVAL; } for (uint32_t j = 0; j < props->count_props; j++) { drmModePropertyRes *info = drmModeGetProperty(drm_fd_, props->props[j]); if (!info) { continue; } std::string property_name(info->name); DRMProperty prop_enum = prop_mgr_.GetPropertyEnum(property_name); if (prop_enum == DRMProperty::INVALID) { DRM_LOGD("DRMProperty %s missing from global property mapping", info->name); drmModeFreeProperty(info); continue; } prop_mgr_.SetPropertyId(prop_enum, info->prop_id); drmModeFreeProperty(info); } drmModeFreeObjectProperties(props); return 0; } void DRMDppsManagerImp::Init(int fd, drmModeRes* res) { std::lock_guard guard(api_lock_); int ret = 0; if (fd < 0 || !res) { DRM_LOGE("Invalid drm fd %d or res %p", fd, res); return; } drm_fd_ = fd; ret = GetDrmResources(res); if (ret) { DRM_LOGE("Failed to get DRM resources %d", ret); return; } else { ret = InitCrtcProps(); if (ret) { DRM_LOGE("Failed to initialize crtc properties %d", ret); return; } ret = InitConnProps(); if (ret) { DRM_LOGE("Failed to initialize conn properties %d", ret); return; } } memset(&dpps_feature_, 0, sizeof(dpps_feature_)); dpps_feature_[kFeatureAd4Mode] = DRMDppsPropInfo { (prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_MODE) == 0 ? 0U : 4U) /* version */, DRMProperty::SDE_DSPP_AD4_MODE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_MODE), false /* is_event */}; dpps_feature_[kFeatureAd4Init] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_INIT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_INIT), false /* is_event */}; dpps_feature_[kFeatureAd4Cfg] = DRMDppsPropInfo { 4 /* version */, DRMProperty::SDE_DSPP_AD4_CFG, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_CFG), false /* is_event */}; dpps_feature_[kFeatureAd4Input] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_INPUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_INPUT), false /* is_event */}; dpps_feature_[kFeatureAd4Backlight] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_BACKLIGHT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_BACKLIGHT), false /* is_event */}; dpps_feature_[kFeatureAd4Assertiveness] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_ASSERTIVENESS, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_ASSERTIVENESS), false /* is_event */}; dpps_feature_[kFeatureAd4Roi] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_ROI, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_ROI), false /* is_event */}; dpps_feature_[kFeatureAd4ManualStrength] = DRMDppsPropInfo {4 /* version */, DRMProperty::SDE_DSPP_AD4_STRENGTH, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_STRENGTH), false /* is_event */}; dpps_feature_[kFeatureAbaHistCtrl] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_DSPP_ABA_HIST_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_HIST_CTRL), false /* is_event */}; dpps_feature_[kFeatureAbaHistIRQ] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_DSPP_ABA_HIST_IRQ, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_HIST_IRQ), false /* is_event */}; dpps_feature_[kFeatureAbaLut] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_DSPP_ABA_LUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_LUT), false /* is_event */}; dpps_feature_[kFeatureSvBlScale] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_DSPP_SV_BL_SCALE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_SV_BL_SCALE), false /* is_event */}; dpps_feature_[kFeatureBacklightScale] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_DSPP_BL_SCALE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_BL_SCALE), false /* is_event */}; if (prop_mgr_.IsPropertyAvailable(DRMProperty::SDE_LTM_VERSION)) { dpps_feature_[kFeatureLtm] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_VERSION, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_VERSION), false /* is_event */}; dpps_feature_[kFeatureLtmInit] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_INIT, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_INIT), false /* is_event */}; dpps_feature_[kFeatureLtmCfg] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_CFG, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_CFG), false /* is_event */}; dpps_feature_[kFeatureLtmNoiseThresh] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_NOISE_THRESH, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_NOISE_THRESH), false /* is_event */}; dpps_feature_[kFeatureLtmBufferCtrl] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_BUFFER_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_BUFFER_CTRL), false /* is_event */}; dpps_feature_[kFeatureLtmQueueBuffer] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_QUEUE_BUFFER, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER), false /* is_event */}; dpps_feature_[kFeatureLtmQueueBuffer2] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_QUEUE_BUFFER2, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER2), false /* is_event */}; dpps_feature_[kFeatureLtmQueueBuffer3] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_QUEUE_BUFFER3, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER3), false /* is_event */}; dpps_feature_[kFeatureLtmHistCtrl] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_HIST_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_HIST_CTRL), false /* is_event */}; dpps_feature_[kFeatureLtmVlut] = DRMDppsPropInfo {1 /* version */, DRMProperty::SDE_LTM_VLUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_VLUT), false /* is_event */}; } else { DRM_LOGI("LTM properties are not available"); } dpps_feature_[kFeaturePowerEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureAbaHistEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureBackLightEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureAdAttBlEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureLtmHistEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureLtmWbPbEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; dpps_feature_[kFeatureLtmOffEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */}; } void DRMDppsManagerImp::CacheDppsFeature(uint32_t obj_id, va_list args) { std::lock_guard guard(api_lock_); uint32_t feature_id = va_arg(args, uint32_t); uint64_t value = va_arg(args, uint64_t); struct DRMDppsPropInfo* info; if (feature_id >= kDppsFeaturesMax) { DRM_LOGE("Invalid feature id %d for obj_id 0x%x", feature_id, obj_id); return; } info = &dpps_feature_[feature_id]; info->obj_id = obj_id; info->value = value; if (info->is_event) { dpps_dirty_event_.push_back(*info); } else { for (auto &it : dpps_dirty_prop_) { if ((it.obj_id == info->obj_id) && (it.prop_id == info->prop_id)) { it.value = info->value; return; } } dpps_dirty_prop_.push_back(*info); } } void DRMDppsManagerImp::CommitDppsFeatures(drmModeAtomicReq *req, const DRMDisplayToken &tok) { std::lock_guard guard(api_lock_); int ret = 0; if (!req) return; // Set Dpps properties if (!dpps_dirty_prop_.empty()) { for (auto it = dpps_dirty_prop_.begin(); it != dpps_dirty_prop_.end();) { if (it->obj_id == tok.crtc_id || it->obj_id == tok.conn_id) { ret = drmModeAtomicAddProperty(req, it->obj_id, it->prop_id, it->value); if (ret < 0) DRM_LOGE("AtomicAddProperty failed obj_id 0x%x, prop_id %d ret %d ", it->obj_id, it->prop_id, ret); else it = dpps_dirty_prop_.erase(it); } else { it++; } } } // Set Dpps events if (!dpps_dirty_event_.empty()) { for (auto it = dpps_dirty_event_.begin(); it != dpps_dirty_event_.end();) { if (!it->value) continue; struct DRMDppsEventInfo info = *(struct DRMDppsEventInfo*)it->value; struct drm_msm_event_req event_req = {}; int ret; if (it->obj_id == tok.crtc_id || it->obj_id == tok.conn_id) { event_req.object_id = it->obj_id; event_req.object_type = info.object_type; event_req.event = info.event_type; if (info.enable) ret = drmIoctl(info.drm_fd, DRM_IOCTL_MSM_REGISTER_EVENT, &event_req); else ret = drmIoctl(info.drm_fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &event_req); if (ret) { ret = -errno; if (ret == -EALREADY) { DRM_LOGI("Duplicated request to set event 0x%x, object_id %u, object_type 0x%x, enable %d", event_req.event, event_req.object_id, info.object_type, info.enable); } else { DRM_LOGE("Failed to set event 0x%x, object_id %u, object_type 0x%x, enable %d, ret %d", event_req.event, event_req.object_id, info.object_type, info.enable, ret); } } if (ret != -ENODEV) it = dpps_dirty_event_.erase(it); else it++; } else { it++; } } } } void DRMDppsManagerImp::GetDppsFeatureInfo(DRMDppsFeatureInfo *info) { std::lock_guard guard(api_lock_); int ret = 0; struct DRMDppsPropInfo* prop_info; if (!info) { DRM_LOGE("Invalid info NULL"); return; } DRMDPPSFeatureID id = info->id; if (id >= kDppsFeaturesMax) { DRM_LOGE("Invalid feature id %d", id); return; } info->version = dpps_feature_[id].version; if ((id == kFeatureLtmBufferCtrl) && (dpps_feature_[kFeatureLtm].prop_id != 0)) { /* setup ION buffers for LTM */ ret = InitLtmBuffers(info); if (ret) { DRM_LOGE("Failed to init LTM buffers %d", ret); return; } else { prop_info = &dpps_feature_[kFeatureLtmBufferCtrl]; prop_info->obj_id = info->obj_id; for (const auto& it : ltm_buffers_ctrl_map_) { if (it.first == info->obj_id) prop_info->value = (uint64_t)&(it.second); } dpps_dirty_prop_.push_back(*prop_info); } } } int DRMDppsManagerImp::InitLtmBuffers(struct DRMDppsFeatureInfo *info) { int ret = 0; uint32_t buffer_size, i = 0, bpp = 0; void* uva; struct DRMDppsLtmBuffers *buffers; DRMDppsLtmBuffers ltm_buffers = {}; drm_msm_ltm_buffers_ctrl ltm_buffers_ctrl = {}; struct drm_prime_handle prime_req; struct drm_mode_fb_cmd2 fb_obj; struct drm_gem_close gem_close; if (drm_fd_ < 0) { DRM_LOGE("Invalid drm_fd_ %d", drm_fd_); return -EINVAL; } for (const auto& it : ltm_buffers_map_) { if (it.first == info->obj_id) { DRM_LOGE("LTM buffer already initialized, obj id %d", info->obj_id); return -EALREADY; } } if (!info->payload || info->payload_size != sizeof(struct DRMDppsLtmBuffers)) { DRM_LOGE("Invalid payload %p size %d expected %zu", info->payload, info->payload_size, sizeof(struct DRMDppsLtmBuffers)); return -EINVAL; } buffers = (struct DRMDppsLtmBuffers *)info->payload; if (buffers->num_of_buffers <= 0 || buffers->num_of_buffers > LTM_BUFFER_SIZE) { DRM_LOGE("Invalid number of buffers %d", buffers->num_of_buffers); return -EINVAL; } std::memset(<m_buffers, 0, sizeof(ltm_buffers)); std::memset(<m_buffers_ctrl, 0, sizeof(ltm_buffers_ctrl)); ltm_buffers.num_of_buffers = buffers->num_of_buffers; buffer_size = sizeof(struct drm_msm_ltm_stats_data) + LTM_GUARD_BYTES; std::memset(&fb_obj, 0, sizeof(drm_mode_fb_cmd2)); fb_obj.pixel_format = DRM_FORMAT_YVYU; /* YVYU gives us a bpp of 16 (2 bytes) so we must take that into account */ fb_obj.height = 2; /* add extra one to compensate integer rounding */ fb_obj.width = buffer_size / (2 * fb_obj.height) + 1; /* bpp for YVYU is 16 */ bpp = 16; fb_obj.flags = DRM_MODE_FB_MODIFIERS; fb_obj.pitches[0] = fb_obj.width * bpp / 8; for (i = 0; i < buffers->num_of_buffers && !ret; i++) { std::memset(&prime_req, 0, sizeof(drm_prime_handle)); prime_req.fd = buffers->ion_buffer_fd[i]; ret = drmIoctl(drm_fd_, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_req); if (ret) { ret = -errno; DRM_LOGE("failed get prime handle: %d", ret); break; } ltm_buffers.ion_buffer_fd[i] = buffers->ion_buffer_fd[i]; fb_obj.handles[0] = prime_req.handle; ret = drmIoctl(drm_fd_, DRM_IOCTL_MODE_ADDFB2, &fb_obj); if (ret) { ret = -errno; DRM_LOGE("return value from addFB2: %d", ret); break; } ltm_buffers.drm_fb_id[i] = buffers->drm_fb_id[i] = fb_obj.fb_id; ltm_buffers_ctrl.fds[i] = ltm_buffers.drm_fb_id[i]; /** * ADDFB2 will take reference to GEM handles, * so drop reference taken by PrimeFDtoHandle now */ std::memset(&gem_close, 0, sizeof(gem_close)); gem_close.handle = prime_req.handle; ret = drmIoctl(drm_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close); if(ret) { ret = -errno; DRM_LOGE("return value from GEM_CLOSE: %d\n", ret); break; } uva = drm_mmap(0, buffers->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, buffers->ion_buffer_fd[i], 0); if (uva == MAP_FAILED) { ret = -errno; DRM_LOGE("failed to get uva: %d", ret); break; } ltm_buffers.uva[i] = buffers->uva[i] = uva; } if (!ret) { buffers->status = 0; ltm_buffers.buffer_size = buffers->buffer_size; ltm_buffers_ctrl.num_of_buffers = ltm_buffers.num_of_buffers; DRM_LOGV("InitLtmBuffers return successful"); } else { DeInitLtmBuffers(); buffers->status = ret; return ret; } ltm_buffers_map_.push_back(std::make_pair(info->obj_id, std::move(ltm_buffers))); ltm_buffers_ctrl_map_.push_back(std::make_pair(info->obj_id, std::move(ltm_buffers_ctrl))); return ret; } int DRMDppsManagerImp::DeInitLtmBuffers() { int ret = 0; uint32_t i = 0; if (drm_fd_ < 0) { return -EINVAL; } for (auto& it : ltm_buffers_map_) { DRMDppsLtmBuffers& ltm_buffers = it.second; for (i = 0; i < ltm_buffers.num_of_buffers; i++) { if (ltm_buffers.uva[i]) { drm_munmap(ltm_buffers.uva[i], ltm_buffers.buffer_size); ltm_buffers.uva[i] = NULL; } if (ltm_buffers.drm_fb_id[i] >= 0) { #ifdef DRM_IOCTL_MSM_RMFB2 ret = drmIoctl(drm_fd_, DRM_IOCTL_MSM_RMFB2, <m_buffers.drm_fb_id[i]); if (ret) { ret = errno; DRM_LOGE("RMFB2 failed for fb_id %d with error %d", ltm_buffers.drm_fb_id[i], ret); } #endif ltm_buffers.drm_fb_id[i] = -1; } ltm_buffers.ion_buffer_fd[i] = -1; } ltm_buffers.num_of_buffers = 0; ltm_buffers.buffer_size = 0; } for (auto& it : ltm_buffers_ctrl_map_) { drm_msm_ltm_buffers_ctrl& ltm_buffers_ctrl = it.second; std::memset(<m_buffers_ctrl, 0, sizeof(ltm_buffers_ctrl)); } ltm_buffers_map_.clear(); ltm_buffers_ctrl_map_.clear(); return 0; } } // namespace sde_drm