"LA.UM.8.6.r1-04000-89xx.0"

Change-Id: If142cc92b0250dc10fbb3dff72a9503aa9c70610
This commit is contained in:
ZeeLog 2020-03-31 22:44:53 +02:00
commit 293643a59f
28 changed files with 564 additions and 56 deletions

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2019, 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 __COMPOSER_EXTN_INTF_H__
#define __COMPOSER_EXTN_INTF_H__
#include <dlfcn.h>
#include "frame_scheduler_intf.h"
#define COMPOSER_EXTN_REV_MAJOR (1)
#define COMPOSER_EXTN_REV_MINOR (0)
#define COMPOSER_EXTN_VERSION_TAG ((uint16_t) ((COMPOSER_EXTN_REV_MAJOR << 8) \
| COMPOSER_EXTN_REV_MINOR))
namespace composer {
class ComposerExtnIntf {
public:
virtual int CreateFrameScheduler(FrameSchedulerIntf **intf) = 0;
virtual void DestroyFrameScheduler(FrameSchedulerIntf *intf) = 0;
protected:
virtual ~ComposerExtnIntf() { }
};
class ComposerExtnLib {
public:
static ComposerExtnIntf * GetInstance() {
return g_composer_ext_lib_.composer_ext_intf_;
}
private:
const char *lib_name = "libcomposerextn.qti.so";
typedef int (*CreateComposerExtn)(uint16_t version, ComposerExtnIntf **intf);
typedef void (*DestroyComposerExtn)(ComposerExtnIntf *intf);
ComposerExtnLib() {
lib_obj_ = ::dlopen(lib_name, RTLD_NOW);
if (!lib_obj_) {
return;
}
create_composer_ext_fn_ = reinterpret_cast<CreateComposerExtn>(
::dlsym(lib_obj_, "CreateComposerExtn"));
destroy_composer_ext_fn_ = reinterpret_cast<DestroyComposerExtn>(
::dlsym(lib_obj_, "DestroyComposerExtn"));
if (create_composer_ext_fn_ && destroy_composer_ext_fn_) {
create_composer_ext_fn_(COMPOSER_EXTN_VERSION_TAG, &composer_ext_intf_);
}
}
~ComposerExtnLib() {
if (composer_ext_intf_) {
destroy_composer_ext_fn_(composer_ext_intf_);
}
if (lib_obj_) {
::dlclose(lib_obj_);
}
}
static ComposerExtnLib g_composer_ext_lib_;
void *lib_obj_ = nullptr;
CreateComposerExtn create_composer_ext_fn_ = nullptr;
DestroyComposerExtn destroy_composer_ext_fn_ = nullptr;
ComposerExtnIntf *composer_ext_intf_ = nullptr;
};
} // namespace composer
#endif // __COMPOSER_EXTN_INTF_H__

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2019, 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 __FRAME_SCHEDULER_INTF_H__
#define __FRAME_SCHEDULER_INTF_H__
#include <utils/Timers.h>
namespace composer {
class FrameSchedulerIntf {
public:
virtual int UpdateFrameScheduling(int fenceFd, nsecs_t *timeStamp) = 0;
protected:
virtual ~FrameSchedulerIntf() { }
};
} // namespace composer
#endif // __FRAME_SCHEDULER_INTF_H__

60
include/layer_extn_intf.h Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2019, 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 __LAYER_EXTN_INTF_H__
#define __LAYER_EXTN_INTF_H__
#include <sys/types.h>
#include <vector>
#include <string>
namespace composer {
#define LAYER_EXTN_LIBRARY_NAME "liblayerext.qti.so"
#define CREATE_LAYER_EXTN_INTERFACE "CreateLayerExtnInterface"
#define DESTROY_LAYER_EXTN_INTERFACE "DestroyLayerExtnInterface"
#define LAYER_EXTN_REVISION_MAJOR (1)
#define LAYER_EXTN_REVISION_MINOR (0)
#define LAYER_EXTN_VERSION_TAG ((uint16_t) ((LAYER_EXTN_REVISION_MAJOR << 8) \
| LAYER_EXTN_REVISION_MINOR))
class LayerExtnIntf {
public:
virtual ~LayerExtnIntf() = default;
virtual int GetLayerClass(const std::string &name) = 0;
};
typedef bool (*CreateLayerExtnInterface)(uint16_t version, LayerExtnIntf **interface);
typedef void (*DestroyLayerExtnInterface)(LayerExtnIntf *interface);
} // namespace composer
#endif // __LAYER_EXTN_INTF_H__

View File

