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