Snap for 10453563 from fc9082a0c1ef9b58afa76624bd6f02da343a18cd to mainline-conscrypt-release

Change-Id: I497c218279a9e404f88db078545cd67466f6d2b3
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..03af56d
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,13 @@
+BasedOnStyle: Google
+
+AccessModifierOffset: -4
+AlignOperands: false
+AllowShortFunctionsOnASingleLine: Inline
+AlwaysBreakBeforeMultilineStrings: false
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+ConstructorInitializerIndentWidth: 6
+ContinuationIndentWidth: 8
+IndentWidth: 4
+PenaltyBreakBeforeFirstCallParameter: 100000
+SpacesBeforeTrailingComments: 1
diff --git a/histogram/histogram.h b/histogram/histogram.h
new file mode 100644
index 0000000..a7b41ce
--- /dev/null
+++ b/histogram/histogram.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 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 HISTOGRAM_GS201_H_
+#define HISTOGRAM_GS201_H_
+
+#include <../gs101/include/histogram/HistogramInfo.h>
+#include <../gs101/include/histogram/histogram_control.h>
+#include <aidl/com/google/hardware/pixel/display/HistogramPos.h>
+
+using HistogramPos =
+    ::aidl::com::google::hardware::pixel::display::HistogramPos;
+
+class IDLHistogram : public HistogramInfo {
+ public:
+  IDLHistogram() : HistogramInfo(HistogramType::HISTOGRAM_HIDL) {}
+  virtual ~IDLHistogram() {}
+  virtual void setHistogramPos(HistogramPos pos) {
+      std::unique_lock<std::mutex> lk(mSetHistInfoMutex);
+      mHistogramPos = pos;
+  }
+  HistogramPos getHistogramPos() {
+      std::unique_lock<std::mutex> lk(mSetHistInfoMutex);
+      return mHistogramPos;
+  }
+
+ private:
+  HistogramPos mHistogramPos = HistogramPos::POST;
+};
+
+#endif  // HISTOGRAM_GS201_H_
diff --git a/include/gs101/displaycolor/displaycolor_gs101.h b/include/gs101/displaycolor/displaycolor_gs101.h
index b2ef7f9..ffc33bc 100644
--- a/include/gs101/displaycolor/displaycolor_gs101.h
+++ b/include/gs101/displaycolor/displaycolor_gs101.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,289 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef DISPLAYCOLOR_GS101_H_
-#define DISPLAYCOLOR_GS101_H_
+#pragma once
 
