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