blob: 0339526863d471f7bb7e85dcb2ef3e65b2225e41 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EXYNOS_DISPLAY_MODULE_H
#define EXYNOS_DISPLAY_MODULE_H
#include <gs101/displaycolor/displaycolor_gs101.h>
#include "ExynosDeviceModule.h"
#include "ExynosDisplay.h"
#include "ExynosLayer.h"
#include "ExynosPrimaryDisplay.h"
constexpr char kAtcJsonRaw[] =
"{\"version\":\"0.0\",\"modes\":[{\"name\":\"normal\",\"lux_map\":[0,5000,10000,"
"50000,70000],\"ambient_light_map\":[0,0,12,32,63],\"strength_map\":[0,0,128,128,200],"
"\"st_up_step\":2, \"st_down_step\":2,"
"\"sub_setting\":{\"local_tone_gain\":128,\"noise_suppression_gain\":128,\"dither\":0,"
"\"plain_weight_1\":10,\"plain_weight_2\":14,\"color_transform_mode\":2,\"preprocessing_"
"enable\":1,\"upgrade_on\":0,\"TDR_max\":900,\"TDR_min\":256,\"backlight\":255,\"dimming_"
"step\":4,\"scale_mode\":1,\"threshold_1\":1,\"threshold_2\":1,\"threshold_3\":1,\"gain_"
"limit\":511,\"lt_calc_ab_shift\":1}}]}";
constexpr char kAtcProfilePath[] = "vendor/etc/atc_profile.json";
constexpr char kAtcProfileVersionStr[] = "version";
constexpr char kAtcProfileModesStr[] = "modes";
constexpr char kAtcProfileModeNameStr[] = "name";
constexpr char kAtcProfileLuxMapStr[] = "lux_map";
constexpr char kAtcProfileAlMapStr[] = "ambient_light_map";
constexpr char kAtcProfileStMapStr[] = "strength_map";
constexpr char kAtcProfileSubSettingStr[] = "sub_setting";
constexpr char kAtcProfileStUpStepStr[] = "st_up_step";
constexpr char kAtcProfileStDownStepStr[] = "st_down_step";
constexpr uint32_t kAtcStStep = 2;
constexpr char kAtcModeNormalStr[] = "normal";
constexpr char kAtcModeHbmStr[] = "hbm";
constexpr char kAtcModePowerSaveStr[] = "power_save";
#define ATC_AMBIENT_LIGHT_FILE_NAME "/sys/class/dqe/atc/ambient_light"
#define ATC_ST_FILE_NAME "/sys/class/dqe/atc/st"
#define ATC_ENABLE_FILE_NAME "/sys/class/dqe/atc/en"
#define ATC_LT_FILE_NAME "/sys/class/dqe/atc/lt"
#define ATC_NS_FILE_NAME "/sys/class/dqe/atc/ns"
#define ATC_DITHER_FILE_NAME "/sys/class/dqe/atc/dither"
#define ATC_PL_W1_FILE_NAME "/sys/class/dqe/atc/pl_w1"
#define ATC_PL_W2_FILE_NAME "/sys/class/dqe/atc/pl_w2"
#define ATC_CTMODE_FILE_NAME "/sys/class/dqe/atc/ctmode"
#define ATC_PP_EN_FILE_NAME "/sys/class/dqe/atc/pp_en"
#define ATC_UPGRADE_ON_FILE_NAME "/sys/class/dqe/atc/upgrade_on"
#define ATC_TDR_MAX_FILE_NAME "/sys/class/dqe/atc/tdr_max"
#define ATC_TDR_MIN_FILE_NAME "/sys/class/dqe/atc/tdr_min"
#define ATC_BACKLIGHT_FILE_NAME "/sys/class/dqe/atc/back_light"
#define ATC_DSTEP_FILE_NAME "/sys/class/dqe/atc/dstep"
#define ATC_SCALE_MODE_FILE_NAME "/sys/class/dqe/atc/scale_mode"
#define ATC_THRESHOLD_1_FILE_NAME "/sys/class/dqe/atc/threshold_1"
#define ATC_THRESHOLD_2_FILE_NAME "/sys/class/dqe/atc/threshold_2"
#define ATC_THRESHOLD_3_FILE_NAME "/sys/class/dqe/atc/threshold_3"
#define ATC_GAIN_LIMIT_FILE_NAME "/sys/class/dqe/atc/gain_limit"
#define ATC_LT_CALC_AB_SHIFT_FILE_NAME "/sys/class/dqe/atc/lt_calc_ab_shift"
const std::unordered_map<std::string, std::string> kAtcSubSetting =
{{"local_tone_gain", ATC_LT_FILE_NAME},
{"noise_suppression_gain", ATC_NS_FILE_NAME},
{"dither", ATC_DITHER_FILE_NAME},
{"plain_weight_1", ATC_PL_W1_FILE_NAME},
{"plain_weight_2", ATC_PL_W2_FILE_NAME},
{"color_transform_mode", ATC_CTMODE_FILE_NAME},
{"preprocessing_enable", ATC_PP_EN_FILE_NAME},
{"upgrade_on", ATC_UPGRADE_ON_FILE_NAME},
{"TDR_max", ATC_TDR_MAX_FILE_NAME},
{"TDR_min", ATC_TDR_MIN_FILE_NAME},
{"backlight", ATC_BACKLIGHT_FILE_NAME},
{"dimming_step", ATC_DSTEP_FILE_NAME},
{"scale_mode", ATC_SCALE_MODE_FILE_NAME},
{"threshold_1", ATC_THRESHOLD_1_FILE_NAME},
{"threshold_2", ATC_THRESHOLD_2_FILE_NAME},
{"threshold_3", ATC_THRESHOLD_3_FILE_NAME},
{"gain_limit", ATC_GAIN_LIMIT_FILE_NAME},
{"lt_calc_ab_shift", ATC_LT_CALC_AB_SHIFT_FILE_NAME}};
namespace gs101 {
using namespace displaycolor;
class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay {
public:
ExynosPrimaryDisplayModule(uint32_t index, ExynosDevice *device);
~ExynosPrimaryDisplayModule();
void usePreDefinedWindow(bool use);
virtual int32_t validateWinConfigData();
void doPreProcessing();
virtual int32_t getColorModes(
uint32_t* outNumModes,
int32_t* outModes);
virtual int32_t setColorMode(int32_t mode);
virtual int32_t getRenderIntents(int32_t mode, uint32_t* outNumIntents,
int32_t* outIntents);
virtual int32_t setColorModeWithRenderIntent(int32_t mode,
int32_t intent);
virtual int32_t setColorTransform(const float* matrix, int32_t hint);
virtual int deliverWinConfigData();
virtual int32_t updateColorConversionInfo();
virtual int32_t updatePresentColorConversionInfo();
virtual bool checkRrCompensationEnabled() {
const DisplayType display = getDisplayTypeFromIndex(mIndex);
IDisplayColorGS101* displayColorInterface = getDisplayColorInterface();
return displayColorInterface->IsRrCompensationEnabled(display);
}
virtual bool isColorCalibratedByDevice();
virtual int32_t getColorAdjustedDbv(uint32_t &dbv_adj);
virtual void initLbe();
virtual void setLbeState(LbeState state);
virtual void setLbeAmbientLight(int value);
virtual LbeState getLbeState();
class DisplaySceneInfo {
public:
struct LayerMappingInfo {
bool operator==(const LayerMappingInfo &rhs) const {
return ((dppIdx == rhs.dppIdx) && (planeId == rhs.planeId));
}
// index in DisplayScene::layer_data
uint32_t dppIdx;
// assigned drm plane id in last color setting update
uint32_t planeId;
};
bool colorSettingChanged = false;
bool displaySettingDelivered = false;
DisplayScene displayScene;
/*
* Index of LayerColorData in DisplayScene::layer_data
* and assigned plane id in last color setting update.
* for each layer, including client composition
* key: ExynosMPPSource*
* data: LayerMappingInfo
*/
std::map<ExynosMPPSource*, LayerMappingInfo> layerDataMappingInfo;
std::map<ExynosMPPSource*, LayerMappingInfo> prev_layerDataMappingInfo;
void reset() {
colorSettingChanged = false;
prev_layerDataMappingInfo = layerDataMappingInfo;
layerDataMappingInfo.clear();
};
template <typename T, typename M>
void updateInfoSingleVal(T &dst, M &src) {
if (src != dst) {
colorSettingChanged = true;
dst = src;
}
};
template <typename T, typename M>
void updateInfoVectorVal(std::vector<T> &dst, M *src, uint32_t size) {
if ((dst.size() != size) ||
!std::equal(dst.begin(), dst.end(), src)) {
colorSettingChanged = true;
dst.resize(size);
for (uint32_t i = 0; i < size; i++) {
dst[i] = src[i];
}
}
};
void setColorMode(hwc::ColorMode mode) {
updateInfoSingleVal(displayScene.color_mode, mode);
};
void setRenderIntent(hwc::RenderIntent intent) {
updateInfoSingleVal(displayScene.render_intent, intent);
};
void setColorTransform(const float* matrix) {
for (uint32_t i = 0; i < displayScene.matrix.size(); i++) {
if (displayScene.matrix[i] != matrix[i]) {
colorSettingChanged = true;
displayScene.matrix[i] = matrix[i];
}
}
}
LayerColorData& getLayerColorDataInstance(uint32_t index);
int32_t setLayerDataMappingInfo(ExynosMPPSource* layer, uint32_t index);
void setLayerDataspace(LayerColorData& layerColorData,
hwc::Dataspace dataspace);
void disableLayerHdrStaticMetadata(LayerColorData& layerColorData);
void setLayerHdrStaticMetadata(LayerColorData& layerColorData,
const ExynosHdrStaticInfo& exynosHdrStaticInfo);
void setLayerColorTransform(LayerColorData& layerColorData,
std::array<float, TRANSFORM_MAT_SIZE> &matrix);
void disableLayerHdrDynamicMetadata(LayerColorData& layerColorData);
void setLayerHdrDynamicMetadata(LayerColorData& layerColorData,
const ExynosHdrDynamicInfo& exynosHdrDynamicInfo);
int32_t setLayerColorData(LayerColorData& layerData,
ExynosLayer* layer, float dimSdrRatio);
int32_t setClientCompositionColorData(
const ExynosCompositionInfo& clientCompositionInfo,
LayerColorData& layerData, float dimSdrRatio);
bool needDisplayColorSetting();
void printDisplayScene();
void printLayerColorData(const LayerColorData& layerData);
};
bool hasDisplayColor() {
IDisplayColorGS101* displayColorInterface = getDisplayColorInterface();
return displayColorInterface != nullptr;
}
/* Call getDppForLayer() only if hasDppForLayer() is true */
bool hasDppForLayer(ExynosMPPSource* layer);
const IDisplayColorGS101::IDpp& getDppForLayer(ExynosMPPSource* layer);
int32_t getDppIndexForLayer(ExynosMPPSource* layer);
/* Check if layer's assigned plane id has changed, save the new planeId.
* call only if hasDppForLayer is true */
bool checkAndSaveLayerPlaneId(ExynosMPPSource* layer, uint32_t planeId) {
auto &info = mDisplaySceneInfo.layerDataMappingInfo[layer];
bool change = info.planeId != planeId;
info.planeId = planeId;
return change;
}
size_t getNumOfDpp() {
const DisplayType display = getDisplayTypeFromIndex(mIndex);
IDisplayColorGS101* displayColorInterface = getDisplayColorInterface();
return displayColorInterface->GetPipelineData(display)->Dpp().size();
};
const IDisplayColorGS101::IDqe& getDqe()
{
const DisplayType display = getDisplayTypeFromIndex(mIndex);
IDisplayColorGS101* displayColorInterface = getDisplayColorInterface();
return displayColorInterface->GetPipelineData(display)->Dqe();
};
private:
int32_t setLayersColorData();
DisplaySceneInfo mDisplaySceneInfo;
struct atc_lux_map {
uint32_t lux;
uint32_t al;
uint32_t st;
};
struct atc_mode {
std::vector<atc_lux_map> lux_map;
std::unordered_map<std::string, int32_t> sub_setting;
uint32_t st_up_step;
uint32_t st_down_step;
};
bool parseAtcProfile();
int32_t setAtcMode(std::string mode_name);
uint32_t getAtcLuxMapIndex(std::vector<atc_lux_map>, uint32_t lux);
int32_t setAtcAmbientLight(uint32_t ambient_light);
int32_t setAtcStrength(uint32_t strenght);
int32_t setAtcStDimming(uint32_t target);
int32_t setAtcEnable(bool enable);
void checkAtcAnimation();
bool isInAtcAnimation() {
if (mAtcStStepCount > 0)
return true;
else
return false;
};
DisplayType getDisplayTypeFromIndex(uint32_t index) {
return (index >= DisplayType::DISPLAY_MAX) ? DisplayType::DISPLAY_PRIMARY
: DisplayType(mIndex);
};
IDisplayColorGS101* getDisplayColorInterface() {
ExynosDeviceModule* device = (ExynosDeviceModule*)mDevice;
return device->getDisplayColorInterface();
}
bool isForceColorUpdate() const { return mForceColorUpdate; }
void setForceColorUpdate(bool force) { mForceColorUpdate = force; }
bool isDisplaySwitched(int32_t mode, int32_t prevMode);
std::map<std::string, atc_mode> mAtcModeSetting;
bool mAtcInit;
LbeState mCurrentLbeState = LbeState::OFF;
std::string mCurrentAtcModeName;
uint32_t mCurrentLux = 0;
uint32_t mAtcLuxMapIndex = 0;
CtrlValue<uint32_t> mAtcAmbientLight;
CtrlValue<uint32_t> mAtcStrength;
CtrlValue<uint32_t> mAtcEnable;
std::unordered_map<std::string, CtrlValue<int32_t>> mAtcSubSetting;
uint32_t mAtcStStepCount = 0;
uint32_t mAtcStTarget = 0;
uint32_t mAtcStUpStep;
uint32_t mAtcStDownStep;
Mutex mAtcStMutex;
bool mPendingAtcOff;
bool mForceColorUpdate = false;
protected:
virtual int32_t setPowerMode(int32_t mode) override;
};
} // namespace gs101
#endif