summaryrefslogtreecommitdiff
path: root/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h
blob: c6404d385b759aaac99848b4897c0e41e2e0a2a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
 * Copyright (C) 2019 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 EXYNOS_DISPLAY_MODULE_H
#define EXYNOS_DISPLAY_MODULE_H

#include "ExynosDeviceModule.h"
#include "ExynosDisplay.h"
#include "ExynosLayer.h"
#include "ExynosPrimaryDisplay.h"

constexpr char kAtcJsonRaw[] =
        "{\"version\":\"0.0\",\"modes\":[{\"name\":\"normal\",\"lux_map\":[0,5000,10000,"
        "50000,70000],\"ambient_light_map\":[0,0,12,32,63],\"strength_map\":[0,0,128,128,200],"
        "\"st_up_step\":2, \"st_down_step\":2,"
        "\"sub_setting\":{\"local_tone_gain\":128,\"noise_suppression_gain\":128,\"dither\":0,"
        "\"plain_weight_1\":10,\"plain_weight_2\":14,\"color_transform_mode\":2,\"preprocessing_"
        "enable\":1,\"upgrade_on\":0,\"TDR_max\":900,\"TDR_min\":256,\"backlight\":255,\"dimming_"
        "step\":4,\"scale_mode\":1,\"threshold_1\":1,\"threshold_2\":1,\"threshold_3\":1,\"gain_"
        "limit\":511,\"lt_calc_ab_shift\":1}}]}";

constexpr char kAtcProfilePath[] = "vendor/etc/atc_profile.json";
constexpr char kAtcProfileVersionStr[] = "version";
constexpr char kAtcProfileModesStr[] = "modes";
constexpr char kAtcProfileModeNameStr[] = "name";
constexpr char kAtcProfileLuxMapStr[] = "lux_map";
constexpr char kAtcProfileAlMapStr[] = "ambient_light_map";
constexpr char kAtcProfileStMapStr[] = "strength_map";
constexpr char kAtcProfileSubSettingStr[] = "sub_setting";
constexpr char kAtcProfileStUpStepStr[] = "st_up_step";
constexpr char kAtcProfileStDownStepStr[] = "st_down_step";
constexpr uint32_t kAtcStStep = 2;

constexpr char kAtcModeNormalStr[] = "normal";
constexpr char kAtcModeHbmStr[] = "hbm";
constexpr char kAtcModePowerSaveStr[] = "power_save";

#define ATC_AMBIENT_LIGHT_FILE_NAME "/sys/class/dqe%d/atc/ambient_light"
#define ATC_ST_FILE_NAME "/sys/class/dqe%d/atc/st"
#define ATC_ENABLE_FILE_NAME "/sys/class/dqe%d/atc/en"
#define ATC_LT_FILE_NAME "/sys/class/dqe%d/atc/lt"
#define ATC_NS_FILE_NAME "/sys/class/dqe%d/atc/ns"
#define ATC_DITHER_FILE_NAME "/sys/class/dqe%d/atc/dither"
#define ATC_PL_W1_FILE_NAME "/sys/class/dqe%d/atc/pl_w1"
#define ATC_PL_W2_FILE_NAME "/sys/class/dqe%d/atc/pl_w2"
#define ATC_CTMODE_FILE_NAME "/sys/class/dqe%d/atc/ctmode"
#define ATC_PP_EN_FILE_NAME "/sys/class/dqe%d/atc/pp_en"
#define ATC_UPGRADE_ON_FILE_NAME "/sys/class/dqe%d/atc/upgrade_on"
#define ATC_TDR_MAX_FILE_NAME "/sys/class/dqe%d/atc/tdr_max"
#define ATC_TDR_MIN_FILE_NAME "/sys/class/dqe%d/atc/tdr_min"
#define ATC_BACKLIGHT_FILE_NAME "/sys/class/dqe%d/atc/back_light"
#define ATC_DSTEP_FILE_NAME "/sys/class/dqe%d/atc/dstep"
#define ATC_SCALE_MODE_FILE_NAME "/sys/class/dqe%d/atc/scale_mode"
#define ATC_THRESHOLD_1_FILE_NAME "/sys/class/dqe%d/atc/threshold_1"
#define ATC_THRESHOLD_2_FILE_NAME "/sys/class/dqe%d/atc/threshold_2"
#define ATC_THRESHOLD_3_FILE_NAME "/sys/class/dqe%d/atc/threshold_3"
#define ATC_GAIN_LIMIT_FILE_NAME "/sys/class/dqe%d/atc/gain_limit"
#define ATC_LT_CALC_AB_SHIFT_FILE_NAME "/sys/class/dqe%d/atc/lt_calc_ab_shift"

