diff options
-rw-r--r-- | libhwc2.1/libdevice/ExynosDisplay.cpp | 1 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp | 114 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h | 34 | ||||
-rw-r--r-- | libhwc2.1/libresource/ExynosMPP.cpp | 18 |
4 files changed, 117 insertions, 50 deletions
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp index a29927d..fe927ae 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.cpp +++ b/libhwc2.1/libdevice/ExynosDisplay.cpp @@ -4631,6 +4631,7 @@ int32_t ExynosDisplay::validateDisplay( int32_t ExynosDisplay::startPostProcessing() { + ATRACE_CALL(); int ret = NO_ERROR; String8 errString; diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp index 27d541b..f8ca948 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp @@ -120,21 +120,26 @@ bool FramebufferManager::validateLayerInfo(uint32_t state, uint32_t drmFormat, return true; } -bool FramebufferManager::checkShrink() { +void FramebufferManager::checkShrink() { Mutex::Autolock lock(mMutex); mCacheShrinkPending = mCachedLayerBuffers.size() > MAX_CACHED_LAYERS; - return mCacheShrinkPending; + mCacheM2mSecureShrinkPending = + mCachedM2mSecureLayerBuffers.size() > MAX_CACHED_M2M_SECURE_LAYERS; } void FramebufferManager::cleanup(const ExynosLayer *layer) { ATRACE_CALL(); Mutex::Autolock lock(mMutex); - if (auto it = mCachedLayerBuffers.find(layer); it != mCachedLayerBuffers.end()) { - mCleanBuffers.splice(mCleanBuffers.end(), std::move(it->second)); - mCachedLayerBuffers.erase(it); - } + auto clean = [&](std::map<const ExynosLayer *, FBList> &layerBuffs) { + if (auto it = layerBuffs.find(layer); it != layerBuffs.end()) { + mCleanBuffers.splice(mCleanBuffers.end(), std::move(it->second)); + layerBuffs.erase(it); + } + }; + clean(mCachedLayerBuffers); + clean(mCachedM2mSecureLayerBuffers); } void FramebufferManager::removeFBsThreadRoutine() @@ -161,6 +166,7 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint uint32_t bpp = 0; uint32_t bufferNum, planeNum = 0; uint32_t bufWidth, bufHeight = 0; + bool isM2mSecureLayer = (config.protection && config.layer && config.layer->mM2mMPP); DrmArray<uint32_t> pitches = {0}; DrmArray<uint32_t> offsets = {0}; DrmArray<uint64_t> modifiers = {0}; @@ -200,7 +206,7 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint return -EINVAL; } - fbId = findCachedFbId(config.layer, + fbId = findCachedFbId(config.layer, isM2mSecureLayer, [bufferDesc = Framebuffer::BufferDesc{config.buffer_id, drmFormat, config.protection}]( auto &buffer) { return buffer->bufferDesc == bufferDesc; }); @@ -259,7 +265,7 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint handles[0] = 0xff000000; bpp = getBytePerPixelOfPrimaryPlane(HAL_PIXEL_FORMAT_BGRA_8888); pitches[0] = config.dst.w * bpp; - fbId = findCachedFbId(config.layer, + fbId = findCachedFbId(config.layer, isM2mSecureLayer, [colorDesc = Framebuffer::SolidColorDesc{bufWidth, bufHeight}]( auto &buffer) { return buffer->colorDesc == colorDesc; }); if (fbId != 0) { @@ -291,11 +297,10 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint if (config.layer || config.buffer_id) { Mutex::Autolock lock(mMutex); - auto &cachedBuffers = mCachedLayerBuffers[config.layer]; - auto maxCachedBufferSize = MAX_CACHED_BUFFERS_PER_LAYER; - if (config.protection && config.layer && config.layer->mM2mMPP) { - maxCachedBufferSize = MAX_CACHED_SECURE_BUFFERS_PER_G2D_LAYER; - } + auto &cachedBuffers = (!isM2mSecureLayer) ? mCachedLayerBuffers[config.layer] + : mCachedM2mSecureLayerBuffers[config.layer]; + auto maxCachedBufferSize = (!isM2mSecureLayer) ? MAX_CACHED_BUFFERS_PER_LAYER + : MAX_CACHED_M2M_SECURE_BUFFERS_PER_LAYER; if (cachedBuffers.size() > maxCachedBufferSize) { ALOGW("FBManager: cached buffers size %zu exceeds limitation(%zu) while adding fbId %d", @@ -313,6 +318,7 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint Framebuffer::BufferDesc{config.buffer_id, drmFormat, config.protection})); mHasSecureFramebuffer |= (isFramebuffer(config.layer) && config.protection); + mHasM2mSecureLayerBuffer |= isM2mSecureLayer; } } else { ALOGW("FBManager: possible leakage fbId %d was created", fbId); @@ -321,7 +327,7 @@ int32_t FramebufferManager::getBuffer(const exynos_win_config_data &config, uint return 0; } -void FramebufferManager::flip(bool hasSecureFrameBuffer) { +void FramebufferManager::flip(const bool hasSecureFrameBuffer, const bool hasM2mSecureLayerBuffer) { bool needCleanup = false; { Mutex::Autolock lock(mMutex); @@ -329,6 +335,10 @@ void FramebufferManager::flip(bool hasSecureFrameBuffer) { if (!hasSecureFrameBuffer) { destroySecureFramebufferLocked(); } + + if (!hasM2mSecureLayerBuffer) { + destroyM2mSecureLayerBufferLocked(); + } needCleanup = mCleanBuffers.size() > 0; } @@ -341,6 +351,7 @@ void FramebufferManager::releaseAll() { Mutex::Autolock lock(mMutex); mCachedLayerBuffers.clear(); + mCachedM2mSecureLayerBuffers.clear(); mCleanBuffers.clear(); } @@ -358,31 +369,50 @@ void FramebufferManager::freeBufHandle(uint32_t handle) { } } -void FramebufferManager::markInuseLayerLocked(const ExynosLayer *layer) { - if (mCacheShrinkPending) { +void FramebufferManager::markInuseLayerLocked(const ExynosLayer *layer, + const bool isM2mSecureLayer) { + if (!isM2mSecureLayer && mCacheShrinkPending) { mCachedLayersInuse.insert(layer); } -} -void FramebufferManager::destroyUnusedLayersLocked() { - if (!mCacheShrinkPending || mCachedLayersInuse.size() == mCachedLayerBuffers.size()) { - mCachedLayersInuse.clear(); - return; + if (isM2mSecureLayer && mCacheM2mSecureShrinkPending) { + mCachedM2mSecureLayersInuse.insert(layer); } +} - ALOGW("FBManager: shrink cached layers from %zu to %zu", mCachedLayerBuffers.size(), - mCachedLayersInuse.size()); - - for (auto layer = mCachedLayerBuffers.begin(); layer != mCachedLayerBuffers.end();) { - if (mCachedLayersInuse.find(layer->first) == mCachedLayersInuse.end()) { - mCleanBuffers.splice(mCleanBuffers.end(), std::move(layer->second)); - layer = mCachedLayerBuffers.erase(layer); - } else { - ++layer; +void FramebufferManager::destroyUnusedLayersLocked() { + auto destroyUnusedLayers = + [&](const bool &cacheShrinkPending, std::set<const ExynosLayer *> &cachedLayersInuse, + std::map<const ExynosLayer *, FBList> &cachedLayerBuffers) -> bool { + if (!cacheShrinkPending || cachedLayersInuse.size() == cachedLayerBuffers.size()) { + cachedLayersInuse.clear(); + return false; + } + + for (auto layer = cachedLayerBuffers.begin(); layer != cachedLayerBuffers.end();) { + if (cachedLayersInuse.find(layer->first) == cachedLayersInuse.end()) { + mCleanBuffers.splice(mCleanBuffers.end(), std::move(layer->second)); + layer = cachedLayerBuffers.erase(layer); + } else { + ++layer; + } } + cachedLayersInuse.clear(); + return true; + }; + + auto cachedLayerSize = mCachedLayerBuffers.size(); + if (destroyUnusedLayers(mCacheShrinkPending, mCachedLayersInuse, mCachedLayerBuffers)) { + ALOGW("FBManager: shrink cached layers from %zu to %zu", cachedLayerSize, + mCachedLayerBuffers.size()); } - mCachedLayersInuse.clear(); + cachedLayerSize = mCachedM2mSecureLayerBuffers.size(); + if (destroyUnusedLayers(mCacheM2mSecureShrinkPending, mCachedM2mSecureLayersInuse, + mCachedM2mSecureLayerBuffers)) { + ALOGW("FBManager: shrink cached M2M secure layers from %zu to %zu", cachedLayerSize, + mCachedM2mSecureLayerBuffers.size()); + } } void FramebufferManager::destroySecureFramebufferLocked() { @@ -408,6 +438,22 @@ void FramebufferManager::destroySecureFramebufferLocked() { } } +void FramebufferManager::destroyM2mSecureLayerBufferLocked() { + if (!mHasM2mSecureLayerBuffer) { + return; + } + + mHasM2mSecureLayerBuffer = false; + + for (auto &layer : mCachedM2mSecureLayerBuffers) { + auto &bufferList = layer.second; + if (bufferList.size()) { + mCleanBuffers.splice(mCleanBuffers.end(), bufferList, bufferList.begin(), + bufferList.end()); + } + } +} + void ExynosDisplayDrmInterface::destroyLayer(ExynosLayer *layer) { mFBManager.cleanup(layer); } @@ -1443,6 +1489,7 @@ int32_t ExynosDisplayDrmInterface::setupCommitFromDisplayConfig( const std::unique_ptr<DrmPlane> &plane, uint32_t &fbId) { + ATRACE_CALL(); int ret = NO_ERROR; if (fbId == 0) { @@ -1723,14 +1770,16 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData() std::unordered_map<uint32_t, uint32_t> planeEnableInfo; android::String8 result; bool hasSecureFrameBuffer = false; + bool hasM2mSecureLayerBuffer = false; if (mExynosDisplay->isFrameUpdate()) { mFrameCounter++; } funcReturnCallback retCallback([&]() { if ((ret == NO_ERROR) && !drmReq.getError()) { - mFBManager.flip(hasSecureFrameBuffer); + mFBManager.flip(hasSecureFrameBuffer, hasM2mSecureLayerBuffer); } else if (ret == -ENOMEM) { + ALOGW("OOM, release all cached buffers by FBManager"); mFBManager.releaseAll(); } }); @@ -1827,6 +1876,7 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData() return ret; } hasSecureFrameBuffer |= (isFramebuffer(config.layer) && config.protection); + hasM2mSecureLayerBuffer |= (config.protection && config.layer && config.layer->mM2mMPP); /* Set this plane is enabled */ planeEnableInfo[plane->id()] = 1; } diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h index 78ed3e4..0ad50bc 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h @@ -63,7 +63,7 @@ class FramebufferManager { // layer. Those fbIds will be cleaned up once the layer was destroyed. int32_t getBuffer(const exynos_win_config_data &config, uint32_t &fbId); - bool checkShrink(); + void checkShrink(); void cleanup(const ExynosLayer *layer); @@ -71,7 +71,7 @@ class FramebufferManager { // layers after the previous fdIds were update successfully on the // screen. // This should be called after the frame update. - void flip(bool hasSecureFrameBuffer); + void flip(const bool hasSecureFrameBuffer, const bool hasM2mSecureLayerBuffer); // release all currently tracked buffers, this can be called for example when display is turned // off @@ -112,7 +112,8 @@ class FramebufferManager { using FBList = std::list<std::unique_ptr<Framebuffer>>; template <class UnaryPredicate> - uint32_t findCachedFbId(const ExynosLayer *layer, UnaryPredicate predicate); + uint32_t findCachedFbId(const ExynosLayer *layer, const bool isM2mSecureLayer, + UnaryPredicate predicate); int addFB2WithModifiers(uint32_t state, uint32_t width, uint32_t height, uint32_t drmFormat, const DrmArray<uint32_t> &handles, const DrmArray<uint32_t> &pitches, @@ -126,15 +127,19 @@ class FramebufferManager { void freeBufHandle(uint32_t handle); void removeFBsThreadRoutine(); - void markInuseLayerLocked(const ExynosLayer *layer) REQUIRES(mMutex); + void markInuseLayerLocked(const ExynosLayer *layer, const bool isM2mSecureLayer) + REQUIRES(mMutex); void destroyUnusedLayersLocked() REQUIRES(mMutex); void destroySecureFramebufferLocked() REQUIRES(mMutex); + void destroyM2mSecureLayerBufferLocked() REQUIRES(mMutex); int mDrmFd = -1; - // mCachedLayerBuffers map keep the relationship between Layer and - // FBList. The map entry will be deleted once the layer is destroyed. + // mCachedLayerBuffers map keep the relationship between Layer and FBList. + // mCachedM2mSecureLayerBuffers map keep the relationship between M2M secure + // Layer and FBList. The map entry will be deleted once the layer is destroyed. std::map<const ExynosLayer *, FBList> mCachedLayerBuffers; + std::map<const ExynosLayer *, FBList> mCachedM2mSecureLayerBuffers; // mCleanBuffers list keeps fbIds of destroyed layers. Those fbIds will // be destroyed in mRmFBThread thread. @@ -143,11 +148,15 @@ class FramebufferManager { // mCacheShrinkPending is set when we want to clean up unused layers // in mCachedLayerBuffers. When the flag is set, mCachedLayersInuse will // keep in-use layers in this frame update. Those unused layers will be - // freed at the end of the update. + // freed at the end of the update. mCacheM2mSecureShrinkPending is same to + // mCacheShrinkPending but for mCachedM2mSecureLayerBuffers. // TODO: have a better way to maintain inuse layers bool mCacheShrinkPending = false; + bool mCacheM2mSecureShrinkPending = false; bool mHasSecureFramebuffer = false; + bool mHasM2mSecureLayerBuffer = false; std::set<const ExynosLayer *> mCachedLayersInuse; + std::set<const ExynosLayer *> mCachedM2mSecureLayersInuse; std::thread mRmFBThread; bool mRmFBThreadRunning = false; @@ -155,8 +164,9 @@ class FramebufferManager { Mutex mMutex; static constexpr size_t MAX_CACHED_LAYERS = 16; + static constexpr size_t MAX_CACHED_M2M_SECURE_LAYERS = 1; static constexpr size_t MAX_CACHED_BUFFERS_PER_LAYER = 32; - static constexpr size_t MAX_CACHED_SECURE_BUFFERS_PER_G2D_LAYER = 3; + static constexpr size_t MAX_CACHED_M2M_SECURE_BUFFERS_PER_LAYER = 3; }; inline bool isFramebuffer(const ExynosLayer *layer) { @@ -164,10 +174,12 @@ inline bool isFramebuffer(const ExynosLayer *layer) { } template <class UnaryPredicate> -uint32_t FramebufferManager::findCachedFbId(const ExynosLayer *layer, UnaryPredicate predicate) { +uint32_t FramebufferManager::findCachedFbId(const ExynosLayer *layer, const bool isM2mSecureLayer, + UnaryPredicate predicate) { Mutex::Autolock lock(mMutex); - markInuseLayerLocked(layer); - const auto &cachedBuffers = mCachedLayerBuffers[layer]; + markInuseLayerLocked(layer, isM2mSecureLayer); + const auto &cachedBuffers = + (!isM2mSecureLayer) ? mCachedLayerBuffers[layer] : mCachedM2mSecureLayerBuffers[layer]; const auto it = std::find_if(cachedBuffers.begin(), cachedBuffers.end(), predicate); return (it != cachedBuffers.end()) ? (*it)->fbId : 0; } diff --git a/libhwc2.1/libresource/ExynosMPP.cpp b/libhwc2.1/libresource/ExynosMPP.cpp index ae30482..119420e 100644 --- a/libhwc2.1/libresource/ExynosMPP.cpp +++ b/libhwc2.1/libresource/ExynosMPP.cpp @@ -1001,9 +1001,10 @@ int32_t ExynosMPP::allocOutBuf(uint32_t w, uint32_t h, uint32_t format, uint64_t mDstImgs[index].format = format; MPP_LOGD(eDebugMPP|eDebugBuf, "free outbuf[%d] %p", index, freeDstBuf.bufferHandle); - if (freeDstBuf.bufferHandle != NULL) + + if (freeDstBuf.bufferHandle != NULL) { freeOutBuf(freeDstBuf); - else { + } else { if (mAssignedDisplay != NULL) { freeDstBuf.acrylicAcquireFenceFd = fence_close(freeDstBuf.acrylicAcquireFenceFd, mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D); @@ -1399,9 +1400,10 @@ int32_t ExynosMPP::setupDst(exynos_mpp_img_info *dstImgInfo) if (dstImgInfo->bufferType == MPP_BUFFER_SECURE_DRM) attribute |= AcrylicCanvas::ATTR_PROTECTED; - if (mAssignedDisplay != NULL) + if (mAssignedDisplay != NULL) { mAcrylicHandle->setCanvasDimension(pixel_align(mAssignedDisplay->mXres, G2D_JUSTIFIED_DST_ALIGN), pixel_align(mAssignedDisplay->mYres, G2D_JUSTIFIED_DST_ALIGN)); + } /* setup dst */ if (needCompressDstBuf()) { @@ -1923,13 +1925,15 @@ int32_t ExynosMPP::requestHWStateChange(uint32_t state) return NO_ERROR; } - if (state == MPP_HW_STATE_RUNNING) + if (state == MPP_HW_STATE_RUNNING) { mHWState = MPP_HW_STATE_RUNNING; - else if (state == MPP_HW_STATE_IDLE) { - if (mLastStateFenceFd >= 0) + } else if (state == MPP_HW_STATE_IDLE) { + if (mLastStateFenceFd >= 0) { mResourceManageThread->addStateFence(mLastStateFenceFd); - else + } else { mHWState = MPP_HW_STATE_IDLE; + } + mLastStateFenceFd = -1; if ((mPhysicalType == MPP_G2D) && (mHWBusyFlag == false)) { |