-#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_
+#include "../../gs101/include/gs101/displaycolor/displaycolor_gs101.h"
diff --git a/libcap/acrylic_capability.h b/libcap/acrylic_capability.h
new file mode 100644
index 0000000..ff49f1a
--- /dev/null
+++ b/libcap/acrylic_capability.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include <cstring>
+
+#include <log/log.h>
+
+#include <exynos_format.h> // hardware/smasung_slsi/exynos/include
+#include <mali_gralloc_formats.h>
+
+static uint32_t all_fimg2d_gs201_formats[] = {
+    HAL_PIXEL_FORMAT_RGBA_8888,
+    HAL_PIXEL_FORMAT_BGRA_8888,
+    HAL_PIXEL_FORMAT_RGBA_1010102,
+    HAL_PIXEL_FORMAT_RGBX_8888,
+    HAL_PIXEL_FORMAT_RGB_888,
+    HAL_PIXEL_FORMAT_RGB_565,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P,
+    HAL_PIXEL_FORMAT_YCrCb_420_SP,                  // NV21 (YVU420 semi-planar)
+    HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M,         // NV21 on multi-buffer
+    HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL,    // NV21 on multi-buffer
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP,           // NV12 (YUV420 semi-planar)
+    HAL_PIXEL_FORMAT_GOOGLE_NV12_SP,                // NV12 (YUV420 semi-planar)
+    MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I,     // NV12 AFBC
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN,          // NV12 with MFC alignment constraints
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M,
+    // NV12M with MFC alignment constraints on multi-buffer
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV,
+    // NV12M with MFC alignment constraints on multi-buffer
+    HAL_PIXEL_FORMAT_YCbCr_422_SP,                  // YUV422 2P (YUV422 semi-planar)
+    HAL_PIXEL_FORMAT_YCBCR_P010,
+    HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B,
+    MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60,
+    HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80,
+};
+
+static int all_hwc_gs201_dataspaces[] = {
+    HAL_DATASPACE_STANDARD_BT709,
+    HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_BT2020,
+    HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_BT601_625,
+    HAL_DATASPACE_STANDARD_BT601_625 | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT601_625 | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_BT601_525,
+    HAL_DATASPACE_STANDARD_BT601_525 | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT601_525 | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED,
+    HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED,
+    HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_DCI_P3,
+    HAL_DATASPACE_STANDARD_DCI_P3 | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_DCI_P3 | HAL_DATASPACE_RANGE_LIMITED,
+    HAL_DATASPACE_STANDARD_FILM,
+    HAL_DATASPACE_STANDARD_FILM | HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_STANDARD_FILM | HAL_DATASPACE_RANGE_LIMITED,
+    // 0 should be treated as BT709 Limited range
+    0,
+    HAL_DATASPACE_RANGE_FULL,
+    HAL_DATASPACE_RANGE_LIMITED,
+    // Deprecated legacy dataspace definitions
+    HAL_DATASPACE_SRGB,
+    HAL_DATASPACE_JFIF,
+    HAL_DATASPACE_BT601_525,
+    HAL_DATASPACE_BT601_625,
+    HAL_DATASPACE_BT709,
+};
+
+const static stHW2DCapability __capability_fimg2d_gs201 = {
+    .max_upsampling_num = {8, 8},
+    .max_downsampling_factor = {4, 4},
+    .max_upsizing_num = {8, 8},
+    .max_downsizing_factor = {4, 4},
+    .min_src_dimension = {1, 1},
+    .max_src_dimension = {8192, 8192},
+    .min_dst_dimension = {1, 1},
+    .max_dst_dimension = {8192, 8192},
+    .min_pix_align = {1, 1},
+    .rescaling_count = 0,
+    .compositing_mode = HW2DCapability::BLEND_NONE | HW2DCapability::BLEND_SRC_COPY
+                         | HW2DCapability::BLEND_SRC_OVER,
+    .transform_type = HW2DCapability::TRANSFORM_ALL,
+    .auxiliary_feature = HW2DCapability::FEATURE_PLANE_ALPHA | HW2DCapability::FEATURE_UORDER_WRITE
+                         | HW2DCapability::FEATURE_AFBC_ENCODE | HW2DCapability::FEATURE_AFBC_DECODE
+                         | HW2DCapability::FEATURE_SOLIDCOLOR,
+    .num_formats = ARRSIZE(all_fimg2d_gs201_formats),
+    .num_dataspaces = ARRSIZE(all_hwc_gs201_dataspaces),
+    .max_layers = 4,
+    .pixformats = all_fimg2d_gs201_formats,
+    .dataspaces = all_hwc_gs201_dataspaces,
+    .base_align = 1,
+};
+
+static const HW2DCapability capability_fimg2d_gs201(__capability_fimg2d_gs201);
+
+inline Acrylic *createAcrylicCompositorG2D(const char *spec)
+{
+    Acrylic *compositor = nullptr;
+
+    if (strcmp(spec, "fimg2d_gs201") == 0) {
+        compositor = new AcrylicCompositorG2D(capability_fimg2d_gs201, /*halfmt_to_g2dfmt*/ true);
+    }
+    return compositor;
+}
diff --git a/libhwc2.1/Android.mk b/libhwc2.1/Android.mk
index da34a56..20c85f0 100644
--- a/libhwc2.1/Android.mk
+++ b/libhwc2.1/Android.mk
@@ -13,9 +13,11 @@
 # limitations under the License.
 
 LOCAL_SRC_FILES += \
+	../../gs101/libhwc2.1/libcolormanager/DisplayColorModule.cpp \
 	../../gs101/libhwc2.1/libdevice/ExynosDeviceModule.cpp \
 	../../gs101/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp \
 	../../gs101/libhwc2.1/libresource/ExynosMPPModule.cpp \
