msm8998: Update to LA.UM.5.7.R1.07.00.00.253.052
msm8998: from hardware/qcom/display11f3152
Merge AU_LINUX_ANDROID_LA.UM.5.7.R1.07.00.00.253.042 on remote branchc8edaff
Promotion of display.lnx.3.0-00073.4b9f87f
sdm: Fix infinite frame invalidates during camera bandwidth mode change. During camera bandwidth mode change, need_invalidate is set to true for to request new draw cycles to allow new bandwidth mode to take effect. This variable is not reset after mode is changed.fcd4ec5
Merge "sdm: Enable autorefresh only one single buffer layer is present"d92bdf3
Merge "sdm: Fix Map rect for offset in source domain"982952a
Merge "sdm: Multi rect partial update changes"1e4ca32
Merge "hwc1: Add support for getHdrCapabilities"6abdf82
Promotion of display.lnx.3.0-00070.c906e98
sdm: Enable autorefresh only one single buffer layer is presentb82c9a0
sdm: Fix partial update control in display mode switch6064cad
sdm: Fix Map rect for offset in source domain48a392c
hwc1: Add support for getHdrCapabilities5036d3d
hwc2: Protect AcceptDisplayChanges with the hwc session lock249e03b
sdm: Multi rect partial update changesbce1d81
Merge "sdm: Issue two null commits for command mode panels"c41e42c
sdm: Issue two null commits for command mode panelsebf4a0d
hwc2: Fix missing unaligned width settingecf1b50
sdm: color-manager: Detail Enhancer Enhancements.b2771bf
display: Add color Metadata8b3dddc
Merge "sdm : Allow configurable sdm layer limit for external"770e328
Merge "HWC: Set skip to layers with Non Integral Source Crop"e78a97f
Merge "gralloc: Return an error if the buffer was not mapped"a61a5f8
sdm : Allow configurable sdm layer limit for externaldebd5ce
gralloc: Return an error if the buffer was not mappeda9f9000
HWC: Set skip to layers with Non Integral Source Crop Bug: 33556391 Change-Id: If1886c87a823d583e5cec891468f5e2e2199d607 Signed-off-by: Thierry Strudel <tstrudel@google.com>
This commit is contained in:
parent
a558e9f988
commit
d62c8a289f
|
@ -1,5 +1,5 @@
|
|||
sdm-libs := sdm/libs
|
||||
display-hals := libqservice libqdutils $(sdm-libs)/utils $(sdm-libs)/core
|
||||
display-hals := include libqservice libqdutils $(sdm-libs)/utils $(sdm-libs)/core
|
||||
|
||||
ifneq ($(TARGET_IS_HEADLESS), true)
|
||||
display-hals += libcopybit liblight libmemtrack hdmi_cec \
|
||||
|
|
|
@ -5,6 +5,10 @@ display_top := $(call my-dir)
|
|||
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
|
||||
common_flags += -Wconversion -Wall -Werror -std=c++11
|
||||
|
||||
ifeq ($(call is-board-platform-in-list, msmcobalt msm8998), true)
|
||||
common_flags += -DUSE_COLOR_METADATA
|
||||
endif
|
||||
|
||||
use_hwc2 := false
|
||||
ifeq ($(TARGET_USES_HWC2), true)
|
||||
use_hwc2 := true
|
||||
|
@ -17,6 +21,7 @@ ifneq ($(TARGET_IS_HEADLESS), true)
|
|||
common_includes += $(display_top)/libcopybit
|
||||
endif
|
||||
|
||||
common_includes += $(display_top)/include
|
||||
common_includes += $(display_top)/sdm/include
|
||||
|
||||
common_header_export_path := qcom/display
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(LOCAL_PATH)/../common.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
|
||||
LOCAL_COPY_HEADERS := color_metadata.h
|
||||
|
||||
include $(BUILD_COPY_HEADERS)
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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 __COLOR_METADATA_H__
|
||||
#define __COLOR_METADATA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
typedef enum ColorRange {
|
||||
Range_Limited = 0,
|
||||
Range_Full = 1,
|
||||
Range_Max = 0xff,
|
||||
} ColorRange;
|
||||
|
||||
// The following values matches the HEVC spec
|
||||
typedef enum ColorPrimaries {
|
||||
// Unused = 0;
|
||||
ColorPrimaries_BT709_5 = 1, // ITU-R BT.709-5 or equivalent
|
||||
/* Unspecified = 2, Reserved = 3*/
|
||||
ColorPrimaries_BT470_6M = 4, // ITU-R BT.470-6 System M or equivalent
|
||||
ColorPrimaries_BT601_6_625 = 5, // ITU-R BT.601-6 625 or equivalent
|
||||
ColorPrimaries_BT601_6_525 = 6, // ITU-R BT.601-6 525 or equivalent
|
||||
ColorPrimaries_SMPTE_240M = 7, // SMPTE_240M
|
||||
ColorPrimaries_GenericFilm = 8, // Generic Film
|
||||
ColorPrimaries_BT2020 = 9, // ITU-R BT.2020 or equivalent
|
||||
ColorPrimaries_SMPTE_ST428 = 10, // SMPTE_240M
|
||||
ColorPrimaries_AdobeRGB = 11,
|
||||
ColorPrimaries_DCIP3 = 12,
|
||||
ColorPrimaries_Max = 0xff,
|
||||
} ColorPrimaries;
|
||||
|
||||
typedef enum GammaTransfer {
|
||||
// Unused = 0;
|
||||
Transfer_sRGB = 1, // ITR-BT.709-5
|
||||
/* Unspecified = 2, Reserved = 3 */
|
||||
Transfer_Gamma2_2 = 4,
|
||||
Transfer_Gamma2_8 = 5,
|
||||
Transfer_SMPTE_170M = 6, // BT.601-6 525 or 625
|
||||
Transfer_SMPTE_240M = 7, // SMPTE_240M
|
||||
Transfer_Linear = 8,
|
||||
Transfer_HLG = 9,
|
||||
Transfer_XvYCC = 11, // IEC 61966-2-4
|
||||
Transfer_BT1361 = 12, // Rec.ITU-R BT.1361 extended gamut
|
||||
Transfer_SMPTE_ST2084 = 16, // 2084
|
||||
// transfers unlikely to be required by Android
|
||||
Transfer_ST_428 = 17, // SMPTE ST 428-1
|
||||
Transfer_Max = 0xff,
|
||||
} GammaTransfer;
|
||||
|
||||
typedef enum MatrixCoEfficients {
|
||||
MatrixCoEff_Identity = 0,
|
||||
MatrixCoEff_BT709_5 = 1,
|
||||
/* Unspecified = 2, Reserved = 3 */
|
||||
MatrixCoEff_BT601_6_625 = 5,
|
||||
MatrixCoEff_BT601_6_525 = 6,
|
||||
MatrixCoEff_SMPTE240M = 7, // used with 601_525_Unadjusted
|
||||
MatrixCoEff_BT2020 = 9,
|
||||
MatrixCoEff_BT2020Constant = 10,
|
||||
MatrixCoEff_BT601_6_Unadjusted = 11, // Used with BT601_625(KR=0.222, KB=0.071)
|
||||
MatrixCoEff_DCIP3 = 12,
|
||||
MatrixCoEff_Max = 0xff,
|
||||
} MatrixCoEfficients;
|
||||
|
||||
typedef struct Primaries {
|
||||
uint32_t rgbPrimaries[3][2]; // unit 1/50000;
|
||||
uint32_t whitePoint[2]; // unit 1/50000;
|
||||
} Primaries;
|
||||
|
||||
typedef struct MasteringDisplay {
|
||||
bool colorVolumeSEIEnabled;
|
||||
Primaries primaries;
|
||||
uint32_t maxDisplayLuminance; // unit: cd/m^2.
|
||||
uint32_t minDisplayLuminance; // unit: 1/10000 cd/m^2.
|
||||
} MasteringDisplay;
|
||||
|
||||
typedef struct ContentLightLevel {
|
||||
bool lightLevelSEIEnabled;
|
||||
uint32_t maxContentLightLevel; // unit: cd/m^2.
|
||||
uint32_t minPicAverageLightLevel; // unit: 1/10000 cd/m^2.
|
||||
} ContentLightLevel;
|
||||
|
||||
typedef struct ColorRemappingInfo {
|
||||
bool criEnabled;
|
||||
uint32_t crId;
|
||||
uint32_t crCancelFlag;
|
||||
uint32_t crPersistenceFlag;
|
||||
uint32_t crVideoSignalInfoPresentFlag;
|
||||
uint32_t crRange;
|
||||
ColorPrimaries crPrimaries;
|
||||
GammaTransfer crTransferFunction;
|
||||
MatrixCoEfficients crMatrixCoefficients;
|
||||
uint32_t crInputBitDepth;
|
||||
uint32_t crOutputBitDepth;
|
||||
uint32_t crPreLutNumValMinusOne[3];
|
||||
uint32_t crPreLutCodedValue[3*33];
|
||||
uint32_t crPreLutTargetValue[3*33];
|
||||
uint32_t crMatrixPresentFlag;
|
||||
uint32_t crLog2MatrixDenom;
|
||||
int32_t crCoefficients[3*3];
|
||||
uint32_t crPostLutNumValMinusOne[3];
|
||||
uint32_t crPostLutCodedValue[3*33];
|
||||
uint32_t crPostLutTargetValue[3*33];
|
||||
} ColorRemappingInfo;
|
||||
|
||||
typedef struct ColorMetaData {
|
||||
// Default values based on sRGB, needs to be overridden in gralloc
|
||||
// based on the format and size.
|
||||
ColorPrimaries colorPrimaries;
|
||||
ColorRange range;
|
||||
GammaTransfer transfer;
|
||||
MatrixCoEfficients matrixCoefficients;
|
||||
|
||||
MasteringDisplay masteringDisplayInfo;
|
||||
ContentLightLevel contentLightLevel;
|
||||
ColorRemappingInfo cRI;
|
||||
} ColorMetaData;
|
||||
|
||||
typedef struct Color10Bit {
|
||||
uint32_t R: 10;
|
||||
uint32_t G: 10;
|
||||
uint32_t B: 10;
|
||||
uint32_t A: 2;
|
||||
} Color10Bit;
|
||||
|
||||
typedef struct Lut3d {
|
||||
uint16_t dim; // dimension of each side of LUT cube (ex: 13, 17)in lutEntries
|
||||
uint16_t gridSize; // number of elements in the gridEntries
|
||||
/* Matrix ordering convension
|
||||
for (b = 0; b < dim; b++) {
|
||||
for (g = 0; g < dim; g++) {
|
||||
for (r = 0; r < dim; r++) {
|
||||
read/write [mR mG mB] associated w/ 3DLUT[r][g][b] to/from file
|
||||
}
|
||||
}
|
||||
} */
|
||||
Color10Bit *lutEntries;
|
||||
bool validLutEntries; // Indicates if entries are valid and can be used.
|
||||
/*
|
||||
The grid is a 1D LUT for each of the R,G,B channels that can be
|
||||
used to apply an independent nonlinear transformation to each
|
||||
channel before it is used as a coordinate for addressing
|
||||
the uniform 3D LUT. This effectively creates a non-uniformly
|
||||
sampled 3D LUT. This is useful for having independent control
|
||||
of the sampling grid density along each dimension for greater
|
||||
precision in spite of having a relatively small number of samples.i
|
||||
*/
|
||||
Color10Bit *gridEntries;
|
||||
bool validGridEntries; // Indicates if entries are valid and can be used.
|
||||
} Lut3d;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __COLOR_METADATA_H__
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -55,6 +55,27 @@ static IMemAlloc* getAllocator(int flags)
|
|||
return memalloc;
|
||||
}
|
||||
|
||||
static int gralloc_map_metadata(buffer_handle_t handle) {
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
hnd->base_metadata = 0;
|
||||
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
|
||||
void *mappedAddress = MAP_FAILED;
|
||||
unsigned int size = 0;
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
mappedAddress = MAP_FAILED;
|
||||
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
|
||||
int ret = memalloc->map_buffer(&mappedAddress, size,
|
||||
hnd->offset_metadata, hnd->fd_metadata);
|
||||
if(ret || mappedAddress == MAP_FAILED) {
|
||||
ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
|
||||
hnd, hnd->fd_metadata, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gralloc_map(gralloc_module_t const* module,
|
||||
buffer_handle_t handle)
|
||||
{
|
||||
|
@ -68,7 +89,6 @@ static int gralloc_map(gralloc_module_t const* module,
|
|||
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
|
||||
void *mappedAddress = MAP_FAILED;
|
||||
hnd->base = 0;
|
||||
hnd->base_metadata = 0;
|
||||
|
||||
// Dont map framebuffer and secure buffers
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
|
||||
|
@ -83,23 +103,21 @@ static int gralloc_map(gralloc_module_t const* module,
|
|||
}
|
||||
|
||||
hnd->base = uint64_t(mappedAddress) + hnd->offset;
|
||||
} else {
|
||||
// Cannot map secure buffers or framebuffers, but still need to map
|
||||
// metadata for secure buffers.
|
||||
// If mapping a secure buffers fails, the framework needs to get
|
||||
// an error code.
|
||||
err = -EACCES;
|
||||
}
|
||||
|
||||
//Allow mapping of metadata for all buffers including secure ones, but not
|
||||
//of framebuffer
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
mappedAddress = MAP_FAILED;
|
||||
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
|
||||
err = memalloc->map_buffer(&mappedAddress, size,
|
||||
hnd->offset_metadata, hnd->fd_metadata);
|
||||
if(err || mappedAddress == MAP_FAILED) {
|
||||
ALOGE("Could not mmap handle %p, fd=%d (%s)",
|
||||
handle, hnd->fd_metadata, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
|
||||
int metadata_err = gralloc_map_metadata(handle);
|
||||
if (!err) {
|
||||
err = metadata_err;
|
||||
}
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gralloc_unmap(gralloc_module_t const* module,
|
||||
|
@ -153,20 +171,11 @@ int gralloc_register_buffer(gralloc_module_t const* module,
|
|||
if (!module || private_handle_t::validate(handle) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* NOTE: we need to initialize the buffer as not mapped/not locked
|
||||
* because it shouldn't when this function is called the first time
|
||||
* in a new process. Ideally these flags shouldn't be part of the
|
||||
* handle, but instead maintained in the kernel or at least
|
||||
* out-of-line
|
||||
*/
|
||||
|
||||
int err = gralloc_map(module, handle);
|
||||
if (err) {
|
||||
ALOGE("%s: gralloc_map failed", __FUNCTION__);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
int err = gralloc_map(module, handle);
|
||||
/* Do not fail register_buffer for secure buffers*/
|
||||
if (err == -EACCES)
|
||||
err = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
int gralloc_unregister_buffer(gralloc_module_t const* module,
|
||||
|
@ -403,7 +412,30 @@ int gralloc_perform(struct gralloc_module_t const* module,
|
|||
return res;
|
||||
}
|
||||
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
|
||||
if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
|
||||
if (!metadata) {
|
||||
break;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
} else if (metadata->operation & COLOR_METADATA) {
|
||||
ColorMetaData *colorMetadata = &metadata->color;
|
||||
res = 0;
|
||||
switch (colorMetadata->colorPrimaries) {
|
||||
case ColorPrimaries_BT709_5:
|
||||
*color_space = HAL_CSC_ITU_R_709;
|
||||
break;
|
||||
case ColorPrimaries_BT601_6_525:
|
||||
*color_space = ((colorMetadata->range) ?
|
||||
HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
|
||||
break;
|
||||
case ColorPrimaries_BT2020:
|
||||
*color_space = (colorMetadata->range) ?
|
||||
HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
|
||||
break;
|
||||
default:
|
||||
res = -EINVAL;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} else if(metadata->operation & UPDATE_COLOR_SPACE) {
|
||||
*color_space = metadata->colorSpace;
|
||||
res = 0;
|
||||
}
|
||||
|
|
|
@ -588,7 +588,27 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
|
||||
if (metadata && metadata->operation & UPDATE_COLOR_SPACE) {
|
||||
if (!metadata) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
} else if (metadata->operation & COLOR_METADATA) {
|
||||
ColorMetaData *colorMetadata = &metadata->color;
|
||||
switch (colorMetadata->colorPrimaries) {
|
||||
case ColorPrimaries_BT709_5:
|
||||
*color_space = HAL_CSC_ITU_R_709;
|
||||
break;
|
||||
case ColorPrimaries_BT601_6_525:
|
||||
*color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
|
||||
break;
|
||||
case ColorPrimaries_BT2020:
|
||||
*color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} else if (metadata->operation & UPDATE_COLOR_SPACE) {
|
||||
*color_space = metadata->colorSpace;
|
||||
}
|
||||
} break;
|
||||
|
|
|
@ -95,6 +95,11 @@ int setMetaData(private_handle_t *handle, DispParamType paramType,
|
|||
case SET_VT_TIMESTAMP:
|
||||
data->vtTimeStamp = *((uint64_t *)param);
|
||||
break;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
case COLOR_METADATA:
|
||||
data->color = *((ColorMetaData *)param);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ALOGE("Unknown paramType %d", paramType);
|
||||
break;
|
||||
|
@ -196,6 +201,11 @@ int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
|
|||
case GET_VT_TIMESTAMP:
|
||||
*((uint64_t *)param) = data->vtTimeStamp;
|
||||
break;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
case GET_COLOR_METADATA:
|
||||
*((ColorMetaData *)param) = data->color;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ALOGE("Unknown paramType %d", paramType);
|
||||
break;
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#ifndef _QDMETADATA_H
|
||||
#define _QDMETADATA_H
|
||||
|
||||
#ifdef USE_COLOR_METADATA
|
||||
#include <color_metadata.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -91,11 +95,15 @@ struct MetaData_t {
|
|||
|
||||
/* Set by camera to program the VT Timestamp */
|
||||
uint64_t vtTimeStamp;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
/* Color Aspects + HDR info */
|
||||
ColorMetaData color;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum DispParamType {
|
||||
SET_VT_TIMESTAMP = 0x0001,
|
||||
UNUSED1 = 0x0002,
|
||||
COLOR_METADATA = 0x0002,
|
||||
PP_PARAM_INTERLACED = 0x0004,
|
||||
UNUSED2 = 0x0008,
|
||||
UNUSED3 = 0x0010,
|
||||
|
@ -114,6 +122,7 @@ enum DispParamType {
|
|||
|
||||
enum DispFetchParamType {
|
||||
GET_VT_TIMESTAMP = 0x0001,
|
||||
GET_COLOR_METADATA = 0x0002,
|
||||
GET_PP_PARAM_INTERLACED = 0x0004,
|
||||
GET_BUFFER_GEOMETRY = 0x0080,
|
||||
GET_REFRESH_RATE = 0x0100,
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
|
||||
SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
|
||||
SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
|
||||
GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
|
||||
COMMAND_LIST_END = 400,
|
||||
};
|
||||
|
||||
|
|
|
@ -238,6 +238,7 @@ struct PPDETuningCfg {
|
|||
struct PPDETuningCfgData {
|
||||
uint32_t cfg_en = 0;
|
||||
PPDETuningCfg params;
|
||||
bool cfg_pending = false;
|
||||
};
|
||||
|
||||
struct SDEGamutCfg {
|
||||
|
|
|
@ -58,8 +58,8 @@ class ExtensionInterface {
|
|||
PartialUpdateInterface **interface) = 0;
|
||||
virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
|
||||
|
||||
virtual DisplayError CreateStrategyExtn(DisplayType type, HWDisplayMode mode,
|
||||
HWS3DMode s3d_mode,
|
||||
virtual DisplayError CreateStrategyExtn(DisplayType type, const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info,
|
||||
const HWMixerAttributes &mixer_attributes,
|
||||
const DisplayConfigVariableInfo &fb_config,
|
||||
StrategyInterface **interface) = 0;
|
||||
|
|
|
@ -236,6 +236,8 @@ struct HWPanelInfo {
|
|||
char panel_name[256] = {0}; // Panel name
|
||||
HWS3DMode s3d_mode = kS3DModeNone; // Panel's current s3d mode.
|
||||
int panel_max_brightness = 0; // Max panel brightness
|
||||
uint32_t left_roi_count = 1; // Number if ROI supported on left panel
|
||||
uint32_t right_roi_count = 1; // Number if ROI supported on right panel
|
||||
|
||||
bool operator !=(const HWPanelInfo &panel_info) {
|
||||
return ((port != panel_info.port) || (mode != panel_info.mode) ||
|
||||
|
@ -249,8 +251,9 @@ struct HWPanelInfo {
|
|||
(dfps_porch_mode != panel_info.dfps_porch_mode) ||
|
||||
(ping_pong_split != panel_info.ping_pong_split) ||
|
||||
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||
(split_info != panel_info.split_info) ||
|
||||
(s3d_mode != panel_info.s3d_mode));
|
||||
(split_info != panel_info.split_info) || (s3d_mode != panel_info.s3d_mode) ||
|
||||
(left_roi_count != panel_info.left_roi_count) ||
|
||||
(right_roi_count != panel_info.right_roi_count));
|
||||
}
|
||||
|
||||
bool operator ==(const HWPanelInfo &panel_info) {
|
||||
|
@ -431,13 +434,16 @@ struct HWLayersInfo {
|
|||
LayerRect updated_src_rect[kMaxSDELayers]; // Updated layer src rects in s3d mode
|
||||
LayerRect updated_dst_rect[kMaxSDELayers]; // Updated layer dst rects in s3d mode
|
||||
bool updating[kMaxSDELayers] = {0}; // Updated by strategy, considering plane_alpha+updating
|
||||
uint32_t roi_index[kMaxSDELayers] = {0}; // Stores the ROI index where the layers are visible.
|
||||
|
||||
uint32_t count = 0; // Total number of layers which need to be set on hardware.
|
||||
|
||||
int sync_handle = -1;
|
||||
|
||||
LayerRect left_partial_update; // Left ROI.
|
||||
LayerRect right_partial_update; // Right ROI.
|
||||
std::vector<LayerRect> left_frame_roi; // Left ROI.
|
||||
std::vector<LayerRect> right_frame_roi; // Right ROI.
|
||||
|
||||
bool roi_split = false; // Indicates separated left and right ROI
|
||||
|
||||
bool use_hw_cursor = false; // Indicates that HWCursor pipe needs to be used for cursor layer
|
||||
DestScaleInfoMap dest_scale_info_map = {};
|
||||
|
|
|
@ -48,7 +48,8 @@ class StrategyInterface {
|
|||
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
|
||||
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
|
||||
virtual DisplayError Stop() = 0;
|
||||
virtual DisplayError Reconfigure(HWDisplayMode mode, HWS3DMode s3d_mode,
|
||||
virtual DisplayError Reconfigure(const HWPanelInfo &hw_panel_info,
|
||||
const HWResourceInfo &hw_res_info,
|
||||
const HWMixerAttributes &mixer_attributes,
|
||||
const DisplayConfigVariableInfo &fb_config) = 0;
|
||||
virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
|
||||
|
|
|
@ -78,6 +78,7 @@ class Debug {
|
|||
static bool IsAVRDisabled();
|
||||
static bool IsExtAnimDisabled();
|
||||
static DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
|
||||
static int GetExtMaxlayers();
|
||||
static bool GetProperty(const char *property_name, char *value);
|
||||
static bool SetProperty(const char *property_name, const char *value);
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ DisplayError CompManager::RegisterDisplay(DisplayType type,
|
|||
// resources for the added display is configured properly.
|
||||
if (!display_comp_ctx->is_primary_panel) {
|
||||
safe_mode_ = true;
|
||||
max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
|
||||
|
@ -213,7 +214,7 @@ void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_la
|
|||
|
||||
// Limit 2 layer SDE Comp if its not a Primary Display
|
||||
if (!display_comp_ctx->is_primary_panel) {
|
||||
constraints->max_layers = 2;
|
||||
constraints->max_layers = max_sde_ext_layers_;
|
||||
}
|
||||
|
||||
// If a strategy fails after successfully allocating resources, then set safe mode
|
||||
|
|
|
@ -106,6 +106,7 @@ class CompManager : public DumpImpl {
|
|||
HWResourceInfo hw_res_info_;
|
||||
ExtensionInterface *extension_intf_ = NULL;
|
||||
uint32_t max_layers_ = kMaxSDELayers;
|
||||
uint32_t max_sde_ext_layers_ = 0;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -518,14 +518,17 @@ void DisplayBase::AppendDump(char *buffer, uint32_t length) {
|
|||
DumpImpl::AppendString(buffer, length, "\n");
|
||||
|
||||
HWLayersInfo &layer_info = hw_layers_.info;
|
||||
LayerRect &l_roi = layer_info.left_partial_update;
|
||||
LayerRect &r_roi = layer_info.right_partial_update;
|
||||
DumpImpl::AppendString(buffer, length, "\nROI(L T R B) : LEFT(%d %d %d %d)", INT(l_roi.left),
|
||||
INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
|
||||
|
||||
if (IsValid(r_roi)) {
|
||||
DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
|
||||
INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
|
||||
for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
|
||||
LayerRect &l_roi = layer_info.left_frame_roi.at(i);
|
||||
LayerRect &r_roi = layer_info.right_frame_roi.at(i);
|
||||
|
||||
DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i,
|
||||
INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
|
||||
if (IsValid(r_roi)) {
|
||||
DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
|
||||
INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
|
||||
}
|
||||
}
|
||||
|
||||
const char *header = "\n| Idx | Comp Type | Split | WB | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Flags | Deci(HxV) | CS |"; //NOLINT
|
||||
|
|
|
@ -106,10 +106,17 @@ DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
|
|||
DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
|
||||
lock_guard<recursive_mutex> obj(recursive_mutex_);
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t app_layer_count = hw_layers_.info.app_layer_count;
|
||||
|
||||
// Enabling auto refresh is async and needs to happen before commit ioctl
|
||||
if (hw_panel_info_.mode == kModeCommand) {
|
||||
hw_intf_->SetAutoRefresh(layer_stack->flags.single_buffered_layer_present);
|
||||
bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
|
||||
bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
|
||||
|
||||
hw_intf_->SetAutoRefresh(enable);
|
||||
if (need_refresh) {
|
||||
event_handler_->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
bool set_idle_timeout = comp_manager_->CanSetIdleTimeout(display_comp_ctx_);
|
||||
|
@ -127,6 +134,10 @@ DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
|
|||
} else {
|
||||
hw_intf_->SetIdleTimeoutMs(0);
|
||||
}
|
||||
} else if (switch_to_cmd_) {
|
||||
uint32_t pending;
|
||||
switch_to_cmd_ = false;
|
||||
ControlPartialUpdate(true /* enable */, &pending);
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -191,7 +202,7 @@ DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
|
|||
ControlPartialUpdate(false /* enable */, &pending);
|
||||
hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
|
||||
} else if (mode == kModeCommand) {
|
||||
ControlPartialUpdate(true /* enable */, &pending);
|
||||
switch_to_cmd_ = true;
|
||||
hw_intf_->SetIdleTimeoutMs(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ class DisplayPrimary : public DisplayBase, HWEventHandler {
|
|||
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
|
||||
"msm_fb_thermal_level", "thread_exit"};
|
||||
bool avr_prop_disabled_ = false;
|
||||
bool switch_to_cmd_ = false;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -799,8 +799,8 @@ void HWDevice::PopulateHWPanelInfo() {
|
|||
DLOGI("Device type = %d, Display Port = %d, Display Mode = %d, Device Node = %d, Is Primary = %d",
|
||||
device_type_, hw_panel_info_.port, hw_panel_info_.mode, fb_node_index_,
|
||||
hw_panel_info_.is_primary_panel);
|
||||
DLOGI("Partial Update = %d, Dynamic FPS = %d",
|
||||
hw_panel_info_.partial_update, hw_panel_info_.dynamic_fps);
|
||||
DLOGI("Partial Update = %d, supported roi_count =%d, Dynamic FPS = %d",
|
||||
hw_panel_info_.partial_update, hw_panel_info_.left_roi_count, hw_panel_info_.dynamic_fps);
|
||||
DLOGI("Align: left = %d, width = %d, top = %d, height = %d",
|
||||
hw_panel_info_.left_align, hw_panel_info_.width_align,
|
||||
hw_panel_info_.top_align, hw_panel_info_.height_align);
|
||||
|
@ -881,6 +881,9 @@ void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
|
|||
panel_info->is_primary_panel = atoi(tokens[1]);
|
||||
} else if (!strncmp(tokens[0], "is_pluggable", strlen("is_pluggable"))) {
|
||||
panel_info->is_pluggable = atoi(tokens[1]);
|
||||
} else if (!strncmp(tokens[0], "pu_roi_cnt", strlen("pu_roi_cnt"))) {
|
||||
panel_info->left_roi_count = UINT32(atoi(tokens[1]));
|
||||
panel_info->right_roi_count = UINT32(atoi(tokens[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,18 +363,27 @@ DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
|
|||
|
||||
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
|
||||
|
||||
LayerRect left_roi = hw_layer_info.left_partial_update;
|
||||
LayerRect right_roi = hw_layer_info.right_partial_update;
|
||||
LayerRect left_roi = hw_layer_info.left_frame_roi.at(0);
|
||||
LayerRect right_roi = hw_layer_info.right_frame_roi.at(0);
|
||||
|
||||
mdp_commit.left_roi.x = UINT32(left_roi.left);
|
||||
mdp_commit.left_roi.y = UINT32(left_roi.top);
|
||||
mdp_commit.left_roi.w = UINT32(left_roi.right - left_roi.left);
|
||||
mdp_commit.left_roi.h = UINT32(left_roi.bottom - left_roi.top);
|
||||
|
||||
// Update second roi information in right_roi
|
||||
if (hw_layer_info.left_frame_roi.size() == 2) {
|
||||
right_roi = hw_layer_info.left_frame_roi.at(1);
|
||||
}
|
||||
|
||||
// SDM treats ROI as one full coordinate system.
|
||||
// In case source split is disabled, However, Driver assumes Mixer to operate in
|
||||
// different co-ordinate system.
|
||||
if (!hw_resource_.is_src_split && IsValid(right_roi)) {
|
||||
mdp_commit.right_roi.x = UINT32(right_roi.left) - mixer_attributes_.split_left;
|
||||
if (IsValid(right_roi)) {
|
||||
mdp_commit.right_roi.x = UINT32(right_roi.left);
|
||||
if (!hw_resource_.is_src_split) {
|
||||
mdp_commit.right_roi.x = UINT32(right_roi.left) - mixer_attributes_.split_left;
|
||||
}
|
||||
mdp_commit.right_roi.y = UINT32(right_roi.top);
|
||||
mdp_commit.right_roi.w = UINT32(right_roi.right - right_roi.left);
|
||||
mdp_commit.right_roi.h = UINT32(right_roi.bottom - right_roi.top);
|
||||
|
|
|
@ -46,9 +46,8 @@ DisplayError Strategy::Init() {
|
|||
DisplayError error = kErrorNone;
|
||||
|
||||
if (extension_intf_) {
|
||||
error = extension_intf_->CreateStrategyExtn(display_type_, hw_panel_info_.mode,
|
||||
hw_panel_info_.s3d_mode, mixer_attributes_,
|
||||
fb_config_, &strategy_intf_);
|
||||
error = extension_intf_->CreateStrategyExtn(display_type_, hw_resource_info_, hw_panel_info_,
|
||||
mixer_attributes_, fb_config_, &strategy_intf_);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to create strategy");
|
||||
return error;
|
||||
|
@ -182,15 +181,19 @@ void Strategy::GenerateROI() {
|
|||
split_display = true;
|
||||
}
|
||||
|
||||
hw_layers_info_->left_frame_roi = {};
|
||||
hw_layers_info_->right_frame_roi = {};
|
||||
|
||||
if (split_display) {
|
||||
float left_split = FLOAT(mixer_attributes_.split_left);
|
||||
hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, layer_mixer_height};
|
||||
hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, layer_mixer_width,
|
||||
layer_mixer_height};
|
||||
hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
|
||||
left_split, layer_mixer_height));
|
||||
hw_layers_info_->right_frame_roi.push_back(LayerRect(left_split,
|
||||
0.0f, layer_mixer_width, layer_mixer_height));
|
||||
} else {
|
||||
hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, layer_mixer_width,
|
||||
layer_mixer_height};
|
||||
hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
|
||||
layer_mixer_width, layer_mixer_height));
|
||||
hw_layers_info_->right_frame_roi.push_back(LayerRect(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,8 +218,8 @@ DisplayError Strategy::Reconfigure(const HWPanelInfo &hw_panel_info,
|
|||
mixer_attributes, display_attributes,
|
||||
&partial_update_intf_);
|
||||
|
||||
error = strategy_intf_->Reconfigure(hw_panel_info.mode, hw_panel_info.s3d_mode, mixer_attributes,
|
||||
fb_config);
|
||||
error = strategy_intf_->Reconfigure(hw_panel_info, hw_resource_info_, mixer_attributes,
|
||||
fb_config);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -423,65 +423,67 @@ int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display)
|
|||
DisplayDetailEnhancerData de_data;
|
||||
|
||||
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
|
||||
if (!de_tuning_cfg_data->cfg_en) {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 0;
|
||||
} else {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 1;
|
||||
if (de_tuning_cfg_data->cfg_pending == true) {
|
||||
if (!de_tuning_cfg_data->cfg_en) {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 0;
|
||||
} else {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 1;
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
|
||||
de_data.override_flags |= kOverrideDESharpen1;
|
||||
de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.clip = de_tuning_cfg_data->params.clip;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
|
||||
de_data.override_flags |= kOverrideDEClip;
|
||||
de_data.clip = de_tuning_cfg_data->params.clip;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
|
||||
de_data.override_flags |= kOverrideDEThrQuiet;
|
||||
de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
|
||||
de_data.override_flags |= kOverrideDEThrDieout;
|
||||
de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_low = de_tuning_cfg_data->params.thr_low;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
|
||||
de_data.override_flags |= kOverrideDEThrLow;
|
||||
de_data.thr_low = de_tuning_cfg_data->params.thr_low;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_high = de_tuning_cfg_data->params.thr_high;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
|
||||
de_data.override_flags |= kOverrideDEThrHigh;
|
||||
de_data.thr_high = de_tuning_cfg_data->params.thr_high;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
switch (de_tuning_cfg_data->params.quality) {
|
||||
case kDeContentQualLow:
|
||||
de_data.quality_level = kContentQualityLow;
|
||||
break;
|
||||
case kDeContentQualMedium:
|
||||
de_data.quality_level = kContentQualityMedium;
|
||||
break;
|
||||
case kDeContentQualHigh:
|
||||
de_data.quality_level = kContentQualityHigh;
|
||||
break;
|
||||
case kDeContentQualUnknown:
|
||||
default:
|
||||
de_data.quality_level = kContentQualityUnknown;
|
||||
break;
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
|
||||
switch (de_tuning_cfg_data->params.quality) {
|
||||
case kDeContentQualLow:
|
||||
de_data.quality_level = kContentQualityLow;
|
||||
break;
|
||||
case kDeContentQualMedium:
|
||||
de_data.quality_level = kContentQualityMedium;
|
||||
break;
|
||||
case kDeContentQualHigh:
|
||||
de_data.quality_level = kContentQualityHigh;
|
||||
break;
|
||||
case kDeContentQualUnknown:
|
||||
default:
|
||||
de_data.quality_level = kContentQualityUnknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = hwc_display->SetDetailEnhancerConfig(de_data);
|
||||
if (err) {
|
||||
DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
|
||||
err = hwc_display->SetDetailEnhancerConfig(de_data);
|
||||
if (err) {
|
||||
DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
|
||||
}
|
||||
de_tuning_cfg_data->cfg_pending = false;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -454,6 +454,7 @@ int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
|
|||
for (size_t i = 0; i < num_hw_layers; i++) {
|
||||
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
|
||||
|
||||
const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
|
||||
Layer *layer = layer_stack_.layers.at(i);
|
||||
int ret = PrepareLayerParams(&content_list->hwLayers[i], layer);
|
||||
|
||||
|
@ -471,6 +472,15 @@ int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
|
|||
ApplyScanAdjustment(&scaled_display_frame);
|
||||
|
||||
SetRect(scaled_display_frame, &layer->dst_rect);
|
||||
if (pvt_handle) {
|
||||
bool NonIntegralSourceCrop = IsNonIntegralSourceCrop(hwc_layer.sourceCropf);
|
||||
bool secure = (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) ||
|
||||
(pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) ||
|
||||
(pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
|
||||
if (NonIntegralSourceCrop && !secure) {
|
||||
layer->flags.skip = true;
|
||||
}
|
||||
}
|
||||
SetRect(hwc_layer.sourceCropf, &layer->src_rect);
|
||||
ApplyDeInterlaceAdjustment(layer);
|
||||
|
||||
|
@ -611,7 +621,7 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
|
|||
|
||||
size_t num_hw_layers = content_list->numHwLayers;
|
||||
|
||||
if (!skip_prepare_) {
|
||||
if (!skip_prepare_cnt) {
|
||||
DisplayError error = display_intf_->Prepare(&layer_stack_);
|
||||
if (error != kErrorNone) {
|
||||
if (error == kErrorShutDown) {
|
||||
|
@ -629,7 +639,7 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
|
|||
} else {
|
||||
// Skip is not set
|
||||
MarkLayersForGPUBypass(content_list);
|
||||
skip_prepare_ = false;
|
||||
skip_prepare_cnt = skip_prepare_cnt - 1;
|
||||
DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", secure_display_active_ ? "Starting" :
|
||||
"Stopping");
|
||||
flush_ = true;
|
||||
|
@ -799,6 +809,17 @@ bool HWCDisplay::IsLayerUpdating(hwc_display_contents_1_t *content_list, const L
|
|||
(layer_stack_.flags.geometry_changed));
|
||||
}
|
||||
|
||||
bool HWCDisplay::IsNonIntegralSourceCrop(const hwc_frect_t &source) {
|
||||
if ((source.left != roundf(source.left)) ||
|
||||
(source.top != roundf(source.top)) ||
|
||||
(source.right != roundf(source.right)) ||
|
||||
(source.bottom != roundf(source.bottom))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void HWCDisplay::SetRect(const hwc_rect_t &source, LayerRect *target) {
|
||||
target->left = FLOAT(source.left);
|
||||
target->top = FLOAT(source.top);
|
||||
|
|
|
@ -175,6 +175,7 @@ class HWCDisplay : public DisplayEventHandler {
|
|||
DisplayError SetMetaData(const private_handle_t *pvt_handle, Layer *layer);
|
||||
bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
|
||||
bool IsLayerUpdating(hwc_display_contents_1_t *content_list, const Layer *layer);
|
||||
bool IsNonIntegralSourceCrop(const hwc_frect_t &source);
|
||||
uint32_t GetUpdatingLayersCount(uint32_t app_layer_count);
|
||||
bool SingleVideoLayerUpdating(uint32_t app_layer_count);
|
||||
bool IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions);
|
||||
|
@ -209,7 +210,7 @@ class HWCDisplay : public DisplayEventHandler {
|
|||
bool shutdown_pending_ = false;
|
||||
bool use_blit_comp_ = false;
|
||||
bool secure_display_active_ = false;
|
||||
bool skip_prepare_ = false;
|
||||
uint32_t skip_prepare_cnt = 0;
|
||||
bool solid_fill_enable_ = false;
|
||||
bool disable_animation_ = false;
|
||||
uint32_t solid_fill_color_ = 0;
|
||||
|
|
|
@ -303,14 +303,25 @@ void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active, bool force_
|
|||
DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
|
||||
secure_display_active);
|
||||
secure_display_active_ = secure_display_active;
|
||||
skip_prepare_ = true;
|
||||
skip_prepare_cnt = 1;
|
||||
|
||||
// Avoid flush for command mode panels when no external displays are connected
|
||||
// Issue two null commits for command mode panels when external displays are connected.
|
||||
// Two null commits are required to handle non secure to secure transitions at 30fps.
|
||||
// TODO(user): Need two null commits on video mode also to handle transition cases of
|
||||
// primary at higher fps (ex60) and external at lower fps.
|
||||
|
||||
// Avoid flush for command mode panels when no external displays are connected.
|
||||
// This is to avoid flicker/blink on primary during transitions.
|
||||
DisplayConfigFixedInfo display_config;
|
||||
display_intf_->GetConfig(&display_config);
|
||||
if ((display_config.is_cmdmode) && (force_flush == false)) {
|
||||
DLOGI("Avoid flush for command mode panel");
|
||||
skip_prepare_ = false;
|
||||
if (display_config.is_cmdmode) {
|
||||
if (force_flush) {
|
||||
DLOGI("Issue two null commits for command mode panels");
|
||||
skip_prepare_cnt = 2;
|
||||
} else {
|
||||
DLOGI("Avoid flush for command mode panel when no external displays are connected");
|
||||
skip_prepare_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <sync/sync.h>
|
||||
#include <profiler.h>
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
|
||||
#include "hwc_buffer_allocator.h"
|
||||
#include "hwc_buffer_sync_handler.h"
|
||||
|
@ -274,6 +275,7 @@ int HWCSession::Prepare(hwc_composer_device_1 *device, size_t num_displays,
|
|||
|
||||
if (hwc_session->need_invalidate_) {
|
||||
hwc_procs->invalidate(hwc_procs);
|
||||
hwc_session->need_invalidate_ = false;
|
||||
}
|
||||
|
||||
hwc_session->HandleSecureDisplaySession(displays);
|
||||
|
@ -775,6 +777,10 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa
|
|||
status = SetMixerResolution(input_parcel);
|
||||
break;
|
||||
|
||||
case qService::IQService::GET_HDR_CAPABILITIES:
|
||||
status = GetHdrCapabilities(input_parcel, output_parcel);
|
||||
break;
|
||||
|
||||
default:
|
||||
DLOGW("QService command = %d is not supported", command);
|
||||
return -EINVAL;
|
||||
|
@ -1182,6 +1188,24 @@ android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_pa
|
|||
return 0;
|
||||
}
|
||||
|
||||
android::status_t HWCSession::GetHdrCapabilities(const android::Parcel *input_parcel,
|
||||
android::Parcel *output_parcel) {
|
||||
// TODO(akumarkr): Get values from display intf
|
||||
// uint32_t dpy = UINT32(input_parcel->readInt32());
|
||||
std::vector<int32_t> supported_hdr_types;
|
||||
supported_hdr_types.push_back(HAL_HDR_HDR10);
|
||||
float max_luminance = 500.0;
|
||||
float max_average_luminance = 200.0;
|
||||
float min_luminance = 0.5;
|
||||
if (output_parcel != nullptr) {
|
||||
output_parcel->writeInt32Vector(supported_hdr_types);
|
||||
output_parcel->writeFloat(max_luminance);
|
||||
output_parcel->writeFloat(max_average_luminance);
|
||||
output_parcel->writeFloat(min_luminance);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
|
||||
int type = input_parcel->readInt32();
|
||||
bool enable = (input_parcel->readInt32() > 0);
|
||||
|
|
|
@ -125,6 +125,8 @@ class HWCSession : hwc_composer_device_1_t, public qClient::BnQClient {
|
|||
android::Parcel *output_parcel);
|
||||
android::status_t SetMixerResolution(const android::Parcel *input_parcel);
|
||||
android::status_t SetDisplayPort(DisplayPort sdm_disp_port, int *hwc_disp_port);
|
||||
android::status_t GetHdrCapabilities(const android::Parcel *input_parcel,
|
||||
android::Parcel *output_parcel);
|
||||
|
||||
static Locker locker_;
|
||||
CoreInterface *core_intf_ = NULL;
|
||||
|
|
|
@ -279,65 +279,67 @@ int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display)
|
|||
DisplayDetailEnhancerData de_data;
|
||||
|
||||
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
|
||||
if (!de_tuning_cfg_data->cfg_en) {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 0;
|
||||
} else {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 1;
|
||||
if (de_tuning_cfg_data->cfg_pending == true) {
|
||||
if (!de_tuning_cfg_data->cfg_en) {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 0;
|
||||
} else {
|
||||
de_data.override_flags = kOverrideDEEnable;
|
||||
de_data.enable = 1;
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
|
||||
de_data.override_flags |= kOverrideDESharpen1;
|
||||
de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.clip = de_tuning_cfg_data->params.clip;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
|
||||
de_data.override_flags |= kOverrideDEClip;
|
||||
de_data.clip = de_tuning_cfg_data->params.clip;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
|
||||
de_data.override_flags |= kOverrideDEThrQuiet;
|
||||
de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
|
||||
de_data.override_flags |= kOverrideDEThrDieout;
|
||||
de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_low = de_tuning_cfg_data->params.thr_low;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
|
||||
de_data.override_flags |= kOverrideDEThrLow;
|
||||
de_data.thr_low = de_tuning_cfg_data->params.thr_low;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
de_data.thr_high = de_tuning_cfg_data->params.thr_high;
|
||||
}
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
|
||||
de_data.override_flags |= kOverrideDEThrHigh;
|
||||
de_data.thr_high = de_tuning_cfg_data->params.thr_high;
|
||||
}
|
||||
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
|
||||
de_data.override_flags |= kOverrideDEEnable;
|
||||
switch (de_tuning_cfg_data->params.quality) {
|
||||
case kDeContentQualLow:
|
||||
de_data.quality_level = kContentQualityLow;
|
||||
break;
|
||||
case kDeContentQualMedium:
|
||||
de_data.quality_level = kContentQualityMedium;
|
||||
break;
|
||||
case kDeContentQualHigh:
|
||||
de_data.quality_level = kContentQualityHigh;
|
||||
break;
|
||||
case kDeContentQualUnknown:
|
||||
default:
|
||||
de_data.quality_level = kContentQualityUnknown;
|
||||
break;
|
||||
if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
|
||||
switch (de_tuning_cfg_data->params.quality) {
|
||||
case kDeContentQualLow:
|
||||
de_data.quality_level = kContentQualityLow;
|
||||
break;
|
||||
case kDeContentQualMedium:
|
||||
de_data.quality_level = kContentQualityMedium;
|
||||
break;
|
||||
case kDeContentQualHigh:
|
||||
de_data.quality_level = kContentQualityHigh;
|
||||
break;
|
||||
case kDeContentQualUnknown:
|
||||
default:
|
||||
de_data.quality_level = kContentQualityUnknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = hwc_display->SetDetailEnhancerConfig(de_data);
|
||||
if (err) {
|
||||
DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
|
||||
err = hwc_display->SetDetailEnhancerConfig(de_data);
|
||||
if (err) {
|
||||
DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
|
||||
}
|
||||
de_tuning_cfg_data->cfg_pending = false;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -386,6 +386,8 @@ void HWCDisplay::BuildLayerStack() {
|
|||
LayerBuffer *layer_buffer = layer->input_buffer;
|
||||
layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
|
||||
layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
|
||||
layer_buffer->unaligned_width = layer_buffer->width;
|
||||
layer_buffer->unaligned_height = layer_buffer->height;
|
||||
layer_buffer->acquire_fence_fd = -1;
|
||||
layer_buffer->release_fence_fd = -1;
|
||||
layer->src_rect.left = 0;
|
||||
|
|
|
@ -215,7 +215,8 @@ static hwc2_function_pointer_t AsFP(T function) {
|
|||
// HWC2 functions returned in GetFunction
|
||||
// Defined in the same order as in the HWC2 header
|
||||
|
||||
static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
|
||||
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
|
||||
SCOPE_LOCK(locker_);
|
||||
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
|
||||
}
|
||||
|
||||
|
@ -590,7 +591,7 @@ hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
|
|||
|
||||
switch (descriptor) {
|
||||
case HWC2::FunctionDescriptor::AcceptDisplayChanges:
|
||||
return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(AcceptDisplayChanges);
|
||||
return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
|
||||
case HWC2::FunctionDescriptor::CreateLayer:
|
||||
return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
|
||||
case HWC2::FunctionDescriptor::CreateVirtualDisplay:
|
||||
|
|
|
@ -82,6 +82,7 @@ class HWCSession : hwc2_device_t, public qClient::BnQClient {
|
|||
|
||||
// HWC2 Functions that require a concrete implementation in hwc session
|
||||
// and hence need to be member functions
|
||||
static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
|
||||
static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t *out_layer_id);
|
||||
static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <utils/debug.h>
|
||||
#include <utils/constants.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sdm {
|
||||
|
||||
|
@ -163,7 +164,7 @@ bool Debug::IsExtAnimDisabled() {
|
|||
}
|
||||
|
||||
DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
|
||||
char value[64];
|
||||
char value[64] = {};
|
||||
|
||||
DisplayError error = debug_.debug_handler_->GetProperty("sdm.mixer_resolution", value);
|
||||
if (error !=kErrorNone) {
|
||||
|
@ -178,6 +179,13 @@ DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
|
|||
return kErrorNone;
|
||||
}
|
||||
|
||||
int Debug::GetExtMaxlayers() {
|
||||
int max_external_layers = 0;
|
||||
debug_.debug_handler_->GetProperty("sdm.max_external_layers", &max_external_layers);
|
||||
|
||||
return std::max(max_external_layers, 2);
|
||||
}
|
||||
|
||||
bool Debug::GetProperty(const char* property_name, char* value) {
|
||||
if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
|
||||
return false;
|
||||
|
|
|
@ -205,6 +205,10 @@ void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const Lay
|
|||
return;
|
||||
}
|
||||
|
||||
int x_offset = INT(src_domain.left);
|
||||
int y_offset = INT(src_domain.top);
|
||||
|
||||
LayerRect modified_in_rect = Reposition(in_rect, -x_offset, -y_offset);
|
||||
float src_domain_width = src_domain.right - src_domain.left;
|
||||
float src_domain_height = src_domain.bottom - src_domain.top;
|
||||
float dst_domain_width = dst_domain.right - dst_domain.left;
|
||||
|
@ -213,10 +217,10 @@ void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const Lay
|
|||
float width_ratio = dst_domain_width / src_domain_width;
|
||||
float height_ratio = dst_domain_height / src_domain_height;
|
||||
|
||||
out_rect->left = dst_domain.left + (width_ratio * in_rect.left);
|
||||
out_rect->top = dst_domain.top + (height_ratio * in_rect.top);
|
||||
out_rect->right = dst_domain.left + (width_ratio * in_rect.right);
|
||||
out_rect->bottom = dst_domain.top + (height_ratio * in_rect.bottom);
|
||||
out_rect->left = dst_domain.left + (width_ratio * modified_in_rect.left);
|
||||
out_rect->top = dst_domain.top + (height_ratio * modified_in_rect.top);
|
||||
out_rect->right = dst_domain.left + (width_ratio * modified_in_rect.right);
|
||||
out_rect->bottom = dst_domain.top + (height_ratio * modified_in_rect.bottom);
|
||||
}
|
||||
|
||||
RectOrientation GetOrientation(const LayerRect &in_rect) {
|
||||
|
|
Loading…
Reference in New Issue