blob: f49d534798a0f9e1bf3320e99fd61e1d197e57cb [file] [log] [blame]
/*
* Copyright (C) 2012 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.
*/
//#define LOG_NDEBUG 0
#include "ExynosHWCDebug.h"
#include "ExynosPrimaryDisplay.h"
#include "ExynosDevice.h"
#include "ExynosHWCHelper.h"
#include "ExynosExternalDisplay.h"
#include "ExynosDisplayFbInterfaceModule.h"
#include "ExynosDisplayDrmInterface.h"
extern struct exynos_hwc_control exynosHWCControl;
ExynosPrimaryDisplay::ExynosPrimaryDisplay(uint32_t __unused type, ExynosDevice *device)
: ExynosDisplay(HWC_DISPLAY_PRIMARY, device)
{
// TODO : Hard coded here
mNumMaxPriorityAllowed = 5;
/* Initialization */
mDisplayId = HWC_DISPLAY_PRIMARY;
mDisplayName = android::String8("PrimaryDisplay");
// Prepare multi resolution
// Will be exynosHWCControl.multiResoultion
mResolutionInfo.nNum = 1;
mResolutionInfo.nResolution[0].w = 1440;
mResolutionInfo.nResolution[0].h = 2960;
mResolutionInfo.nDSCYSliceSize[0] = 40;
mResolutionInfo.nDSCXSliceSize[0] = 1440 / 2;
mResolutionInfo.nPanelType[0] = PANEL_DSC;
mResolutionInfo.nResolution[1].w = 1080;
mResolutionInfo.nResolution[1].h = 2220;
mResolutionInfo.nDSCYSliceSize[1] = 30;
mResolutionInfo.nDSCXSliceSize[1] = 1080 / 2;
mResolutionInfo.nPanelType[1] = PANEL_DSC;
mResolutionInfo.nResolution[2].w = 720;
mResolutionInfo.nResolution[2].h = 1480;
mResolutionInfo.nDSCYSliceSize[2] = 74;
mResolutionInfo.nDSCXSliceSize[2] = 720;
mResolutionInfo.nPanelType[2] = PANEL_LEGACY;
}
ExynosPrimaryDisplay::~ExynosPrimaryDisplay()
{
}
void ExynosPrimaryDisplay::setDDIScalerEnable(int width, int height) {
if (exynosHWCControl.setDDIScaler == false) return;
ALOGI("DDISCALER Info : setDDIScalerEnable(w=%d,h=%d)", width, height);
mNewScaledWidth = width;
mNewScaledHeight = height;
mXres = width;
mYres = height;
}
int ExynosPrimaryDisplay::getDDIScalerMode(int width, int height) {
if (exynosHWCControl.setDDIScaler == false) return 1;
// Check if panel support support resolution or not.
for (uint32_t i=0; i < mResolutionInfo.nNum; i++) {
if (mResolutionInfo.nResolution[i].w * mResolutionInfo.nResolution[i].h ==
static_cast<uint32_t>(width * height))
return i + 1;
}
return 1; // WQHD
}
int32_t ExynosPrimaryDisplay::setPowerMode(
int32_t /*hwc2_power_mode_t*/ mode) {
Mutex::Autolock lock(mDisplayMutex);
#ifndef USES_DOZEMODE
if ((mode == HWC2_POWER_MODE_DOZE) || (mode == HWC2_POWER_MODE_DOZE_SUSPEND))
return HWC2_ERROR_UNSUPPORTED;
#endif
/* TODO state check routine should be added */
int fb_blank = -1;
if (mode == HWC_POWER_MODE_DOZE ||
mode == HWC_POWER_MODE_DOZE_SUSPEND) {
if (mPowerModeState != HWC_POWER_MODE_DOZE &&
mPowerModeState != HWC_POWER_MODE_OFF &&
mPowerModeState != HWC_POWER_MODE_DOZE_SUSPEND) {
fb_blank = FB_BLANK_POWERDOWN;
clearDisplay();
} else {
ALOGE("DOZE or Power off called twice, mPowerModeState : %d", mPowerModeState);
}
} else if (mode == HWC_POWER_MODE_OFF) {
fb_blank = FB_BLANK_POWERDOWN;
clearDisplay();
ALOGV("HWC2: Clear display (power off)");
} else {
fb_blank = FB_BLANK_UNBLANK;
}
ALOGD("%s:: FBIOBLANK mode(%d), blank(%d)", __func__, mode, fb_blank);
if (fb_blank == FB_BLANK_POWERDOWN)
mDREnable = false;
else if (fb_blank == FB_BLANK_UNBLANK)
mDREnable = mDRDefault;
// check the dynamic recomposition thread by following display
mDevice->checkDynamicRecompositionThread();
mDisplayInterface->setPowerMode(mode);
mPowerModeState = (hwc2_power_mode_t)mode;
ALOGD("%s:: S3CFB_POWER_MODE mode(%d), blank(%d)", __func__, mode, fb_blank);
if (mode == HWC_POWER_MODE_OFF) {
/* It should be called from validate() when the screen is on */
mSkipFrame = true;
setGeometryChanged(GEOMETRY_DISPLAY_POWER_OFF);
if ((mRenderingState >= RENDERING_STATE_VALIDATED) &&
(mRenderingState < RENDERING_STATE_PRESENTED))
closeFencesForSkipFrame(RENDERING_STATE_VALIDATED);
mRenderingState = RENDERING_STATE_NONE;
} else {
setGeometryChanged(GEOMETRY_DISPLAY_POWER_ON);
}
return HWC2_ERROR_NONE;
}
bool ExynosPrimaryDisplay::getHDRException(ExynosLayer* __unused layer)
{
return false;
}
void ExynosPrimaryDisplay::initDisplayInterface(uint32_t interfaceType)
{
if (interfaceType == INTERFACE_TYPE_DRM)
mDisplayInterface = std::make_unique<ExynosDisplayDrmInterface>((ExynosDisplay *)this);
else
mDisplayInterface = std::make_unique<ExynosPrimaryDisplayFbInterfaceModule>((ExynosDisplay *)this);
mDisplayInterface->init(this);
}