const std::unordered_map<std::string, std::string> kAtcSubSetting =
        {{"local_tone_gain", ATC_LT_FILE_NAME},
         {"noise_suppression_gain", ATC_NS_FILE_NAME},
         {"dither", ATC_DITHER_FILE_NAME},
         {"plain_weight_1", ATC_PL_W1_FILE_NAME},
         {"plain_weight_2", ATC_PL_W2_FILE_NAME},
         {"color_transform_mode", ATC_CTMODE_FILE_NAME},
         {"preprocessing_enable", ATC_PP_EN_FILE_NAME},
         {"upgrade_on", ATC_UPGRADE_ON_FILE_NAME},
         {"TDR_max", ATC_TDR_MAX_FILE_NAME},
         {"TDR_min", ATC_TDR_MIN_FILE_NAME},
         {"backlight", ATC_BACKLIGHT_FILE_NAME},
         {"dimming_step", ATC_DSTEP_FILE_NAME},
         {"scale_mode", ATC_SCALE_MODE_FILE_NAME},
         {"threshold_1", ATC_THRESHOLD_1_FILE_NAME},
         {"threshold_2", ATC_THRESHOLD_2_FILE_NAME},
         {"threshold_3", ATC_THRESHOLD_3_FILE_NAME},
         {"gain_limit", ATC_GAIN_LIMIT_FILE_NAME},
         {"lt_calc_ab_shift", ATC_LT_CALC_AB_SHIFT_FILE_NAME}};

namespace gs101 {

using namespace displaycolor;

class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay {
    using GsInterfaceType = gs::ColorDrmBlobFactory::GsInterfaceType;
    public:
        ExynosPrimaryDisplayModule(uint32_t index, ExynosDevice* device,
                                   const std::string& displayName);
        ~ExynosPrimaryDisplayModule();
        void usePreDefinedWindow(bool use);
        virtual int32_t validateWinConfigData();
        void doPreProcessing();
        virtual int32_t getColorModes(
                uint32_t* outNumModes,
                int32_t* outModes);
        virtual int32_t setColorMode(int32_t mode);
        virtual int32_t getRenderIntents(int32_t mode, uint32_t* outNumIntents,
                int32_t* outIntents);
        virtual int32_t setColorModeWithRenderIntent(int32_t mode,
                int32_t intent);
        virtual int32_t setColorTransform(const float* matrix, int32_t hint);
        virtual int32_t getClientTargetProperty(
                hwc_client_target_property_t* outClientTargetProperty,
                HwcDimmingStage *outDimmingStage = nullptr) override;
        virtual int deliverWinConfigData();
        virtual int32_t updateColorConversionInfo();
        virtual int32_t resetColorMappingInfo(ExynosMPPSource* mppSrc);
        virtual int32_t updatePresentColorConversionInfo();
        virtual bool checkRrCompensationEnabled() {
            const DisplayType display = getDcDisplayType();
            GsInterfaceType* displayColorInterface = getDisplayColorInterface();
            return displayColorInterface
                ? displayColorInterface->IsRrCompensationEnabled(display)
                : false;
        }

