blob: b2ef7f901c94dd7b252c7ea4b1f432f73c7aee77 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DISPLAYCOLOR_GS101_H_
#define DISPLAYCOLOR_GS101_H_
#include <array>
#include <functional>
#include <memory>
#include <displaycolor/displaycolor.h>
namespace displaycolor {
/// An interface for accessing GS101 color management data.
class IDisplayColorGS101 : public IDisplayColorGeneric {
private:
/// Register data for matrices in DPP and DQE.
template <typename T, size_t kDimensions>
struct MatrixData {
/**
* DQE0_GAMMA_MATRIX_COEFF0..4[GAMMA_MATRIX_COEFF_xx]
* DQE0_LINEAR_MATRIX_COEFF0..4[LINEAR_MATRIX_COEFF_xx]
* DPP_HDR_LSI_L#_GM_COEF0..8[COEF], #(0..5)
*/
std::array<T, kDimensions * kDimensions> coeffs{};
/**
* DQE0_GAMMA_MATRIX_OFFSET0..1[GAMMA_MATRIX_COEFF_n]
* DQE0_LINEAR_MATRIX_OFFSET0..1[LINEAR_MATRIX_COEFF_n]
* DPP_HDR_LSI_L#_GM_OFFS0..2[OFFS], #(0..5)
*/
std::array<T, kDimensions> offsets{};
};
public:
/**
* @brief Interface for accessing data for DPP stages.
*
* Note that the data returned by this interface is applicable to both DPP
* in DPU and the HDR blocks in G2D. These two IPs' register specs are
* identical, with one caveat: While all G2D layers support display tone
* mapping (DTM) for HDR10+, only DPP layers L1/L3/L5 support this stage.
*/
struct IDpp {
private:
/// Register data for transfer function LUTs in DPP)
template <typename XT, typename YT, size_t N>
struct TransferFunctionData {
/**
* DPP_HDR_LSI_L#_EOTF_POSX0~64[POSXn], #(0..5), n(0..1)
* DPP_HDR_LSI_L#_OETF_POSX0~16[POSXn], #(0..5), n(0..1)
* DPP_HDR_LSI_L#_TM_POSX0~16[POSXn], #(1, 3, 5), n(0..1)
*/
std::array<XT, N> posx;
/**
* DPP_HDR_LSI_L#_EOTF_POSY0~128[POSY0], #(0..5)
* DPP_HDR_LSI_L#_OETF_POSY0~16[POSYn] #(0..5), n(0..1)
* DPP_HDR_LSI_L#_TM_POSY0~32[POSY0], #(1, 3, 5)
*/
std::array<YT, N> posy;
};
struct EotfConfigType {
using XContainer = uint16_t;
using YContainer = uint32_t;
static constexpr size_t kLutLen = 129;
TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
};
struct GmConfigType {
using Container = uint32_t;
static constexpr size_t kDimensions = 3;
MatrixData<Container, kDimensions> matrix_data;
};
struct DtmConfigType {
using XContainer = uint16_t;
using YContainer = uint32_t;
static constexpr size_t kLutLen = 33;
TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
uint16_t coeff_r; // DPP_HDR_LSI_L#_TM_COEF[COEFR] #(1, 3, 5)
uint16_t coeff_g; // DPP_HDR_LSI_L#_TM_COEF[COEFG] #(1, 3, 5)
uint16_t coeff_b; // DPP_HDR_LSI_L#_TM_COEF[COEFB] #(1, 3, 5)
uint16_t rng_x_min; // DPP_HDR_LSI_L#_TM_RNGX[MINX] #(1, 3, 5)
uint16_t rng_x_max; // DPP_HDR_LSI_L#_TM_RNGX[MAXX] #(1, 3, 5)
uint16_t rng_y_min; // DPP_HDR_LSI_L#_TM_RNGY[MINY] #(1, 3, 5)
uint16_t rng_y_max; // DPP_HDR_LSI_L#_TM_RNGY[MAXY] #(1, 3, 5)
};
struct OetfConfigType {
using XContainer = uint32_t;
using YContainer = uint16_t;
static constexpr size_t kLutLen = 33;
TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
};
public:
/// Register data for the EOTF LUT in DPP.
using EotfData = DisplayStage<EotfConfigType>;
/// Register data for the gamut mapping (GM) matrix in DPP.
using GmData = DisplayStage<GmConfigType>;
/**
* @brief Register data for the DTM stage in DPP.
*
* Note that this data is only applicable to DPP in layers L1/L3/L5 and
* G2D layers. Other DPPs do not support DTM. DTM data will be provided
* for any layer whose DisplayScene::LayerColorData contains HDR dynamic
* metadata. It is the caller's (typically HWComposer) responsibility to
* validate layers and HW capabilities correctly, before calling this
* API.
*/
using DtmData = DisplayStage<DtmConfigType>;
/// Register data for the OETF LUT in DPP.
using OetfData = DisplayStage<OetfConfigType>;
/// Get data for the EOTF LUT.
virtual const EotfData& EotfLut() const = 0;
/// Get data for the gamut mapping (GM) matrix.
virtual const GmData& Gm() const = 0;
/**
* @brief Get data for the DTM LUT. Only used for HDR10+, and only
* applicable to DPPs that support this functionality.
*/
virtual const DtmData& Dtm() const = 0;
/// Get data for the OETF LUT.
virtual const OetfData& OetfLut() const = 0;
virtual ~IDpp() {}
};
/// Interface for accessing data for DQE stages.
struct IDqe {
private:
/// 32-bit DQE dither register, same definition as in uapi
struct DitherConfigType {
uint8_t en : 1;
uint8_t mode : 1;
uint8_t frame_con : 1;
uint8_t frame_offset : 2;
uint8_t table_sel_r : 1;
uint8_t table_sel_g : 1;
uint8_t table_sel_b : 1;
uint32_t reserved : 24;
};
struct DqeControlConfigType {
/// DQE force 10bpc mode
bool force_10bpc = false;
/// flag to use cgc_dither
bool cgc_dither_override = false;
/// CGC dither register value
union {
DitherConfigType cgc_dither_reg = {};
uint8_t cgc_dither; // only lowest 8 bit is used
};
/// flag to use disp_dither
bool disp_dither_override = false;
/// Display dither register value
union {
DitherConfigType disp_dither_reg = {};
uint8_t disp_dither; // only lowest 8 bit is used
};
};
struct DqeMatrixConfigType {
using Container = uint16_t;
static constexpr size_t kDimensions = 3;
struct MatrixData<Container, kDimensions> matrix_data;
};
struct DegammaConfigType {
using Container = uint16_t;
static constexpr size_t kLutLen = 65;
std::array<Container, kLutLen> values;
};
struct CgcConfigType {
using Container = uint32_t;
static constexpr size_t kChannelLutLen = 2457;
/// DQE0_CGC_LUT_R_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
std::array<Container, kChannelLutLen> r_values{};
/// DQE0_CGC_LUT_G_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
std::array<Container, kChannelLutLen> g_values{};
/// DQE0_CGC_LUT_B_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
std::array<Container, kChannelLutLen> b_values{};
};
struct RegammaConfigType {
using Container = uint16_t;
static constexpr size_t kChannelLutLen = 65;
/// REGAMMA LUT_R_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
std::array<Container, kChannelLutLen> r_values{};
/// REGAMMA LUT_G_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
std::array<Container, kChannelLutLen> g_values{};
/// REGAMMA LUT_B_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
std::array<Container, kChannelLutLen> b_values{};
};
public:
/// DQE control data
using DqeControlData = DisplayStage<DqeControlConfigType>;
/// Register data for the gamma and linear matrices in DQE.
using DqeMatrixData = DisplayStage<DqeMatrixConfigType>;
/// Register data for the degamma LUT in DQE.
using DegammaLutData = DisplayStage<DegammaConfigType>;
/// Register data for CGC.
using CgcData = DisplayStage<CgcConfigType>;
/// Register data for the regamma LUT.
using RegammaLutData = DisplayStage<RegammaConfigType>;
/// Get DQE control data
virtual const DqeControlData& DqeControl() const = 0;
/// Get data for the gamma-space matrix.
virtual const DqeMatrixData& GammaMatrix() const = 0;
/// Get data for the 1D de-gamma LUT (EOTF).
virtual const DegammaLutData& DegammaLut() const = 0;
/// Get data for the linear-space matrix.
virtual const DqeMatrixData& LinearMatrix() const = 0;
/// Get data for the Color Gamut Conversion stage (3D LUT).
virtual const CgcData& Cgc() const = 0;
/// Get data for the 3x1D re-gamma LUTa (OETF).
virtual const RegammaLutData& RegammaLut() const = 0;
virtual ~IDqe() {}
};
/// Interface for accessing particular display color data
struct IDisplayPipelineData {
/**
* @brief Get handles to Display Pre-Processor (DPP) data accessors.
*
* The order of the returned DPP handles match the order of the
* LayerColorData provided as part of struct DisplayScene and
* IDisplayColorGeneric::Update().
*/
virtual std::vector<std::reference_wrapper<const IDpp>> Dpp() const = 0;
/// Get a handle to Display Quality Enhancer (DQE) data accessors.
virtual const IDqe& Dqe() const = 0;
/// Get a handle to panel data accessors
virtual const IPanel& Panel() const = 0;
virtual ~IDisplayPipelineData() {}
};
/// Get pipeline color data for specified display type
virtual const IDisplayPipelineData* GetPipelineData(
DisplayType display) const = 0;
virtual ~IDisplayColorGS101() {}
};
extern "C" {
/// Get the GS101 instance.
IDisplayColorGS101* GetDisplayColorGS101(size_t display_num);
}
} // namespace displaycolor
#endif // DISPLAYCOLOR_GS101_H_