+	../../gs201/libhwc2.1/libresource/ExynosMPPModule.cpp \
 	../../gs101/libhwc2.1/libresource/ExynosResourceManagerModule.cpp	\
 	../../gs101/libhwc2.1/libexternaldisplay/ExynosExternalDisplayModule.cpp \
 	../../gs101/libhwc2.1/libvirtualdisplay/ExynosVirtualDisplayModule.cpp \
@@ -25,4 +27,5 @@
 LOCAL_CFLAGS += -DDISPLAY_COLOR_LIB=\"libdisplaycolor.so\"
 
 LOCAL_C_INCLUDES += \
+	$(TOP)/hardware/google/graphics/gs201/histogram \
 	$(TOP)/hardware/google/graphics/gs101/include
diff --git a/libhwc2.1/ExynosHWCModule.h b/libhwc2.1/ExynosHWCModule.h
index cbf6056..d816bdc 100644
--- a/libhwc2.1/ExynosHWCModule.h
+++ b/libhwc2.1/ExynosHWCModule.h
@@ -19,10 +19,33 @@
 
 #include "../../gs101/libhwc2.1/ExynosHWCModule.h"
 
-#ifdef EARLY_WAKUP_NODE_0_BASE
-#undef EARLY_WAKUP_NODE_0_BASE
-#endif
+namespace gs201 {
 
-#define EARLY_WAKUP_NODE_0_BASE	"/sys/devices/platform/1c240000.drmdecon/early_wakeup"
+static const char *early_wakeup_node_0_base =
+    "/sys/devices/platform/1c240000.drmdecon/early_wakeup";
+
+static const dpp_channel_map_t idma_channel_map[] = {
+    /* GF physical index is switched to change assign order */
+    /* DECON_IDMA is not used */
+    {MPP_DPP_GF,     0, IDMA(0),   IDMA(0)},
+    {MPP_DPP_VGRFS,  0, IDMA(1),   IDMA(1)},
+    {MPP_DPP_GF,     1, IDMA(2),   IDMA(2)},
+    {MPP_DPP_VGRFS,  1, IDMA(3),   IDMA(3)},
+    {MPP_DPP_GF,     2, IDMA(4),   IDMA(4)},
+    {MPP_DPP_VGRFS,  2, IDMA(5),   IDMA(5)},
+    {MPP_P_TYPE_MAX, 0, IDMA(6),   IDMA(6)}, // not idma but..
+    {static_cast<mpp_phycal_type_t>(MAX_DECON_DMA_TYPE), 0, MAX_DECON_DMA_TYPE, IDMA(7)}
+};
+
+static const exynos_mpp_t available_otf_mpp_units[] = {
+    {MPP_DPP_GF, MPP_LOGICAL_DPP_GF, "DPP_GF0", 0, 0, HWC_DISPLAY_PRIMARY_BIT, 0, 0},
+    {MPP_DPP_GF, MPP_LOGICAL_DPP_GF, "DPP_GF1", 1, 0, HWC_DISPLAY_PRIMARY_BIT, 0, 0},
+    {MPP_DPP_GF, MPP_LOGICAL_DPP_GF, "DPP_GF2", 2, 0, HWC_DISPLAY_PRIMARY_BIT, 0, 0},
+    {MPP_DPP_VGRFS, MPP_LOGICAL_DPP_VGRFS, "DPP_VGRFS0", 0, 0, HWC_DISPLAY_PRIMARY_BIT, 0, 0},
+    {MPP_DPP_VGRFS, MPP_LOGICAL_DPP_VGRFS, "DPP_VGRFS1", 1, 0, HWC_DISPLAY_PRIMARY_BIT, 0, 0},
+    {MPP_DPP_VGRFS, MPP_LOGICAL_DPP_VGRFS, "DPP_VGRFS2", 2, 0, HWC_DISPLAY_SECONDARY_BIT, 0, 0}
+};
+
+} // namespace gs201
 
 #endif // ANDROID_EXYNOS_HWC_MODULE_GS201_H_