        virtual bool isColorCalibratedByDevice();

        virtual int32_t getColorAdjustedDbv(uint32_t &dbv_adj);

        virtual void initLbe();
        virtual bool isLbeSupported();
        virtual void setLbeState(LbeState state);
        virtual void setLbeAmbientLight(int value);
        virtual LbeState getLbeState();

        virtual PanelCalibrationStatus getPanelCalibrationStatus();

        class DisplaySceneInfo {
            public:
                struct LayerMappingInfo {
                    bool operator==(const LayerMappingInfo &rhs) const {
                        return ((dppIdx == rhs.dppIdx) && (planeId == rhs.planeId));
                    }

                    // index in DisplayScene::layer_data
                    uint32_t dppIdx;
                    // assigned drm plane id in last color setting update
                    uint32_t planeId;
                    static constexpr uint32_t kPlaneIdNone = std::numeric_limits<uint32_t>::max();
                };
                bool colorSettingChanged = false;
                bool displaySettingDelivered = false;
                DisplayScene displayScene;

                /*
                 * Index of LayerColorData in DisplayScene::layer_data
                 * and assigned plane id in last color setting update.
                 * for each layer, including client composition
                 * key: ExynosMPPSource*
                 * data: LayerMappingInfo
                 */
                std::map<ExynosMPPSource*, LayerMappingInfo> layerDataMappingInfo;
                std::map<ExynosMPPSource*, LayerMappingInfo> prev_layerDataMappingInfo;

                void reset() {
                    colorSettingChanged = false;
                    prev_layerDataMappingInfo = layerDataMappingInfo;
                    layerDataMappingInfo.clear();
                };

                template <typename T, typename M>
                void updateInfoSingleVal(T &dst, M &src) {
                    if (src != dst) {
                        colorSettingChanged = true;
                        dst = src;
                    }
                };

                template <typename T, typename M>
                void updateInfoVectorVal(std::vector<T> &dst, M *src, uint32_t size) {
                    if ((dst.size() != size) ||
                        !std::equal(dst.begin(), dst.end(), src)) {
                        colorSettingChanged = true;
                        dst.resize(size);
                        for (uint32_t i = 0; i < size; i++) {
                            dst[i] = src[i];
                        }
                    }
                };

                void setColorMode(hwc::ColorMode mode) {
                    updateInfoSingleVal(displayScene.color_mode, mode);
                };

                void setRenderIntent(hwc::RenderIntent intent) {
                    updateInfoSingleVal(displayScene.render_intent, intent);
                };

                void setColorTransform(const float* matrix) {
                    for (uint32_t i = 0; i < displayScene.matrix.size(); i++) {
                        if (displayScene.matrix[i] != matrix[i]) {
                            colorSettingChanged = true;
                            displayScene.matrix[i] = matrix[i];
                        }
                    }
                }

                LayerColorData& getLayerColorDataInstance(uint32_t index);
                int32_t setLayerDataMappingInfo(ExynosMPPSource* layer, uint32_t index);
                void setLayerDataspace(LayerColorData& layerColorData,
                        hwc::Dataspace dataspace);
                void disableLayerHdrStaticMetadata(LayerColorData& layerColorData);
                void setLayerHdrStaticMetadata(LayerColorData& layerColorData,
                        const ExynosHdrStaticInfo& exynosHdrStaticInfo);
                void setLayerColorTransform(LayerColorData& layerColorData,
                        std::array<float, TRANSFORM_MAT_SIZE> &matrix);
                void disableLayerHdrDynamicMetadata(LayerColorData& layerColorData);
                void setLayerHdrDynamicMetadata(LayerColorData& layerColorData,
                        const ExynosHdrDynamicInfo& exynosHdrDynamicInfo);
                int32_t setLayerColorData(LayerColorData& layerData,
                        ExynosLayer* layer, float dimSdrRatio);
                int32_t setClientCompositionColorData(
                    const ExynosCompositionInfo& clientCompositionInfo,
                    LayerColorData& layerData, float dimSdrRatio);
                bool needDisplayColorSetting();
                void printDisplayScene();
                void printLayerColorData(const LayerColorData& layerData);
        };

