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