summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp1
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp114
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h34
-rw-r--r--libhwc2.1/libresource/ExynosMPP.cpp18
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)) {