• 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 FramebufferManager {
55     public:
FramebufferManager()56         FramebufferManager(){};
57         ~FramebufferManager();
58         void init(int drmFd);
59 
60         // get buffer for provided config, if a buffer with same config is already cached it will be
61         // reused otherwise one will be allocated. returns fbId that can be used to attach to the
62         // plane, any buffers allocated/reused with this call will be bound to the corresponding
63         // layer. Those fbIds will be cleaned up once the layer was destroyed.
64         int32_t getBuffer(const exynos_win_config_data &config, uint32_t &fbId);
65 
66         void checkShrink();
67 
68         void cleanup(const ExynosLayer *layer);
69 
70         // The flip function is to help clean up the cached fbIds of destroyed
71         // layers after the previous fdIds were update successfully on the
72         // screen.
73         // This should be called after the frame update.
74         void flip(const bool hasSecureFrameBuffer, const bool hasM2mSecureLayerBuffer);
75 
76         // release all currently tracked buffers, this can be called for example when display is turned
77         // off
78         void releaseAll();
79 
80     private:
81         // this struct should contain elements that can be used to identify framebuffer more easily
82         struct Framebuffer {
83             struct BufferDesc {
84                 uint64_t bufferId;
85                 int drmFormat;
86                 bool isSecure;
87                 bool operator==(const Framebuffer::BufferDesc &rhs) const {
88                     return (bufferId == rhs.bufferId && drmFormat == rhs.drmFormat &&
89                             isSecure == rhs.isSecure);
90                 }
91             };
92             struct SolidColorDesc {
93                 uint32_t width;
94                 uint32_t height;
95                 bool operator==(const Framebuffer::SolidColorDesc &rhs) const {
96                     return (width == rhs.width && height == rhs.height);
97                 }
98             };
99 
FramebufferFramebuffer100             explicit Framebuffer(int fd, uint32_t fb, BufferDesc desc)
101                   : drmFd(fd), fbId(fb), bufferDesc(desc){};
FramebufferFramebuffer102             explicit Framebuffer(int fd, uint32_t fb, SolidColorDesc desc)
103                   : drmFd(fd), fbId(fb), colorDesc(desc){};
~FramebufferFramebuffer104             ~Framebuffer() { drmModeRmFB(drmFd, fbId); };
105             int drmFd;
106             uint32_t fbId;
107             union {
108                 BufferDesc bufferDesc;
109                 SolidColorDesc colorDesc;
110             };
111         };
112         using FBList = std::list<std::unique_ptr<Framebuffer>>;
113 
114         template <class UnaryPredicate>
115         uint32_t findCachedFbId(const ExynosLayer *layer, const bool isM2mSecureLayer,
116                                 UnaryPredicate predicate);
117         int addFB2WithModifiers(uint32_t state, uint32_t width, uint32_t height, uint32_t drmFormat,
118                                 const DrmArray<uint32_t> &handles,
119                                 const DrmArray<uint32_t> &pitches,
120                                 const DrmArray<uint32_t> &offsets,
121                                 const DrmArray<uint64_t> &modifier, uint32_t *buf_id,
122                                 uint32_t flags);
123         bool validateLayerInfo(uint32_t state, uint32_t pixel_format,
124                                const DrmArray<uint32_t> &handles,
125                                const DrmArray<uint64_t> &modifier);
126         uint32_t getBufHandleFromFd(int fd);
127         void freeBufHandle(uint32_t handle);
128         void removeFBsThreadRoutine();
129 
130         void markInuseLayerLocked(const ExynosLayer *layer, const bool isM2mSecureLayer)
131                 REQUIRES(mMutex);
132         void destroyUnusedLayersLocked() REQUIRES(mMutex);
133         void destroySecureFramebufferLocked() REQUIRES(mMutex);
134         void destroyM2mSecureLayerBufferLocked() REQUIRES(mMutex);
135 
136         int mDrmFd = -1;
137 
138         // mCachedLayerBuffers map keep the relationship between Layer and FBList.
139         // mCachedM2mSecureLayerBuffers map keep the relationship between M2M secure
140         // Layer and FBList. The map entry will be deleted once the layer is destroyed.
141         std::map<const ExynosLayer *, FBList> mCachedLayerBuffers;
142         std::map<const ExynosLayer *, FBList> mCachedM2mSecureLayerBuffers;
143 
144         // mCleanBuffers list keeps fbIds of destroyed layers. Those fbIds will
145         // be destroyed in mRmFBThread thread.
146         FBList mCleanBuffers;
147 
148         // mCacheShrinkPending is set when we want to clean up unused layers
149         // in mCachedLayerBuffers. When the flag is set, mCachedLayersInuse will
150         // keep in-use layers in this frame update. Those unused layers will be
151         // freed at the end of the update. mCacheM2mSecureShrinkPending is same to
152         // mCacheShrinkPending but for mCachedM2mSecureLayerBuffers.
153         // TODO: have a better way to maintain inuse layers
154         bool mCacheShrinkPending = false;
155         bool mCacheM2mSecureShrinkPending = false;
156         bool mHasSecureFramebuffer = false;
157         bool mHasM2mSecureLayerBuffer = false;
158         std::set<const ExynosLayer *> mCachedLayersInuse;
159         std::set<const ExynosLayer *> mCachedM2mSecureLayersInuse;
160 
161         std::thread mRmFBThread;
162         bool mRmFBThreadRunning = false;
163         Condition mFlipDone;
164         Mutex mMutex;
165 
166         static constexpr size_t MAX_CACHED_LAYERS = 16;
167         static constexpr size_t MAX_CACHED_M2M_SECURE_LAYERS = 1;
168         static constexpr size_t MAX_CACHED_BUFFERS_PER_LAYER = 32;
169         static constexpr size_t MAX_CACHED_M2M_SECURE_BUFFERS_PER_LAYER = 3;
170 };
171 
isFramebuffer(const ExynosLayer * layer)172 inline bool isFramebuffer(const ExynosLayer *layer) {
173     return layer == nullptr;
174 }
175 
176 template <class UnaryPredicate>
findCachedFbId(const ExynosLayer * layer,const bool isM2mSecureLayer,UnaryPredicate predicate)177 uint32_t FramebufferManager::findCachedFbId(const ExynosLayer *layer, const bool isM2mSecureLayer,
178                                             UnaryPredicate predicate) {
179     Mutex::Autolock lock(mMutex);
180     markInuseLayerLocked(layer, isM2mSecureLayer);
181     const auto &cachedBuffers =
182             (!isM2mSecureLayer) ? mCachedLayerBuffers[layer] : mCachedM2mSecureLayerBuffers[layer];
183     const auto it = std::find_if(cachedBuffers.begin(), cachedBuffers.end(), predicate);
184     return (it != cachedBuffers.end()) ? (*it)->fbId : 0;
185 }
186 
187 class ExynosDisplayDrmInterface :
188     public ExynosDisplayInterface,
189     public VsyncCallback
190 {
191     public:
192         class DrmModeAtomicReq {
193             public:
194                 DrmModeAtomicReq(ExynosDisplayDrmInterface *displayInterface);
195                 ~DrmModeAtomicReq();
196 
197                 DrmModeAtomicReq(const DrmModeAtomicReq&) = delete;
198                 DrmModeAtomicReq& operator=(const DrmModeAtomicReq&) = delete;
199 
pset()200                 drmModeAtomicReqPtr pset() { return mPset; };
savePset()201                 void savePset() {
202                     if (mSavedPset) {
203                         drmModeAtomicFree(mSavedPset);
204                     }
205                     mSavedPset = drmModeAtomicDuplicate(mPset);
206                 }
restorePset()207                 void restorePset() {
208                     if (mPset) {
209                         drmModeAtomicFree(mPset);
210                     }
211                     mPset = mSavedPset;
212                     mSavedPset = NULL;
213                 }
214 
setError(int err)215                 void setError(int err) { mError = err; };
getError()216                 int getError() { return mError; };
217                 int32_t atomicAddProperty(const uint32_t id,
218                         const DrmProperty &property,
219                         uint64_t value, bool optional = false);
220                 String8& dumpAtomicCommitInfo(String8 &result, bool debugPrint = false);
221                 int commit(uint32_t flags, bool loggingForDebug = false);
addOldBlob(uint32_t blob_id)222                 void addOldBlob(uint32_t blob_id) {
223                     mOldBlobs.push_back(blob_id);
224                 };
destroyOldBlobs()225                 int destroyOldBlobs() {
226                     for (auto &blob : mOldBlobs) {
227                         int ret = mDrmDisplayInterface->mDrmDevice->DestroyPropertyBlob(blob);
228                         if (ret) {
229                             HWC_LOGE(mDrmDisplayInterface->mExynosDisplay,
230                                     "Failed to destroy old blob after commit %d", ret);
231                             return ret;
232                         }
233                     }
234                     mOldBlobs.clear();
235                     return NO_ERROR;
236                 };
237             private:
238                 drmModeAtomicReqPtr mPset;
239                 drmModeAtomicReqPtr mSavedPset;
240                 int mError = 0;
241                 ExynosDisplayDrmInterface *mDrmDisplayInterface = NULL;
242                 /* Destroy old blobs after commit */
243                 std::vector<uint32_t> mOldBlobs;
drmFd()244                 int drmFd() const { return mDrmDisplayInterface->mDrmDevice->fd(); }
245         };
246         class ExynosVsyncCallback {
247             public:
enableVSync(bool enable)248                 void enableVSync(bool enable) {
249                     mVsyncEnabled = enable;
250                     resetVsyncTimeStamp();
251                 };
getVSyncEnabled()252                 bool getVSyncEnabled() { return mVsyncEnabled; };
setDesiredVsyncPeriod(uint64_t period)253                 void setDesiredVsyncPeriod(uint64_t period) {
254                     mDesiredVsyncPeriod = period;
255                     resetVsyncTimeStamp();
256                 };
getDesiredVsyncPeriod()257                 uint64_t getDesiredVsyncPeriod() { return mDesiredVsyncPeriod;};
getVsyncTimeStamp()258                 uint64_t getVsyncTimeStamp() { return mVsyncTimeStamp; };
getVsyncPeriod()259                 uint64_t getVsyncPeriod() { return mVsyncPeriod; };
260                 bool Callback(int display, int64_t timestamp);
resetVsyncTimeStamp()261                 void resetVsyncTimeStamp() { mVsyncTimeStamp = 0; };
resetDesiredVsyncPeriod()262                 void resetDesiredVsyncPeriod() { mDesiredVsyncPeriod = 0;};
263             private:
264                 bool mVsyncEnabled = false;
265                 uint64_t mVsyncTimeStamp = 0;
266                 uint64_t mVsyncPeriod = 0;
267                 uint64_t mDesiredVsyncPeriod = 0;
268         };
269         void Callback(int display, int64_t timestamp) override;
270 
271         ExynosDisplayDrmInterface(ExynosDisplay *exynosDisplay);
272         ~ExynosDisplayDrmInterface();
273         virtual void init(ExynosDisplay *exynosDisplay);
274         virtual int32_t setPowerMode(int32_t mode);
275         virtual int32_t setLowPowerMode() override;
isDozeModeAvailable()276         virtual bool isDozeModeAvailable() const {
277             return mDozeDrmMode.h_display() > 0 && mDozeDrmMode.v_display() > 0;
278         };
279         virtual int32_t setVsyncEnabled(uint32_t enabled);
280         virtual int32_t getDisplayConfigs(
281                 uint32_t* outNumConfigs,
282                 hwc2_config_t* outConfigs);
283         virtual void dumpDisplayConfigs();
284         virtual bool supportDataspace(int32_t dataspace);
285         virtual int32_t getColorModes(uint32_t* outNumModes, int32_t* outModes);
286         virtual int32_t setColorMode(int32_t mode);
287         virtual int32_t setActiveConfig(hwc2_config_t config);
288         virtual int32_t setCursorPositionAsync(uint32_t x_pos, uint32_t y_pos);
289         virtual int32_t updateHdrCapabilities();
290         virtual int32_t deliverWinConfigData();
291         virtual int32_t clearDisplay(bool needModeClear = false);
292         virtual int32_t disableSelfRefresh(uint32_t disable);
293         virtual int32_t setForcePanic();
getDisplayFd()294         virtual int getDisplayFd() { return mDrmDevice->fd(); };
295         virtual int32_t initDrmDevice(DrmDevice *drmDevice);
296         virtual int getDrmDisplayId(uint32_t type, uint32_t index);
getMaxWindowNum()297         virtual uint32_t getMaxWindowNum() { return mMaxWindowNum; };
298         virtual int32_t getReadbackBufferAttributes(int32_t* /*android_pixel_format_t*/ outFormat,
299                 int32_t* /*android_dataspace_t*/ outDataspace);
300         virtual int32_t getDisplayIdentificationData(uint8_t* outPort,
301                 uint32_t* outDataSize, uint8_t* outData);
302         virtual bool needRefreshOnLP();
303 
304         /* For HWC 2.4 APIs */
305         virtual int32_t getDisplayVsyncPeriod(
306                 hwc2_vsync_period_t* outVsyncPeriod);
307         virtual int32_t getConfigChangeDuration();
308         virtual int32_t getVsyncAppliedTime(hwc2_config_t config,
309                 int64_t* actualChangeTime);
310         virtual int32_t setActiveConfigWithConstraints(
311                 hwc2_config_t config, bool test = false);
312 
setDisplayColorSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq __unused & drmReq)313         virtual int32_t setDisplayColorSetting(
314                 ExynosDisplayDrmInterface::DrmModeAtomicReq __unused &drmReq) {
315             return NO_ERROR;
316         }
setPlaneColorSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq & drmReq,const std::unique_ptr<DrmPlane> & plane,const exynos_win_config_data & config,uint32_t & solidColor)317         virtual int32_t setPlaneColorSetting(
318                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq,
319                 const std::unique_ptr<DrmPlane> &plane,
320                 const exynos_win_config_data& config,
321                 uint32_t &solidColor)
322         { return NO_ERROR;};
323         virtual void destroyLayer(ExynosLayer *layer) override;
324 
325         /* For HWC 3.0 APIs */
326         virtual int32_t getDisplayIdleTimerSupport(bool &outSupport);
327         virtual int32_t getDefaultModeId(int32_t *modeId) override;
328 
329         virtual int32_t waitVBlank();
getDesiredRefreshRate()330         float getDesiredRefreshRate() { return mDesiredModeState.mode.v_refresh(); }
getOperationRate()331         int32_t getOperationRate() {
332             if (mExynosDisplay->mOperationRateManager) {
333                     return mExynosDisplay->mOperationRateManager->getTargetOperationRate();
334             }
335             return 0;
336         }
337 
338         /* For Histogram */
setDisplayHistogramSetting(ExynosDisplayDrmInterface::DrmModeAtomicReq & drmReq)339         virtual int32_t setDisplayHistogramSetting(
340                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) {
341             return NO_ERROR;
342         }
343 
344         /* For Histogram Multi Channel support */
345         int32_t setDisplayHistogramChannelSetting(
346                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq, uint8_t channelId,
347                 void *blobData, size_t blobLength);
348         int32_t clearDisplayHistogramChannelSetting(
349                 ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq, uint8_t channelId);
350         enum class HistogramChannelIoctl_t {
351             /* send the histogram data request by calling histogram_channel_request_ioctl */
352             REQUEST = 0,
353 
354             /* cancel the histogram data request by calling histogram_channel_cancel_ioctl */
355             CANCEL,
356         };
357         virtual int32_t sendHistogramChannelIoctl(HistogramChannelIoctl_t control,
358                                                   uint8_t channelId) const;
359 
getFrameCount()360         int32_t getFrameCount() { return mFrameCounter; }
registerHistogramInfo(const std::shared_ptr<IDLHistogram> & info)361         virtual void registerHistogramInfo(const std::shared_ptr<IDLHistogram> &info) { return; }
setHistogramControl(hidl_histogram_control_t enabled)362         virtual int32_t setHistogramControl(hidl_histogram_control_t enabled) { return NO_ERROR; }
setHistogramData(void * bin)363         virtual int32_t setHistogramData(void *bin) { return NO_ERROR; }
getActiveModeHDisplay()364         int32_t getActiveModeHDisplay() { return mActiveModeState.mode.h_display(); }
getActiveModeVDisplay()365         int32_t getActiveModeVDisplay() { return mActiveModeState.mode.v_display(); }
getActiveModeId()366         uint32_t getActiveModeId() { return mActiveModeState.mode.id(); }
getPanelFullResolutionHSize()367         int32_t getPanelFullResolutionHSize() { return mPanelFullResolutionHSize; }
getPanelFullResolutionVSize()368         int32_t getPanelFullResolutionVSize() { return mPanelFullResolutionVSize; }
getCrtcId()369         uint32_t getCrtcId() { return mDrmCrtc->id(); }
370         int32_t triggerClearDisplayPlanes();
371 
372     protected:
373         enum class HalMipiSyncType : uint32_t {
374             HAL_MIPI_CMD_SYNC_REFRESH_RATE = 0,
375             HAL_MIPI_CMD_SYNC_LHBM,
376             HAL_MIPI_CMD_SYNC_GHBM,
377             HAL_MIPI_CMD_SYNC_BL,
378             HAL_MIPI_CMD_SYNC_OP_RATE,
379         };
380 
381         struct ModeState {
382             enum ModeStateType {
383                 MODE_STATE_NONE = 0U,
384                 MODE_STATE_REFRESH_RATE = 1U << 0,
385                 MODE_STATE_RESOLUTION = 1U << 1,
386                 MODE_STATE_FORCE_MODE_SET = 1U << 2,
387             };
388             DrmMode mode;
389             uint32_t blob_id = 0;
390             uint32_t old_blob_id = 0;
setModeModeState391             void setMode(const DrmMode newMode, const uint32_t modeBlob,
392                     DrmModeAtomicReq &drmReq) {
393                 if (newMode.v_refresh() != mode.v_refresh()) {
394                     mModeState |= ModeStateType::MODE_STATE_REFRESH_RATE;
395                 }
396                 if (isFullModeSwitch(newMode)) {
397                     mModeState |= ModeStateType::MODE_STATE_RESOLUTION;
398                 }
399 
400                 drmReq.addOldBlob(old_blob_id);
401                 mode = newMode;
402                 old_blob_id = blob_id;
403                 blob_id = modeBlob;
404             };
resetModeState405             void reset() {
406                 *this = {};
407             };
applyModeState408             void apply(ModeState &toModeState, DrmModeAtomicReq &drmReq) {
409                 toModeState.setMode(mode, blob_id, drmReq);
410                 drmReq.addOldBlob(old_blob_id);
411                 reset();
412             };
413 
414             int32_t mModeState = ModeStateType::MODE_STATE_NONE;
forceModeSetModeState415             void forceModeSet() { mModeState |= ModeStateType::MODE_STATE_FORCE_MODE_SET; }
clearPendingModeStateModeState416             void clearPendingModeState() { mModeState = ModeStateType::MODE_STATE_NONE; }
needsModeSetModeState417             bool needsModeSet() const { return mModeState != ModeStateType::MODE_STATE_NONE; }
isSeamlessModeState418             bool isSeamless() const { return !(mModeState & ModeStateType::MODE_STATE_RESOLUTION); }
isFullModeSwitchModeState419             bool isFullModeSwitch(const DrmMode &newMode) {
420                 if ((mode.h_display() != newMode.h_display()) ||
421                     (mode.v_display() != newMode.v_display()))
422                     return true;
423                 return false;
424             }
425         };
426         int32_t createModeBlob(const DrmMode &mode, uint32_t &modeBlob);
427         int32_t setDisplayMode(DrmModeAtomicReq &drmReq, const uint32_t modeBlob);
428         int32_t clearDisplayMode(DrmModeAtomicReq &drmReq);
429         int32_t clearDisplayPlanes(DrmModeAtomicReq &drmReq);
430         int32_t chosePreferredConfig();
431         int getDeconChannel(ExynosMPP *otfMPP);
432         /*
433          * This function adds FB and gets new fb id if fbId is 0,
434          * if fbId is not 0, this reuses fbId.
435          */
436         int32_t setupCommitFromDisplayConfig(DrmModeAtomicReq &drmReq,
437                 const exynos_win_config_data &config,
438                 const uint32_t configIndex,
439                 const std::unique_ptr<DrmPlane> &plane,
440                 uint32_t &fbId);
441 
442         int32_t setupPartialRegion(DrmModeAtomicReq &drmReq);
443         void parseBlendEnums(const DrmProperty &property);
444         void parseStandardEnums(const DrmProperty &property);
445         void parseTransferEnums(const DrmProperty &property);
446         void parseRangeEnums(const DrmProperty &property);
447         void parseColorModeEnums(const DrmProperty &property);
448         void parseMipiSyncEnums(const DrmProperty &property);
449         void updateMountOrientation();
450         void parseRCDId(const DrmProperty &property);
451 
452         int32_t setupWritebackCommit(DrmModeAtomicReq &drmReq);
453         int32_t clearWritebackCommit(DrmModeAtomicReq &drmReq);
454 
455     private:
456         int32_t updateColorSettings(DrmModeAtomicReq &drmReq, uint64_t dqeEnabled);
457         int32_t getLowPowerDrmModeModeInfo();
458         int32_t setActiveDrmMode(DrmMode const &mode);
setMaxWindowNum(uint32_t num)459         void setMaxWindowNum(uint32_t num) { mMaxWindowNum = num; };
460         int32_t getSpecialChannelId(uint32_t planeId);
461 
462     protected:
463         struct PartialRegionState {
464             struct drm_clip_rect partial_rect = {0, 0, 0, 0};
465             uint32_t blob_id = 0;
isUpdatedPartialRegionState466             bool isUpdated(drm_clip_rect rect) {
467                 return ((partial_rect.x1 != rect.x1) ||
468                         (partial_rect.y1 != rect.y1) ||
469                         (partial_rect.x2 != rect.x2) ||
470                         (partial_rect.y2 != rect.y2));
471             };
472         };
473 
474         struct BlockingRegionState {
475             struct decon_win_rect mRegion;
476             uint32_t mBlobId = 0;
477 
478             inline bool operator==(const decon_win_rect &rhs) const {
479                 return mRegion.x == rhs.x && mRegion.y == rhs.y && mRegion.w == rhs.w &&
480                         mRegion.h == rhs.h;
481             }
482             inline bool operator!=(const decon_win_rect &rhs) const { return !(*this == rhs); }
483         };
484 
485         class DrmReadbackInfo {
486             public:
487                 void init(DrmDevice *drmDevice, uint32_t displayId);
~DrmReadbackInfo()488                 ~DrmReadbackInfo() {
489                     if (mDrmDevice == NULL)
490                         return;
491                     if (mOldFbId > 0)
492                         drmModeRmFB(mDrmDevice->fd(), mOldFbId);
493                     if (mFbId > 0)
494                         drmModeRmFB(mDrmDevice->fd(), mFbId);
495                 }
getWritebackConnector()496                 DrmConnector* getWritebackConnector() { return mWritebackConnector; };
setFbId(uint32_t fbId)497                 void setFbId(uint32_t fbId) {
498                     if ((mDrmDevice != NULL) && (mOldFbId > 0))
499                         drmModeRmFB(mDrmDevice->fd(), mOldFbId);
500                     mOldFbId = mFbId;
501                     mFbId = fbId;
502                 }
503                 void pickFormatDataspace();
504                 static constexpr uint32_t PREFERRED_READBACK_FORMAT =
505                     HAL_PIXEL_FORMAT_RGBA_8888;
506                 uint32_t mReadbackFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
507                 bool mNeedClearReadbackCommit = false;
508             private:
509                 DrmDevice *mDrmDevice = NULL;
510                 DrmConnector *mWritebackConnector = NULL;
511                 uint32_t mFbId = 0;
512                 uint32_t mOldFbId = 0;
513                 std::vector<uint32_t> mSupportedFormats;
514         };
515         DrmDevice *mDrmDevice;
516         DrmCrtc *mDrmCrtc;
517         DrmConnector *mDrmConnector;
518         VSyncWorker mDrmVSyncWorker;
519         ExynosVsyncCallback mVsyncCallback;
520         ModeState mActiveModeState;
521         ModeState mDesiredModeState;
522         PartialRegionState mPartialRegionState;
523         BlockingRegionState mBlockState;
524         /* Mapping plane id to ExynosMPP, key is plane id */
525         std::unordered_map<uint32_t, ExynosMPP*> mExynosMPPsForPlane;
526 
527         DrmEnumParser::MapHal2DrmEnum mBlendEnums;
528         DrmEnumParser::MapHal2DrmEnum mStandardEnums;
529         DrmEnumParser::MapHal2DrmEnum mTransferEnums;
530         DrmEnumParser::MapHal2DrmEnum mRangeEnums;
531         DrmEnumParser::MapHal2DrmEnum mColorModeEnums;
532         DrmEnumParser::MapHal2DrmEnum mMipiSyncEnums;
533 
534         DrmReadbackInfo mReadbackInfo;
535         FramebufferManager mFBManager;
536         std::array<uint8_t, MONITOR_DESCRIPTOR_DATA_LENGTH> mMonitorDescription;
537 
538     private:
539         int32_t getDisplayFakeEdid(uint8_t &outPort, uint32_t &outDataSize, uint8_t *outData);
540 
541         String8 mDisplayTraceName;
542         DrmMode mDozeDrmMode;
543         uint32_t mMaxWindowNum = 0;
544         int32_t mFrameCounter = 0;
545         int32_t mPanelFullResolutionHSize = 0;
546         int32_t mPanelFullResolutionVSize = 0;
547 
548         /**
549          * retrievePanelFullResolution
550          *
551          * Retrieve the panel full resolution by looking into the modes of the mDrmConnector
552          * and store the full resolution info in mPanelFullResolutionHSize (x component) and
553          * mPanelFullResolutionVSize (y component).
554          *
555          * Note: this function will be called only once in initDrmDevice()
556          */
557         void retrievePanelFullResolution();
558 
559     public:
560         virtual bool readHotplugStatus();
561 };
562 
563 #endif
564