• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "histogram_mediator.h"
17 
HistogramMediator(ExynosDisplay * display)18 histogram::HistogramMediator::HistogramMediator(ExynosDisplay *display) {
19     mDisplay = display;
20     ExynosDisplayDrmInterface *moduleDisplayInterface =
21             static_cast<ExynosDisplayDrmInterface *>(display->mDisplayInterface.get());
22     mIDLHistogram = std::make_shared<HistogramReceiver>();
23 
24     moduleDisplayInterface->registerHistogramInfo(mIDLHistogram);
25     moduleDisplayInterface->getPanelResolution();
26 }
getFrameCount()27 uint32_t histogram::HistogramMediator::getFrameCount() {
28     ExynosDisplayDrmInterface *moduleDisplayInterface =
29             static_cast<ExynosDisplayDrmInterface *>(mDisplay->mDisplayInterface.get());
30     return moduleDisplayInterface->getFrameCount();
31 }
32 
isDisplayPowerOff()33 bool histogram::HistogramMediator::isDisplayPowerOff() {
34     if (!mDisplay->mPowerModeState.has_value() ||
35         ((mDisplay->mPowerModeState.value() == HWC2_POWER_MODE_OFF) ||
36          (mDisplay->mPowerModeState.value() == HWC2_POWER_MODE_DOZE))) {
37         return true;
38     }
39     return false;
40 }
41 
isSecureContentPresenting()42 bool histogram::HistogramMediator::isSecureContentPresenting() {
43     Mutex::Autolock lock(mDisplay->mDRMutex);
44     for (uint32_t i = 0; i < mDisplay->mLayers.size(); i++) {
45         ExynosLayer *layer = mDisplay->mLayers[i];
46         if (layer != NULL && layer->isDrm()) { /* there is some DRM layer */
47             return true;
48         }
49     }
50     return false;
51 }
requestHist()52 histogram::HistogramErrorCode histogram::HistogramMediator::requestHist() {
53     if (isSecureContentPresenting()) { /* there is some DRM layer */
54         return histogram::HistogramErrorCode::DRM_PLAYING;
55     }
56     ExynosDisplayDrmInterface *moduleDisplayInterface =
57             static_cast<ExynosDisplayDrmInterface *>(mDisplay->mDisplayInterface.get());
58 
59     if (moduleDisplayInterface->setHistogramControl(
60                 hidl_histogram_control_t::HISTOGRAM_CONTROL_REQUEST) != NO_ERROR) {
61         return histogram::HistogramErrorCode::ENABLE_HIST_ERROR;
62     }
63     {
64         std::unique_lock<std::mutex> lk(mIDLHistogram->mDataCollectingMutex);
65         mIDLHistogram->mHistReq_pending = true;
66     }
67     return histogram::HistogramErrorCode::NONE;
68 }
69 
cancelHistRequest()70 histogram::HistogramErrorCode histogram::HistogramMediator::cancelHistRequest() {
71     ExynosDisplayDrmInterface *moduleDisplayInterface =
72             static_cast<ExynosDisplayDrmInterface *>(mDisplay->mDisplayInterface.get());
73 
74     if (moduleDisplayInterface->setHistogramControl(
75                 hidl_histogram_control_t::HISTOGRAM_CONTROL_CANCEL) != NO_ERROR) {
76         return histogram::HistogramErrorCode::DISABLE_HIST_ERROR;
77     }
78     return histogram::HistogramErrorCode::NONE;
79 }
80 
callbackHistogram(char16_t * bin)81 void histogram::HistogramMediator::HistogramReceiver::callbackHistogram(char16_t *bin) {
82     std::unique_lock<std::mutex> lk(mDataCollectingMutex);
83     if (mHistReq_pending == true) {
84         std::memcpy(mHistData, bin, HISTOGRAM_BINS_SIZE * sizeof(char16_t));
85         mHistReq_pending = false;
86     }
87     mHistData_cv.notify_all();
88 }
89 
calculateThreshold(const RoiRect & roi)90 int histogram::HistogramMediator::calculateThreshold(const RoiRect &roi) {
91     int threshold = ((roi.bottom - roi.top) * (roi.right - roi.left)) >> 16;
92     return threshold + 1;
93 }
94 
setRoiWeightThreshold(const RoiRect roi,const Weight weight,const HistogramPos pos)95 histogram::HistogramErrorCode histogram::HistogramMediator::setRoiWeightThreshold(
96         const RoiRect roi, const Weight weight, const HistogramPos pos) {
97     int threshold = calculateThreshold(roi);
98     mIDLHistogram->setHistogramROI((uint16_t)roi.left, (uint16_t)roi.top,
99                                    (uint16_t)(roi.right - roi.left),
100                                    (uint16_t)(roi.bottom - roi.top));
101     mIDLHistogram->setHistogramWeights(weight.weightR, weight.weightG, weight.weightB);
102     mIDLHistogram->setHistogramThreshold(threshold);
103     mIDLHistogram->setHistogramPos(pos);
104 
105     return histogram::HistogramErrorCode::NONE;
106 }
107 
collectRoiLuma(std::vector<char16_t> * buf)108 histogram::HistogramErrorCode histogram::HistogramMediator::collectRoiLuma(
109         std::vector<char16_t> *buf) {
110     std::unique_lock<std::mutex> lk(mIDLHistogram->mDataCollectingMutex);
111 
112     mIDLHistogram->mHistData_cv.wait_for(lk, std::chrono::milliseconds(50), [this]() {
113         return (!isDisplayPowerOff() && !mIDLHistogram->mHistReq_pending);
114     });
115     if (mIDLHistogram->mHistReq_pending == false) setSampleFrameCounter(getFrameCount());
116     buf->assign(mIDLHistogram->mHistData, mIDLHistogram->mHistData + HISTOGRAM_BINS_SIZE);
117 
118     return histogram::HistogramErrorCode::NONE;
119 }
120 
calRoi(RoiRect roi)121 histogram::RoiRect histogram::HistogramMediator::calRoi(RoiRect roi) {
122     RoiRect roi_return = {-1, -1, -1, -1};
123     ExynosDisplayDrmInterface *moduleDisplayInterface =
124             static_cast<ExynosDisplayDrmInterface *>(mDisplay->mDisplayInterface.get());
125     roi_return.left = roi.left * moduleDisplayInterface->getActiveModeHDisplay() /
126             moduleDisplayInterface->panelHsize();
127     roi_return.top = roi.top * moduleDisplayInterface->getActiveModeVDisplay() /
128             moduleDisplayInterface->panelVsize();
129     roi_return.right = roi.right * moduleDisplayInterface->getActiveModeHDisplay() /
130             moduleDisplayInterface->panelHsize();
131     roi_return.bottom = roi.bottom * moduleDisplayInterface->getActiveModeVDisplay() /
132             moduleDisplayInterface->panelVsize();
133     return roi_return;
134 }
135