@ -169,6 +169,7 @@ struct DisplayConfigVariableInfo {
uint32_t fps = 0; //!< Frame rate per second.
uint32_t vsync_period_ns = 0; //!< VSync period in nanoseconds.
bool is_yuv = false; //!< If the display output is in YUV format.
uint32_t pixel_formats = 0;
};
/*! @brief Event data associated with VSync event.

View File

@ -503,6 +503,7 @@ struct HWDisplayAttributes : DisplayConfigVariableInfo {
uint32_t v_pulse_width = 0; //!< Vertical pulse width of panel
uint32_t h_total = 0; //!< Total width of panel (hActive + hFP + hBP + hPulseWidth)
uint32_t v_total = 0; //!< Total height of panel (vActive + vFP + vBP + vPulseWidth)
uint32_t clock_khz = 0; //!< Stores the pixel clock of panel in khz
std::bitset<32> s3d_config {}; //!< Stores the bit mask of S3D modes
bool operator !=(const HWDisplayAttributes &display_attributes) {
@ -517,6 +518,8 @@ struct HWDisplayAttributes : DisplayConfigVariableInfo {
(v_back_porch != display_attributes.v_back_porch) ||
(v_pulse_width != display_attributes.v_pulse_width) ||
(h_total != display_attributes.h_total) ||
(pixel_formats != display_attributes.pixel_formats) ||
(clock_khz != display_attributes.clock_khz) ||
(is_yuv != display_attributes.is_yuv));
}

View File

@ -66,6 +66,7 @@ DisplayError DisplayBase::Init() {
error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
if (error == kErrorNone) {
DLOGI("User mixer res. wxh = %dx%d",mixer_attributes_.width, mixer_attributes_.height);
hw_intf_->SetMixerAttributes(mixer_attributes_);
}
@ -144,6 +145,16 @@ DisplayError DisplayBase::Deinit() {
return kErrorNone;
}
void DisplayBase::CheckMinMixerResolution(uint32_t *width, uint32_t *height) {
HWDisplayAttributes display_attributes = {};
hw_intf_->GetDisplayAttributes(mixer_config_index_, &display_attributes);
// Minimum cap is mixer res. provided in property.
if (*width < display_attributes.x_pixels || *height < display_attributes.y_pixels) {
*width = display_attributes.x_pixels;
*height = display_attributes.y_pixels;
DLOGV("Cap min mixer resolution");
}
}
DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
std::vector<Layer *> &layers = layer_stack->layers;
HWLayersInfo &hw_layers_info = hw_layers_.info;
@ -504,12 +515,18 @@ DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
if (active_index == index) {
return kErrorNone;
}
HWDisplayAttributes act_display_attributes = {};
hw_intf_->GetDisplayAttributes(active_index, &act_display_attributes);
HWDisplayAttributes new_display_attributes = {};
hw_intf_->GetDisplayAttributes(index, &new_display_attributes);
if(new_display_attributes == act_display_attributes) {
return kErrorNone;
}
error = hw_intf_->SetDisplayAttributes(index);
if (error != kErrorNone) {
return error;
}
panel_config_index_ = index;
return ReconfigureDisplay();
}
@ -1017,15 +1034,22 @@ DisplayError DisplayBase::ReconfigureDisplay() {
HWMixerAttributes mixer_attributes;
HWPanelInfo hw_panel_info;
uint32_t active_index = 0;
error = hw_intf_->GetActiveConfig(&active_index);
if (error != kErrorNone) {
return error;
}
error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
if (error != kErrorNone) {
return error;
if (dest_scale_enabled_) {
if (active_index != mixer_config_index_) {
// we are here because Client of SDM has changed the active config
error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
} else {
error = hw_intf_->GetDisplayAttributes(panel_config_index_, &display_attributes);
}
} else {
error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
if (error != kErrorNone) {
return error;
}
}
error = hw_intf_->GetMixerAttributes(&mixer_attributes);
@ -1057,6 +1081,7 @@ DisplayError DisplayBase::ReconfigureDisplay() {
mixer_attributes_ = mixer_attributes;
hw_panel_info_ = hw_panel_info;
DLOGV("Display reconfigured.");
return kErrorNone;
}
@ -1198,6 +1223,10 @@ bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *n
*new_mixer_width = display_width;
*new_mixer_height = display_height;
}
if (*new_mixer_width > display_width || *new_mixer_height > display_height) {
*new_mixer_width = display_width;
*new_mixer_height = display_height;
}
return true;
}

View File

@ -146,6 +146,7 @@ class DisplayBase : public DisplayInterface {
std::string *value);
DisplayError GetHdrColorMode(std::string *color_mode, bool *found_hdr);
bool IsSupportColorModeAttribute(const std::string &color_mode);
void CheckMinMixerResolution(uint32_t *width, uint32_t *height);
recursive_mutex recursive_mutex_;
DisplayType display_type_;
@ -183,6 +184,9 @@ class DisplayBase : public DisplayInterface {
std::string current_color_mode_ = "hal_native";
bool hdr_playback_mode_ = false;
int disable_hdr_lut_gen_ = 0;
uint32_t panel_config_index_ = 0;
uint32_t mixer_config_index_ = 0;
bool dest_scale_enabled_ = false;
};
} // namespace sdm

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2014 - 2018, 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:
@ -27,6 +27,7 @@
#include <map>
#include <utility>
#include <vector>
#include <cmath>
#include "display_hdmi.h"
#include "hw_interface.h"
@ -34,6 +35,10 @@
#define __CLASS__ "DisplayHDMI"
#define FMT_RGB 1
#define FMT_ONLY_YUV 2
#define FMT_RGB_YUV 3
namespace sdm {
DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
@ -66,13 +71,63 @@ DisplayError DisplayHDMI::Init() {
if (error != kErrorNone) {
HWInterface::Destroy(hw_intf_);
}
panel_config_index_ = active_mode_index;
error = DisplayBase::Init();
if (error != kErrorNone) {
DisplayBase::Deinit();
HWInterface::Destroy(hw_intf_);
return error;
}
HWDisplayAttributes display_attributes = {};
hw_intf_->GetDisplayAttributes(active_mode_index, &display_attributes);
uint32_t display_width = display_attributes.x_pixels;
uint32_t display_height = display_attributes.y_pixels;
uint32_t index = 0;
bool dest_scale = false;
HWDisplayInterfaceInfo hw_disp_info = {};
hw_info_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
if (hw_disp_info.type == kHDMI) {
dest_scale = (mixer_attributes_.width != display_width ||
mixer_attributes_.height != display_height);
}
if (dest_scale) {
// When DS is enabled SDM clients should see active config equal to mixer resolution.
// active config = mixer config // if DS is enabled
error = hw_intf_->GetConfigIndex(mixer_attributes_.width, mixer_attributes_.height, &index);
if (error !=kErrorNone) {
// If mixer resolution does not match with any display resolution supported by TV,
// then use second best config as mixer resolution.
uint32_t closest_config_index = GetClosestConfig(mixer_attributes_.width,
mixer_attributes_.height);
if (active_mode_index == closest_config_index) {
dest_scale_enabled_ = false;
} else {
dest_scale_enabled_ = true;
}
hw_intf_->SetActiveConfig(closest_config_index);
mixer_config_index_ = closest_config_index;
HWDisplayAttributes display_attributes = {};
hw_intf_->GetDisplayAttributes(closest_config_index, &display_attributes);
mixer_attributes_.width = display_attributes.x_pixels;
mixer_attributes_.height = display_attributes.y_pixels;
hw_intf_->SetMixerAttributes(mixer_attributes_);
hw_intf_->SetConfigAttributes(mixer_config_index_, mixer_attributes_.width,
mixer_attributes_.height);
} else {
hw_intf_->SetActiveConfig(index);
mixer_config_index_ = index;
dest_scale_enabled_ = true;
}
}
if (dest_scale_enabled_) {
DLOGI("DS enabled. User config = %d",mixer_config_index_);
}
DLOGI("Mixer wxh = %dx%d Display wxh= %dx%d",mixer_attributes_.width, mixer_attributes_.height,
display_width,display_height);
GetScanSupport();
underscan_supported_ = (scan_support_ == kScanAlwaysUnderscanned) || (scan_support_ == kScanBoth);
@ -86,8 +141,12 @@ DisplayError DisplayHDMI::Init() {
(kS3dFormatTopBottom, kS3DModeTB));
s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
(kS3dFormatFramePacking, kS3DModeFP));
if (hw_disp_info.type == kHDMI) {
error = HWEventsInterface::Create(kPrimary, this, event_list_, &hw_events_intf_);
} else {
error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_);
}
error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_);
if (error != kErrorNone) {
DisplayBase::Deinit();
HWInterface::Destroy(hw_intf_);
@ -105,7 +164,9 @@ DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
uint32_t display_width = display_attributes_.x_pixels;
uint32_t display_height = display_attributes_.y_pixels;
if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
if (dest_scale_enabled_ && NeedsMixerReconfiguration(layer_stack, &new_mixer_width,
&new_mixer_height)) {
CheckMinMixerResolution(&new_mixer_width, &new_mixer_height);
error = ReconfigureMixer(new_mixer_width, new_mixer_height);
if (error != kErrorNone) {
ReconfigureMixer(display_width, display_height);
@ -160,16 +221,44 @@ DisplayError DisplayHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)
return hw_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
}
uint32_t DisplayHDMI::GetClosestConfig(uint32_t width, uint32_t height) {
if ((UINT32_MAX / width < height) || (UINT32_MAX / height < width)) {
//uint overflow
return panel_config_index_;
}
uint32_t num_modes = 0, index = 0;
hw_intf_->GetNumDisplayAttributes(&num_modes);
uint32_t area = width * height;
std::vector<uint32_t> area_modes(num_modes);
// Get display attribute for each mode
std::vector<HWDisplayAttributes> attrib(num_modes);
for (index = 0; index < num_modes; index++) {
hw_intf_->GetDisplayAttributes(index, &attrib[index]);
area_modes[index] = attrib[index].y_pixels * attrib[index].x_pixels;
}
uint32_t least_area_diff = display_attributes_.x_pixels*display_attributes_.y_pixels;
uint32_t least_diff_index = panel_config_index_;
for (index = 0; index < num_modes; index++) {
if (abs(INT(area_modes[index]) - INT(area)) < INT(least_area_diff)) {
least_diff_index = index;
least_area_diff = UINT32(abs(INT(area_modes[index]) - INT(area)));
}
}
DLOGV("Closest config index = %d",least_diff_index);
return least_diff_index;
}
uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
uint32_t best_index = 0, index;
uint32_t num_modes = 0;
hw_intf_->GetNumDisplayAttributes(&num_modes);
DLOGI("Number of modes = %d",num_modes);
// Get display attribute for each mode
std::vector<HWDisplayAttributes> attrib(num_modes);
for (index = 0; index < num_modes; index++) {
hw_intf_->GetDisplayAttributes(index, &attrib[index]);
DLOGI("Index = %d. wxh = %dx%d",index, attrib[index].x_pixels, attrib[index].y_pixels);
}
// Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone
@ -184,16 +273,30 @@ uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
if (!attrib[index].s3d_config[s3d_mode])
continue;
// From the available configs, select the best
// Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60
if (attrib[index].y_pixels > attrib[best_index].y_pixels) {
uint32_t best_clock_khz = attrib[best_index].pixel_formats == FMT_ONLY_YUV ?
attrib[best_index].clock_khz/2 : attrib[best_index].clock_khz;
uint32_t current_clock_khz = attrib[index].pixel_formats == FMT_ONLY_YUV ?
attrib[index].clock_khz/2 : attrib[index].clock_khz;
if (current_clock_khz > best_clock_khz) {
DLOGI("Best index = %d .Best pixel clock = %d .Previous best was %d",
index,current_clock_khz,best_clock_khz);
best_index = UINT32(index);
} else if (attrib[index].y_pixels == attrib[best_index].y_pixels) {
} else if (current_clock_khz == best_clock_khz) {
if (attrib[index].x_pixels > attrib[best_index].x_pixels) {
DLOGI("Best index = %d .Best xpixel = %d .Previous best was %d",
index,attrib[index].x_pixels,attrib[best_index].x_pixels);
best_index = UINT32(index);
} else if (attrib[index].x_pixels == attrib[best_index].x_pixels) {
if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
if (attrib[index].y_pixels > attrib[best_index].y_pixels) {
DLOGI("Best index = %d .Best ypixel = %d .Previous best was %d",
index,attrib[index].y_pixels,attrib[best_index].y_pixels);
best_index = UINT32(index);
} else if (attrib[index].y_pixels == attrib[best_index].y_pixels) {
if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
DLOGI("Best index = %d .Best vsync_period = %d .Previous best was %d",
index,attrib[index].vsync_period_ns,attrib[best_index].vsync_period_ns);
best_index = UINT32(index);
}
}
}
}

View File

@ -56,6 +56,7 @@ class DisplayHDMI : public DisplayBase, HWEventHandler {
private:
uint32_t GetBestConfig(HWS3DMode s3d_mode);
uint32_t GetClosestConfig(uint32_t width, uint32_t height);
void GetScanSupport();
void SetS3DMode(LayerStack *layer_stack);

View File

@ -973,7 +973,7 @@ DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
return kErrorNone;
}
DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
DisplayError HWDeviceDRM::SetMixerAttributes(HWMixerAttributes &mixer_attributes) {
if (!hw_resource_.hw_dest_scalar_info.count) {
return kErrorNotSupported;
}
@ -1061,4 +1061,19 @@ DisplayError HWDeviceDRM::GetDynamicDSIClock(uint64_t *bitclk) {
return kErrorNotSupported;
}
DisplayError HWDeviceDRM::SetActiveConfig(uint32_t active_config) {
return kErrorNone;
}
DisplayError HWDeviceDRM::GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index) {
return kErrorNone;
}
DisplayError HWDeviceDRM::SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height) {
return kErrorNone;
}
} // namespace sdm

View File

@ -58,6 +58,7 @@ class HWDeviceDRM : public HWInterface {
protected:
// From HWInterface
virtual DisplayError GetActiveConfig(uint32_t *active_config);
virtual DisplayError SetActiveConfig(uint32_t active_config);
virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
virtual DisplayError GetDisplayAttributes(uint32_t index,
HWDisplayAttributes *display_attributes);
@ -89,10 +90,12 @@ class HWDeviceDRM : public HWInterface {
virtual DisplayError SetAutoRefresh(bool enable) { return kErrorNone; }
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError SetMixerAttributes(HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
virtual DisplayError SetDynamicDSIClock(uint64_t bitclk);
virtual DisplayError GetDynamicDSIClock(uint64_t *bitclk);
virtual DisplayError GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index);
virtual DisplayError SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height);
enum {
kHWEventVSync,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2014 - 2019, 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
@ -156,6 +156,10 @@ DisplayError HWDevice::GetConfigIndex(uint32_t mode, uint32_t *index) {
return kErrorNone;
}
DisplayError HWDevice::GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index) {
return kErrorNone;
}
DisplayError HWDevice::PowerOn() {
DTRACE_SCOPED();
@ -1342,17 +1346,37 @@ DisplayError HWDevice::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
return kErrorNone;
}
DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
DisplayError HWDevice::SetMixerAttributes(HWMixerAttributes &mixer_attributes) {
if (!hw_resource_.hw_dest_scalar_info.count) {
return kErrorNotSupported;
}
uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
uint32_t align_y = 2;
if (mixer_attributes.width > display_attributes_.x_pixels ||
mixer_attributes.height > display_attributes_.y_pixels) {
DLOGW_IF(kTagDriverConfig, "Input resolution exceeds display resolution! input: res %dx%d "\
"display: res %dx%d", mixer_attributes.width, mixer_attributes.height,
display_attributes_.x_pixels, display_attributes_.y_pixels);
return kErrorNotSupported;
float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
if (scale_x > max_scale_up) {
DLOGW_IF(kTagDriverConfig, "Up scaling ratio exceeds for destination scalar upscale " \
"limit scale_x %f max_scale_up %f", scale_x, max_scale_up);
mixer_attributes.width = UINT32(FLOAT(display_attributes_.x_pixels) / max_scale_up);
}
if (scale_y > max_scale_up) {
DLOGW_IF(kTagDriverConfig, "Up scaling ratio exceeds for destination scalar upscale " \
"limit scale_y %f max_scale_up %f", scale_y, max_scale_up);
mixer_attributes.height = UINT32(FLOAT(display_attributes_.y_pixels) / max_scale_up);
}
if (mixer_attributes.width > display_attributes_.x_pixels) {
mixer_attributes.width = display_attributes_.x_pixels;
DLOGW_IF(kTagDriverConfig, "Input mixer width exceeds display width! input: res %d "\
"display: res %d", mixer_attributes.width, display_attributes_.x_pixels);
}
if(mixer_attributes.height > display_attributes_.y_pixels) {
mixer_attributes.height = display_attributes_.y_pixels;
DLOGW_IF(kTagDriverConfig, "Input mixer height exceeds display height! input: res %d "\
"display: res %d", mixer_attributes.height, display_attributes_.y_pixels);
}
uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
@ -1363,7 +1387,7 @@ DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attribu
if (mixer_attributes.width > max_input_width) {
DLOGW_IF(kTagDriverConfig, "Input width exceeds width limit! input_width %d width_limit %d",
mixer_attributes.width, max_input_width);
return kErrorNotSupported;
mixer_attributes.width = max_input_width;
}
float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
@ -1374,16 +1398,43 @@ DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attribu
DLOGW_IF(kTagDriverConfig, "Aspect ratio mismatch! input: res %dx%d display: res %dx%d",
mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
display_attributes_.y_pixels);
return kErrorNotSupported;
}
uint32_t new_mixer_width = FloorToMultipleOf(UINT32((display_aspect_ratio) *
mixer_attributes.height), align_x);
float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
if (scale_x > max_scale_up || scale_y > max_scale_up) {
DLOGW_IF(kTagDriverConfig, "Up scaling ratio exceeds for destination scalar upscale " \
"limit scale_x %f scale_y %f max_scale_up %f", scale_x, scale_y, max_scale_up);
return kErrorNotSupported;
if (new_mixer_width > max_input_width || new_mixer_width > display_attributes_.x_pixels) {
uint32_t new_mixer_height = FloorToMultipleOf(UINT32(FLOAT(mixer_attributes.width) /
display_aspect_ratio), align_y);
if (new_mixer_height > display_attributes_.y_pixels) {
mixer_attributes.width = display_attributes_.x_pixels;
mixer_attributes.height = display_attributes_.y_pixels;
} else {
mixer_attributes.height = new_mixer_height;
mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
if (display_aspect_ratio != mixer_aspect_ratio) {
uint32_t new_mixer_width = FloorToMultipleOf(UINT32((display_aspect_ratio) *
mixer_attributes.height), align_x);
if (new_mixer_width > max_input_width || new_mixer_width > display_attributes_.x_pixels) {
mixer_attributes.width = display_attributes_.x_pixels;
mixer_attributes.height = display_attributes_.y_pixels;
} else {
mixer_attributes.width = new_mixer_width;
}
}
}
} else {
mixer_attributes.width = new_mixer_width;
mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
if (display_aspect_ratio != mixer_aspect_ratio) {
uint32_t new_mixer_height = FloorToMultipleOf(UINT32(FLOAT(mixer_attributes.width) /
display_aspect_ratio), align_y);
if (new_mixer_height > display_attributes_.y_pixels) {
mixer_attributes.width = display_attributes_.x_pixels;
mixer_attributes.height = display_attributes_.y_pixels;
} else {
mixer_attributes.height = new_mixer_height;
}
}
}
}
float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
@ -1394,6 +1445,7 @@ DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attribu
mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
}
DLOGV_IF(kTagDriverConfig, "New mixer wxh = %dx%d", mixer_attributes_.width, mixer_attributes_.height);
return kErrorNone;
}
@ -1411,6 +1463,10 @@ DisplayError HWDevice::SetDynamicDSIClock(uint64_t bitclk) {
return kErrorNotSupported;
}
DisplayError HWDevice::SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height) {
return kErrorNone;
}
DisplayError HWDevice::GetDynamicDSIClock(uint64_t *bitclk) {
return kErrorNotSupported;
}

View File

@ -70,6 +70,7 @@ class HWDevice : public HWInterface {
virtual DisplayError SetDisplayAttributes(uint32_t index);
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
virtual DisplayError GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index);
virtual DisplayError PowerOn();
virtual DisplayError PowerOff();
virtual DisplayError Doze();
@ -94,10 +95,11 @@ class HWDevice : public HWInterface {
virtual DisplayError SetAutoRefresh(bool enable) { return kErrorNone; }
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError SetMixerAttributes(HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
virtual DisplayError SetDynamicDSIClock(uint64_t bitclk);
virtual DisplayError GetDynamicDSIClock(uint64_t *bitclk);
virtual DisplayError SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height);
enum {
kHWEventVSync,

View File

@ -149,7 +149,7 @@ static uint32_t GetContentType(const LayerBuffer &layer_buffer) {
#endif
static bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
fb_var_screeninfo *info) {
fb_var_screeninfo *info, bool hdr_enabled) {
if (!mode || !info) {
return false;
}
@ -174,9 +174,13 @@ static bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
info->grayscale = V4L2_PIX_FMT_RGB24;
// If the mode supports YUV420 set grayscale to the FOURCC value for YUV420.
std::bitset<32> pixel_formats = mode->pixel_formats;
if (pixel_formats[1]) {
if (pixel_formats[1] && !pixel_formats[0]) {
info->grayscale = V4L2_PIX_FMT_NV12;
}
if (pixel_formats[1] && pixel_formats[0] && hdr_enabled) {
info->grayscale = V4L2_PIX_FMT_NV12;
}
if (!mode->active_low_h) {
info->sync |= (uint32_t)FB_SYNC_HOR_HIGH_ACT;
@ -266,6 +270,11 @@ DisplayError HWHDMI::GetActiveConfig(uint32_t *active_config_index) {
return kErrorNone;
}
DisplayError HWHDMI::SetActiveConfig(uint32_t active_config) {
active_config_index_ = active_config;
return kErrorNone;
}
DisplayError HWHDMI::ReadEDIDInfo() {
ssize_t length = -1;
char edid_str[kPageSize] = {'\0'};
@ -329,6 +338,7 @@ DisplayError HWHDMI::GetDisplayAttributes(uint32_t index,
}
display_attributes->x_pixels = timing_mode->active_h;
display_attributes->y_pixels = timing_mode->active_v;
DLOGV("index = %d. x = %d. y=%d",index,timing_mode->active_h,timing_mode->active_v);
display_attributes->v_front_porch = timing_mode->front_porch_v;
display_attributes->v_back_porch = timing_mode->back_porch_v;
display_attributes->v_pulse_width = timing_mode->pulse_width_v;
@ -347,8 +357,10 @@ DisplayError HWHDMI::GetDisplayAttributes(uint32_t index,
GetDisplayS3DSupport(index, display_attributes);
std::bitset<32> pixel_formats = timing_mode->pixel_formats;
display_attributes->pixel_formats = timing_mode->pixel_formats;
display_attributes->is_yuv = pixel_formats[1];
display_attributes->clock_khz = timing_mode->pixel_freq;
return kErrorNone;
}
@ -367,7 +379,7 @@ DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
return kErrorHardware;
}
DLOGI("GetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3],
DLOGI("GetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", (vscreeninfo.reserved[3] >>16 & 0xFF),
vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
@ -381,7 +393,7 @@ DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
}
}
if (MapHDMIDisplayTiming(timing_mode, &vscreeninfo) == false) {
if (MapHDMIDisplayTiming(timing_mode, &vscreeninfo, hw_panel_info_.hdr_enabled) == false) {
return kErrorParameters;
}
@ -393,7 +405,7 @@ DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
return kErrorHardware;
}
DLOGI("SetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3] & 0xFF00,
DLOGI("SetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", (vscreeninfo.reserved[3]>>16 & 0xFF),
vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
@ -425,6 +437,39 @@ DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
return kErrorNone;
}
DisplayError HWHDMI::SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height)
{
if (index >= hdmi_modes_.size()) {
return kErrorNotSupported;
}
// Get the resolution info from the look up table
msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
if (cur->video_format == hdmi_modes_[index]) {
timing_mode = cur;
break;
}
}
timing_mode->active_h = width;
timing_mode->active_v = height;
return kErrorNone;
}
DisplayError HWHDMI::GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index) {
// Get the resolution info from the look up table
for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
if (cur->active_h == width && cur->active_v == height) {
*index = i;
return kErrorNone;
}
}
return kErrorNotSupported;
}
DisplayError HWHDMI::GetConfigIndex(uint32_t mode, uint32_t *index) {
// Check if the mode is valid and return corresponding index
for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
@ -491,9 +536,8 @@ DisplayError HWHDMI::GetMaxCEAFormat(uint32_t *max_cea_format) {
DisplayError HWHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
DisplayError error = kErrorNone;
int fd = -1;
char data[kMaxStringLength] = {'\0'};
char data[kMaxStringLength] = "/sys/devices/virtual/hdcp/msm_hdcp/min_level_change";
snprintf(data, sizeof(data), "%s%d/hdcp2p2/min_level_change", fb_path_, fb_node_index_);
fd = Sys::open_(data, O_WRONLY);
if (fd < 0) {

View File

@ -76,6 +76,7 @@ class HWHDMI : public HWDevice {
virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
// Requirement to call this only after the first config has been explicitly set by client
virtual DisplayError GetActiveConfig(uint32_t *active_config);
virtual DisplayError SetActiveConfig(uint32_t active_config);
virtual DisplayError GetDisplayAttributes(uint32_t index,
HWDisplayAttributes *display_attributes);
virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info);
@ -84,6 +85,8 @@ class HWHDMI : public HWDevice {
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual DisplayError SetDisplayAttributes(uint32_t index);
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
virtual DisplayError GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index);
virtual DisplayError SetConfigAttributes(uint32_t index, uint32_t width, uint32_t height);
virtual DisplayError Validate(HWLayers *hw_layers);
virtual DisplayError Commit(HWLayers *hw_layers);
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);

View File

@ -652,7 +652,7 @@ DisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig *feature_list) {
return kErrorNone;
}
DisplayError HWPrimary::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
DisplayError HWPrimary::SetMixerAttributes(HWMixerAttributes &mixer_attributes) {
if (IsResolutionSwitchEnabled()) {
return kErrorNotSupported;
}
@ -732,5 +732,10 @@ DisplayError HWPrimary::GetDynamicDSIClock(uint64_t *bitclk) {
return kErrorNone;
}
DisplayError HWPrimary::SetActiveConfig(uint32_t active_config) {
active_config_index_ = active_config;
return kErrorNone;
}
} // namespace sdm

View File

@ -41,6 +41,7 @@ class HWPrimary : public HWDevice {
virtual DisplayError Init();
virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
virtual DisplayError GetActiveConfig(uint32_t *active_config);
virtual DisplayError SetActiveConfig(uint32_t active_config);
virtual DisplayError GetDisplayAttributes(uint32_t index,
HWDisplayAttributes *display_attributes);
virtual DisplayError SetDisplayAttributes(uint32_t index);
@ -59,7 +60,7 @@ class HWPrimary : public HWDevice {
virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError SetAutoRefresh(bool enable);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError SetMixerAttributes(HWMixerAttributes &mixer_attributes);
virtual DisplayError SetDynamicDSIClock(uint64_t bitclk);
virtual DisplayError GetDynamicDSIClock(uint64_t *bitclk);

View File

@ -148,7 +148,6 @@ void HWScaleV2::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
mdp_dest_scalar[index].flags = mdp_scale->enable ? MDP_DESTSCALER_ENABLE : 0;
if (scale_data.enable.detail_enhance) {
mdp_dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
}

View File

@ -82,5 +82,10 @@ DisplayError HWVirtual::GetDisplayAttributes(uint32_t index,
}
DisplayError HWVirtual::SetActiveConfig(uint32_t active_config) {
return kErrorNone;
}
} // namespace sdm

View File

@ -33,13 +33,14 @@ class HWVirtual : public HWDevice {
public:
HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
virtual DisplayError SetMixerAttributes(HWMixerAttributes &mixer_attributes) {
return kErrorNotSupported;
}
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
virtual DisplayError GetDisplayAttributes(uint32_t index,
HWDisplayAttributes *display_attributes);
virtual DisplayError SetActiveConfig(uint32_t active_config);
protected:
virtual DisplayError Init();

View File

@ -75,13 +75,16 @@ class HWInterface {
virtual DisplayError Init() = 0;
virtual DisplayError Deinit() = 0;
virtual DisplayError GetActiveConfig(uint32_t *active_config) = 0;
virtual DisplayError SetActiveConfig(uint32_t active_config) = 0;
virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
virtual DisplayError GetDisplayAttributes(uint32_t index,
HWDisplayAttributes *display_attributes) = 0;
virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
virtual DisplayError SetConfigAttributes(uint32_t index, uint32_t w, uint32_t h) = 0;
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0;
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
virtual DisplayError GetConfigIndex(uint32_t width, uint32_t height, uint32_t *index) = 0;
virtual DisplayError PowerOn() = 0;
virtual DisplayError PowerOff() = 0;
virtual DisplayError Doze() = 0;
@ -106,7 +109,7 @@ class HWInterface {
virtual DisplayError SetAutoRefresh(bool enable) = 0;
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode) = 0;
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError SetMixerAttributes(HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) = 0;
virtual DisplayError SetDynamicDSIClock(uint64_t bitclk) = 0;
virtual DisplayError GetDynamicDSIClock(uint64_t *bitclk) = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@ -953,6 +953,10 @@ HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
}
DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
if (is_primary_) {
callbacks_->Vsync(HWC_DISPLAY_PRIMARY, vsync.timestamp);
return kErrorNone;
}
callbacks_->Vsync(id_, vsync.timestamp);
return kErrorNone;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@ -150,6 +150,9 @@ class HWCDisplay : public DisplayEventHandler {
return kErrorNotSupported;
}
int SetPanelBrightness(int level);
void SetIsPrimaryPanel(bool is_primary) {
is_primary_ = is_primary;
}
int GetPanelBrightness(int *level);
int ToggleScreenUpdates(bool enable);
int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, PPDisplayAPIPayload *out_payload,
@ -317,6 +320,7 @@ class HWCDisplay : public DisplayEventHandler {
bool skip_validate_ = false;
bool animating_ = false;
bool fbt_valid_ = false;
bool is_primary_ = false;
};
inline int HWCDisplay::Perform(uint32_t operation, ...) {

View File

@ -277,4 +277,10 @@ void HWCDisplayExternal::GetUnderScanConfig() {
}
}
DisplayError HWCDisplayExternal::SetMixerResolution(uint32_t width, uint32_t height) {
DisplayError error = display_intf_->SetMixerResolution(width, height);
validated_.reset();
return error;
}
} // namespace sdm

View File

@ -57,6 +57,7 @@ class HWCDisplayExternal : public HWCDisplay {
void GetUnderScanConfig();
static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
uint32_t *virtual_width, uint32_t *virtual_height);
DisplayError SetMixerResolution(uint32_t width, uint32_t height);
DisplayNull display_null_;
int underscan_width_ = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@ -200,6 +200,7 @@ int HWCSession::Init() {
CreateNullDisplay();
null_display_active_ = true;
}
hwc_display_[HWC_DISPLAY_PRIMARY]->SetIsPrimaryPanel(true);
} else {
// Create and power on primary display
status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
@ -584,6 +585,7 @@ int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
}
}
hwc_session->need_invalidate_ = false;
hwc_session->callback_reg_ = true;
return INT32(error);
}
@ -1551,8 +1553,12 @@ void HWCSession::ResetPanel() {
int HWCSession::HotPlugHandler(bool connected) {
int status = 0;
bool notify_hotplug = false;
if (!first_commit_ && !connected && hdmi_is_primary_) {
if (!first_commit_ && !connected && hdmi_is_primary_ && !null_display_active_) {
SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
DLOGI("Disconnect event before first commit");
HWCDisplayExternal::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
CreateNullDisplay();
null_display_active_ = true;
return 0;
}

View File

@ -317,6 +317,7 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli
bool is_composer_up_ = false;
bool null_display_active_ = false;
Locker callbacks_lock_;
bool callback_reg_ = false;
};
} // namespace sdm

View File

@ -313,9 +313,12 @@ int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
if (disp_id != HWC_DISPLAY_EXTERNAL) {
DLOGE("Not supported for display");
} else if (!hwc_display_[disp_id]) {
} else if (!hwc_display_[disp_id] && !hdmi_is_primary_) {
DLOGW("Display is not connected");
} else {
if (hdmi_is_primary_) {
disp_id = HWC_DISPLAY_PRIMARY;
}
return hwc_display_[disp_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
}
@ -459,7 +462,9 @@ Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
Refresh(HWC_DISPLAY_PRIMARY);
if (callback_reg_) {
Refresh(HWC_DISPLAY_PRIMARY);
}
if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
return -EINVAL;