1 /* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #ifndef __COLOR_PARAMS_H__ 31 #define __COLOR_PARAMS_H__ 32 33 #include <stdio.h> 34 #include <string.h> 35 #include <utils/locker.h> 36 #include <utils/constants.h> 37 #include <core/sdm_types.h> 38 #include <core/display_interface.h> 39 #include "hw_info_types.h" 40 41 namespace sdm { 42 43 // Bitmap Pending action to indicate to the caller what's pending to be taken care of. 44 enum PendingAction { 45 kInvalidating = BITMAP(0), 46 kApplySolidFill = BITMAP(1), 47 kDisableSolidFill = BITMAP(2), 48 kEnterQDCMMode = BITMAP(3), 49 kExitQDCMMode = BITMAP(4), 50 kSetPanelBrightness = BITMAP(5), 51 kNoAction = BITMAP(31), 52 }; 53 54 // ENUM to identify different Postprocessing feature block to program. 55 // Note: For each new entry added here, also need update hw_interface::GetPPFeaturesVersion<> 56 // AND HWPrimary::SetPPFeatures<>. 57 enum PPGlobalColorFeatureID { 58 kGlobalColorFeaturePcc, 59 kGlobalColorFeatureIgc, 60 kGlobalColorFeaturePgc, 61 kMixerColorFeatureGc, 62 kGlobalColorFeaturePaV2, 63 kGlobalColorFeatureDither, 64 kGlobalColorFeatureGamut, 65 kGlobalColorFeaturePADither, 66 kMaxNumPPFeatures, 67 }; 68 69 struct PPPendingParams { 70 PendingAction action = kNoAction; 71 void *params = NULL; 72 }; 73 74 struct PPColorInfo { 75 uint32_t r_bitdepth = 0; 76 uint32_t r = 0; 77 uint32_t g_bitdepth = 0; 78 uint32_t g = 0; 79 uint32_t b_bitdepth = 0; 80 uint32_t b = 0; 81 }; 82 83 struct PPColorFillParams { 84 uint32_t flags = 0; 85 struct { 86 uint32_t width = 0; 87 uint32_t height = 0; 88 int32_t x = 0; 89 int32_t y = 0; 90 } rect; 91 92 PPColorInfo color; 93 }; 94 95 struct PPFeatureVersion { 96 // SDE ASIC versioning its PP block at each specific feature level. 97 static const uint32_t kSDEIgcV17 = 1; 98 static const uint32_t kSDEPgcV17 = 5; 99 static const uint32_t kSDEDitherV17 = 7; 100 static const uint32_t kSDEGamutV17 = 9; 101 static const uint32_t kSDEPaV17 = 11; 102 static const uint32_t kSDEPccV17 = 13; 103 static const uint32_t kSDEPADitherV17 = 15; 104 static const uint32_t kSDELegacyPP = 17; 105 106 uint32_t version[kMaxNumPPFeatures]; PPFeatureVersionPPFeatureVersion107 PPFeatureVersion() { memset(version, 0, sizeof(version)); } 108 }; 109 110 struct PPHWAttributes : HWResourceInfo, HWPanelInfo, DisplayConfigVariableInfo { 111 char panel_name[256] = "generic_panel"; 112 PPFeatureVersion version; 113 int panel_max_brightness = 0; 114 115 void Set(const HWResourceInfo &hw_res, const HWPanelInfo &panel_info, 116 const DisplayConfigVariableInfo &attr, const PPFeatureVersion &feature_ver); 117 }; 118 119 struct PPDisplayAPIPayload { 120 bool own_payload = false; // to indicate if *payload is owned by this or just a reference. 121 uint32_t size = 0; 122 uint8_t *payload = NULL; 123 124 PPDisplayAPIPayload() = default; PPDisplayAPIPayloadPPDisplayAPIPayload125 PPDisplayAPIPayload(uint32_t size, uint8_t *param) 126 : size(size), payload(param) {} 127 128 template <typename T> CreatePayloadPPDisplayAPIPayload129 DisplayError CreatePayload(T *&output) { 130 DisplayError ret = kErrorNone; 131 132 payload = new uint8_t[sizeof(T)](); 133 if (!payload) { 134 ret = kErrorMemory; 135 output = NULL; 136 } else { 137 this->size = sizeof(T); 138 output = reinterpret_cast<T *>(payload); 139 own_payload = true; 140 } 141 return ret; 142 } 143 DestroyPayloadPPDisplayAPIPayload144 inline void DestroyPayload() { 145 if (payload && own_payload) { 146 delete[] payload; 147 payload = NULL; 148 size = 0; 149 } else { 150 payload = NULL; 151 size = 0; 152 } 153 } 154 }; 155 156 struct SDEGamutCfg { 157 static const int kGamutTableNum = 4; 158 static const int kGamutScaleoffTableNum = 3; 159 static const int kGamutTableSize = 1229; 160 static const int kGamutTableCoarseSize = 32; 161 static const int kGamutScaleoffSize = 16; 162 uint32_t mode; 163 uint32_t map_en; 164 uint32_t tbl_size[kGamutTableNum]; 165 uint32_t *c0_data[kGamutTableNum]; 166 uint32_t *c1_c2_data[kGamutTableNum]; 167 uint32_t tbl_scale_off_sz[kGamutScaleoffTableNum]; 168 uint32_t *scale_off_data[kGamutScaleoffTableNum]; 169 }; 170 171 struct SDEPccCoeff { 172 uint32_t c = 0; 173 uint32_t r = 0; 174 uint32_t g = 0; 175 uint32_t b = 0; 176 uint32_t rg = 0; 177 uint32_t gb = 0; 178 uint32_t rb = 0; 179 uint32_t rgb = 0; 180 }; 181 182 struct SDEPccCfg { 183 SDEPccCoeff red; 184 SDEPccCoeff green; 185 SDEPccCoeff blue; 186 187 static SDEPccCfg *Init(uint32_t arg __attribute__((__unused__))); GetConfigSDEPccCfg188 SDEPccCfg *GetConfig() { return this; } 189 }; 190 191 struct SDEDitherCfg { 192 uint32_t g_y_depth; 193 uint32_t r_cr_depth; 194 uint32_t b_cb_depth; 195 uint32_t length; 196 uint32_t dither_matrix[16]; 197 uint32_t temporal_en; 198 199 static SDEDitherCfg *Init(uint32_t arg __attribute__((__unused__))); GetConfigSDEDitherCfg200 SDEDitherCfg *GetConfig() { return this; } 201 }; 202 203 struct SDEPADitherData { 204 uint32_t data_flags; 205 uint32_t matrix_size; 206 uint64_t matrix_data_addr; 207 uint32_t strength; 208 uint32_t offset_en; 209 }; 210 211 class SDEPADitherWrapper : private SDEPADitherData { 212 public: 213 static SDEPADitherWrapper *Init(uint32_t arg __attribute__((__unused__))); ~SDEPADitherWrapper()214 ~SDEPADitherWrapper() { 215 if (buffer_) 216 delete[] buffer_; 217 } GetConfig(void)218 inline SDEPADitherData *GetConfig(void) { return this; } 219 220 private: SDEPADitherWrapper()221 SDEPADitherWrapper() {} 222 uint32_t *buffer_ = NULL; 223 }; 224 225 struct SDEPaMemColorData { 226 uint32_t adjust_p0 = 0; 227 uint32_t adjust_p1 = 0; 228 uint32_t adjust_p2 = 0; 229 uint32_t blend_gain = 0; 230 uint8_t sat_hold = 0; 231 uint8_t val_hold = 0; 232 uint32_t hue_region = 0; 233 uint32_t sat_region = 0; 234 uint32_t val_region = 0; 235 }; 236 237 struct SDEPaData { 238 static const int kSixZoneLUTSize = 384; 239 uint32_t mode = 0; 240 uint32_t hue_adj = 0; 241 uint32_t sat_adj = 0; 242 uint32_t val_adj = 0; 243 uint32_t cont_adj; 244 SDEPaMemColorData skin; 245 SDEPaMemColorData sky; 246 SDEPaMemColorData foliage; 247 uint32_t six_zone_thresh = 0; 248 uint32_t six_zone_adj_p0 = 0; 249 uint32_t six_zone_adj_p1 = 0; 250 uint8_t six_zone_sat_hold = 0; 251 uint8_t six_zone_val_hold = 0; 252 uint32_t six_zone_len = 0; 253 uint32_t *six_zone_curve_p0 = NULL; 254 uint32_t *six_zone_curve_p1 = NULL; 255 }; 256 257 struct SDEIgcLUTData { 258 static const int kMaxIgcLUTEntries = 256; 259 uint32_t table_fmt = 0; 260 uint32_t len = 0; 261 uint32_t *c0_c1_data = NULL; 262 uint32_t *c2_data = NULL; 263 }; 264 265 struct SDEPgcLUTData { 266 static const int kPgcLUTEntries = 1024; 267 uint32_t len = 0; 268 uint32_t *c0_data = NULL; 269 uint32_t *c1_data = NULL; 270 uint32_t *c2_data = NULL; 271 }; 272 273 // Wrapper on HW block config data structure to encapsulate the details of allocating 274 // and destroying from the caller. 275 class SDEGamutCfgWrapper : private SDEGamutCfg { 276 public: 277 enum GamutMode { 278 GAMUT_FINE_MODE = 0x01, 279 GAMUT_COARSE_MODE, 280 }; 281 282 // This factory method will be used by libsdm-color.so data producer to be populated with 283 // converted config values for SDE feature blocks. 284 static SDEGamutCfgWrapper *Init(uint32_t arg); 285 286 // Data consumer<Commit thread> will be responsible to destroy it once the feature is commited. ~SDEGamutCfgWrapper()287 ~SDEGamutCfgWrapper() { 288 if (buffer_) 289 delete[] buffer_; 290 } 291 292 // Data consumer will use this method to retrieve contained feature configuration. GetConfig(void)293 inline SDEGamutCfg *GetConfig(void) { return this; } 294 295 private: SDEGamutCfgWrapper()296 SDEGamutCfgWrapper() {} 297 uint32_t *buffer_ = NULL; 298 }; 299 300 class SDEPaCfgWrapper : private SDEPaData { 301 public: 302 static SDEPaCfgWrapper *Init(uint32_t arg = 0); ~SDEPaCfgWrapper()303 ~SDEPaCfgWrapper() { 304 if (buffer_) 305 delete[] buffer_; 306 } GetConfig(void)307 inline SDEPaData *GetConfig(void) { return this; } 308 309 private: SDEPaCfgWrapper()310 SDEPaCfgWrapper() {} 311 uint32_t *buffer_ = NULL; 312 }; 313 314 class SDEIgcLUTWrapper : private SDEIgcLUTData { 315 public: 316 static SDEIgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__))); ~SDEIgcLUTWrapper()317 ~SDEIgcLUTWrapper() { 318 if (buffer_) 319 delete[] buffer_; 320 } GetConfig(void)321 inline SDEIgcLUTData *GetConfig(void) { return this; } 322 323 private: SDEIgcLUTWrapper()324 SDEIgcLUTWrapper() {} 325 uint32_t *buffer_ = NULL; 326 }; 327 328 class SDEPgcLUTWrapper : private SDEPgcLUTData { 329 public: 330 static SDEPgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__))); ~SDEPgcLUTWrapper()331 ~SDEPgcLUTWrapper() { 332 if (buffer_) 333 delete[] buffer_; 334 } GetConfig(void)335 inline SDEPgcLUTData *GetConfig(void) { return this; } 336 337 private: SDEPgcLUTWrapper()338 SDEPgcLUTWrapper() {} 339 uint32_t *buffer_ = NULL; 340 }; 341 342 // Base Postprocessing features information. 343 class PPFeatureInfo { 344 public: 345 uint32_t enable_flags_ = 0; // bitmap to indicate subset of parameters enabling or not. 346 uint32_t feature_version_ = 0; 347 uint32_t feature_id_ = 0; 348 uint32_t disp_id_ = 0; 349 uint32_t pipe_id_ = 0; 350 ~PPFeatureInfo()351 virtual ~PPFeatureInfo() {} 352 virtual void *GetConfigData(void) const = 0; 353 }; 354 355 // Individual Postprocessing feature representing physical attributes and information 356 // This template class wrapping around abstract data type representing different 357 // post-processing features. It will take output from ColorManager converting from raw metadata. 358 // The configuration will directly pass into HWInterface to program the hardware accordingly. 359 template <typename T> 360 class TPPFeatureInfo : public PPFeatureInfo { 361 public: ~TPPFeatureInfo()362 virtual ~TPPFeatureInfo() { 363 if (params_) 364 delete params_; 365 } 366 367 // API for data consumer to get underlying data configs to program into pp hardware block. GetConfigData(void)368 virtual void *GetConfigData(void) const { return params_->GetConfig(); } 369 370 // API for data producer to get access to underlying data configs to populate it. GetParamsReference(void)371 T *GetParamsReference(void) { return params_; } 372 373 // API for create this template object. 374 static TPPFeatureInfo *Init(uint32_t arg = 0) { 375 TPPFeatureInfo *info = new TPPFeatureInfo(); 376 if (info) { 377 info->params_ = T::Init(arg); 378 if (!info->params_) { 379 delete info; 380 info = NULL; 381 } 382 } 383 384 return info; 385 } 386 387 protected: 388 TPPFeatureInfo() = default; 389 390 private: 391 T *params_ = NULL; 392 }; 393 394 // This singleton class serves as data exchanging central between data producer 395 // <libsdm-color.so> and data consumer<SDM and HWC.> 396 // This class defines PP pending features to be programmed, which generated from 397 // ColorManager. Dirty flag indicates some features are available to be programmed. 398 // () Lock is needed since the object wil be accessed from 2 tasks. 399 // All API exposed are not threadsafe, it's caller's responsiblity to acquire the locker. 400 class PPFeaturesConfig { 401 public: PPFeaturesConfig()402 PPFeaturesConfig() { memset(feature_, 0, sizeof(feature_)); } ~PPFeaturesConfig()403 ~PPFeaturesConfig() { Reset(); } 404 405 // ColorManager installs one TFeatureInfo<T> to take the output configs computed 406 // from ColorManager, containing all physical features to be programmed and also compute 407 // metadata/populate into T. AddFeature(uint32_t feature_id,PPFeatureInfo * feature)408 inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) { 409 if (feature_id < kMaxNumPPFeatures) 410 feature_[feature_id] = feature; 411 412 return kErrorNone; 413 } 414 GetLocker(void)415 inline Locker &GetLocker(void) { return locker_; } 416 417 // Once all features are consumed, destroy/release all TFeatureInfo<T> on the list, 418 // then clear dirty_ flag and return the lock to the TFeatureInfo<T> producer. 419 void Reset(); 420 421 // Consumer to call this to retrieve all the TFeatureInfo<T> on the list to be programmed. 422 DisplayError RetrieveNextFeature(PPFeatureInfo **feature); 423 IsDirty()424 inline bool IsDirty() { return dirty_; } MarkAsDirty()425 inline void MarkAsDirty() { dirty_ = true; } 426 427 private: 428 bool dirty_ = 0; 429 Locker locker_; 430 PPFeatureInfo *feature_[kMaxNumPPFeatures]; // reference to TFeatureInfo<T>. 431 uint32_t next_idx_ = 0; 432 }; 433 434 } // namespace sdm 435 436 #endif // __COLOR_PARAMS_H__ 437