Loading libs/gui/BLASTBufferQueue.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <cutils/properties.h> #include <gui/BLASTBufferQueue.h> #include <gui/BufferItemConsumer.h> #include <gui/GLConsumer.h> Loading Loading @@ -99,7 +101,11 @@ BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, mHeight(height), mNextTransaction(nullptr) { BufferQueue::createBufferQueue(&mProducer, &mConsumer); mConsumer->setMaxAcquiredBufferCount(MAX_ACQUIRED_BUFFERS); int8_t disableTripleBuffer = property_get_bool("ro.sf.disable_triple_buffer", 0); if (!disableTripleBuffer) { mProducer->setMaxDequeuedBufferCount(2); } mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true); static int32_t id = 0; Loading Loading @@ -183,7 +189,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence void BLASTBufferQueue::processNextBufferLocked() { ATRACE_CALL(); if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) { if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) { return; } Loading libs/gui/include/gui/BLASTBufferQueue.h +3 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ private: std::mutex mMutex; std::condition_variable mCallbackCV; static const int MAX_ACQUIRED_BUFFERS = 2; // BufferQueue internally allows 1 more than // the max to be acquired static const int MAX_ACQUIRED_BUFFERS = 1; int32_t mNumFrameAvailable GUARDED_BY(mMutex); int32_t mNumAcquired GUARDED_BY(mMutex); Loading services/automotive/display/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,8 @@ cc_binary { local_include_dirs: [ "include", ], cflags: [ "-DLOG_TAG=\"AutomotiveDisplayService\"" ], } services/automotive/display/AutomotiveDisplayProxyService.cpp +118 −52 Original line number Diff line number Diff line Loading @@ -27,97 +27,163 @@ namespace display { namespace V1_0 { namespace implementation { Return<sp<IGraphicBufferProducer>> AutomotiveDisplayProxyService::getIGraphicBufferProducer() { if (mSurface == nullptr) { status_t err; mSurfaceComposerClient = new SurfaceComposerClient(); err = mSurfaceComposerClient->initCheck(); if (err != NO_ERROR) { ALOGE("SurfaceComposerClient::initCheck error: %#x", err); mSurfaceComposerClient = nullptr; return nullptr; } const auto displayToken = SurfaceComposerClient::getInternalDisplayToken(); Return<sp<IGraphicBufferProducer>> AutomotiveDisplayProxyService::getIGraphicBufferProducer(uint64_t id) { auto it = mDisplays.find(id); sp<IBinder> displayToken = nullptr; sp<SurfaceControl> surfaceControl = nullptr; if (it == mDisplays.end()) { displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id); if (displayToken == nullptr) { ALOGE("Failed to get internal display "); ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); return nullptr; } err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &mDpyConfig); // Get the resolution from stored display state. DisplayConfig displayConfig = {}; auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig); if (err != NO_ERROR) { ALOGE("Failed to get active display config"); ALOGE("Failed to get display configuration of %lX. " "This display will be ignored.", (unsigned long)id); return nullptr; } err = SurfaceComposerClient::getDisplayState(displayToken, &mDpyState); ui::DisplayState displayState = {}; err = SurfaceComposerClient::getDisplayState(displayToken, &displayState); if (err != NO_ERROR) { ALOGE("Failed to get display state"); ALOGE("Failed to get current display status of %lX. " "This display will be ignored.", (unsigned long)id); return nullptr; } const ui::Size& resolution = mDpyConfig.resolution; auto width = resolution.getWidth(); auto height = resolution.getHeight(); auto displayWidth = displayConfig.resolution.getWidth(); auto displayHeight = displayConfig.resolution.getHeight(); if ((displayState.orientation != ui::ROTATION_0) && (displayState.orientation != ui::ROTATION_180)) { std::swap(displayWidth, displayHeight); } if (mDpyState.orientation == ui::ROTATION_90 || mDpyState.orientation == ui::ROTATION_270) { std::swap(width, height); sp<android::SurfaceComposerClient> surfaceClient = new SurfaceComposerClient(); err = surfaceClient->initCheck(); if (err != NO_ERROR) { ALOGE("SurfaceComposerClient::initCheck error: %#x", err); return nullptr; } mSurfaceControl = mSurfaceComposerClient->createSurface( String8("Automotive Display"), width, height, // Create a SurfaceControl instance surfaceControl = surfaceClient->createSurface( String8::format("AutomotiveDisplay::%lX", (unsigned long)id), displayWidth, displayHeight, PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque); if (mSurfaceControl == nullptr || !mSurfaceControl->isValid()) { ALOGE("Failed to create SurfaceControl"); mSurfaceComposerClient = nullptr; mSurfaceControl = nullptr; if (surfaceControl == nullptr || !surfaceControl->isValid()) { ALOGE("Failed to create SurfaceControl."); return nullptr; } // SurfaceControl::getSurface is guaranteed to be not null. mSurface = mSurfaceControl->getSurface(); // Store DisplayDesc descriptor = {displayToken, surfaceControl}; mDisplays.insert_or_assign(id, std::move(descriptor)); } else { displayToken = it->second.token; surfaceControl = it->second.surfaceControl; } // SurfaceControl::getSurface is guaranteed to be not null. auto targetSurface = surfaceControl->getSurface(); return new ::android::hardware::graphics::bufferqueue::V2_0::utils:: B2HGraphicBufferProducer( mSurface->getIGraphicBufferProducer()); B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer()); } Return<bool> AutomotiveDisplayProxyService::showWindow() { status_t status = NO_ERROR; if (mSurfaceControl != nullptr) { status = SurfaceComposerClient::Transaction{} .setLayer( mSurfaceControl, 0x7FFFFFFF) // always on top .show(mSurfaceControl) .apply(); } else { ALOGE("showWindow: Failed to get a valid SurfaceControl!"); Return<bool> AutomotiveDisplayProxyService::showWindow(uint64_t id) { auto it = mDisplays.find(id); if (it == mDisplays.end()) { ALOGE("Given display token is invalid or unknown."); return false; } return status == NO_ERROR; ui::DisplayState displayState; auto err = SurfaceComposerClient::getDisplayState(it->second.token, &displayState); if (err != NO_ERROR) { ALOGE("Failed to get current state of the display 0x%lX", (unsigned long)id); return false; } Return<bool> AutomotiveDisplayProxyService::hideWindow() { status_t status = NO_ERROR; SurfaceComposerClient::Transaction t; t.setDisplayLayerStack(it->second.token, displayState.layerStack); t.setLayerStack(it->second.surfaceControl, displayState.layerStack); if (mSurfaceControl != nullptr) { status = SurfaceComposerClient::Transaction{} .hide(mSurfaceControl) status_t status = t.setLayer(it->second.surfaceControl, 0x7FFFFFFF) .show(it->second.surfaceControl) .apply(); } else { ALOGE("hideWindow: Failed to get a valid SurfaceControl!"); return status == NO_ERROR; } Return<bool> AutomotiveDisplayProxyService::hideWindow(uint64_t id) { auto it = mDisplays.find(id); if (it == mDisplays.end()) { ALOGE("Given display token is invalid or unknown."); return false; } status_t status = SurfaceComposerClient::Transaction{} .hide(it->second.surfaceControl) .apply(); return status == NO_ERROR; } Return<void> AutomotiveDisplayProxyService::getDisplayIdList(getDisplayIdList_cb _cb) { hardware::hidl_vec<uint64_t> ids; // Get stable IDs of all available displays and get their tokens and // descriptors. auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds(); ids.resize(displayIds.size()); for (auto i = 0; i < displayIds.size(); ++i) { ids[i] = displayIds[i]; } _cb(ids); return hardware::Void(); } Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) { HwDisplayConfig activeConfig; HwDisplayState activeState; auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id); if (displayToken == nullptr) { ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); } else { DisplayConfig displayConfig = {}; auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig); if (err != NO_ERROR) { ALOGW("Failed to get display configuration of %lX. " "This display will be ignored.", (unsigned long)id); } ui::DisplayState displayState = {}; err = SurfaceComposerClient::getDisplayState(displayToken, &displayState); if (err != NO_ERROR) { ALOGW("Failed to get current display status of %lX. " "This display will be ignored.", (unsigned long)id); } activeConfig.setToExternal((uint8_t*)&displayConfig, sizeof(DisplayConfig)); activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState)); } _cb(activeConfig, activeState); return hardware::Void(); } } // namespace implementation } // namespace V1_0 } // namespace display Loading services/automotive/display/include/AutomotiveDisplayProxyService.h +20 −20 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ #pragma once #include <android/frameworks/automotive/display/1.0/IAutomotiveDisplayProxyService.h> #include <gui/ISurfaceComposer.h> #include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <ui/DisplayConfig.h> #include <ui/DisplayState.h> #include <tuple> #include <vector> namespace android { namespace frameworks { Loading @@ -31,32 +33,30 @@ namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::sp; using ::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer; using ::android::sp; class AutomotiveDisplayProxyService : public IAutomotiveDisplayProxyService { public: Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer() override; Return<bool> showWindow() override; Return<bool> hideWindow() override; Return<void> getDisplayInfo(getDisplayInfo_cb _info_cb) override { HwDisplayConfig cfg; cfg.setToExternal((uint8_t*)&mDpyConfig, sizeof(DisplayConfig)); HwDisplayState state; state.setToExternal((uint8_t*)&mDpyState, sizeof(DisplayState)); typedef struct DisplayDesc { sp<IBinder> token; sp<SurfaceControl> surfaceControl; } DisplayDesc; _info_cb(cfg, state); return hardware::Void(); } class AutomotiveDisplayProxyService : public IAutomotiveDisplayProxyService { public: Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer(uint64_t id) override; Return<bool> showWindow(uint64_t id) override; Return<bool> hideWindow(uint64_t id) override; Return<void> getDisplayIdList(getDisplayIdList_cb _cb) override; Return<void> getDisplayInfo(uint64_t, getDisplayInfo_cb _cb) override; private: sp<android::Surface> mSurface; sp<android::SurfaceComposerClient> mSurfaceComposerClient; sp<android::SurfaceControl> mSurfaceControl; DisplayConfig mDpyConfig; ui::DisplayState mDpyState; uint8_t getDisplayPort(const uint64_t id) { return (id & 0xF); } std::unordered_map<uint64_t, DisplayDesc> mDisplays; }; } // namespace implementation } // namespace V1_0 } // namespace display Loading Loading
libs/gui/BLASTBufferQueue.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <cutils/properties.h> #include <gui/BLASTBufferQueue.h> #include <gui/BufferItemConsumer.h> #include <gui/GLConsumer.h> Loading Loading @@ -99,7 +101,11 @@ BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, mHeight(height), mNextTransaction(nullptr) { BufferQueue::createBufferQueue(&mProducer, &mConsumer); mConsumer->setMaxAcquiredBufferCount(MAX_ACQUIRED_BUFFERS); int8_t disableTripleBuffer = property_get_bool("ro.sf.disable_triple_buffer", 0); if (!disableTripleBuffer) { mProducer->setMaxDequeuedBufferCount(2); } mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true); static int32_t id = 0; Loading Loading @@ -183,7 +189,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence void BLASTBufferQueue::processNextBufferLocked() { ATRACE_CALL(); if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) { if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) { return; } Loading
libs/gui/include/gui/BLASTBufferQueue.h +3 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ private: std::mutex mMutex; std::condition_variable mCallbackCV; static const int MAX_ACQUIRED_BUFFERS = 2; // BufferQueue internally allows 1 more than // the max to be acquired static const int MAX_ACQUIRED_BUFFERS = 1; int32_t mNumFrameAvailable GUARDED_BY(mMutex); int32_t mNumAcquired GUARDED_BY(mMutex); Loading
services/automotive/display/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,8 @@ cc_binary { local_include_dirs: [ "include", ], cflags: [ "-DLOG_TAG=\"AutomotiveDisplayService\"" ], }
services/automotive/display/AutomotiveDisplayProxyService.cpp +118 −52 Original line number Diff line number Diff line Loading @@ -27,97 +27,163 @@ namespace display { namespace V1_0 { namespace implementation { Return<sp<IGraphicBufferProducer>> AutomotiveDisplayProxyService::getIGraphicBufferProducer() { if (mSurface == nullptr) { status_t err; mSurfaceComposerClient = new SurfaceComposerClient(); err = mSurfaceComposerClient->initCheck(); if (err != NO_ERROR) { ALOGE("SurfaceComposerClient::initCheck error: %#x", err); mSurfaceComposerClient = nullptr; return nullptr; } const auto displayToken = SurfaceComposerClient::getInternalDisplayToken(); Return<sp<IGraphicBufferProducer>> AutomotiveDisplayProxyService::getIGraphicBufferProducer(uint64_t id) { auto it = mDisplays.find(id); sp<IBinder> displayToken = nullptr; sp<SurfaceControl> surfaceControl = nullptr; if (it == mDisplays.end()) { displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id); if (displayToken == nullptr) { ALOGE("Failed to get internal display "); ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); return nullptr; } err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &mDpyConfig); // Get the resolution from stored display state. DisplayConfig displayConfig = {}; auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig); if (err != NO_ERROR) { ALOGE("Failed to get active display config"); ALOGE("Failed to get display configuration of %lX. " "This display will be ignored.", (unsigned long)id); return nullptr; } err = SurfaceComposerClient::getDisplayState(displayToken, &mDpyState); ui::DisplayState displayState = {}; err = SurfaceComposerClient::getDisplayState(displayToken, &displayState); if (err != NO_ERROR) { ALOGE("Failed to get display state"); ALOGE("Failed to get current display status of %lX. " "This display will be ignored.", (unsigned long)id); return nullptr; } const ui::Size& resolution = mDpyConfig.resolution; auto width = resolution.getWidth(); auto height = resolution.getHeight(); auto displayWidth = displayConfig.resolution.getWidth(); auto displayHeight = displayConfig.resolution.getHeight(); if ((displayState.orientation != ui::ROTATION_0) && (displayState.orientation != ui::ROTATION_180)) { std::swap(displayWidth, displayHeight); } if (mDpyState.orientation == ui::ROTATION_90 || mDpyState.orientation == ui::ROTATION_270) { std::swap(width, height); sp<android::SurfaceComposerClient> surfaceClient = new SurfaceComposerClient(); err = surfaceClient->initCheck(); if (err != NO_ERROR) { ALOGE("SurfaceComposerClient::initCheck error: %#x", err); return nullptr; } mSurfaceControl = mSurfaceComposerClient->createSurface( String8("Automotive Display"), width, height, // Create a SurfaceControl instance surfaceControl = surfaceClient->createSurface( String8::format("AutomotiveDisplay::%lX", (unsigned long)id), displayWidth, displayHeight, PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque); if (mSurfaceControl == nullptr || !mSurfaceControl->isValid()) { ALOGE("Failed to create SurfaceControl"); mSurfaceComposerClient = nullptr; mSurfaceControl = nullptr; if (surfaceControl == nullptr || !surfaceControl->isValid()) { ALOGE("Failed to create SurfaceControl."); return nullptr; } // SurfaceControl::getSurface is guaranteed to be not null. mSurface = mSurfaceControl->getSurface(); // Store DisplayDesc descriptor = {displayToken, surfaceControl}; mDisplays.insert_or_assign(id, std::move(descriptor)); } else { displayToken = it->second.token; surfaceControl = it->second.surfaceControl; } // SurfaceControl::getSurface is guaranteed to be not null. auto targetSurface = surfaceControl->getSurface(); return new ::android::hardware::graphics::bufferqueue::V2_0::utils:: B2HGraphicBufferProducer( mSurface->getIGraphicBufferProducer()); B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer()); } Return<bool> AutomotiveDisplayProxyService::showWindow() { status_t status = NO_ERROR; if (mSurfaceControl != nullptr) { status = SurfaceComposerClient::Transaction{} .setLayer( mSurfaceControl, 0x7FFFFFFF) // always on top .show(mSurfaceControl) .apply(); } else { ALOGE("showWindow: Failed to get a valid SurfaceControl!"); Return<bool> AutomotiveDisplayProxyService::showWindow(uint64_t id) { auto it = mDisplays.find(id); if (it == mDisplays.end()) { ALOGE("Given display token is invalid or unknown."); return false; } return status == NO_ERROR; ui::DisplayState displayState; auto err = SurfaceComposerClient::getDisplayState(it->second.token, &displayState); if (err != NO_ERROR) { ALOGE("Failed to get current state of the display 0x%lX", (unsigned long)id); return false; } Return<bool> AutomotiveDisplayProxyService::hideWindow() { status_t status = NO_ERROR; SurfaceComposerClient::Transaction t; t.setDisplayLayerStack(it->second.token, displayState.layerStack); t.setLayerStack(it->second.surfaceControl, displayState.layerStack); if (mSurfaceControl != nullptr) { status = SurfaceComposerClient::Transaction{} .hide(mSurfaceControl) status_t status = t.setLayer(it->second.surfaceControl, 0x7FFFFFFF) .show(it->second.surfaceControl) .apply(); } else { ALOGE("hideWindow: Failed to get a valid SurfaceControl!"); return status == NO_ERROR; } Return<bool> AutomotiveDisplayProxyService::hideWindow(uint64_t id) { auto it = mDisplays.find(id); if (it == mDisplays.end()) { ALOGE("Given display token is invalid or unknown."); return false; } status_t status = SurfaceComposerClient::Transaction{} .hide(it->second.surfaceControl) .apply(); return status == NO_ERROR; } Return<void> AutomotiveDisplayProxyService::getDisplayIdList(getDisplayIdList_cb _cb) { hardware::hidl_vec<uint64_t> ids; // Get stable IDs of all available displays and get their tokens and // descriptors. auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds(); ids.resize(displayIds.size()); for (auto i = 0; i < displayIds.size(); ++i) { ids[i] = displayIds[i]; } _cb(ids); return hardware::Void(); } Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) { HwDisplayConfig activeConfig; HwDisplayState activeState; auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id); if (displayToken == nullptr) { ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); } else { DisplayConfig displayConfig = {}; auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig); if (err != NO_ERROR) { ALOGW("Failed to get display configuration of %lX. " "This display will be ignored.", (unsigned long)id); } ui::DisplayState displayState = {}; err = SurfaceComposerClient::getDisplayState(displayToken, &displayState); if (err != NO_ERROR) { ALOGW("Failed to get current display status of %lX. " "This display will be ignored.", (unsigned long)id); } activeConfig.setToExternal((uint8_t*)&displayConfig, sizeof(DisplayConfig)); activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState)); } _cb(activeConfig, activeState); return hardware::Void(); } } // namespace implementation } // namespace V1_0 } // namespace display Loading
services/automotive/display/include/AutomotiveDisplayProxyService.h +20 −20 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ #pragma once #include <android/frameworks/automotive/display/1.0/IAutomotiveDisplayProxyService.h> #include <gui/ISurfaceComposer.h> #include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <ui/DisplayConfig.h> #include <ui/DisplayState.h> #include <tuple> #include <vector> namespace android { namespace frameworks { Loading @@ -31,32 +33,30 @@ namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::sp; using ::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer; using ::android::sp; class AutomotiveDisplayProxyService : public IAutomotiveDisplayProxyService { public: Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer() override; Return<bool> showWindow() override; Return<bool> hideWindow() override; Return<void> getDisplayInfo(getDisplayInfo_cb _info_cb) override { HwDisplayConfig cfg; cfg.setToExternal((uint8_t*)&mDpyConfig, sizeof(DisplayConfig)); HwDisplayState state; state.setToExternal((uint8_t*)&mDpyState, sizeof(DisplayState)); typedef struct DisplayDesc { sp<IBinder> token; sp<SurfaceControl> surfaceControl; } DisplayDesc; _info_cb(cfg, state); return hardware::Void(); } class AutomotiveDisplayProxyService : public IAutomotiveDisplayProxyService { public: Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer(uint64_t id) override; Return<bool> showWindow(uint64_t id) override; Return<bool> hideWindow(uint64_t id) override; Return<void> getDisplayIdList(getDisplayIdList_cb _cb) override; Return<void> getDisplayInfo(uint64_t, getDisplayInfo_cb _cb) override; private: sp<android::Surface> mSurface; sp<android::SurfaceComposerClient> mSurfaceComposerClient; sp<android::SurfaceControl> mSurfaceControl; DisplayConfig mDpyConfig; ui::DisplayState mDpyState; uint8_t getDisplayPort(const uint64_t id) { return (id & 0xF); } std::unordered_map<uint64_t, DisplayDesc> mDisplays; }; } // namespace implementation } // namespace V1_0 } // namespace display Loading