diff --git a/libhwc2.1/ExynosResourceRestriction.h b/libhwc2.1/ExynosResourceRestriction.h
index 35db6ce..3583fbd 100644
--- a/libhwc2.1/ExynosResourceRestriction.h
+++ b/libhwc2.1/ExynosResourceRestriction.h
@@ -19,4 +19,126 @@
 
 #include "../../gs101/libhwc2.1/ExynosResourceRestriction.h"
 
+namespace gs201 {
+
+static feature_support_t feature_table[] = {
+    {MPP_DPP_GF,
+        MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE |
+        MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V |
+        MPP_ATTR_DIM |
+        MPP_ATTR_WCG | MPP_ATTR_HDR10 |
+        MPP_ATTR_LAYER_TRANSFORM
+    },
+
+    {MPP_DPP_VGRFS,
+        MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_SCALE |
+        MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V | MPP_ATTR_ROT_90 |
+        MPP_ATTR_DIM |
+        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS |
+        MPP_ATTR_LAYER_TRANSFORM
+    },
+
+    {MPP_G2D,
+        MPP_ATTR_AFBC | MPP_ATTR_SCALE |
+        MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V | MPP_ATTR_ROT_90 |
+        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS | MPP_ATTR_USE_CAPA |
+        MPP_ATTR_LAYER_TRANSFORM
+    }
+};
+
+static const restriction_key_t restriction_format_table[] = {
+    {MPP_DPP_GF, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_DPP_GF, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_DPP_GF, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_DPP_GF, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_DPP_GF, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_YCBCR_P010, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 0},
+    {MPP_DPP_VG, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_YCBCR_P010, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 0},
+    {MPP_DPP_VGS, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_YCBCR_P010, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 0},
+    {MPP_DPP_VGF, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_YCBCR_P010, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 0},
+    {MPP_DPP_VGRFS, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_RGB_565, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_RGB_888, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_8888, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_RGBX_8888, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_BGRA_8888, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_RGBA_1010102, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_YCrCb_420_SP, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 0},
+    {MPP_G2D, NODE_NONE, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 0},
+};
+
+} // namespace gs201
+
 #endif // EXYNOS_RESOURCE_RESTRICTION_GS201_H_
diff --git a/libhwc2.1/libmaindisplay/DisplayColorLoader.h b/libhwc2.1/libcolormanager/DisplayColorModule.h
similarity index 62%
rename from libhwc2.1/libmaindisplay/DisplayColorLoader.h
rename to libhwc2.1/libcolormanager/DisplayColorModule.h
index 3ee9007..9d9f609 100644
--- a/libhwc2.1/libmaindisplay/DisplayColorLoader.h
+++ b/libhwc2.1/libcolormanager/DisplayColorModule.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,15 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef DISPLAY_COLOR_LOADER_GS201_H
-#define DISPLAY_COLOR_LOADER_GS201_H
+#pragma once
 
