surfaceflinger: cache HWC client targets and buffers
Remember HWC client targets and buffers, and make sure we send each
unique slot/handle pair only once. This allows the composer to
clone/register/retain each buffer only once.
Test: builds and boots
Change-Id: Ib485189043a9c132031e82d4d7380ace3bf9453d
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7335be7..76c710a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -376,13 +376,20 @@
#ifdef USE_HWC2
// -----------------------------------------------------------------------
+ void eraseHwcLayer(int32_t hwcId) {
+ mHwcLayers.erase(hwcId);
+
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+ mHwcBufferCaches.erase(hwcId);
+ }
+
bool hasHwcLayer(int32_t hwcId) {
if (mHwcLayers.count(hwcId) == 0) {
return false;
}
if (mHwcLayers[hwcId].layer->isAbandoned()) {
ALOGI("Erasing abandoned layer %s on %d", mName.string(), hwcId);
- mHwcLayers.erase(hwcId);
+ eraseHwcLayer(hwcId);
return false;
}
return true;
@@ -398,8 +405,11 @@
void setHwcLayer(int32_t hwcId, std::shared_ptr<HWC2::Layer>&& layer) {
if (layer) {
mHwcLayers[hwcId].layer = layer;
+
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+ mHwcBufferCaches[hwcId] = HWComposerBufferCache();
} else {
- mHwcLayers.erase(hwcId);
+ eraseHwcLayer(hwcId);
}
}
@@ -489,6 +499,7 @@
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
virtual void onFrameAvailable(const BufferItem& item) override;
virtual void onFrameReplaced(const BufferItem& item) override;
+ virtual void onBuffersReleased() override;
virtual void onSidebandStreamChanged() override;
void commitTransaction(const State& stateToCommit);
@@ -642,6 +653,7 @@
FenceTimeline mReleaseTimeline;
// main thread
+ int mActiveBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
sp<GraphicBuffer> mActiveBuffer;
sp<NativeHandle> mSidebandStream;
Rect mCurrentCrop;
@@ -681,6 +693,12 @@
gfx::FloatRect sourceCrop;
};
std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+ // We need one HWComposerBufferCache for each HWC display. We cannot have
+ // HWComposerBufferCache in HWCInfo because HWCInfo can only be accessed
+ // from the main thread.
+ Mutex mHwcBufferCacheMutex;
+ std::unordered_map<int32_t, HWComposerBufferCache> mHwcBufferCaches;
#else
bool mIsGlesComposition;
#endif