• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 
17 #ifndef _EXYNOSDISPLAYDRMINTERFACE_H
18 #define _EXYNOSDISPLAYDRMINTERFACE_H
19 
20 #include <drm/samsung_drm.h>
21 #include <utils/Condition.h>
22 #include <utils/Mutex.h>
23 #include <xf86drmMode.h>
24 
25 #include <list>
26 #include <unordered_map>
27 
28 #include "ExynosDisplay.h"
29 #include "ExynosDisplayInterface.h"
30 #include "ExynosHWC.h"
31 #include "ExynosMPP.h"
32 #include "drmconnector.h"
33 #include "drmcrtc.h"
34 #include "histogram/histogram.h"
35 #include "vsyncworker.h"
36 
37 /* Max plane number of buffer object */
38 #define HWC_DRM_BO_MAX_PLANES 4
39 
40 /* Monitor Descriptor data is 13 bytes in VESA EDID Standard */
41 #define MONITOR_DESCRIPTOR_DATA_LENGTH 13
42 
43 #ifndef HWC_FORCE_PANIC_PATH
44 #define HWC_FORCE_PANIC_PATH "/d/dpu/panic"
45 #endif
46 
47 using namespace android;
48 
49 class ExynosDevice;
50 
51 template <typename T>
52 using DrmArray = std::array<T, HWC_DRM_BO_MAX_PLANES>;
53 
54 class DisplayConfigGroupIdGenerator {
55 public:
56     DisplayConfigGroupIdGenerator() = default;
57     ~DisplayConfigGroupIdGenerator() = default;
58 
59     // Vrr will utilize the last two parameters. In the case of non-vrr, they are automatically set
60     // to 0. Avoid using this class with a mix of Vrr and non-Vrr settings, as doing so may yield
61     // unexpected results.
62     int getGroupId(int width, int height, int minFrameInterval = 0, int vsyncPeriod = 0) {
63         const auto &key = std::make_tuple(width, height, minFrameInterval, vsyncPeriod);
64         if (groups_.count(key) > 0) {
65             return groups_[key];
66         }
67         size_t last_id = groups_.size();
68         groups_[key] = last_id;
69         return last_id;
70     }
71 
72 private:
73     std::map<std::tuple<int, int, int, int>, int> groups_;
74 };
75 
76 class FramebufferManager {
77     public:
FramebufferManager()78         FramebufferManager(){};
79         ~FramebufferManager();
80         void init(int drmFd);
81 
82         // get buffer for provided config, if a buffer with same config is already cached it will be
83         // reused otherwise one will be allocated. returns fbId that can be used to attach to the
84         // plane, any buffers allocated/reused with this call will be bound to the corresponding
85         // layer. Those fbIds will be cleaned up once the layer was destroyed.
86         int32_t getBuffer(const exynos_win_config_data &config, uint32_t &fbId);
87 
88         void checkShrink();
89 
90         void cleanup(const ExynosLayer *layer);
91         void destroyAllSecureBuffers();
92         int32_t uncacheLayerBuffers(const ExynosLayer* layer,
93                                     const std::vector<buffer_handle_t>& buffers);
94 
95         // The flip function is to help clean up the cached fbIds of destroyed
96         // layers after the previous fdIds were update successfully on the
97         // screen.
98         // This should be called after the frame update.
99         void flip(const bool hasSecureBuffer);
100 
101         // release all currently tracked buffers, this can be called for example when display is turned
102         // off
103         void releaseAll();
104 
105     private:
106         // this struct should contain elements that can be used to identify framebuffer more easily
107         struct Framebuffer {
108             struct BufferDesc {
109                 uint64_t bufferId;
110                 int drmFormat;
111                 bool isSecure;
112                 bool operator==(const Framebuffer::BufferDesc &rhs) const {
113                     return (bufferId == rhs.bufferId && drmFormat == rhs.drmFormat &&
114                             isSecure == rhs.isSecure);
115                 }
116                 bool operator<(const Framebuffer::BufferDesc& rhs) const {
117                     if (bufferId != rhs.bufferId) {
118                         return bufferId < rhs.bufferId;
119                     }
120                     if (drmFormat != rhs.drmFormat) {
121                         return drmFormat < rhs.drmFormat;
122                     }
123                     return isSecure < rhs.isSecure;
124                 }
125             };
126             struct SolidColorDesc {
127                 uint32_t width;
128                 uint32_t height;
129                 bool operator==(const Framebuffer::SolidColorDesc &rhs) const {
130                     return (width == rhs.width && height == rhs.height);
131                 }
132             };
133 
FramebufferFramebuffer134             explicit Framebuffer(int fd, uint32_t fb, BufferDesc desc)
135                   : drmFd(fd), fbId(fb), bufferDesc(desc){};
FramebufferFramebuffer136             explicit Framebuffer(int fd, uint32_t fb, SolidColorDesc desc)
137                   : drmFd(fd), fbId(fb), colorDesc(desc){};
~FramebufferFramebuffer138             ~Framebuffer() { drmModeRmFB(drmFd, fbId); };
139             int drmFd;
140             uint32_t fbId;
141             union {
142                 BufferDesc bufferDesc;
143                 SolidColorDesc colorDesc;
144             };
145         };
146         using FBList = std::list<std::unique_ptr<Framebuffer>>;
147 
148         template <class UnaryPredicate>
149         uint32_t findCachedFbId(const ExynosLayer* layer, const bool isSecureBuffer,
150                                 UnaryPredicate predicate);
151         int addFB2WithModifiers(uint32_t state, uint32_t width, uint32_t height, uint32_t drmFormat,
152                                 const DrmArray<uint32_t> &handles,
153                                 const DrmArray<uint32_t> &pitches,
154                                 const DrmArray<uint32_t> &offsets,
155                                 const DrmArray<uint64_t> &modifier, uint32_t *buf_id,
156                                 uint32_t flags);
157         bool validateLayerInfo(uint32_t state, uint32_t pixel_format,
158                                const DrmArray<uint32_t> &handles,
159                                const DrmArray<uint64_t> &modifier);
160         uint32_t getBufHandleFromFd(int fd);
161         void freeBufHandle(uint32_t handle);
162         void removeFBsThreadRoutine();
163 
164         void markInuseLayerLocked(const ExynosLayer* layer, const bool isSecureBuffer)
165                 REQUIRES(mMutex);
166         void destroyUnusedLayersLocked() REQUIRES(mMutex);
167         void destroyAllSecureBuffersLocked() REQUIRES(mMutex);
168 
169         int mDrmFd = -1;
170 
171         // mCachedLayerBuffers map keep the relationship between Layer and FBList.
172         // mCachedSecureLayerBuffers map keep the relationship between secure
173         // Layer and FBList. The map entry will be deleted once the layer is destroyed.
174         std::map<const ExynosLayer *, FBList> mCachedLayerBuffers;
175         std::map<const ExynosLayer*, FBList> mCachedSecureLayerBuffers;
176 
177         // mCleanBuffers list keeps fbIds of destroyed layers. Those fbIds will
178         // be destroyed in mRmFBThread thread.
179         FBList mCleanBuffers;
180 
181         // mCacheShrinkPending is set when we want to clean up unused layers
182         // in mCachedLayerBuffers. When the flag is set, mCachedLayersInuse will
183         // keep in-use layers in this frame update. Those unused layers will be
184         // freed at the end of the update. mCacheSecureShrinkPending is same to
185         // mCacheShrinkPending but for mCachedSecureLayerBuffers.
186         // TODO: have a better way to maintain inuse layers
187         bool mCacheShrinkPending = false;
188         bool mCacheSecureShrinkPending = false;
189         std::set<const ExynosLayer *> mCachedLayersInuse;
190         std::set<const ExynosLayer*> mCachedSecureLayersInuse;
191 
192         std::thread mRmFBThread;
193         bool mRmFBThreadRunning = false;
194         Condition mFlipDone;
195         Mutex mMutex;
196 
197         static constexpr size_t MAX_CACHED_LAYERS = 16;
198         static constexpr size_t MAX_CACHED_SECURE_LAYERS = 1;
199         static constexpr size_t MAX_CACHED_BUFFERS_PER_LAYER = 32;
200         static constexpr size_t MAX_CACHED_SECURE_BUFFERS_PER_LAYER = 3;
201 };
202 
203 template <class UnaryPredicate>
findCachedFbId(const ExynosLayer * layer,const bool isSecureBuffer,UnaryPredicate predicate)204 uint32_t FramebufferManager::findCachedFbId(const ExynosLayer* layer, const bool isSecureBuffer,
205                                             UnaryPredicate predicate) {
206     Mutex::Autolock lock(mMutex);
207     markInuseLayerLocked(layer, isSecureBuffer);
208     const auto& cachedBuffers =
209             (!isSecureBuffer) ? mCachedLayerBuffers[layer] : mCachedSecureLayerBuffers[layer];
210     const auto it = std::find_if(cachedBuffers.begin(), cachedBuffers.end(), predicate);
211     return (it != cachedBuffers.end()) ? (*it)->fbId : 0;
212 }
213 
214 class ExynosDisplayDrmInterface :
215     public ExynosDisplayInterface,
216     public VsyncCallback
217 {
218     public:
219         class DrmModeAtomicReq {
220             public:
221                 DrmModeAtomicReq(ExynosDisplayDrmInterface *displayInterface);
222                 ~DrmModeAtomicReq();
223 
224                 DrmModeAtomicReq(const DrmModeAtomicReq&) = delete;
225                 DrmModeAtomicReq& operator=(const DrmModeAtomicReq&) = delete;
226 
pset()227                 drmModeAtomicReqPtr pset() { return mPset; };
savePset()228                 void savePset() {
229                     if (mSavedPset) {
230                         drmModeAtomicFree(mSavedPset);
231                     }
232                     mSavedPset = drmModeAtomicDuplicate(mPset);
233                 }
restorePset()234                 void restorePset() {
235                     if (mPset) {
236                         drmModeAtomicFree(mPset);
237                     }
238                     mPset = mSavedPset;
239                     mSavedPset = NULL;
240                 }
241 
setError(int err)242                 void setError(int err) { mError = err; };
getError()243                 int getError() { return mError; };
244                 int32_t atomicAddProperty(const uint32_t id,
245                         const DrmProperty &property,
246                         uint64_t value, bool optional = false);
247                 String8& dumpAtomicCommitInfo(String8 &result, bool debugPrint = false);
248                 int commit(uint32_t flags, bool loggingForDebug = false);
addOldBlob(uint32_t blob_id)249                 void addOldBlob(uint32_t blob_id) {
250                     mOldBlobs.push_back(blob_id);
251                 };
destroyOldBlobs()252                 int destroyOldBlobs() {
253                     for (auto &blob : mOldBlobs) {
254                         int ret = mDrmDisplayInterface->mDrmDevice->DestroyPropertyBlob(blob);
255                         if (ret) {
256                             HWC_LOGE(mDrmDisplayInterface->mExynosDisplay,
257                                     "Failed to destroy old blob after commit %d", ret);
258                             return ret;
259                         }
260                     }
261                     mOldBlobs.clear();
262                     return NO_ERROR;
263                 };
264                 void dumpDrmAtomicCommitMessage(int err);
265 
setAckCallback(std::function<void ()> callback)266                 void setAckCallback(std::function<void()> callback) {
267                     mAckCallback = std::move(callback);
268                 };
269 
270             private:
271                 drmModeAtomicReqPtr mPset;
272                 drmModeAtomicReqPtr mSavedPset;
273                 int mError = 0;
274                 ExynosDisplayDrmInterface *mDrmDisplayInterface = NULL;
275                 /* Destroy old blobs after commit */
276                 std::vector<uint32_t> mOldBlobs;
drmFd()277                 int drmFd() const { return mDrmDisplayInterface->mDrmDevice->fd(); }
278 
279                 std::function<void()> mAckCallback;
280 
281                 static constexpr uint32_t kAllowDumpDrmAtomicMessageTimeMs = 5000U;
282                 static constexpr const char* kDrmModuleParametersDebugNode =
283                         "/sys/module/drm/parameters/debug";
284                 static constexpr const int kEnableDrmAtomicMessage = 16;
285                 static constexpr const int kDisableDrmDebugMessage = 0;
286 
287         };
288         class ExynosVsyncCallback {
289             public:
enableVSync(bool enable)290                 void enableVSync(bool enable) {
291                     mVsyncEnabled = enable;
292                     resetVsyncTimeStamp();
293                 };
getVSyncEnabled()294                 bool getVSyncEnabled() { return mVsyncEnabled; };
setDesiredVsyncPeriod(uint64_t period)295                 void setDesiredVsyncPeriod(uint64_t period) {
296                     mDesiredVsyncPeriod = period;
297                     resetVsyncTimeStamp();
298                 };
getDesiredVsyncPeriod()299                 uint64_t getDesiredVsyncPeriod() { return mDesiredVsyncPeriod;};
getVsyncTimeStamp()300                 uint64_t getVsyncTimeStamp() { return mVsyncTimeStamp; };
getVsyncPeriod()301                 uint64_t getVsyncPeriod() { return mVsyncPeriod; };
302                 bool Callback(int display, int64_t timestamp);
resetVsyncTimeStamp()303                 void resetVsyncTimeStamp() { mVsyncTimeStamp = 0; };
resetDesiredVsyncPeriod()304                 void resetDesiredVsyncPeriod() { mDesiredVsyncPeriod = 0;};
305             private:
306                 bool mVsyncEnabled = false;
307                 uint64_t mVsyncTimeStamp = 0;
308                 uint64_t mVsyncPeriod = 0;
309                 uint64_t mDesiredVsyncPeriod = 0;
310         };
311         void Callback(int display, int64_t timestamp) override;
312 
313         ExynosDisplayDrmInterface(ExynosDisplay *exynosDisplay);
314         ~ExynosDisplayDrmInterface();
315         virtual void init(ExynosDisplay *exynosDisplay);
316         virtual int32_t setPowerMode(int32_t mode);
317         virtual int32_t setLowPowerMode() override;
isDozeModeAvailable()318         virtual bool isDozeModeAvailable() const {
319             return mDozeDrmMode.h_display() > 0 && mDozeDrmMode.v_display() > 0;
320         };
321         virtual int32_t setVsyncEnabled(uint32_t enabled);
322         virtual int32_t getDisplayConfigs(
323                 uint32_t* outNumConfigs,
324                 hwc2_config_t* outConfigs);
325         virtual void dumpDisplayConfigs();
326         virtual bool supportDataspace(int32_t dataspace);
327         virtual int32_t getColorModes(uint32_t* outNumModes, int32_t* outModes);
328         virtual int32_t setColorMode(int32_t mode);
329         virtual int32_t setActiveConfig(hwc2_config_t config);
330         virtual int32_t setCursorPositionAsync(uint32_t x_pos, uint32_t y_pos);
331         virtual int32_t updateHdrCapabilities();
332         virtual int32_t deliverWinConfigData();
333         virtual int32_t clearDisplay(bool needModeClear = false);
334         virtual int32_t disableSelfRefresh(uint32_t disable);
335         virtual int32_t setForcePanic();
getDisplayFd()336         virtual int getDisplayFd() { return mDrmDevice->fd(); };
337         virtual int32_t initDrmDevice(DrmDevice *drmDevice);
338         virtual int getDrmDisplayId(uint32_t type, uint32_t index);
getMaxWindowNum()339         virtual uint32_t getMaxWindowNum() { return mMaxWindowNum; };
340         virtual int32_t getReadbackBufferAttributes(int32_t* /*android_pixel_format_t*/ outFormat,
341                 int32_t* /*android_dataspace_t*/ outDataspace);
342         virtual int32_t getDisplayIdentificationData(uint8_t* outPort,
343                 uint32_t* outDataSize, uint8_t* outData);
344         virtual bool needRefreshOnLP();
345 
346         /* For HWC 2.4 APIs */
347         virtual int32_t getDisplayVsyncPeriod(
348                 hwc2_vsync_period_t* outVsyncPeriod);
349         virtual int32_t getConfigChangeDuration();
350         virtual int32_t getVsyncAppliedTime(hwc2_config_t config,
351                 int64_t* actualChangeTime);
352         virtual int32_t setActiveConfigWithConstraints(
353                 hwc2_config_t config, bool test = false);
354 
setDisplayColorSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq __unused & drmReq)355         virtual int32_t setDisplayColorSetting(
356                 ExynosDisplayDrmInterface::DrmModeAtomicReq __unused &drmReq) {
357             return NO_ERROR;
358         }
setPlaneColorSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq & drmReq,const std::unique_ptr<DrmPlane> & plane,const exynos_win_config_data & config,uint32_t & solidColor)359         virtual int32_t setPlaneColorSetting(
360                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq,
361                 const std::unique_ptr<DrmPlane> &plane,
362                 const exynos_win_config_data& config,
363                 uint32_t &solidColor)
364         { return NO_ERROR;};
365         virtual void destroyLayer(ExynosLayer *layer) override;
366 
367         /* For HWC 3.0 APIs */
368         virtual int32_t getDisplayIdleTimerSupport(bool &outSupport);
369         virtual int32_t getDefaultModeId(int32_t *modeId) override;
370 
371         virtual int32_t waitVBlank();
getDesiredRefreshRate()372         float getDesiredRefreshRate() { return mDesiredModeState.mode.v_refresh(); }
getOperationRate()373         int32_t getOperationRate() {
374             if (mExynosDisplay->mOperationRateManager) {
375                     return mExynosDisplay->mOperationRateManager->getTargetOperationRate();
376             }
377             return 0;
378         }
379 
380         /* For Histogram */
setDisplayHistogramSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq & drmReq)381         virtual int32_t setDisplayHistogramSetting(
382                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) {
383             return NO_ERROR;
384         }
385 
386         /* For Histogram Multi Channel support */
387         int32_t setHistogramChannelConfigBlob(ExynosDisplayDrmInterface::DrmModeAtomicReq& drmReq,
388                                               uint8_t channelId, uint32_t blobId);
389         int32_t clearHistogramChannelConfigBlob(ExynosDisplayDrmInterface::DrmModeAtomicReq& drmReq,
390                                                 uint8_t channelId);
391         enum class HistogramChannelIoctl_t {
392             /* send the histogram data request by calling histogram_channel_request_ioctl */
393             REQUEST = 0,
394 
395             /* cancel the histogram data request by calling histogram_channel_cancel_ioctl */
396             CANCEL,
397         };
398         int32_t sendHistogramChannelIoctl(HistogramChannelIoctl_t control, uint32_t blobId) const;
399 
400         enum class ContextHistogramIoctl_t {
401             /* send the histogram event request by calling histogram_event_request_ioctl */
402             REQUEST = 0,
403             /* send the histogram event request by calling histogram_event_cancel_ioctl */
404             CANCEL,
405         };
406         int32_t sendContextHistogramIoctl(ContextHistogramIoctl_t control, uint32_t blobId) const;
407 
getFrameCount()408         int32_t getFrameCount() { return mFrameCounter; }
registerHistogramInfo(const std::shared_ptr<IDLHistogram> & info)409         virtual void registerHistogramInfo(const std::shared_ptr<IDLHistogram> &info) { return; }
setHistogramControl(hidl_histogram_control_t enabled)410         virtual int32_t setHistogramControl(hidl_histogram_control_t enabled) { return NO_ERROR; }
setHistogramData(void * bin)411         virtual int32_t setHistogramData(void *bin) { return NO_ERROR; }
getActiveModeHDisplay()412         int32_t getActiveModeHDisplay() { return mActiveModeState.mode.h_display(); }
getActiveModeVDisplay()413         int32_t getActiveModeVDisplay() { return mActiveModeState.mode.v_display(); }
getActiveModeId()414         uint32_t getActiveModeId() { return mActiveModeState.mode.id(); }
getPanelFullResolutionHSize()415         int32_t getPanelFullResolutionHSize() { return mPanelFullResolutionHSize; }
getPanelFullResolutionVSize()416         int32_t getPanelFullResolutionVSize() { return mPanelFullResolutionVSize; }
getCrtcId()417         uint32_t getCrtcId() { return mDrmCrtc->id(); }
418         int32_t triggerClearDisplayPlanes();
419 
420         virtual void setXrrSettings(const XrrSettings_t& settings) override;
isVrrSupported()421         bool isVrrSupported() const { return mXrrSettings.versionInfo.isVrr(); }
isMrrV2()422         bool isMrrV2() const {
423             return (!mXrrSettings.versionInfo.isVrr()) &&
424                     (mXrrSettings.versionInfo.minorVersion == 2);
425         }
426 
427         void handleDrmPropertyUpdate(uint32_t connector_id, uint32_t prop_id);
428 
429         /* store the manufacturer info and product id from EDID
430          * - Manufacturer ID is stored in EDID byte 8 and 9.
431          * - Manufacturer product ID is stored in EDID byte 10 and 11.
432          */
433         virtual void setManufacturerInfo(uint8_t edid8, uint8_t edid9) override;
getManufacturerInfo()434         virtual uint32_t getManufacturerInfo() override { return mManufacturerInfo; }
435         virtual void setProductId(uint8_t edid10, uint8_t edid11) override;
getProductId()436         virtual uint32_t getProductId() override { return mProductId; }
437 
438         // This function will swap crtc/decon assigned to this display, with the crtc/decon of
439         // the provided |anotherDisplay|. It is used on foldable devices, where decon0/1 support
440         // color management, but decon2 doesn't, to re-assign the decon0/1 of a powered off primary
441         // display for the external display. When the external display is disconnected, this
442         // function is called again with the same |anotherDisplay| parameter to restore the
443         // original crtc/decon assignment of the external and primary display.
444         // See b/329034082 for details.
445         virtual int32_t swapCrtcs(ExynosDisplay* anotherDisplay) override;
446         // After swapCrtcs has been successfully done, this function will return the display, whose
447         // crtc/decon this display is currently using.
448         virtual ExynosDisplay* borrowedCrtcFrom() override;
449 
450         virtual int32_t uncacheLayerBuffers(const ExynosLayer* __unused layer,
451                                             const std::vector<buffer_handle_t>& buffers) override;
452 
453     protected:
454         enum class HalMipiSyncType : uint32_t {
455             HAL_MIPI_CMD_SYNC_REFRESH_RATE = 0,
456             HAL_MIPI_CMD_SYNC_LHBM,
457             HAL_MIPI_CMD_SYNC_GHBM,
458             HAL_MIPI_CMD_SYNC_BL,
459             HAL_MIPI_CMD_SYNC_OP_RATE,
460         };
461 
462         struct ModeState {
463             enum ModeStateType {
464                 MODE_STATE_NONE = 0U,
465                 MODE_STATE_REFRESH_RATE = 1U << 0,
466                 MODE_STATE_RESOLUTION = 1U << 1,
467                 MODE_STATE_FORCE_MODE_SET = 1U << 2,
468             };
469             DrmMode mode;
470             uint32_t blob_id = 0;
471             uint32_t old_blob_id = 0;
setModeModeState472             void setMode(const DrmMode newMode, const uint32_t modeBlob,
473                     DrmModeAtomicReq &drmReq) {
474                 if (newMode.v_refresh() != mode.v_refresh()) {
475                     mModeState |= ModeStateType::MODE_STATE_REFRESH_RATE;
476                 }
477                 if (isFullModeSwitch(newMode)) {
478                     mModeState |= ModeStateType::MODE_STATE_RESOLUTION;
479                 }
480 
481                 drmReq.addOldBlob(old_blob_id);
482                 mode = newMode;
483                 old_blob_id = blob_id;
484                 blob_id = modeBlob;
485             };
resetModeState486             void reset() {
487                 *this = {};
488             };
applyModeState489             void apply(ModeState &toModeState, DrmModeAtomicReq &drmReq) {
490                 toModeState.setMode(mode, blob_id, drmReq);
491                 drmReq.addOldBlob(old_blob_id);
492                 reset();
493             };
494 
495             int32_t mModeState = ModeStateType::MODE_STATE_NONE;
forceModeSetModeState496             void forceModeSet() { mModeState |= ModeStateType::MODE_STATE_FORCE_MODE_SET; }
clearPendingModeStateModeState497             void clearPendingModeState() { mModeState = ModeStateType::MODE_STATE_NONE; }
needsModeSetModeState498             bool needsModeSet() const { return mModeState != ModeStateType::MODE_STATE_NONE; }
isSeamlessModeState499             bool isSeamless() const { return !(mModeState & ModeStateType::MODE_STATE_RESOLUTION); }
isFullModeSwitchModeState500             bool isFullModeSwitch(const DrmMode &newMode) {
501                 if ((mode.h_display() != newMode.h_display()) ||
502                     (mode.v_display() != newMode.v_display()))
503                     return true;
504                 return false;
505             }
506         };
507         int32_t createModeBlob(const DrmMode &mode, uint32_t &modeBlob);
508         int32_t setDisplayMode(DrmModeAtomicReq& drmReq, const uint32_t& modeBlob,
509                                const uint32_t& modeId);
510         int32_t clearDisplayMode(DrmModeAtomicReq &drmReq);
511         int32_t clearDisplayPlanes(DrmModeAtomicReq &drmReq);
512         int32_t choosePreferredConfig();
513         int getDeconChannel(ExynosMPP *otfMPP);
514         /*
515          * This function adds FB and gets new fb id if fbId is 0,
516          * if fbId is not 0, this reuses fbId.
517          */
518         int32_t setupCommitFromDisplayConfig(DrmModeAtomicReq &drmReq,
519                 const exynos_win_config_data &config,
520                 const uint32_t configIndex,
521                 const std::unique_ptr<DrmPlane> &plane,
522                 uint32_t &fbId);
523 
524         int32_t setupPartialRegion(DrmModeAtomicReq &drmReq);
525         void parseBlendEnums(const DrmProperty &property);
526         void parseStandardEnums(const DrmProperty &property);
527         void parseTransferEnums(const DrmProperty &property);
528         void parseRangeEnums(const DrmProperty &property);
529         void parseColorModeEnums(const DrmProperty &property);
530         void parseMipiSyncEnums(const DrmProperty &property);
531         void updateMountOrientation();
532         void parseRCDId(const DrmProperty &property);
533 
534         int32_t setupWritebackCommit(DrmModeAtomicReq &drmReq);
535         int32_t clearWritebackCommit(DrmModeAtomicReq &drmReq);
536 
537     private:
538         int32_t updateColorSettings(DrmModeAtomicReq &drmReq, uint64_t dqeEnabled);
539         int32_t getLowPowerDrmModeModeInfo();
540         int32_t setActiveDrmMode(DrmMode const &mode);
setMaxWindowNum(uint32_t num)541         void setMaxWindowNum(uint32_t num) { mMaxWindowNum = num; };
542         int32_t getSpecialChannelId(uint32_t planeId);
543 
544     protected:
545         struct PartialRegionState {
546             struct drm_clip_rect partial_rect = {0, 0, 0, 0};
547             uint32_t blob_id = 0;
isUpdatedPartialRegionState548             bool isUpdated(drm_clip_rect rect) {
549                 return ((partial_rect.x1 != rect.x1) ||
550                         (partial_rect.y1 != rect.y1) ||
551                         (partial_rect.x2 != rect.x2) ||
552                         (partial_rect.y2 != rect.y2));
553             };
554         };
555 
556         struct BlockingRegionState {
557             struct decon_win_rect mRegion;
558             uint32_t mBlobId = 0;
559 
560             inline bool operator==(const decon_win_rect &rhs) const {
561                 return mRegion.x == rhs.x && mRegion.y == rhs.y && mRegion.w == rhs.w &&
562                         mRegion.h == rhs.h;
563             }
564             inline bool operator!=(const decon_win_rect &rhs) const { return !(*this == rhs); }
565         };
566 
567         class DrmReadbackInfo {
568             public:
569                 void init(DrmDevice *drmDevice, uint32_t displayId);
~DrmReadbackInfo()570                 ~DrmReadbackInfo() {
571                     if (mDrmDevice == NULL)
572                         return;
573                     if (mOldFbId > 0)
574                         drmModeRmFB(mDrmDevice->fd(), mOldFbId);
575                     if (mFbId > 0)
576                         drmModeRmFB(mDrmDevice->fd(), mFbId);
577                 }
getWritebackConnector()578                 DrmConnector* getWritebackConnector() { return mWritebackConnector; };
setFbId(uint32_t fbId)579                 void setFbId(uint32_t fbId) {
580                     if ((mDrmDevice != NULL) && (mOldFbId > 0))
581                         drmModeRmFB(mDrmDevice->fd(), mOldFbId);
582                     mOldFbId = mFbId;
583                     mFbId = fbId;
584                 }
585                 void pickFormatDataspace();
586                 static constexpr uint32_t PREFERRED_READBACK_FORMAT =
587                     HAL_PIXEL_FORMAT_RGBA_8888;
588                 uint32_t mReadbackFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
589                 bool mNeedClearReadbackCommit = false;
590             private:
591                 DrmDevice *mDrmDevice = NULL;
592                 DrmConnector *mWritebackConnector = NULL;
593                 uint32_t mFbId = 0;
594                 uint32_t mOldFbId = 0;
595                 std::vector<uint32_t> mSupportedFormats;
596         };
597         DrmDevice *mDrmDevice;
598         DrmCrtc *mDrmCrtc;
599         DrmConnector *mDrmConnector;
600         VSyncWorker mDrmVSyncWorker;
601         ExynosVsyncCallback mVsyncCallback;
602         ModeState mActiveModeState;
603         ModeState mDesiredModeState;
604         PartialRegionState mPartialRegionState;
605         BlockingRegionState mBlockState;
606         /* Mapping plane id to ExynosMPP, key is plane id */
607         std::unordered_map<uint32_t, ExynosMPP*> mExynosMPPsForPlane;
608 
609         ExynosDisplay* mBorrowedCrtcFrom = nullptr;
610 
611         DrmEnumParser::MapHal2DrmEnum mBlendEnums;
612         DrmEnumParser::MapHal2DrmEnum mStandardEnums;
613         DrmEnumParser::MapHal2DrmEnum mTransferEnums;
614         DrmEnumParser::MapHal2DrmEnum mRangeEnums;
615         DrmEnumParser::MapHal2DrmEnum mColorModeEnums;
616         DrmEnumParser::MapHal2DrmEnum mMipiSyncEnums;
617 
618         DrmReadbackInfo mReadbackInfo;
619         FramebufferManager mFBManager;
620         std::array<uint8_t, MONITOR_DESCRIPTOR_DATA_LENGTH> mMonitorDescription;
621         nsecs_t mLastDumpDrmAtomicMessageTime;
622         bool mIsResolutionSwitchInProgress = false;
623 
624     private:
625         int32_t getDisplayFakeEdid(uint8_t &outPort, uint32_t &outDataSize, uint8_t *outData);
626 
627         String8 mDisplayTraceName;
628         DrmMode mDozeDrmMode;
629         uint32_t mMaxWindowNum = 0;
630         int32_t mFrameCounter = 0;
631         int32_t mPanelFullResolutionHSize = 0;
632         int32_t mPanelFullResolutionVSize = 0;
633 
634         // Vrr related settings.
635         XrrSettings_t mXrrSettings;
636 
637         /**
638          * retrievePanelFullResolution
639          *
640          * Retrieve the panel full resolution by looking into the modes of the mDrmConnector
641          * and store the full resolution info in mPanelFullResolutionHSize (x component) and
642          * mPanelFullResolutionVSize (y component).
643          *
644          * Note: this function will be called only once in initDrmDevice()
645          */
646         void retrievePanelFullResolution();
647 
648         const uint8_t kEDIDManufacturerIDByte1 = 8;
649         const uint8_t kEDIDManufacturerIDByte2 = 9;
650         const uint8_t kEDIDProductIDByte1 = 10;
651         const uint8_t kEDIDProductIDByte2 = 11;
652         uint32_t mManufacturerInfo;
653         uint32_t mProductId;
654         bool mIsFirstClean = true;
655 
656     public:
657         virtual bool readHotplugStatus();
658         virtual int readHotplugErrorCode();
659         virtual void resetHotplugErrorCode();
660 };
661 
662 #endif
663