-#include "../../gs101/libhwc2.1/libmaindisplay/DisplayColorLoader.h"
-
-namespace gs201 {
-
-using DisplayColorLoader = gs101::DisplayColorLoader;
-
-}  // namespace gs201
-
-#endif // DISPLAY_COLOR_LOADER_GS201_H
+#include "../../../gs101/libhwc2.1/libcolormanager/DisplayColorModule.h"
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp
index 1bfccc2..6d941cd 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp
@@ -78,7 +78,7 @@
 }
 
 int32_t ExynosDisplayDrmInterfaceModule::createCgcDMAFromIDqe(
-        const IDisplayColorGS101::IDqe::CgcData &cgcData)
+        const GsInterfaceType::IDqe::CgcData &cgcData)
 {
     if ((cgcData.config->r_values.size() != DRM_SAMSUNG_CGC_LUT_REG_CNT) ||
         (cgcData.config->g_values.size() != DRM_SAMSUNG_CGC_LUT_REG_CNT) ||
@@ -120,8 +120,8 @@
         return NO_ERROR;
 
     ExynosPrimaryDisplayModule* display = (ExynosPrimaryDisplayModule*)mExynosDisplay;
-    const IDisplayColorGS101::IDqe &dqe = display->getDqe();
-    const IDisplayColorGS101::IDqe::CgcData &cgcData = dqe.Cgc();
+    const GsInterfaceType::IDqe &dqe = display->getDqe();
+    const GsInterfaceType::IDqe::CgcData &cgcData = dqe.Cgc();
 
     /* dirty bit is valid only if enable is true */
     if (!mForceDisplayColorSetting && cgcData.enable && !cgcData.dirty)
@@ -175,6 +175,45 @@
 
     return setCgcLutDmaProperty(mDrmCrtc->cgc_lut_fd_property(), drmReq);
 }
+
+int32_t ExynosDisplayDrmInterfaceModule::setHistoPosProperty(
+    const DrmProperty &prop,
+    ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) {
+  if (!prop.id()) return NO_ERROR;
+
+  int32_t ret = 0;
+
+  if ((ret = drmReq.atomicAddProperty(
+           mDrmCrtc->id(), prop, (uint64_t)mHistogramInfo->getHistogramPos(),
+           true)) < 0) {
+    HWC_LOGE(mExynosDisplay, "%s: Fail to set histogram position property",
+             __func__);
+    return ret;
+  }
+
+  return NO_ERROR;
+}
+
+int32_t ExynosDisplayDrmInterfaceModule::setDisplayHistogramSetting(
+    ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) {
+  if ((isHistogramInfoRegistered() == false) || (isPrimary() == false)) return NO_ERROR;
+
+  int32_t ret =
+      gs101::ExynosDisplayDrmInterfaceModule::setDisplayHistogramSetting(
+          drmReq);
+  if (ret != NO_ERROR) return ret;
+
+  ret = setHistoPosProperty(mDrmCrtc->histogram_position_property(), drmReq);
+
+  return ret;
+}
+
+void ExynosDisplayDrmInterfaceModule::registerHistogramInfo(
+        const std::shared_ptr<IDLHistogram> &info) {
+  gs101::ExynosDisplayDrmInterfaceModule::registerHistogramInfo(info);
+  mHistogramInfo = info;
+}
+
 //////////////////////////////////////////////////// ExynosPrimaryDisplayDrmInterfaceModule //////////////////////////////////////////////////////////////////
 ExynosPrimaryDisplayDrmInterfaceModule::ExynosPrimaryDisplayDrmInterfaceModule(ExynosDisplay *exynosDisplay)
   : ExynosDisplayDrmInterfaceModule(exynosDisplay)
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h
index e7a1ca9..d2c3040 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h
@@ -29,6 +29,7 @@
     static constexpr size_t sizeCgcDmaLut = 2 * 3 * DRM_SAMSUNG_CGC_DMA_LUT_ENTRY_CNT;	// 16bit BGR
     static constexpr int32_t disabledCgc = -1;
     static constexpr size_t sizeCgCDataInfo = 2;
+    using GsInterfaceType = gs::ColorDrmBlobFactory::GsInterfaceType;
     public:
         ExynosDisplayDrmInterfaceModule(ExynosDisplay *exynosDisplay);
         virtual ~ExynosDisplayDrmInterfaceModule();
@@ -37,16 +38,27 @@
         virtual int32_t setDisplayColorSetting(
                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq);
 
+        /* For Histogram */
+        virtual int32_t setDisplayHistogramSetting(
+            ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) override;
+        virtual void registerHistogramInfo(const std::shared_ptr<IDLHistogram> &info) override;
+
     private:
-        int32_t createCgcDMAFromIDqe(const IDisplayColorGS101::IDqe::CgcData &cgcData);
+        int32_t createCgcDMAFromIDqe(const GsInterfaceType::IDqe::CgcData &cgcData);
         int32_t setCgcLutDmaProperty(const DrmProperty &prop,
                                      ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq);
+        /* For Histogram */
+        int32_t setHistoPosProperty(
+            const DrmProperty &prop,
+            ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq);
 
         bool mCgcEnabled = false;
 
         using CGCDataInfo = std::pair<int32_t, struct cgc_dma_lut *>;
         std::vector<CGCDataInfo> mCGCDataInfos;
         size_t iCGCDataInfo = 0;
+        /* For Histogram */
+        std::shared_ptr<IDLHistogram> mHistogramInfo;
 };
 
 class ExynosPrimaryDisplayDrmInterfaceModule : public ExynosDisplayDrmInterfaceModule {
diff --git a/libhwc2.1/libresource/ExynosMPPModule.cpp b/libhwc2.1/libresource/ExynosMPPModule.cpp
new file mode 100644
index 0000000..c532117
--- /dev/null
+++ b/libhwc2.1/libresource/ExynosMPPModule.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "ExynosMPPModule.h"
+
+#include "ExynosHWCDebug.h"
+#include "ExynosPrimaryDisplayModule.h"
+#include "ExynosResourceManager.h"
+
+using namespace gs201;
+
+ExynosMPPModule::ExynosMPPModule(ExynosResourceManager *resourceManager, uint32_t physicalType,
+                                 uint32_t logicalType, const char *name, uint32_t physicalIndex,
+                                 uint32_t logicalIndex, uint32_t preAssignInfo)
+      : gs101::ExynosMPPModule(resourceManager, physicalType, logicalType, name, physicalIndex,
+                               logicalIndex, preAssignInfo) {}
+
+ExynosMPPModule::~ExynosMPPModule() {}
+
+/* This function is used to restrict case that current MIF voting can't cover
+ * it. Once a solution is ready, the restriction need to be removed.
+ */
+bool ExynosMPPModule::checkSpecificRestriction(const uint32_t refreshRate,
+                                               const struct exynos_image &src,
+                                               const struct exynos_image &dst) {
+    /* additional restriction for composer in high refresh rate */
+    if (mPhysicalType < MPP_DPP_NUM && refreshRate >= 90) {
+        VendorGraphicBufferMeta gmeta(src.bufferHandle);
+
+        if (isFormatYUV(gmeta.format)) {
+            // 16:9 4k or large YUV layer
+            if (src.w >= 3584 && src.h >= 1600) {
+                return true;
+            }
+            // 9:16 4k or large YUV layer
+            if (src.h >= 2600 && src.w >= 1450 && src.h > dst.h && (dst.h * 100 / src.h) < 67) {
+                return true;
+            }
+        } else if (src.w >= 1680 && src.h > dst.h && (dst.h * 100 / src.h) < 60) {
+            // vertical downscale RGB layer
+            return true;
+        }
+    }
+
+    return ExynosMPP::checkSpecificRestriction(refreshRate, src, dst);
+}
+
+int64_t ExynosMPPModule::isSupported(ExynosDisplay &display,
+                                     struct exynos_image &src,
+                                     struct exynos_image &dst) {
+    if (mPhysicalType < MPP_DPP_NUM && src.bufferHandle != nullptr) {
+        const uint32_t refreshRate = display.getBtsRefreshRate();
+
+        if (checkSpecificRestriction(refreshRate, src, dst)) {
+            return -eMPPSatisfiedRestriction;
+        }
+    }
+
+    return ExynosMPP::isSupported(display, src, dst);
+}
diff --git a/libhwc2.1/libresource/ExynosMPPModule.h b/libhwc2.1/libresource/ExynosMPPModule.h
index 1ecacdf..662c2c4 100644
--- a/libhwc2.1/libresource/ExynosMPPModule.h
+++ b/libhwc2.1/libresource/ExynosMPPModule.h
@@ -21,7 +21,19 @@
 
 namespace gs201 {
 
-using ExynosMPPModule = gs101::ExynosMPPModule;
+class ExynosMPPModule : public gs101::ExynosMPPModule {
+    public:
+        ExynosMPPModule(ExynosResourceManager* resourceManager, uint32_t physicalType,
+                        uint32_t logicalType, const char *name,
+                        uint32_t physicalIndex, uint32_t logicalIndex,
+                        uint32_t preAssignInfo);
+        ~ExynosMPPModule();
+        virtual int64_t isSupported(ExynosDisplay &display, struct exynos_image &src,
+                                    struct exynos_image &dst);
+        virtual bool checkSpecificRestriction(const uint32_t __unused refreshRate,
+                                              const struct exynos_image &src,
+                                              const struct exynos_image &dst);
+};
 
 }  // namespace gs201