        bool hasDisplayColor() {
            GsInterfaceType* displayColorInterface = getDisplayColorInterface();
            return displayColorInterface != nullptr;
        }

        /* Call getDppForLayer() only if hasDppForLayer() is true */
        bool hasDppForLayer(ExynosMPPSource* layer);
        const GsInterfaceType::IDpp& getDppForLayer(ExynosMPPSource* layer);
        int32_t getDppIndexForLayer(ExynosMPPSource* layer);
        /* Check if layer's assigned plane id has changed, save the new planeId.
         * call only if hasDppForLayer is true */
        bool checkAndSaveLayerPlaneId(ExynosMPPSource* layer, uint32_t planeId) {
            auto &info = mDisplaySceneInfo.layerDataMappingInfo[layer];
            bool change = info.planeId != planeId;
            info.planeId = planeId;
            return change;
        }

        const GsInterfaceType::IDqe& getDqe()
        {
            const DisplayType display = getDcDisplayType();
            GsInterfaceType* displayColorInterface = getDisplayColorInterface();
            return displayColorInterface->GetPipelineData(display)->Dqe();
        };

        int32_t updateBrightnessTable();

    private:
        int32_t setLayersColorData();
        DisplaySceneInfo mDisplaySceneInfo;

        struct atc_lux_map {
            uint32_t lux;
            uint32_t al;
            uint32_t st;
        };

        struct atc_mode {
            std::vector<atc_lux_map> lux_map;
            std::unordered_map<std::string, int32_t> sub_setting;
            uint32_t st_up_step;
            uint32_t st_down_step;
        };
        struct atc_sysfs {
            String8 node;
            CtrlValue<int32_t> value;
        };

        bool parseAtcProfile();
        int32_t setAtcMode(std::string mode_name);
        uint32_t getAtcLuxMapIndex(std::vector<atc_lux_map>, uint32_t lux);
        int32_t setAtcAmbientLight(uint32_t ambient_light);
        int32_t setAtcStrength(uint32_t strenght);
        int32_t setAtcStDimming(uint32_t target);
        int32_t setAtcEnable(bool enable);
        void checkAtcAnimation();
        bool isInAtcAnimation() {
            if (mAtcStStepCount > 0)
                return true;
            else
                return false;
        };

        GsInterfaceType* getDisplayColorInterface() {
            ExynosDeviceModule* device = (ExynosDeviceModule*)mDevice;
            return device->getDisplayColorInterface();
        }

        bool isForceColorUpdate() const { return mForceColorUpdate; }
        void setForceColorUpdate(bool force) { mForceColorUpdate = force; }
        bool isDisplaySwitched(int32_t mode, int32_t prevMode);

        std::map<std::string, atc_mode> mAtcModeSetting;
        bool mAtcInit;
        LbeState mCurrentLbeState = LbeState::OFF;
        std::string mCurrentAtcModeName;
        uint32_t mCurrentLux = 0;
        uint32_t mAtcLuxMapIndex = 0;
        struct atc_sysfs mAtcAmbientLight;
        struct atc_sysfs mAtcStrength;
        struct atc_sysfs mAtcEnable;
        std::unordered_map<std::string, struct atc_sysfs> mAtcSubSetting;
        uint32_t mAtcStStepCount = 0;
        uint32_t mAtcStTarget = 0;
        uint32_t mAtcStUpStep;
        uint32_t mAtcStDownStep;
        Mutex mAtcStMutex;
        bool mPendingAtcOff;
        bool mForceColorUpdate = false;
        bool mLbeSupported = false;

    protected:
        virtual int32_t setPowerMode(int32_t mode) override;
};

}  // namespace gs101

#endif