blob: c8274897e996fda8f0fadfa4ee1f9c81c97c1492 [file] [log] [blame]
/*
* 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.
*/
#ifndef __DRM_PLANE_H__
#define __DRM_PLANE_H__
#include <display/drm/sde_drm.h>
#include <drm_interface.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <mutex>
#include "drm_property.h"
#include "drm_pp_manager.h"
namespace sde_drm {
class DRMPlaneManager;
enum DRMPlaneLutState {
kInactive, // Lut is not in use, default
kActive, // Lut is in use
kDirty, // Plane was unset while being LUT was active, mark LUT as dirty
// to make sure it's cleared the next time plane is used
};
class DRMPlane {
public:
explicit DRMPlane(int fd, uint32_t priority);
~DRMPlane();
void InitAndParse(drmModePlane *plane);
void GetId(uint32_t *id) { *id = drm_plane_->plane_id; }
void GetType(DRMPlaneType *type) { *type = plane_type_info_.type; }
void GetPriority(uint32_t *priority) { *priority = priority_; }
void GetAssignedCrtc(uint32_t *crtc_id) { *crtc_id = assigned_crtc_id_; }
void GetRequestedCrtc(uint32_t *crtc_id) { *crtc_id = requested_crtc_id_; }
void SetAssignedCrtc(uint32_t crtc_id) { assigned_crtc_id_ = crtc_id; }
void SetRequestedCrtc(uint32_t crtc_id) { requested_crtc_id_ = crtc_id; }
bool SetScalerConfig(drmModeAtomicReq *req, uint64_t handle);
bool SetCscConfig(drmModeAtomicReq *req, DRMCscType csc_type);
bool ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id);
const DRMPlaneTypeInfo& GetPlaneTypeInfo() { return plane_type_info_; }
void SetDecimation(drmModeAtomicReq *req, uint32_t prop_id, uint32_t prop_value);
void SetExclRect(drmModeAtomicReq *req, DRMRect rect);
void Perform(DRMOps code, drmModeAtomicReq *req, va_list args);
void Dump();
void SetMultiRectMode(drmModeAtomicReq *req, DRMMultiRectMode drm_multirect_mode);
void Unset(bool is_commit, drmModeAtomicReq *req);
void PostValidate(uint32_t crtc_id, bool success);
void PostCommit(uint32_t crtc_id, bool success);
bool SetDgmCscConfig(drmModeAtomicReq *req, uint64_t handle);
void UpdatePPLutFeatureInuse(DRMPPFeatureInfo *data);
void ResetColorLUTs(bool is_commit, drmModeAtomicReq *req);
void ResetColorLUTState(DRMTonemapLutType lut_type, bool is_commit, drmModeAtomicReq *req);
void ResetColorLUT(DRMPPFeatureID id, drmModeAtomicReq *req);
void ResetCache(drmModeAtomicReq *req);
private:
typedef std::map<DRMProperty, std::tuple<uint64_t, drmModePropertyRes *>> PropertyMap;
void ParseProperties();
void GetTypeInfo(const PropertyMap &props);
void PerformWrapper(DRMOps code, drmModeAtomicReq *req, ...);
int fd_ = -1;
uint32_t priority_ = 0;
drmModePlane *drm_plane_ = {};
DRMPlaneTypeInfo plane_type_info_{};
uint32_t assigned_crtc_id_ = 0;
uint32_t requested_crtc_id_ = 0;
DRMPropertyManager prop_mgr_ {};
bool has_excl_rect_ = false;
drm_clip_rect excl_rect_copy_ = {};
std::unique_ptr<DRMPPManager> pp_mgr_ {};
std::unordered_map<uint32_t, uint64_t> tmp_prop_val_map_ {};
std::unordered_map<uint32_t, uint64_t> committed_prop_val_map_ {};
// Only applicable to planes that have scaler
sde_drm_scaler_v2 scaler_v2_config_copy_ = {};
sde_drm_csc_v1 csc_config_copy_ = {};
bool is_lut_configured_ = false;
bool dgm_csc_in_use_ = false;
// Tone-mapping lut properties
DRMPlaneLutState dgm_1d_lut_igc_state_ = kInactive;
DRMPlaneLutState dgm_1d_lut_gc_state_ = kInactive;
DRMPlaneLutState vig_1d_lut_igc_state_ = kInactive;
DRMPlaneLutState vig_3d_lut_gamut_state_ = kInactive;
};
class DRMPlaneManager {
public:
explicit DRMPlaneManager(int fd);
void Init();
void DeInit() {}
void GetPlanesInfo(DRMPlanesInfo *info);
void DumpAll();
void DumpByID(uint32_t id);
void Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args);
void UnsetUnusedResources(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
void ResetColorLutsOnUsedPlanes(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
void RetainPlanes(uint32_t crtc_id);
void SetScalerLUT(const DRMScalerLUTInfo &lut_info);
void UnsetScalerLUT();
void PostValidate(uint32_t crtc_id, bool success);
void PostCommit(uint32_t crtc_id, bool success);
void ResetCache(drmModeAtomicReq *req, uint32_t crtc_id);
private:
void Perform(DRMOps code, drmModeAtomicReq *req, uint32_t obj_id, ...);
int fd_ = -1;
// Map of plane id to DRMPlane *
std::map<uint32_t, std::unique_ptr<DRMPlane>> plane_pool_{};
// Global Scaler LUT blobs
uint32_t dir_lut_blob_id_ = 0;
uint32_t cir_lut_blob_id_ = 0;
uint32_t sep_lut_blob_id_ = 0;
std::mutex lock_;
};
} // namespace sde_drm
#endif // __DRM_PLANE_H__