blob: b92fffbd92f188f8df46ec2405edf2525e6b1a66 [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.
*/
#include "ExynosPrimaryDisplayModule.h"
#include <android-base/file.h>
#include <json/reader.h>
#include <json/value.h>
#include "ExynosDisplayDrmInterfaceModule.h"
#include "ExynosHWCDebug.h"
#ifdef FORCE_GPU_COMPOSITION
extern exynos_hwc_control exynosHWCControl;
#endif
mpp_phycal_type_t getMPPTypeFromDPPChannel(uint32_t channel) {
for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
if(IDMA_CHANNEL_MAP[i].channel == channel)
return IDMA_CHANNEL_MAP[i].type;
}
return MPP_P_TYPE_MAX;
}
// enable map layerDataMappingInfo comparison in needDisplayColorSetting()
inline bool operator==(const ExynosPrimaryDisplayModule::DisplaySceneInfo::LayerMappingInfo &lm1,
const ExynosPrimaryDisplayModule::DisplaySceneInfo::LayerMappingInfo &lm2) {
return lm1.dppIdx == lm2.dppIdx && lm1.planeId == lm2.planeId;
}
ExynosPrimaryDisplayModule::ExynosPrimaryDisplayModule(uint32_t __unused type, ExynosDevice *device)
: ExynosPrimaryDisplay(HWC_DISPLAY_PRIMARY, device), mDisplayColorLoader(DISPLAY_COLOR_LIB)
{
#ifdef FORCE_GPU_COMPOSITION
exynosHWCControl.forceGpu = true;
#endif
mDisplayColorInterface = mDisplayColorLoader.GetDisplayColorGS101(1);
mDisplaySceneInfo.displayScene.dpu_bit_depth = BitDepth::kTen;
}
ExynosPrimaryDisplayModule::~ExynosPrimaryDisplayModule () {
}
void ExynosPrimaryDisplayModule::usePreDefinedWindow(bool use)
{
#ifdef FIX_BASE_WINDOW_INDEX
/* Use fixed base window index */
mBaseWindowIndex = FIX_BASE_WINDOW_INDEX;
return;
#endif
if (use) {
mBaseWindowIndex = PRIMARY_DISP_BASE_WIN[mDevice->mDisplayMode];
mMaxWindowNum = mDisplayInterface->getMaxWindowNum() - PRIMARY_DISP_BASE_WIN[mDevice->mDisplayMode];
} else {
mBaseWindowIndex = 0;
mMaxWindowNum = mDisplayInterface->getMaxWindowNum();
}
}
int32_t ExynosPrimaryDisplayModule::validateWinConfigData()
{
bool flagValidConfig = true;
if (ExynosDisplay::validateWinConfigData() != NO_ERROR)
flagValidConfig = false;
for (size_t i = 0; i < mDpuData.configs.size(); i++) {
struct exynos_win_config_data &config = mDpuData.configs[i];
if (config.state == config.WIN_STATE_BUFFER) {
bool configInvalid = false;
uint32_t mppType = config.assignedMPP->mPhysicalType;
if ((config.src.w != config.dst.w) ||
(config.src.h != config.dst.h)) {
if ((mppType == MPP_DPP_GF) ||
(mppType == MPP_DPP_VG) ||
(mppType == MPP_DPP_VGF)) {
DISPLAY_LOGE("WIN_CONFIG error: invalid assign id : "
"%zu, s_w : %d, d_w : %d, s_h : %d, d_h : %d, mppType : %d",
i, config.src.w, config.dst.w, config.src.h, config.dst.h, mppType);
configInvalid = true;
}
}
if (configInvalid) {
config.state = config.WIN_STATE_DISABLED;
flagValidConfig = false;
}
}
}
if (flagValidConfig)
return NO_ERROR;
else
return -EINVAL;
}
void ExynosPrimaryDisplayModule::doPreProcessing() {
ExynosDisplay::doPreProcessing();
ExynosDisplay *externalDisplay = mDevice->getDisplay(HWC_DISPLAY_EXTERNAL);
ExynosDisplay *virtualDisplay = mDevice->getDisplay(HWC_DISPLAY_VIRTUAL);
if ((externalDisplay->mPlugState) || (virtualDisplay->mPlugState)) {
mDisplayControl.adjustDisplayFrame = true;
} else {
mDisplayControl.adjustDisplayFrame = false;
}
}
int32_t ExynosPrimaryDisplayModule::getColorModes(
uint32_t* outNumModes, int32_t* outModes)
{
const ColorModesMap colorModeMap =
mDisplayColorInterface->ColorModesAndRenderIntents(DisplayType::DISPLAY_PRIMARY);
ALOGD("%s: size(%zu)", __func__, colorModeMap.size());
if (outModes == nullptr) {
*outNumModes = colorModeMap.size();
return HWC2_ERROR_NONE;
}
if (*outNumModes != colorModeMap.size()) {
DISPLAY_LOGE("%s: Invalid color mode size(%d), It should be(%zu)",
__func__, *outNumModes, colorModeMap.size());
return HWC2_ERROR_BAD_PARAMETER;
}
uint32_t index = 0;
for (const auto &it : colorModeMap)
{
outModes[index] = static_cast<int32_t>(it.first);
ALOGD("\tmode[%d] %d", index, outModes[index]);
index++;
}
return HWC2_ERROR_NONE;
}
int32_t ExynosPrimaryDisplayModule::setColorMode(int32_t mode)
{
ALOGD("%s: mode(%d)", __func__, mode);
const ColorModesMap colorModeMap =
mDisplayColorInterface->ColorModesAndRenderIntents(DisplayType::DISPLAY_PRIMARY);
hwc::ColorMode colorMode =
static_cast<hwc::ColorMode>(mode);
const auto it = colorModeMap.find(colorMode);
if (it == colorModeMap.end()) {
DISPLAY_LOGE("%s: Invalid color mode(%d)", __func__, mode);
return HWC2_ERROR_BAD_PARAMETER;
}
mDisplaySceneInfo.setColorMode(colorMode);
if (mColorMode != mode)
setGeometryChanged(GEOMETRY_DISPLAY_COLOR_MODE_CHANGED);
mColorMode = (android_color_mode_t)mode;
return HWC2_ERROR_NONE;
}
int32_t ExynosPrimaryDisplayModule::getRenderIntents(int32_t mode,
uint32_t* outNumIntents, int32_t* outIntents)
{
const ColorModesMap colorModeMap =
mDisplayColorInterface->ColorModesAndRenderIntents(DisplayType::DISPLAY_PRIMARY);
ALOGD("%s, size(%zu)", __func__, colorModeMap.size());
hwc::ColorMode colorMode =
static_cast<hwc::ColorMode>(mode);
const auto it = colorModeMap.find(colorMode);
if (it == colorModeMap.end()) {
DISPLAY_LOGE("%s: Invalid color mode(%d)", __func__, mode);
return HWC2_ERROR_BAD_PARAMETER;
}
auto &renderIntents = it->second;
if (outIntents == NULL) {
*outNumIntents = renderIntents.size();
ALOGD("\tintent num(%zu)", renderIntents.size());
return HWC2_ERROR_NONE;
}
if (*outNumIntents != renderIntents.size()) {
DISPLAY_LOGE("%s: Invalid intent size(%d), It should be(%zu)",
__func__, *outNumIntents, renderIntents.size());
return HWC2_ERROR_BAD_PARAMETER;
}
for (uint32_t i = 0; i < renderIntents.size(); i++)
{
outIntents[i] = static_cast<uint32_t>(renderIntents[i]);
ALOGD("\tintent[%d] %d", i, outIntents[i]);
}
return HWC2_ERROR_NONE;
}
int32_t ExynosPrimaryDisplayModule::setColorModeWithRenderIntent(int32_t mode,
int32_t intent)
{
ALOGD("%s: mode(%d), intent(%d)", __func__, mode, intent);
const ColorModesMap colorModeMap =
mDisplayColorInterface->ColorModesAndRenderIntents(DisplayType::DISPLAY_PRIMARY);
hwc::ColorMode colorMode =
static_cast<hwc::ColorMode>(mode);
hwc::RenderIntent renderIntent =
static_cast<hwc::RenderIntent>(intent);
const auto mode_it = colorModeMap.find(colorMode);
if (mode_it == colorModeMap.end()) {
DISPLAY_LOGE("%s: Invalid color mode(%d)", __func__, mode);
return HWC2_ERROR_BAD_PARAMETER;
}
auto &renderIntents = mode_it->second;
auto intent_it = std::find(renderIntents.begin(),
renderIntents.end(), renderIntent);
if (intent_it == renderIntents.end()) {
DISPLAY_LOGE("%s: Invalid render intent(%d)", __func__, intent);
return HWC2_ERROR_BAD_PARAMETER;
}
mDisplaySceneInfo.setColorMode(colorMode);
mDisplaySceneInfo.setRenderIntent(renderIntent);
if (mColorMode != mode)
setGeometryChanged(GEOMETRY_DISPLAY_COLOR_MODE_CHANGED);
mColorMode = (android_color_mode_t)mode;
return HWC2_ERROR_NONE;
}
int32_t ExynosPrimaryDisplayModule::setColorTransform(
const float* matrix, int32_t hint)
{
if ((hint < HAL_COLOR_TRANSFORM_IDENTITY) ||
(hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA))
return HWC2_ERROR_BAD_PARAMETER;
ALOGI("%s:: %d, %d", __func__, mColorTransformHint, hint);
if (mColorTransformHint != hint)
setGeometryChanged(GEOMETRY_DISPLAY_COLOR_TRANSFORM_CHANGED);
mColorTransformHint = hint;
#ifdef HWC_SUPPORT_COLOR_TRANSFORM
mDisplaySceneInfo.setColorTransform(matrix);
#endif
return HWC2_ERROR_NONE;
}
int32_t ExynosPrimaryDisplayModule::setLayersColorData()
{
int32_t ret = 0;
uint32_t layerNum = 0;
for (uint32_t i = 0; i < mLayers.size(); i++)
{
ExynosLayer* layer = mLayers[i];
if (layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT)
continue;
LayerColorData& layerColorData =
mDisplaySceneInfo.getLayerColorDataInstance(layerNum);
/* set layer data mapping info */
if ((ret = mDisplaySceneInfo.setLayerDataMappingInfo(layer, layerNum))
!= NO_ERROR) {
DISPLAY_LOGE("%s: layer[%d] setLayerDataMappingInfo fail, layerNum(%d)",
__func__, i, layerNum);
return ret;
}
if ((ret = mDisplaySceneInfo.setLayerColorData(layerColorData, layer,
getBrightnessState().dim_sdr_ratio))
!= NO_ERROR) {
DISPLAY_LOGE("%s: layer[%d] setLayerColorData fail, layerNum(%d)",
__func__, i, layerNum);
return ret;
}
layerNum++;
}
if (mClientCompositionInfo.mHasCompositionLayer) {
LayerColorData& layerColorData =
mDisplaySceneInfo.getLayerColorDataInstance(layerNum);
/* set layer data mapping info */
if ((ret = mDisplaySceneInfo.setLayerDataMappingInfo(&mClientCompositionInfo,
layerNum)) != NO_ERROR) {
DISPLAY_LOGE("%s: setLayerDataMappingInfo fail for client composition", __func__);
return ret;
}
if ((ret = mDisplaySceneInfo.setClientCompositionColorData(
mClientCompositionInfo, layerColorData,
getBrightnessState().dim_sdr_ratio)) != NO_ERROR) {
DISPLAY_LOGE("%s: setClientCompositionColorData fail", __func__);
return ret;
}
layerNum++;
}
/* Resize layer_data when layers were destroyed */
if (layerNum < mDisplaySceneInfo.displayScene.layer_data.size())
mDisplaySceneInfo.displayScene.layer_data.resize(layerNum);
return NO_ERROR;
}
bool ExynosPrimaryDisplayModule::hasDppForLayer(ExynosMPPSource* layer)
{
if (mDisplaySceneInfo.layerDataMappingInfo.count(layer) == 0)
return false;
uint32_t index = mDisplaySceneInfo.layerDataMappingInfo[layer].dppIdx;
auto size = mDisplayColorInterface->GetPipelineData(DisplayType::DISPLAY_PRIMARY)->Dpp().size();
if (index >= size) {
DISPLAY_LOGE("%s: invalid dpp index(%d) dpp size(%zu)", __func__, index, size);
return false;
}
return true;
}
const IDisplayColorGS101::IDpp& ExynosPrimaryDisplayModule::getDppForLayer(ExynosMPPSource* layer)
{
uint32_t index = mDisplaySceneInfo.layerDataMappingInfo[layer].dppIdx;
return mDisplayColorInterface->GetPipelineData(DisplayType::DISPLAY_PRIMARY)->Dpp()[index].get();
}
int32_t ExynosPrimaryDisplayModule::getDppIndexForLayer(ExynosMPPSource* layer)
{
if (mDisplaySceneInfo.layerDataMappingInfo.count(layer) == 0)
return -1;
uint32_t index = mDisplaySceneInfo.layerDataMappingInfo[layer].dppIdx;
return static_cast<int32_t>(index);
}
int ExynosPrimaryDisplayModule::deliverWinConfigData()
{
int ret = 0;
ExynosDisplayDrmInterfaceModule *moduleDisplayInterface =
(ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get());
moduleDisplayInterface->setColorSettingChanged(
mDisplaySceneInfo.needDisplayColorSetting());
ret = ExynosDisplay::deliverWinConfigData();
return ret;
}
LayerColorData& ExynosPrimaryDisplayModule::DisplaySceneInfo::getLayerColorDataInstance(
uint32_t index)
{
size_t currentSize = displayScene.layer_data.size();
if (index >= currentSize) {
displayScene.layer_data.resize(currentSize+1);
colorSettingChanged = true;
}
return displayScene.layer_data[index];
}
int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerDataMappingInfo(
ExynosMPPSource* layer, uint32_t index)
{
if (layerDataMappingInfo.count(layer) != 0) {
ALOGE("layer mapping is already inserted (layer: %p, index:%d)",
layer, index);
return -EINVAL;
}
uint32_t oldPlaneId = prev_layerDataMappingInfo.count(layer) != 0 ?
prev_layerDataMappingInfo[layer].planeId : UINT_MAX;
layerDataMappingInfo.insert(std::make_pair(layer, LayerMappingInfo{ index, oldPlaneId }));
return NO_ERROR;
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerDataspace(
LayerColorData& layerColorData,
hwc::Dataspace dataspace)
{
if (layerColorData.dataspace != dataspace) {
colorSettingChanged = true;
layerColorData.dataspace = dataspace;
}
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::disableLayerHdrStaticMetadata(
LayerColorData& layerColorData)
{
if (layerColorData.static_metadata.is_valid) {
colorSettingChanged = true;
layerColorData.static_metadata.is_valid = false;
}
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerHdrStaticMetadata(
LayerColorData& layerColorData,
const ExynosHdrStaticInfo &exynosHdrStaticInfo)
{
if (layerColorData.static_metadata.is_valid == false) {
colorSettingChanged = true;
layerColorData.static_metadata.is_valid = true;
}
updateInfoSingleVal(layerColorData.static_metadata.display_red_primary_x,
exynosHdrStaticInfo.sType1.mR.x);
updateInfoSingleVal(layerColorData.static_metadata.display_red_primary_y,
exynosHdrStaticInfo.sType1.mR.y);
updateInfoSingleVal(layerColorData.static_metadata.display_green_primary_x,
exynosHdrStaticInfo.sType1.mG.x);
updateInfoSingleVal(layerColorData.static_metadata.display_green_primary_y,
exynosHdrStaticInfo.sType1.mG.y);
updateInfoSingleVal(layerColorData.static_metadata.display_blue_primary_x,
exynosHdrStaticInfo.sType1.mB.x);
updateInfoSingleVal(layerColorData.static_metadata.display_blue_primary_y,
exynosHdrStaticInfo.sType1.mB.y);
updateInfoSingleVal(layerColorData.static_metadata.white_point_x,
exynosHdrStaticInfo.sType1.mW.x);
updateInfoSingleVal(layerColorData.static_metadata.white_point_y,
exynosHdrStaticInfo.sType1.mW.y);
updateInfoSingleVal(layerColorData.static_metadata.max_luminance,
exynosHdrStaticInfo.sType1.mMaxDisplayLuminance);
updateInfoSingleVal(layerColorData.static_metadata.min_luminance,
exynosHdrStaticInfo.sType1.mMinDisplayLuminance);
updateInfoSingleVal(layerColorData.static_metadata.max_content_light_level,
exynosHdrStaticInfo.sType1.mMaxContentLightLevel);
updateInfoSingleVal(
layerColorData.static_metadata.max_frame_average_light_level,
exynosHdrStaticInfo.sType1.mMaxFrameAverageLightLevel);
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerColorTransform(
LayerColorData& layerColorData,
std::array<float, TRANSFORM_MAT_SIZE> &matrix)
{
updateInfoSingleVal(layerColorData.matrix, matrix);
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::disableLayerHdrDynamicMetadata(
LayerColorData& layerColorData)
{
if (layerColorData.dynamic_metadata.is_valid) {
colorSettingChanged = true;
layerColorData.dynamic_metadata.is_valid = false;
}
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerHdrDynamicMetadata(
LayerColorData& layerColorData,
const ExynosHdrDynamicInfo &exynosHdrDynamicInfo)
{
if (layerColorData.dynamic_metadata.is_valid == false) {
colorSettingChanged = true;
layerColorData.dynamic_metadata.is_valid = true;
}
updateInfoSingleVal(layerColorData.dynamic_metadata.display_maximum_luminance,
exynosHdrDynamicInfo.data.display_maximum_luminance);
if (!std::equal(layerColorData.dynamic_metadata.maxscl.begin(),
layerColorData.dynamic_metadata.maxscl.end(),
exynosHdrDynamicInfo.data.maxscl)) {
colorSettingChanged = true;
for (uint32_t i = 0 ; i < layerColorData.dynamic_metadata.maxscl.size(); i++) {
layerColorData.dynamic_metadata.maxscl[i] =
exynosHdrDynamicInfo.data.maxscl[i];
}
}
static constexpr uint32_t DYNAMIC_META_DAT_SIZE = 15;
updateInfoVectorVal(layerColorData.dynamic_metadata.maxrgb_percentages,
exynosHdrDynamicInfo.data.maxrgb_percentages,
DYNAMIC_META_DAT_SIZE);
updateInfoVectorVal(layerColorData.dynamic_metadata.maxrgb_percentiles,
exynosHdrDynamicInfo.data.maxrgb_percentiles,
DYNAMIC_META_DAT_SIZE);
updateInfoSingleVal(layerColorData.dynamic_metadata.tm_flag,
exynosHdrDynamicInfo.data.tone_mapping.tone_mapping_flag);
updateInfoSingleVal(layerColorData.dynamic_metadata.tm_knee_x,
exynosHdrDynamicInfo.data.tone_mapping.knee_point_x);
updateInfoSingleVal(layerColorData.dynamic_metadata.tm_knee_y,
exynosHdrDynamicInfo.data.tone_mapping.knee_point_y);
updateInfoVectorVal(layerColorData.dynamic_metadata.bezier_curve_anchors,
exynosHdrDynamicInfo.data.tone_mapping.bezier_curve_anchors,
DYNAMIC_META_DAT_SIZE);
}
int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setClientCompositionColorData(
const ExynosCompositionInfo &clientCompositionInfo, LayerColorData& layerData,
float dimSdrRatio)
{
setLayerDataspace(layerData,
static_cast<hwc::Dataspace>(clientCompositionInfo.mDataSpace));
disableLayerHdrStaticMetadata(layerData);
disableLayerHdrDynamicMetadata(layerData);
if (dimSdrRatio != 1.0) {
std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix = {
dimSdrRatio, 0.0, 0.0, 0.0,
0.0, dimSdrRatio, 0.0, 0.0,
0.0, 0.0, dimSdrRatio, 0.0,
0.0, 0.0, 0.0, 1.0
};
setLayerColorTransform(layerData, scaleMatrix);
}
return NO_ERROR;
}
int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerColorData(
LayerColorData& layerData, ExynosLayer* layer, float dimSdrRatio)
{
setLayerDataspace(layerData,
static_cast<hwc::Dataspace>(layer->mDataSpace));
if (layer->mIsHdrLayer) {
if (layer->getMetaParcel() == nullptr) {
HDEBUGLOGE("%s:: meta data parcel is null", __func__);
return -EINVAL;
}
if (layer->getMetaParcel()->eType & VIDEO_INFO_TYPE_HDR_STATIC)
setLayerHdrStaticMetadata(layerData, layer->getMetaParcel()->sHdrStaticInfo);
else
disableLayerHdrStaticMetadata(layerData);
if (layer->getMetaParcel()->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC)
setLayerHdrDynamicMetadata(layerData, layer->getMetaParcel()->sHdrDynamicInfo);
else
disableLayerHdrDynamicMetadata(layerData);
} else {
disableLayerHdrStaticMetadata(layerData);
disableLayerHdrDynamicMetadata(layerData);
}
static std::array<float, TRANSFORM_MAT_SIZE> defaultMatrix {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
if (dimSdrRatio == 1.0 || layer->mIsHdrLayer) {
if (layer->mLayerColorTransform.enable)
setLayerColorTransform(layerData,
layer->mLayerColorTransform.mat);
else
setLayerColorTransform(layerData,
defaultMatrix);
} else {
if (layer->mLayerColorTransform.enable) {
std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix =
layer->mLayerColorTransform.mat;
// scale coeffs
scaleMatrix[0] *= dimSdrRatio;
scaleMatrix[1] *= dimSdrRatio;
scaleMatrix[2] *= dimSdrRatio;
scaleMatrix[4] *= dimSdrRatio;
scaleMatrix[5] *= dimSdrRatio;
scaleMatrix[6] *= dimSdrRatio;
scaleMatrix[8] *= dimSdrRatio;
scaleMatrix[9] *= dimSdrRatio;
scaleMatrix[10] *= dimSdrRatio;
// scale offsets
scaleMatrix[12] *= dimSdrRatio;
scaleMatrix[13] *= dimSdrRatio;
scaleMatrix[14] *= dimSdrRatio;
setLayerColorTransform(layerData, scaleMatrix);
} else {
std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix = {
dimSdrRatio, 0.0, 0.0, 0.0,
0.0, dimSdrRatio, 0.0, 0.0,
0.0, 0.0, dimSdrRatio, 0.0,
0.0, 0.0, 0.0, 1.0
};
setLayerColorTransform(layerData, scaleMatrix);
}
}
return NO_ERROR;
}
int32_t ExynosPrimaryDisplayModule::updateColorConversionInfo()
{
int ret = 0;
/* clear flag and layer mapping info before setting */
mDisplaySceneInfo.reset();
if ((ret = setLayersColorData()) != NO_ERROR)
return ret;
mDisplaySceneInfo.displayScene.force_hdr = getBrightnessState().dim_sdr_ratio != 1.0;
if (hwcCheckDebugMessages(eDebugColorManagement))
mDisplaySceneInfo.printDisplayScene();
if ((ret = mDisplayColorInterface->Update(DisplayType::DISPLAY_PRIMARY,
mDisplaySceneInfo.displayScene)) != 0) {
DISPLAY_LOGE("Display Scene update error (%d)", ret);
return ret;
}
return ret;
}
bool ExynosPrimaryDisplayModule::DisplaySceneInfo::needDisplayColorSetting()
{
/* TODO: Check if we can skip color setting */
/* For now, propage setting every frame */
return true;
if (colorSettingChanged)
return true;
if (prev_layerDataMappingInfo != layerDataMappingInfo)
return true;
return false;
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::printDisplayScene()
{
ALOGD("======================= DisplayScene info ========================");
ALOGD("dpu_bit_depth: %d", static_cast<uint32_t>(displayScene.dpu_bit_depth));
ALOGD("color_mode: %d", static_cast<uint32_t>(displayScene.color_mode));
ALOGD("render_intent: %d", static_cast<uint32_t>(displayScene.render_intent));
ALOGD("matrix");
for (uint32_t i = 0; i < 16; (i += 4)) {
ALOGD("%f, %f, %f, %f",
displayScene.matrix[i], displayScene.matrix[i+1],
displayScene.matrix[i+2], displayScene.matrix[i+3]);
}
ALOGD("layer: %zu ++++++",
displayScene.layer_data.size());
for (uint32_t i = 0; i < displayScene.layer_data.size(); i++) {
ALOGD("layer[%d] info", i);
printLayerColorData(displayScene.layer_data[i]);
}
ALOGD("layerDataMappingInfo: %zu ++++++",
layerDataMappingInfo.size());
for (auto layer : layerDataMappingInfo) {
ALOGD("[layer: %p] [%d, %d]", layer.first, layer.second.dppIdx, layer.second.planeId);
}
}
void ExynosPrimaryDisplayModule::DisplaySceneInfo::printLayerColorData(
const LayerColorData& layerData)
{
ALOGD("dataspace: 0x%8x", static_cast<uint32_t>(layerData.dataspace));
ALOGD("matrix");
for (uint32_t i = 0; i < 16; (i += 4)) {
ALOGD("%f, %f, %f, %f",
layerData.matrix[i], layerData.matrix[i+1],
layerData.matrix[i+2], layerData.matrix[i+3]);
}
ALOGD("static_metadata.is_valid(%d)", layerData.static_metadata.is_valid);
if (layerData.static_metadata.is_valid) {
ALOGD("\tdisplay_red_primary(%d, %d)",
layerData.static_metadata.display_red_primary_x,
layerData.static_metadata.display_red_primary_y);
ALOGD("\tdisplay_green_primary(%d, %d)",
layerData.static_metadata.display_green_primary_x,
layerData.static_metadata.display_green_primary_y);
ALOGD("\tdisplay_blue_primary(%d, %d)",
layerData.static_metadata.display_blue_primary_x,
layerData.static_metadata.display_blue_primary_y);
ALOGD("\twhite_point(%d, %d)",
layerData.static_metadata.white_point_x,
layerData.static_metadata.white_point_y);
}
ALOGD("dynamic_metadata.is_valid(%d)", layerData.dynamic_metadata.is_valid);
if (layerData.dynamic_metadata.is_valid) {
ALOGD("\tdisplay_maximum_luminance: %d",
layerData.dynamic_metadata.display_maximum_luminance);
ALOGD("\tmaxscl(%d, %d, %d)", layerData.dynamic_metadata.maxscl[0],
layerData.dynamic_metadata.maxscl[1],
layerData.dynamic_metadata.maxscl[2]);
ALOGD("\ttm_flag(%d)", layerData.dynamic_metadata.tm_flag);
ALOGD("\ttm_knee_x(%d)", layerData.dynamic_metadata.tm_knee_x);
ALOGD("\ttm_knee_y(%d)", layerData.dynamic_metadata.tm_knee_y);
}
}
bool ExynosPrimaryDisplayModule::parseAtcProfile() {
Json::Value root;
Json::CharReaderBuilder reader_builder;
std::unique_ptr<Json::CharReader> reader(reader_builder.newCharReader());
std::string atc_profile;
if (!android::base::ReadFileToString(kAtcProfilePath, &atc_profile)) {
atc_profile = kAtcJsonRaw;
ALOGI("Use default atc profile file");
}
if (!reader->parse(atc_profile.c_str(), atc_profile.c_str() + atc_profile.size(), &root,
nullptr)) {
ALOGE("Failed to parse atc profile file");
return false;
}
ALOGI("Atc Profile version = %s", root[kAtcProfileVersionStr].asString().c_str());
Json::Value nodes = root[kAtcProfileModesStr];
atc_mode mode;
for (Json::Value::ArrayIndex i = 0; i < nodes.size(); ++i) {
std::string name = nodes[i][kAtcProfileModeNameStr].asString();
if (nodes[i][kAtcProfileLuxMapStr].size() != nodes[i][kAtcProfileAlMapStr].size() &&
nodes[i][kAtcProfileAlMapStr].size() != nodes[i][kAtcProfileStMapStr].size()) {
ALOGE("Atc profile is unavailable !");
return false;
}
uint32_t map_cnt = nodes[i][kAtcProfileLuxMapStr].size();
mode.lux_map.clear();
for (uint32_t index = 0; index < map_cnt; ++index) {
mode.lux_map.emplace_back(atc_lux_map{nodes[i][kAtcProfileLuxMapStr][index].asUInt(),
nodes[i][kAtcProfileAlMapStr][index].asUInt(),
nodes[i][kAtcProfileStMapStr][index].asUInt()});
}
if (nodes[i][kAtcProfileSubSettingStr].size() != kAtcSubSetting.size()) return false;
for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
mode.sub_setting[it->first.c_str()] =
nodes[i][kAtcProfileSubSettingStr][it->first.c_str()].asUInt();
}
auto ret = mAtcModeSetting.insert(std::make_pair(name.c_str(), mode));
if (ret.second == false) {
ALOGE("Atc mode %s is already existed!", ret.first->first.c_str());
return false;
}
}
if (mAtcModeSetting.find(kAtcModeNormalStr) == mAtcModeSetting.end()) {
ALOGW("Failed to find atc normal mode");
return false;
}
return true;
}
void ExynosPrimaryDisplayModule::initLbe() {
if (!parseAtcProfile()) {
ALOGD("Failed to parseAtcMode");
mAtcInit = false;
return;
}
mAtcInit = true;
}
int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(std::vector<atc_lux_map> map, uint32_t lux) {
uint32_t index = 0;
for (uint32_t i = 0; i < map.size(); i++) {
if (lux < map[i].lux) {
break;
}
index = i;
}
if (writeIntToFile(ATC_ST_FILE_NAME, map[index].st) != NO_ERROR) return -EPERM;
if (writeIntToFile(ATC_AMBIENT_LIGHT_FILE_NAME, map[index].al) != NO_ERROR) return -EPERM;
return NO_ERROR;
}
int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name) {
auto it = mAtcModeSetting.find(mode_name);
if (it == mAtcModeSetting.end()) {
ALOGW("Atc %s mode not found", mode_name.c_str());
return -EINVAL;
}
atc_mode mode = it->second;
for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
if (writeIntToFile(it->second.c_str(), mode.sub_setting[it->first.c_str()]) != NO_ERROR)
return -EPERM;
}
if (setAtcAmbientLight(mode.lux_map, mCurrentLux) != NO_ERROR) {
ALOGE("Fail to set atc ambient light for %s mode", mode_name.c_str());
return -EPERM;
}
writeIntToFile(ATC_ENABLE_FILE_NAME, 1);
mCurrentAtcModeName = mode_name;
ALOGI("mCurrentAtcModeName %s", mCurrentAtcModeName.c_str());
return NO_ERROR;
}
void ExynosPrimaryDisplayModule::setLbeState(LbeState state) {
if (!mAtcInit) return;
std::string modeStr;
switch (state) {
case LbeState::OFF:
writeIntToFile(ATC_ENABLE_FILE_NAME, 0);
mCurrentLux = 0;
mCurrentLbeState = LbeState::OFF;
ALOGI("Lbe state off");
return;
case LbeState::NORMAL:
modeStr = kAtcModeNormalStr;
break;
case LbeState::HIGH_BRIGHTNESS:
modeStr = kAtcModeHbmStr;
break;
case LbeState::POWER_SAVE:
modeStr = kAtcModePowerSaveStr;
break;
default:
ALOGE("Lbe state not support");
return;
}
if (setAtcMode(modeStr) == NO_ERROR) mCurrentLbeState = state;
}
void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) {
if (!mAtcInit) return;
auto it = mAtcModeSetting.find(mCurrentAtcModeName);
if (it == mAtcModeSetting.end()) {
ALOGE("Atc mode not found");
return;
}
atc_mode mode = it->second;
if (setAtcAmbientLight(mode.lux_map, value) != NO_ERROR) {
ALOGE("Failed to set atc ambient light");
return;
}
mCurrentLux = value;
}
LbeState ExynosPrimaryDisplayModule::getLbeState() {
return mCurrentLbeState;
}