diff options
author | YongWook Shin <yongwook.shin@samsung.com> | 2021-01-29 18:46:07 +0900 |
---|---|---|
committer | Susi Su <susisu@google.com> | 2022-03-02 14:17:30 +0000 |
commit | 7d821c3185ba38db706485c9d8657af9d29e37ad (patch) | |
tree | 80ddad10daef29bbf86fd038692458e3f671f628 | |
parent | 53aca61bbf60708eaa17ec0d39002e9e21b965db (diff) | |
download | gs101-7d821c3185ba38db706485c9d8657af9d29e37ad.tar.gz |
libhwc2.1: Add Histogram handling codes
It creates Histogram related functions and adds related
handling codes.
Bug: 197519352
Signed-off-by: YongWook Shin <yongwook.shin@samsung.com>
Change-Id: I405e0b09083eb2c242b6bac81caefebc836f0e9a
Merged-In: I405e0b09083eb2c242b6bac81caefebc836f0e9a
(cherry picked from commit 562d354824eaba5d6e6a04dc7286e8d50e433781)
3 files changed, 269 insertions, 0 deletions
diff --git a/include/gs101/histogram/histogram.h b/include/gs101/histogram/histogram.h new file mode 100644 index 0000000..07a1de1 --- /dev/null +++ b/include/gs101/histogram/histogram.h @@ -0,0 +1,91 @@ +/* + * 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_H_ +#define HISTOGRAM_H_ + +typedef enum { + HISTOGRAM_CONTROL_INVALID = 0, + HISTOGRAM_CONTROL_REQUEST = 1, + HISTOGRAM_CONTROL_CANCEL = 2, +} hidl_histogram_control_t; + +namespace gs101 { + +class HistogramInfo { +public: + enum Histogram_Type { HISTOGRAM_SAMPLING, HISTOGRAM_HIDL, HISTOGRAM_TYPE_NUM }; + /// Histogram ROI information, same definition as in uapi + struct HistogramROI { + uint16_t start_x; + uint16_t start_y; + uint16_t hsize; + uint16_t vsize; + }; + /// Histogram Weights information, same definition as in uapi + struct HistogramWeights { + uint16_t weight_r; + uint16_t weight_g; + uint16_t weight_b; + }; + + void setHistogramROI(uint16_t x, uint16_t y, uint16_t h, uint16_t v) { + mHistogramROI.start_x = x; + mHistogramROI.start_y = y; + mHistogramROI.hsize = h; + mHistogramROI.vsize = v; + }; + const struct HistogramROI& getHistogramROI() { return mHistogramROI; } + + void setHistogramWeights(uint16_t r, uint16_t g, uint16_t b) { + mHistogramWeights.weight_r = r; + mHistogramWeights.weight_g = g; + mHistogramWeights.weight_b = b; + }; + const struct HistogramWeights& getHistogramWeights() { return mHistogramWeights; } + + void setHistogramThreshold(uint32_t t) { mHistogramThreshold = t; } + uint32_t getHistogramThreshold() { return mHistogramThreshold; } + + Histogram_Type getHistogramType() { return mHistogramType; } + + HistogramInfo(Histogram_Type type) { mHistogramType = type; } + virtual ~HistogramInfo() {} + +private: + Histogram_Type mHistogramType = HISTOGRAM_TYPE_NUM; + struct HistogramROI mHistogramROI; + struct HistogramWeights mHistogramWeights; + uint32_t mHistogramThreshold = 0; +}; + +class SamplingHistogram : public HistogramInfo { +public: + SamplingHistogram() : HistogramInfo(HISTOGRAM_SAMPLING) {} + virtual ~SamplingHistogram() {} +}; + +class HIDLHistogram : public HistogramInfo { +public: + HIDLHistogram() : HistogramInfo(HISTOGRAM_HIDL) {} + virtual ~HIDLHistogram() {} + + virtual void CallbackHistogram(void* bin) = 0; +}; + +} // namespace gs101 + +#endif // HISTOGRAM_H_ diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp index df71cfb..bfe8eaa 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp @@ -85,6 +85,9 @@ int32_t ExynosDisplayDrmInterfaceModule::initDrmDevice(DrmDevice *drmDevice) initOldDppBlobs(drmDevice); if (mDrmCrtc->force_bpc_property().id()) parseBpcEnums(mDrmCrtc->force_bpc_property()); + + mOldHistoBlobs.init(drmDevice); + return ret; } @@ -786,6 +789,142 @@ const std::string ExynosDisplayDrmInterfaceModule::GetPanelInfo(const std::strin return info; } +/* For Histogram */ +int32_t ExynosDisplayDrmInterfaceModule::createHistoRoiBlob(uint32_t &blobId) { + struct histogram_roi histo_roi; + + histo_roi.start_x = mHistogramInfo->getHistogramROI().start_x; + histo_roi.start_y = mHistogramInfo->getHistogramROI().start_y; + histo_roi.hsize = mHistogramInfo->getHistogramROI().hsize; + histo_roi.vsize = mHistogramInfo->getHistogramROI().vsize; + + int ret = mDrmDevice->CreatePropertyBlob(&histo_roi, sizeof(histo_roi), &blobId); + if (ret) { + HWC_LOGE(mExynosDisplay, "Failed to create histogram roi blob %d", ret); + return ret; + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::createHistoWeightsBlob(uint32_t &blobId) { + struct histogram_weights histo_weights; + + histo_weights.weight_r = mHistogramInfo->getHistogramWeights().weight_r; + histo_weights.weight_g = mHistogramInfo->getHistogramWeights().weight_g; + histo_weights.weight_b = mHistogramInfo->getHistogramWeights().weight_b; + + int ret = mDrmDevice->CreatePropertyBlob(&histo_weights, sizeof(histo_weights), &blobId); + if (ret) { + HWC_LOGE(mExynosDisplay, "Failed to create histogram weights blob %d", ret); + return ret; + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::setDisplayHistoBlob( + const DrmProperty &prop, const uint32_t type, + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) { + if (!prop.id()) return NO_ERROR; + + int32_t ret = NO_ERROR; + uint32_t blobId = 0; + + switch (type) { + case HistoBlobs::ROI: + ret = createHistoRoiBlob(blobId); + break; + case HistoBlobs::WEIGHTS: + ret = createHistoWeightsBlob(blobId); + break; + default: + ret = -EINVAL; + } + if (ret != NO_ERROR) { + HWC_LOGE(mExynosDisplay, "%s: Failed to create blob", __func__); + return ret; + } + + /* Skip setting when previous and current setting is same with 0 */ + if ((blobId == 0) && (mOldHistoBlobs.getBlob(type) == 0)) return ret; + + if ((ret = drmReq.atomicAddProperty(mDrmCrtc->id(), prop, blobId)) < 0) { + HWC_LOGE(mExynosDisplay, "%s: Failed to add property", __func__); + return ret; + } + mOldHistoBlobs.addBlob(type, blobId); + + return ret; +} + +int32_t ExynosDisplayDrmInterfaceModule::setDisplayHistogramSetting( + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) { + if ((mHistogramInfoRegistered == false) || (isPrimary() == false)) return NO_ERROR; + + int ret = NO_ERROR; + + if ((ret = setDisplayHistoBlob(mDrmCrtc->histogram_roi_property(), + static_cast<uint32_t>(HistoBlobs::ROI), drmReq) != NO_ERROR)) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set Histo_ROI blob", __func__); + return ret; + } + if ((ret = setDisplayHistoBlob(mDrmCrtc->histogram_weights_property(), + static_cast<uint32_t>(HistoBlobs::WEIGHTS), + drmReq) != NO_ERROR)) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set Histo_Weights blob", __func__); + return ret; + } + + const DrmProperty &prop_histo_threshold = mDrmCrtc->histogram_threshold_property(); + if (prop_histo_threshold.id()) { + if ((ret = drmReq.atomicAddProperty(mDrmCrtc->id(), prop_histo_threshold, + (uint64_t)(mHistogramInfo->getHistogramThreshold()), + true)) < 0) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set histogram thereshold property", __func__); + return ret; + } + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::setHistogramControl(int32_t control) { + if ((mHistogramInfoRegistered == false) || (isPrimary() == false)) return NO_ERROR; + + int ret = NO_ERROR; + uint32_t crtc_id = mDrmCrtc->id(); + + if (control == HISTOGRAM_CONTROL_REQUEST) { + ret = mDrmDevice->CallVendorIoctl(DRM_IOCTL_EXYNOS_HISTOGRAM_REQUEST, (void *)&crtc_id); + ALOGD("Histogram Requested"); + } else if (control == HISTOGRAM_CONTROL_CANCEL) { + ret = mDrmDevice->CallVendorIoctl(DRM_IOCTL_EXYNOS_HISTOGRAM_CANCEL, (void *)&crtc_id); + ALOGD("Histogram Canceled"); + } + + return ret; +} + +int32_t ExynosDisplayDrmInterfaceModule::setHistogramData(void *bin) { + if (!bin) return -EINVAL; + + /* + * There are two handling methods. + * For ContentSampling in HWC_2.3 API, histogram bin needs to be accumulated. + * For Histogram HIDL, histogram bin need to be sent to HIDL block. + */ + if (mHistogramInfo->getHistogramType() == HistogramInfo::Histogram_Type::HISTOGRAM_HIDL) { + static_cast<HIDLHistogram *>(mHistogramInfo.get())->CallbackHistogram(bin); + } else { + /* + * ContentSampling in HWC2.3 API is not supported + */ + } + + return NO_ERROR; +} + //////////////////////////////////////////////////// ExynosPrimaryDisplayDrmInterfaceModule ////////////////////////////////////////////////////////////////// ExynosPrimaryDisplayDrmInterfaceModule::ExynosPrimaryDisplayDrmInterfaceModule(ExynosDisplay *exynosDisplay) : ExynosDisplayDrmInterfaceModule(exynosDisplay) diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h index 17c47e3..b72f2a7 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h @@ -18,6 +18,7 @@ #define EXYNOS_DISPLAY_DRM_INTERFACE_MODULE_H #include <gs101/displaycolor/displaycolor_gs101.h> +#include <gs101/histogram/histogram.h> #include "ExynosDisplayDrmInterface.h" @@ -69,6 +70,27 @@ class ExynosDisplayDrmInterfaceModule : public ExynosDisplayDrmInterface { void getDisplayInfo(std::vector<displaycolor::DisplayInfo> &display_info); + /* For Histogram */ + int32_t createHistoRoiBlob(uint32_t &blobId); + int32_t createHistoWeightsBlob(uint32_t &blobId); + + virtual int32_t setDisplayHistogramSetting( + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq); + + void registerHistogramInfo(HistogramInfo *info) { + if (info) + mHistogramInfo.reset(info); + else + mHistogramInfo.reset(); + + if (mHistogramInfo.get()) + mHistogramInfoRegistered = true; + else + mHistogramInfoRegistered = false; + } + int32_t setHistogramControl(int32_t enabled); + virtual int32_t setHistogramData(void *bin); + protected: class SaveBlob { public: @@ -147,6 +169,23 @@ class ExynosDisplayDrmInterfaceModule : public ExynosDisplayDrmInterface { }; DrmEnumParser::MapHal2DrmEnum mBpcEnums; + /* For Histogram */ + class HistoBlobs : public SaveBlob { + public: + enum Histo_Blob_Type { + ROI, + WEIGHTS, + HISTO_BLOB_NUM // number of Histogram blobs + }; + void init(DrmDevice *drmDevice) { SaveBlob::init(drmDevice, HISTO_BLOB_NUM); } + }; + int32_t setDisplayHistoBlob(const DrmProperty &prop, const uint32_t type, + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq); + HistoBlobs mOldHistoBlobs; + + std::shared_ptr<HistogramInfo> mHistogramInfo; + bool mHistogramInfoRegistered = false; + private: const std::string GetPanelInfo(const std::string &sysfs_rel, char delim); const std::string GetPanelSerial() { return GetPanelInfo("serial_number", '\n'); } |