Home | History | Annotate | Download | only in hwc2
      1 /*
      2 * Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
      3 *
      4 * Redistribution and use in source and binary forms, with or without
      5 * modification, are permitted provided that the following conditions are
      6 * met:
      7 *     * Redistributions of source code must retain the above copyright
      8 *       notice, this list of conditions and the following disclaimer.
      9 *     * Redistributions in binary form must reproduce the above
     10 *       copyright notice, this list of conditions and the following
     11 *       disclaimer in the documentation and/or other materials provided
     12 *       with the distribution.
     13 *     * Neither the name of The Linux Foundation nor the names of its
     14 *       contributors may be used to endorse or promote products derived
     15 *       from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <dlfcn.h>
     31 #include <cutils/sockets.h>
     32 #include <cutils/native_handle.h>
     33 #include <utils/String16.h>
     34 #include <binder/Parcel.h>
     35 #include <gralloc_priv.h>
     36 #include <hardware/hwcomposer.h>
     37 #include <hardware/hwcomposer_defs.h>
     38 #include <QService.h>
     39 
     40 #include <utils/constants.h>
     41 #include <utils/debug.h>
     42 #include <core/buffer_allocator.h>
     43 #include <private/color_params.h>
     44 #include "hwc_buffer_allocator.h"
     45 #include "hwc_buffer_sync_handler.h"
     46 #include "hwc_session.h"
     47 #include "hwc_debugger.h"
     48 
     49 #define __CLASS__ "HWCColorManager"
     50 
     51 namespace sdm {
     52 
     53 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
     54   uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
     55                         ((params.color.b) & 0xff);
     56   return argb_color;
     57 }
     58 
     59 int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
     60                                              PPDisplayAPIPayload *sink) {
     61   int ret = 0;
     62   uint32_t id(0);
     63   uint32_t size(0);
     64 
     65   id = UINT32(in.readInt32());
     66   size = UINT32(in.readInt32());
     67   if (size > 0 && size == in.dataAvail()) {
     68     const void *data = in.readInplace(size);
     69     const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
     70 
     71     sink->size = size;
     72     sink->payload = const_cast<uint8_t *>(temp);
     73     *disp_id = id;
     74   } else {
     75     DLOGW("Failing size checking, size = %d", size);
     76     ret = -EINVAL;
     77   }
     78 
     79   return ret;
     80 }
     81 
     82 void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
     83                                                android::Parcel *out_parcel) {
     84   out_parcel->writeInt32(INT32(data.size));
     85   if (data.payload)
     86     out_parcel->write(data.payload, data.size);
     87 }
     88 
     89 HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) {
     90   HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator);
     91 
     92   if (color_mgr) {
     93     // Load display API interface library. And retrieve color API function tables.
     94     DynLib &color_apis_lib = color_mgr->color_apis_lib_;
     95     if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
     96       if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
     97         DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
     98               DISPLAY_API_INTERFACE_LIBRARY_NAME);
     99         delete color_mgr;
    100         return NULL;
    101       }
    102     } else {
    103       DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
    104       delete color_mgr;
    105       return NULL;
    106     }
    107     DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
    108 
    109     // Load diagclient library and invokes its entry point to pass in display APIs.
    110     DynLib &diag_client_lib = color_mgr->diag_client_lib_;
    111     if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
    112       if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
    113                                reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
    114         !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
    115                                reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
    116         DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
    117               QDCM_DIAG_CLIENT_LIBRARY_NAME);
    118       } else {
    119         // invoke Diag Client entry point to initialize.
    120         color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
    121         DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
    122               QDCM_DIAG_CLIENT_LIBRARY_NAME);
    123       }
    124     } else {
    125       DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
    126       // only QDCM Diag client failed to be loaded and system still should function.
    127     }
    128   } else {
    129     DLOGE("Unable to create HWCColorManager");
    130     return NULL;
    131   }
    132 
    133   return color_mgr;
    134 }
    135 
    136 HWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) :
    137     buffer_allocator_(buffer_allocator) {
    138 }
    139 
    140 HWCColorManager::~HWCColorManager() {
    141 }
    142 
    143 void HWCColorManager::DestroyColorManager() {
    144   if (qdcm_mode_mgr_) {
    145     delete qdcm_mode_mgr_;
    146   }
    147   if (qdcm_diag_deinit_) {
    148     qdcm_diag_deinit_();
    149   }
    150   delete this;
    151 }
    152 
    153 int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
    154   int ret = 0;
    155 
    156   if (!qdcm_mode_mgr_) {
    157     qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
    158     if (!qdcm_mode_mgr_) {
    159       DLOGE("Unable to create QDCM operating mode manager.");
    160       ret = -EFAULT;
    161     }
    162   }
    163 
    164   if (qdcm_mode_mgr_) {
    165     ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
    166   }
    167 
    168   return ret;
    169 }
    170 
    171 int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
    172   SCOPE_LOCK(locker_);
    173 
    174   if (params) {
    175     solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
    176   } else {
    177     solid_fill_params_ = PPColorFillParams();
    178   }
    179 
    180   uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
    181   if (enable) {
    182     LayerRect solid_fill_rect = {
    183       FLOAT(solid_fill_params_.rect.x), FLOAT(solid_fill_params_.rect.y),
    184       FLOAT(solid_fill_params_.rect.x) + FLOAT(solid_fill_params_.rect.width),
    185       FLOAT(solid_fill_params_.rect.y) + FLOAT(solid_fill_params_.rect.height),
    186     };
    187 
    188     hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
    189     hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_RECT, &solid_fill_rect);
    190   } else {
    191     hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
    192   }
    193 
    194   return 0;
    195 }
    196 
    197 int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
    198   SCOPE_LOCK(locker_);
    199   int ret = 0;
    200 
    201   PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params);
    202 
    203   if (enable) {
    204     std::memset(&buffer_info, 0x00, sizeof(buffer_info));
    205     hwc_display->GetPanelResolution(&buffer_info.buffer_config.width,
    206                                     &buffer_info.buffer_config.height);
    207     if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
    208       buffer_info.buffer_config.format = kFormatRGB888;
    209     } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
    210       buffer_info.buffer_config.format = kFormatRGBA1010102;
    211     } else {
    212       DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
    213       return -EFAULT;
    214     }
    215 
    216     buffer_info.buffer_config.buffer_count = 1;
    217     buffer_info.alloc_buffer_info.fd = -1;
    218     buffer_info.alloc_buffer_info.stride = 0;
    219     buffer_info.alloc_buffer_info.size = 0;
    220 
    221     ret = buffer_allocator_->AllocateBuffer(&buffer_info);
    222     if (ret != 0) {
    223       DLOGE("Buffer allocation failed. ret: %d", ret);
    224       return -ENOMEM;
    225     } else {
    226       void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
    227                           MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
    228 
    229       if (buffer == MAP_FAILED) {
    230         DLOGE("mmap failed. err = %d", errno);
    231         frame_capture_data->buffer = NULL;
    232         ret = buffer_allocator_->FreeBuffer(&buffer_info);
    233         return -EFAULT;
    234       } else {
    235         frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
    236         frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
    237         frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
    238       }
    239       ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
    240       if (ret < 0) {
    241         DLOGE("FrameCaptureAsync failed. ret = %d", ret);
    242       }
    243     }
    244   } else {
    245     ret = hwc_display->GetFrameCaptureStatus();
    246     if (!ret) {
    247       if (frame_capture_data->buffer != NULL) {
    248         if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
    249           DLOGE("munmap failed. err = %d", errno);
    250         }
    251       }
    252       if (buffer_allocator_ != NULL) {
    253         std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
    254         ret = buffer_allocator_->FreeBuffer(&buffer_info);
    255         if (ret != 0) {
    256           DLOGE("FreeBuffer failed. ret = %d", ret);
    257         }
    258       }
    259     } else {
    260       DLOGE("GetFrameCaptureStatus failed. ret = %d", ret);
    261     }
    262   }
    263   return ret;
    264 }
    265 
    266 int HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) {
    267   int err = -1;
    268   DisplayDetailEnhancerData de_data;
    269 
    270   PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
    271   if (de_tuning_cfg_data->cfg_pending == true) {
    272     if (!de_tuning_cfg_data->cfg_en) {
    273       de_data.enable = 0;
    274     } else {
    275       de_data.override_flags = kOverrideDEEnable;
    276       de_data.enable = 1;
    277 
    278       if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
    279         de_data.override_flags |= kOverrideDESharpen1;
    280         de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
    281       }
    282 
    283       if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
    284         de_data.override_flags |= kOverrideDEClip;
    285         de_data.clip = de_tuning_cfg_data->params.clip;
    286       }
    287 
    288       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
    289         de_data.override_flags |= kOverrideDEThrQuiet;
    290         de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
    291       }
    292 
    293       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
    294         de_data.override_flags |= kOverrideDEThrDieout;
    295         de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
    296       }
    297 
    298       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
    299         de_data.override_flags |= kOverrideDEThrLow;
    300         de_data.thr_low = de_tuning_cfg_data->params.thr_low;
    301       }
    302 
    303       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
    304         de_data.override_flags |= kOverrideDEThrHigh;
    305         de_data.thr_high = de_tuning_cfg_data->params.thr_high;
    306       }
    307 
    308       if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
    309         switch (de_tuning_cfg_data->params.quality) {
    310           case kDeContentQualLow:
    311             de_data.quality_level = kContentQualityLow;
    312             break;
    313           case kDeContentQualMedium:
    314             de_data.quality_level = kContentQualityMedium;
    315             break;
    316           case kDeContentQualHigh:
    317             de_data.quality_level = kContentQualityHigh;
    318             break;
    319           case kDeContentQualUnknown:
    320           default:
    321             de_data.quality_level = kContentQualityUnknown;
    322             break;
    323         }
    324       }
    325     }
    326     err = hwc_display->SetDetailEnhancerConfig(de_data);
    327     if (err) {
    328       DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
    329     }
    330     de_tuning_cfg_data->cfg_pending = false;
    331   }
    332   return err;
    333 }
    334 
    335 void HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) {
    336   SCOPE_LOCK(locker_);
    337   int err = -1;
    338   PPPendingParams pending_action;
    339   PPDisplayAPIPayload req_payload;
    340 
    341   pending_action.action = kGetDetailedEnhancerData;
    342   pending_action.params = NULL;
    343 
    344   if (hwc_display) {
    345     err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action);
    346     if (!err && pending_action.action == kConfigureDetailedEnhancer) {
    347       err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display);
    348     }
    349   }
    350   return;
    351 }
    352 
    353 int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
    354   SCOPE_LOCK(locker_);
    355   int err = -1;
    356   err = SetHWDetailedEnhancerConfig(params, hwc_display);
    357   return err;
    358 }
    359 
    360 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
    361     HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
    362     HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
    363     HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
    364 };
    365 
    366 const char *const HWCQDCMModeManager::kSocketName = "pps";
    367 const char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
    368 const char *const HWCQDCMModeManager::kPackageName = "colormanager";
    369 
    370 HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
    371   HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
    372 
    373   if (!mode_mgr) {
    374     DLOGW("No memory to create HWCQDCMModeManager.");
    375     return NULL;
    376   } else {
    377     mode_mgr->socket_fd_ =
    378         ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    379     if (mode_mgr->socket_fd_ < 0) {
    380       // it should not be disastrous and we still can grab wakelock in QDCM mode.
    381       DLOGW("Unable to connect to dpps socket!");
    382     }
    383 
    384     // retrieve system GPU idle timeout value for later to recover.
    385     mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
    386   }
    387 
    388   return mode_mgr;
    389 }
    390 
    391 HWCQDCMModeManager::~HWCQDCMModeManager() {
    392   if (socket_fd_ >= 0)
    393     ::close(socket_fd_);
    394 }
    395 
    396 int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
    397                                              const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
    398                                              bool *was_running) {
    399   int ret = 0;
    400   ssize_t size = 0;
    401   char response[kSocketCMDMaxLength] = {
    402       0,
    403   };
    404 
    405   if (socket_fd_ < 0) {
    406     DLOGW("No socket connection available!");
    407     return -EFAULT;
    408   }
    409 
    410   if (!enable) {  // if client requesting to disable it.
    411     // query CABL status, if off, no action. keep the status.
    412     size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
    413     if (size < 0) {
    414       DLOGW("Unable to send data over socket %s", ::strerror(errno));
    415       ret = -EFAULT;
    416     } else {
    417       size = ::read(socket_fd_, response, kSocketCMDMaxLength);
    418       if (size < 0) {
    419         DLOGW("Unable to read data over socket %s", ::strerror(errno));
    420         ret = -EFAULT;
    421       } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
    422         *was_running = true;
    423       }
    424     }
    425 
    426     if (*was_running) {  // if was running, it's requested to disable it.
    427       size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
    428       if (size < 0) {
    429         DLOGW("Unable to send data over socket %s", ::strerror(errno));
    430         ret = -EFAULT;
    431       }
    432     }
    433   } else {  // if was running, need enable it back.
    434     if (*was_running) {
    435       size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
    436       if (size < 0) {
    437         DLOGW("Unable to send data over socket %s", ::strerror(errno));
    438         ret = -EFAULT;
    439       }
    440     }
    441   }
    442 
    443   return ret;
    444 }
    445 
    446 int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
    447   int ret = 0;
    448 
    449   ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
    450                              &cabl_was_running_);
    451 
    452   // if enter QDCM mode, disable GPU fallback idle timeout.
    453   if (hwc_display) {
    454     uint32_t timeout = enable ? 0 : entry_timeout_;
    455     hwc_display->SetIdleTimeoutMs(timeout);
    456   }
    457 
    458   return ret;
    459 }
    460 
    461 } // namespace sdm
    462