diff options
author | Naseer Ahmed <naseer@codeaurora.org> | 2018-03-16 12:20:27 -0400 |
---|---|---|
committer | Naseer Ahmed <naseer@codeaurora.org> | 2018-03-16 17:13:01 -0400 |
commit | ce9a3c3c9e0de91e1073d042f5c2cf14b2ed1460 (patch) | |
tree | f9b8d8898b691346ea9363e3b39df556ba68ebf1 | |
parent | 7ae93696c4dba51cb616ff11f0baeda4ffced009 (diff) | |
parent | 07bf27fe83daaaec4edb83c0e556d9c229b6b9d3 (diff) | |
download | display-ce9a3c3c9e0de91e1073d042f5c2cf14b2ed1460.tar.gz |
Merge tag 'display.lnx.4.0-180312' into display.lnx.4.0
Change-Id: If3dca0edf21476ac14809748dc4e187da4618dad
31 files changed, 252 insertions, 109 deletions
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp index f2f1caf9..7801005b 100644 --- a/gralloc/gr_utils.cpp +++ b/gralloc/gr_utils.cpp @@ -232,7 +232,6 @@ unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int } else if (IsCompressedRGBFormat(format)) { size = alignedw * alignedh * ASTC_BLOCK_SIZE; } else { - // Below switch should be for only YUV/custom formats switch (format) { case HAL_PIXEL_FORMAT_RAW16: @@ -289,9 +288,11 @@ unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int size = ALIGN(alignedw * alignedh * 2, SIZE_4K); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: - case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); break; case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + case HAL_PIXEL_FORMAT_NV21_ENCODEABLE: size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height); break; case HAL_PIXEL_FORMAT_BLOB: diff --git a/gralloc/gralloc_priv.h b/gralloc/gralloc_priv.h index c6e8ca63..73eacaa1 100644 --- a/gralloc/gralloc_priv.h +++ b/gralloc/gralloc_priv.h @@ -91,6 +91,7 @@ inline int roundUpToPageSize(int x) { #define HAL_PIXEL_FORMAT_RGBA_5551 6 #define HAL_PIXEL_FORMAT_RGBA_4444 7 #define HAL_PIXEL_FORMAT_NV12_ENCODEABLE 0x102 +#define HAL_PIXEL_FORMAT_NV21_ENCODEABLE 0x7FA30C00 #define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS 0x7FA30C04 #define HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED 0x7FA30C03 #define HAL_PIXEL_FORMAT_YCbCr_420_SP 0x109 diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h index 303c89bc..1f813acf 100644 --- a/sdm/include/core/display_interface.h +++ b/sdm/include/core/display_interface.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -388,12 +388,13 @@ class DisplayInterface { /*! @brief Method to set current state of the display device. @param[in] state \link DisplayState \endlink + @param[in] pointer to release fence @return \link DisplayError \endlink @sa SetDisplayState */ - virtual DisplayError SetDisplayState(DisplayState state) = 0; + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence) = 0; /*! @brief Method to set active configuration for variable properties of the display device. diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h index 867bc057..3dd1c6f4 100644 --- a/sdm/include/core/layer_stack.h +++ b/sdm/include/core/layer_stack.h @@ -35,6 +35,7 @@ #include <utils/constants.h> #include <vector> +#include <utility> #include "layer_buffer.h" #include "sdm_types.h" @@ -383,6 +384,9 @@ struct Layer { @sa DisplayInterface::Prepare @sa DisplayInterface::Commit */ + +typedef std::pair<ColorPrimaries, GammaTransfer> PrimariesTransfer; + struct LayerStack { std::vector<Layer *> layers = {}; //!< Vector of layer pointers. @@ -400,7 +404,8 @@ struct LayerStack { LayerStackFlags flags; //!< Flags associated with this layer set. - ColorPrimaries blend_cs = ColorPrimaries_BT709_5; //!< o/p - Blending color space updated by SDM + PrimariesTransfer blend_cs = {ColorPrimaries_BT709_5, Transfer_sRGB}; + //!< o/p - Blending color space updated by SDM }; } // namespace sdm diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp index 136168b9..3bb34414 100644 --- a/sdm/libs/core/display_base.cpp +++ b/sdm/libs/core/display_base.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -60,6 +60,7 @@ DisplayError DisplayBase::Init() { hw_intf_->GetHWPanelInfo(&hw_panel_info_); uint32_t active_index = 0; + int drop_vsync = 0; hw_intf_->GetActiveConfig(&active_index); hw_intf_->GetDisplayAttributes(active_index, &display_attributes_); fb_config_ = display_attributes_; @@ -117,7 +118,8 @@ DisplayError DisplayBase::Init() { // TODO(user): Temporary changes, to be removed when DRM driver supports // Partial update with Destination scaler enabled. SetPUonDestScaler(); - + Debug::Get()->GetProperty("sdm.drop_skewed_vsync", &drop_vsync); + drop_skewed_vsync_ = (drop_vsync == 1); return kErrorNone; CleanupOnError: @@ -342,7 +344,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) { if (error != kErrorNone) { return error; } - + // Stop dropping vsync when first commit is received after idle fallback. + drop_hw_vsync_ = false; DLOGI_IF(kTagDisplay, "Exiting commit for display type : %d", display_type_); return kErrorNone; } @@ -430,7 +433,7 @@ DisplayState DisplayBase::GetLastPowerMode() { return last_power_mode_; } -DisplayError DisplayBase::SetDisplayState(DisplayState state) { +DisplayError DisplayBase::SetDisplayState(DisplayState state, int *release_fence) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; bool active = false; @@ -452,7 +455,7 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state) { break; case kStateOn: - error = hw_intf_->PowerOn(); + error = hw_intf_->PowerOn(release_fence); if (error != kErrorNone) { return error; } @@ -468,13 +471,13 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state) { break; case kStateDoze: - error = hw_intf_->Doze(); + error = hw_intf_->Doze(release_fence); active = true; last_power_mode_ = kStateDoze; break; case kStateDozeSuspend: - error = hw_intf_->DozeSuspend(); + error = hw_intf_->DozeSuspend(release_fence); if (display_type_ != kPrimary) { active = true; } @@ -1029,6 +1032,10 @@ DisplayError DisplayBase::SetVSyncState(bool enable) { if (vsync_enable_ != enable) { error = hw_intf_->SetVSyncState(enable); if (error == kErrorNotSupported) { + if (drop_skewed_vsync_ && (hw_panel_info_.mode == kModeVideo) && + enable && (current_refresh_rate_ == hw_panel_info_.min_fps)) { + drop_hw_vsync_ = true; + } error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable); } if (error == kErrorNone) { @@ -1527,7 +1534,7 @@ DisplayError DisplayBase::ValidateHDR(LayerStack *layer_stack) { // HDR color mode is set when hdr layer is present in layer_stack. // If client flags HDR layer as skipped, then blending happens // in SDR color space. Hence, need to restore the SDR color mode. - if (layer_stack->blend_cs != ColorPrimaries_BT2020) { + if (layer_stack->blend_cs.first != ColorPrimaries_BT2020) { error = SetHDRMode(false); if (error != kErrorNone) { DLOGW("Failed to restore SDR mode"); diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h index 014ea112..5e697d9c 100644 --- a/sdm/libs/core/display_base.h +++ b/sdm/libs/core/display_base.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014-2018, 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: @@ -62,7 +62,7 @@ class DisplayBase : public DisplayInterface { virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info); virtual DisplayError GetActiveConfig(uint32_t *index); virtual DisplayError GetVSyncState(bool *enabled); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual DisplayError SetActiveConfig(uint32_t index); virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) { return kErrorNotSupported; @@ -189,6 +189,9 @@ class DisplayBase : public DisplayInterface { bool hdr_mode_ = false; int disable_hdr_lut_gen_ = 0; DisplayState last_power_mode_ = kStateOff; + bool drop_hw_vsync_ = false; + uint32_t current_refresh_rate_ = 0; + bool drop_skewed_vsync_ = false; }; } // namespace sdm diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp index 8466f8bf..718dd1e8 100644 --- a/sdm/libs/core/display_primary.cpp +++ b/sdm/libs/core/display_primary.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -166,10 +166,10 @@ DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) { return error; } -DisplayError DisplayPrimary::SetDisplayState(DisplayState state) { +DisplayError DisplayPrimary::SetDisplayState(DisplayState state, int *release_fence) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; - error = DisplayBase::SetDisplayState(state); + error = DisplayBase::SetDisplayState(state, release_fence); if (error != kErrorNone) { return error; } @@ -291,7 +291,7 @@ DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate, bool final_ra } DisplayError DisplayPrimary::VSync(int64_t timestamp) { - if (vsync_enable_) { + if (vsync_enable_ && !drop_hw_vsync_) { DisplayEventVSync vsync; vsync.timestamp = timestamp; event_handler_->VSync(vsync); @@ -302,7 +302,9 @@ DisplayError DisplayPrimary::VSync(int64_t timestamp) { void DisplayPrimary::IdleTimeout() { if (hw_panel_info_.mode == kModeVideo) { - event_handler_->HandleEvent(kIdleTimeout); + if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) { + return; + } handle_idle_timeout_ = true; event_handler_->Refresh(); lock_guard<recursive_mutex> obj(recursive_mutex_); @@ -391,19 +393,26 @@ bool DisplayPrimary::NeedsAVREnable() { void DisplayPrimary::ResetPanel() { DisplayError status = kErrorNone; + int release_fence = -1; DLOGI("Powering off primary"); - status = SetDisplayState(kStateOff); + status = SetDisplayState(kStateOff, &release_fence); if (status != kErrorNone) { DLOGE("power-off on primary failed with error = %d", status); } + if (release_fence >= 0) { + ::close(release_fence); + } DLOGI("Restoring power mode on primary"); DisplayState mode = GetLastPowerMode(); - status = SetDisplayState(mode); + status = SetDisplayState(mode, &release_fence); if (status != kErrorNone) { DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status); } + if (release_fence >= 0) { + ::close(release_fence); + } DLOGI("Enabling HWVsync"); status = SetVSyncState(true); diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h index a4dd4b84..21ada7ca 100644 --- a/sdm/libs/core/display_primary.h +++ b/sdm/libs/core/display_primary.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -44,7 +44,7 @@ class DisplayPrimary : public DisplayBase, HWEventHandler { virtual DisplayError Commit(LayerStack *layer_stack); virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending); virtual DisplayError DisablePartialUpdateOneFrame(); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual void SetIdleTimeoutMs(uint32_t active_ms); virtual DisplayError SetDisplayMode(uint32_t mode); virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate); @@ -71,7 +71,6 @@ class DisplayPrimary : public DisplayBase, HWEventHandler { bool avr_prop_disabled_ = false; bool switch_to_cmd_ = false; bool handle_idle_timeout_ = false; - uint32_t current_refresh_rate_ = 0; bool reset_panel_ = false; }; diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp index dfe4fd3d..d46c8c0b 100644 --- a/sdm/libs/core/display_virtual.cpp +++ b/sdm/libs/core/display_virtual.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -161,6 +161,14 @@ DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) { return DisplayBase::Prepare(layer_stack); } +DisplayError DisplayVirtual::GetColorModeCount(uint32_t *mode_count) { + lock_guard<recursive_mutex> obj(recursive_mutex_); + + // Color Manager isn't supported for virtual displays. + *mode_count = 1; + + return kErrorNone; +} } // namespace sdm diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h index eeade9dc..ca154c44 100644 --- a/sdm/libs/core/display_virtual.h +++ b/sdm/libs/core/display_virtual.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -63,6 +63,7 @@ class DisplayVirtual : public DisplayBase { // on virtual display is functional. return kErrorNone; } + virtual DisplayError GetColorModeCount(uint32_t *mode_count); }; } // namespace sdm diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp index 295dafdb..85e95746 100644 --- a/sdm/libs/core/drm/hw_color_manager_drm.cpp +++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp @@ -917,15 +917,49 @@ DisplayError HWColorManagerDrm::GetDrmGamut(const PPFeatureInfo &in_data, DisplayError HWColorManagerDrm::GetDrmPADither(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data) { DisplayError ret = kErrorNone; -#ifdef PP_DRM_ENABLE +#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_DITHER) + struct SDEPADitherData* sde_dither; + struct drm_msm_pa_dither* mdp_dither; + if (!out_data) { DLOGE("Invalid input parameter for PA dither"); return kErrorParameters; } - out_data->id = kPPFeaturesMax; + out_data->id = kFeaturePADither; out_data->type = sde_drm::kPropBlob; out_data->version = in_data.feature_version_; + + out_data->payload_size = sizeof(struct drm_msm_pa_dither); + if (in_data.enable_flags_ & kOpsDisable) { + /* feature disable case */ + out_data->payload = NULL; + return ret; + } else if (!(in_data.enable_flags_ & kOpsEnable)) { + out_data->payload = NULL; + return kErrorParameters; + } + + sde_dither = (struct SDEPADitherData *)in_data.GetConfigData(); + if (sde_dither->matrix_size != DITHER_MATRIX_SZ) { + DLOGE("Invalid dither matrix size %d, exp sz %d", + sde_dither->matrix_size, DITHER_MATRIX_SZ); + return kErrorParameters; + } + + mdp_dither = new drm_msm_pa_dither(); + if (!mdp_dither) { + DLOGE("Failed to allocate memory for dither"); + return kErrorMemory; + } + + mdp_dither->flags = 0; + mdp_dither->strength = sde_dither->strength; + mdp_dither->offset_en = sde_dither->offset_en; + std::memcpy(&mdp_dither->matrix[0], + reinterpret_cast<void*>(sde_dither->matrix_data_addr), + sizeof(uint32_t) * DITHER_MATRIX_SZ); + out_data->payload = mdp_dither; #endif return ret; } diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp index d5bf482d..d28d911b 100644 --- a/sdm/libs/core/drm/hw_device_drm.cpp +++ b/sdm/libs/core/drm/hw_device_drm.cpp @@ -709,7 +709,7 @@ DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) { return kErrorNone; } -DisplayError HWDeviceDRM::PowerOn() { +DisplayError HWDeviceDRM::PowerOn(int *release_fence) { DTRACE_SCOPED(); if (!drm_atomic_intf_) { DLOGE("DRM Atomic Interface is null!"); @@ -727,6 +727,7 @@ DisplayError HWDeviceDRM::PowerOn() { DLOGE("Failed with error: %d", ret); return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); return kErrorNone; } @@ -750,7 +751,7 @@ DisplayError HWDeviceDRM::PowerOff() { return kErrorNone; } -DisplayError HWDeviceDRM::Doze() { +DisplayError HWDeviceDRM::Doze(int *release_fence) { DTRACE_SCOPED(); drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE); @@ -760,10 +761,12 @@ DisplayError HWDeviceDRM::Doze() { return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); + return kErrorNone; } -DisplayError HWDeviceDRM::DozeSuspend() { +DisplayError HWDeviceDRM::DozeSuspend(int *release_fence) { DTRACE_SCOPED(); drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, @@ -774,6 +777,8 @@ DisplayError HWDeviceDRM::DozeSuspend() { return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); + return kErrorNone; } diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h index 3af3b77d..a0f579d4 100644 --- a/sdm/libs/core/drm/hw_device_drm.h +++ b/sdm/libs/core/drm/hw_device_drm.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2018, 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 @@ -67,10 +67,10 @@ class HWDeviceDRM : public HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); - virtual DisplayError PowerOn(); + virtual DisplayError PowerOn(int *release_fence); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp index 245b5738..adf1f1ea 100644 --- a/sdm/libs/core/drm/hw_tv_drm.cpp +++ b/sdm/libs/core/drm/hw_tv_drm.cpp @@ -165,11 +165,11 @@ DisplayError HWTVDRM::PowerOff() { return kErrorNone; } -DisplayError HWTVDRM::Doze() { +DisplayError HWTVDRM::Doze(int *release_fence) { return kErrorNone; } -DisplayError HWTVDRM::DozeSuspend() { +DisplayError HWTVDRM::DozeSuspend(int *release_fence) { return kErrorNone; } diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h index 49384a2f..3e592f97 100644 --- a/sdm/libs/core/drm/hw_tv_drm.h +++ b/sdm/libs/core/drm/hw_tv_drm.h @@ -43,8 +43,8 @@ class HWTVDRM : public HWDeviceDRM { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Commit(HWLayers *hw_layers); virtual void PopulateHWPanelInfo(); diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp index 2c529ae0..1f733a04 100644 --- a/sdm/libs/core/fb/hw_device.cpp +++ b/sdm/libs/core/fb/hw_device.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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 @@ -155,7 +155,7 @@ DisplayError HWDevice::GetConfigIndex(char *mode, uint32_t *index) { return kErrorNone; } -DisplayError HWDevice::PowerOn() { +DisplayError HWDevice::PowerOn(int *release_fence) { DTRACE_SCOPED(); if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) { @@ -174,11 +174,11 @@ DisplayError HWDevice::PowerOff() { return kErrorNone; } -DisplayError HWDevice::Doze() { +DisplayError HWDevice::Doze(int *release_fence) { return kErrorNone; } -DisplayError HWDevice::DozeSuspend() { +DisplayError HWDevice::DozeSuspend(int *release_fence) { return kErrorNone; } diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h index f32c5bda..353cce5b 100644 --- a/sdm/libs/core/fb/hw_device.h +++ b/sdm/libs/core/fb/hw_device.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -70,10 +70,10 @@ class HWDevice : public HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); - virtual DisplayError PowerOn(); + virtual DisplayError PowerOn(int *release_fence); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp index 5ee81219..3f3c28e2 100644 --- a/sdm/libs/core/fb/hw_primary.cpp +++ b/sdm/libs/core/fb/hw_primary.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2015 - 2018, 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 @@ -344,7 +344,7 @@ DisplayError HWPrimary::PowerOff() { return kErrorNone; } -DisplayError HWPrimary::Doze() { +DisplayError HWPrimary::Doze(int *release_fence) { if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) { IOCTL_LOGE(FB_BLANK_NORMAL, device_type_); return kErrorHardware; @@ -353,7 +353,7 @@ DisplayError HWPrimary::Doze() { return kErrorNone; } -DisplayError HWPrimary::DozeSuspend() { +DisplayError HWPrimary::DozeSuspend(int *release_fence) { if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) { IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_); return kErrorHardware; diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h index 69b54452..c6ca5a98 100644 --- a/sdm/libs/core/fb/hw_primary.h +++ b/sdm/libs/core/fb/hw_primary.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +* Copyright (c) 2015-2016, 2018 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: @@ -46,8 +46,8 @@ class HWPrimary : public HWDevice { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); virtual void SetIdleTimeoutMs(uint32_t timeout_ms); diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h index 9bb825e8..483a4df4 100644 --- a/sdm/libs/core/hw_interface.h +++ b/sdm/libs/core/hw_interface.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2018, 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: @@ -85,10 +85,10 @@ class HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index) = 0; virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0; virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0; - virtual DisplayError PowerOn() = 0; + virtual DisplayError PowerOn(int *release_fence) = 0; virtual DisplayError PowerOff() = 0; - virtual DisplayError Doze() = 0; - virtual DisplayError DozeSuspend() = 0; + virtual DisplayError Doze(int *release_fence) = 0; + virtual DisplayError DozeSuspend(int *release_fence) = 0; virtual DisplayError Standby() = 0; virtual DisplayError Validate(HWLayers *hw_layers) = 0; virtual DisplayError Commit(HWLayers *hw_layers) = 0; diff --git a/sdm/libs/hwc2/display_null.cpp b/sdm/libs/hwc2/display_null.cpp index 16f4da66..7e52911c 100644 --- a/sdm/libs/hwc2/display_null.cpp +++ b/sdm/libs/hwc2/display_null.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2018, 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 @@ -50,7 +50,7 @@ DisplayError DisplayNull::GetDisplayState(DisplayState *state) { return kErrorNone; } -DisplayError DisplayNull::SetDisplayState(DisplayState state) { +DisplayError DisplayNull::SetDisplayState(DisplayState state, int *release_fence) { state_ = state; return kErrorNone; } diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h index f6c0ddaa..bd49a162 100644 --- a/sdm/libs/hwc2/display_null.h +++ b/sdm/libs/hwc2/display_null.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2018, 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 @@ -44,7 +44,7 @@ class DisplayNull : public DisplayInterface { virtual ~DisplayNull() { } virtual DisplayError Commit(LayerStack *layer_stack); virtual DisplayError GetDisplayState(DisplayState *state); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info); virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info); virtual bool IsUnderscanSupported() { return true; } diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp index d7514f1c..2cf9af1d 100644 --- a/sdm/libs/hwc2/hwc_display.cpp +++ b/sdm/libs/hwc2/hwc_display.cpp @@ -521,6 +521,7 @@ void HWCDisplay::BuildLayerStack() { } } + bool is_secure = false; const private_handle_t *handle = reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id); if (handle) { @@ -528,21 +529,17 @@ void HWCDisplay::BuildLayerStack() { layer_stack_.flags.video_present = true; } // TZ Protected Buffer - L1 - if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { - layer_stack_.flags.secure_present = true; - } // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback - if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) { + if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER || + handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { layer_stack_.flags.secure_present = true; + is_secure = true; } } - if (layer->flags.skip) { - layer_stack_.flags.skip_present = true; - } - if (layer->input_buffer.flags.secure_display) { secure_display_active = true; + is_secure = true; } if (hwc_layer->IsSingleBuffered() && @@ -568,6 +565,14 @@ void HWCDisplay::BuildLayerStack() { layer_stack_.flags.hdr_present = true; } + if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !hdr_layer) { + layer->flags.skip = true; + } + + if (layer->flags.skip) { + layer_stack_.flags.skip_present = true; + } + // TODO(user): Move to a getter if this is needed at other places hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top), INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)}; @@ -636,8 +641,6 @@ void HWCDisplay::BuildLayerStack() { } // set secure display SetSecureDisplay(secure_display_active); - - layer_stack_invalid_ = false; } void HWCDisplay::BuildSolidFillStack() { @@ -747,9 +750,10 @@ HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { default: return HWC2::Error::BadParameter; } + int release_fence = -1; ATRACE_INT("SetPowerMode ", state); - DisplayError error = display_intf_->SetDisplayState(state); + DisplayError error = display_intf_->SetDisplayState(state, &release_fence); validated_ = false; if (error == kErrorNone) { @@ -763,6 +767,20 @@ HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { return HWC2::Error::BadParameter; } + if (release_fence >= 0) { + for (auto hwc_layer : layer_set_) { + auto fence = hwc_layer->PopBackReleaseFence(); + auto merged_fence = -1; + if (fence >= 0) { + merged_fence = sync_merge("sync_merge", release_fence, fence); + ::close(fence); + } else { + merged_fence = ::dup(release_fence); + } + hwc_layer->PushBackReleaseFence(merged_fence); + } + ::close(release_fence); + } return HWC2::Error::None; } @@ -1001,7 +1019,17 @@ DisplayError HWCDisplay::CECMessage(char *message) { DisplayError HWCDisplay::HandleEvent(DisplayEvent event) { switch (event) { - case kIdleTimeout: + case kIdleTimeout: { + SCOPE_LOCK(HWCSession::locker_[type_]); + if (pending_commit_) { + // If idle timeout event comes in between prepare + // and commit, drop it since device is not really + // idle. + return kErrorNotSupported; + } + validated_ = false; + break; + } case kThermalEvent: case kIdlePowerCollapse: case kPanelDeadEvent: { @@ -1078,7 +1106,7 @@ HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out *out_num_requests = UINT32(layer_requests_.size()); validate_state_ = kNormalValidate; validated_ = true; - + layer_stack_invalid_ = false; return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None); } @@ -1138,7 +1166,7 @@ HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_ for (uint32_t i = 0; i < *out_num_elements; i++, it++) { auto hwc_layer = *it; out_layers[i] = hwc_layer->GetId(); - out_fences[i] = hwc_layer->PopReleaseFence(); + out_fences[i] = hwc_layer->PopFrontReleaseFence(); } } else { *out_num_elements = UINT32(layer_set_.size()); @@ -1305,15 +1333,15 @@ HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) { if (swap_interval_zero_ || layer->flags.single_buffer) { close(layer_buffer->release_fence_fd); } else if (layer->composition != kCompositionGPU) { - hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd); + hwc_layer->PushBackReleaseFence(layer_buffer->release_fence_fd); } else { - hwc_layer->PushReleaseFence(-1); + hwc_layer->PushBackReleaseFence(-1); } } else { // In case of flush, we don't return an error to f/w, so it will get a release fence out of // the hwc_layer's release fence queue. We should push a -1 to preserve release fence // circulation semantics. - hwc_layer->PushReleaseFence(-1); + hwc_layer->PushBackReleaseFence(-1); } layer_buffer->release_fence_fd = -1; diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h index e99ff658..f54572a0 100644 --- a/sdm/libs/hwc2/hwc_display.h +++ b/sdm/libs/hwc2/hwc_display.h @@ -318,6 +318,7 @@ class HWCDisplay : public DisplayEventHandler { int disable_hdr_handling_ = 0; // disables HDR handling. uint32_t display_config_ = 0; bool config_pending_ = false; + bool pending_commit_ = false; private: void DumpInputBuffers(void); diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp index 8e00cfda..45ed8919 100644 --- a/sdm/libs/hwc2/hwc_display_external.cpp +++ b/sdm/libs/hwc2/hwc_display_external.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014-2018, 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 @@ -127,6 +127,7 @@ HWC2::Error HWCDisplayExternal::Validate(uint32_t *out_num_types, uint32_t *out_ if (layer_set_.empty()) { flush_ = true; + validated_ = true; return status; } @@ -238,9 +239,12 @@ int HWCDisplayExternal::SetState(bool connected) { DLOGW("Set frame buffer config failed. Error = %d", error); return -1; } - + int release_fence = -1; display_null_.GetDisplayState(&state); - display_intf_->SetDisplayState(state); + display_intf_->SetDisplayState(state, &release_fence); + if (release_fence >= 0) { + ::close(release_fence); + } validated_ = false; SetVsyncEnabled(HWC2::Vsync::Enable); @@ -252,10 +256,14 @@ int HWCDisplayExternal::SetState(bool connected) { } } else { if (!display_null_.IsActive()) { + int release_fence = -1; // Preserve required attributes of HDMI display that surfaceflinger sees. // Restore HDMI attributes when display is reconnected. display_intf_->GetDisplayState(&state); - display_null_.SetDisplayState(state); + display_null_.SetDisplayState(state, &release_fence); + if (release_fence >= 0) { + ::close(release_fence); + } error = display_intf_->GetFrameBufferConfig(&fb_config); if (error != kErrorNone) { diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp index 531f2093..6149831d 100644 --- a/sdm/libs/hwc2/hwc_display_primary.cpp +++ b/sdm/libs/hwc2/hwc_display_primary.cpp @@ -223,6 +223,7 @@ HWC2::Error HWCDisplayPrimary::Validate(uint32_t *out_num_types, uint32_t *out_n } status = PrepareLayerStack(out_num_types, out_num_requests); + pending_commit_ = true; return status; } @@ -245,7 +246,7 @@ HWC2::Error HWCDisplayPrimary::Present(int32_t *out_retire_fence) { status = HWCDisplay::PostCommitLayerStack(out_retire_fence); } } - + pending_commit_ = false; return status; } diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp index daaf0fda..4250335e 100644 --- a/sdm/libs/hwc2/hwc_layers.cpp +++ b/sdm/libs/hwc2/hwc_layers.cpp @@ -170,14 +170,14 @@ HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator) layer_ = new Layer(); // Fences are deferred, so the first time this layer is presented, return -1 // TODO(user): Verify that fences are properly obtained on suspend/resume - release_fences_.push(-1); + release_fences_.push_back(-1); } HWCLayer::~HWCLayer() { // Close any fences left for this layer while (!release_fences_.empty()) { ::close(release_fences_.front()); - release_fences_.pop(); + release_fences_.pop_front(); } if (layer_) { if (layer_->input_buffer.acquire_fence_fd >= 0) { @@ -435,6 +435,10 @@ HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) { HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) { LayerRect src_rect = {}; SetRect(crop, &src_rect); + non_integral_source_crop_ = ((crop.left != roundf(crop.left)) || + (crop.top != roundf(crop.top)) || + (crop.right != roundf(crop.right)) || + (crop.bottom != roundf(crop.bottom))); if (layer_->src_rect != src_rect) { geometry_changes_ |= kSourceCrop; layer_->src_rect = src_rect; @@ -886,14 +890,28 @@ void HWCLayer::SetComposition(const LayerComposition &sdm_composition) { return; } -void HWCLayer::PushReleaseFence(int32_t fence) { - release_fences_.push(fence); + +void HWCLayer::PushBackReleaseFence(int32_t fence) { + release_fences_.push_back(fence); } -int32_t HWCLayer::PopReleaseFence(void) { + +int32_t HWCLayer::PopBackReleaseFence() { if (release_fences_.empty()) return -1; + + auto fence = release_fences_.back(); + release_fences_.pop_back(); + + return fence; +} + +int32_t HWCLayer::PopFrontReleaseFence() { + if (release_fences_.empty()) + return -1; + auto fence = release_fences_.front(); - release_fences_.pop(); + release_fences_.pop_front(); + return fence; } diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h index ed03c50c..92267445 100644 --- a/sdm/libs/hwc2/hwc_layers.h +++ b/sdm/libs/hwc2/hwc_layers.h @@ -32,7 +32,7 @@ #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 #include <map> -#include <queue> +#include <deque> #include <set> #include "core/buffer_allocator.h" #include "hwc_buffer_allocator.h" @@ -88,8 +88,9 @@ class HWCLayer { int32_t GetLayerDataspace() { return dataspace_; } uint32_t GetGeometryChanges() { return geometry_changes_; } void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; } - void PushReleaseFence(int32_t fence); - int32_t PopReleaseFence(void); + void PushBackReleaseFence(int32_t fence); + int32_t PopBackReleaseFence(void); + int32_t PopFrontReleaseFence(void); bool ValidateAndSetCSC(); bool SupportLocalConversion(ColorPrimaries working_primaries); void ResetValidation() { needs_validate_ = false; } @@ -97,6 +98,7 @@ class HWCLayer { bool IsSingleBuffered() { return single_buffer_; } bool IsScalingPresent(); bool IsRotationPresent(); + bool IsNonIntegralSourceCrop() { return non_integral_source_crop_; } private: Layer *layer_ = nullptr; @@ -104,7 +106,7 @@ class HWCLayer { const hwc2_layer_t id_; const hwc2_display_t display_id_; static std::atomic<hwc2_layer_t> next_id_; - std::queue<int32_t> release_fences_; + std::deque<int32_t> release_fences_; HWCBufferAllocator *buffer_allocator_ = NULL; int32_t dataspace_ = HAL_DATASPACE_UNKNOWN; LayerTransform layer_transform_ = {}; @@ -112,6 +114,7 @@ class HWCLayer { bool needs_validate_ = true; bool single_buffer_ = false; int buffer_fd_ = -1; + bool non_integral_source_crop_ = false; // Composition requested by client(SF) HWC2::Composition client_requested_ = HWC2::Composition::Device; diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index aae91301..11ecb2ec 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -72,6 +72,7 @@ namespace sdm { static HWCUEvent g_hwc_uevent_; Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES]; +static const int kSolidFillDelay = 100 * 1000; void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) { const char *uevent_thread_name = "HWC_UeventThread"; @@ -1502,14 +1503,22 @@ android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]); break; case kApplySolidFill: - ret = color_mgr_->SetSolidFill(pending_action.params, + { + SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); + ret = color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]); + } Refresh(HWC_DISPLAY_PRIMARY); + usleep(kSolidFillDelay); break; case kDisableSolidFill: - ret = color_mgr_->SetSolidFill(pending_action.params, + { + SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); + ret = color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]); + } Refresh(HWC_DISPLAY_PRIMARY); + usleep(kSolidFillDelay); break; case kSetPanelBrightness: brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload); diff --git a/sdm/libs/hwc2/hwc_tonemapper.cpp b/sdm/libs/hwc2/hwc_tonemapper.cpp index 26caec9b..2ae1afc1 100644 --- a/sdm/libs/hwc2/hwc_tonemapper.cpp +++ b/sdm/libs/hwc2/hwc_tonemapper.cpp @@ -146,22 +146,22 @@ void ToneMapSession::SetReleaseFence(int fd) { release_fence_fd_[current_buffer_index_] = dup(fd); } -void ToneMapSession::SetToneMapConfig(Layer *layer) { +void ToneMapSession::SetToneMapConfig(Layer *layer, PrimariesTransfer blend_cs) { // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; - tone_map_config_.colorPrimaries = layer->input_buffer.color_metadata.colorPrimaries; + tone_map_config_.blend_cs = blend_cs; tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer; tone_map_config_.secure = layer->request.flags.secure; tone_map_config_.format = layer->request.format; } -bool ToneMapSession::IsSameToneMapConfig(Layer *layer) { +bool ToneMapSession::IsSameToneMapConfig(Layer *layer, PrimariesTransfer blend_cs) { LayerBuffer& buffer = layer->input_buffer; private_handle_t *handle = static_cast<private_handle_t *>(buffer_info_[0].private_data); int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; return ((tonemap_type == tone_map_config_.type) && - (buffer.color_metadata.colorPrimaries == tone_map_config_.colorPrimaries) && + (blend_cs == tone_map_config_.blend_cs) && (buffer.color_metadata.transfer == tone_map_config_.transfer) && (layer->request.flags.secure == tone_map_config_.secure) && (layer->request.format == tone_map_config_.format) && @@ -197,11 +197,11 @@ int HWCToneMapper::HandleToneMap(LayerStack *layer_stack) { return 0; } } - error = AcquireToneMapSession(layer, &session_index); + error = AcquireToneMapSession(layer, &session_index, layer_stack->blend_cs); fb_session_index_ = INT(session_index); break; default: - error = AcquireToneMapSession(layer, &session_index); + error = AcquireToneMapSession(layer, &session_index, layer_stack->blend_cs); break; } @@ -331,7 +331,8 @@ void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) CloseFd(acquire_fd); } -DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) { +DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index, + PrimariesTransfer blend_cs) { // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut // for Tonemapping. @@ -344,7 +345,7 @@ DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *sessio // Check if we can re-use an existing tone map session. for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) { ToneMapSession *tonemap_session = tone_map_sessions_.at(i); - if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer)) { + if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer, blend_cs)) { tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) % ToneMapSession::kNumIntermediateBuffers; tonemap_session->acquired_ = true; @@ -358,7 +359,7 @@ DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *sessio return kErrorMemory; } - session->SetToneMapConfig(layer); + session->SetToneMapConfig(layer, blend_cs); ToneMapGetInstanceContext ctx; ctx.layer = layer; diff --git a/sdm/libs/hwc2/hwc_tonemapper.h b/sdm/libs/hwc2/hwc_tonemapper.h index 8bef3b1f..e400d293 100644 --- a/sdm/libs/hwc2/hwc_tonemapper.h +++ b/sdm/libs/hwc2/hwc_tonemapper.h @@ -64,7 +64,7 @@ struct ToneMapBlitContext : public SyncTask<ToneMapTaskCode>::TaskContext { struct ToneMapConfig { int type = 0; - ColorPrimaries colorPrimaries = ColorPrimaries_Max; + PrimariesTransfer blend_cs = {ColorPrimaries_BT709_5, Transfer_sRGB}; GammaTransfer transfer = Transfer_Max; LayerBufferFormat format = kFormatRGBA8888; bool secure = false; @@ -78,8 +78,8 @@ class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler { void FreeIntermediateBuffers(); void UpdateBuffer(int acquire_fence, LayerBuffer *buffer); void SetReleaseFence(int fd); - void SetToneMapConfig(Layer *layer); - bool IsSameToneMapConfig(Layer *layer); + void SetToneMapConfig(Layer *layer, PrimariesTransfer blend_cs); + bool IsSameToneMapConfig(Layer *layer, PrimariesTransfer blend_cs); // TaskHandler methods implementation. virtual void OnTask(const ToneMapTaskCode &task_code, @@ -110,7 +110,7 @@ class HWCToneMapper { private: void ToneMap(Layer *layer, ToneMapSession *session); - DisplayError AcquireToneMapSession(Layer *layer, uint32_t *session_index); + DisplayError AcquireToneMapSession(Layer *layer, uint32_t *sess_idx, PrimariesTransfer blend_cs); void DumpToneMapOutput(ToneMapSession *session, int *acquire_fence); std::vector<ToneMapSession*> tone_map_sessions_; |