diff options
-rw-r--r-- | hwc2_device/HwcDisplay.cpp | 1 | ||||
-rw-r--r-- | hwc2_device/HwcLayer.cpp | 80 | ||||
-rw-r--r-- | hwc2_device/HwcLayer.h | 19 |
3 files changed, 100 insertions, 0 deletions
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp index 02df28c..76e2745 100644 --- a/hwc2_device/HwcDisplay.cpp +++ b/hwc2_device/HwcDisplay.cpp @@ -602,6 +602,7 @@ HWC2::Error HwcDisplay::SetClientTarget(buffer_handle_t target, * https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h;l=350;drc=944b68180b008456ed2eb4d4d329e33b19bd5166 */ if (target == nullptr) { + client_layer_.SwChainClearCache(); return HWC2::Error::None; } diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp index f57ad9b..c278732 100644 --- a/hwc2_device/HwcLayer.cpp +++ b/hwc2_device/HwcLayer.cpp @@ -174,6 +174,11 @@ void HwcLayer::ImportFb() { layer_data_.fb = {}; + auto unique_id = BufferInfoGetter::GetInstance()->GetUniqueId(buffer_handle_); + if (unique_id && SwChainGetBufferFromCache(*unique_id)) { + return; + } + layer_data_.bi = BufferInfoGetter::GetInstance()->GetBoInfo(buffer_handle_); if (!layer_data_.bi) { ALOGW("Unable to get buffer information (0x%p)", buffer_handle_); @@ -191,6 +196,10 @@ void HwcLayer::ImportFb() { fb_import_failed_ = true; return; } + + if (unique_id) { + SwChainAddCurrentBuffer(*unique_id); + } } void HwcLayer::PopulateLayerData(bool test) { @@ -211,4 +220,75 @@ void HwcLayer::PopulateLayerData(bool test) { } } +/* SwapChain Cache */ + +bool HwcLayer::SwChainGetBufferFromCache(BufferUniqueId unique_id) { + if (swchain_lookup_table_.count(unique_id) == 0) { + return false; + } + + int seq = swchain_lookup_table_[unique_id]; + + if (swchain_cache_.count(seq) == 0) { + return false; + } + + auto& el = swchain_cache_[seq]; + if (!el.bi) { + return false; + } + + layer_data_.bi = el.bi; + layer_data_.fb = el.fb; + + return true; +} + +void HwcLayer::SwChainReassemble(BufferUniqueId unique_id) { + if (swchain_lookup_table_.count(unique_id) != 0) { + if (swchain_lookup_table_[unique_id] == + int(swchain_lookup_table_.size()) - 1) { + /* Skip same buffer */ + return; + } + if (swchain_lookup_table_[unique_id] == 0) { + swchain_reassembled_ = true; + return; + } + /* Tracking error */ + SwChainClearCache(); + return; + } + + swchain_lookup_table_[unique_id] = int(swchain_lookup_table_.size()); +} + +void HwcLayer::SwChainAddCurrentBuffer(BufferUniqueId unique_id) { + if (!swchain_reassembled_) { + SwChainReassemble(unique_id); + } + + if (swchain_reassembled_) { + if (swchain_lookup_table_.count(unique_id) == 0) { + SwChainClearCache(); + return; + } + + int seq = swchain_lookup_table_[unique_id]; + + if (swchain_cache_.count(seq) == 0) { + swchain_cache_[seq] = {}; + } + + swchain_cache_[seq].bi = layer_data_.bi; + swchain_cache_[seq].fb = layer_data_.fb; + } +} + +void HwcLayer::SwChainClearCache() { + swchain_cache_.clear(); + swchain_lookup_table_.clear(); + swchain_reassembled_ = false; +} + } // namespace android
\ No newline at end of file diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h index 92e9476..41b3dbb 100644 --- a/hwc2_device/HwcLayer.h +++ b/hwc2_device/HwcLayer.h @@ -19,6 +19,7 @@ #include <hardware/hwcomposer2.h> +#include "bufferinfo/BufferInfoGetter.h" #include "compositor/LayerData.h" namespace android { @@ -118,6 +119,24 @@ class HwcLayer { void ImportFb(); bool bi_get_failed_{}; bool fb_import_failed_{}; + + /* SwapChain Cache */ + public: + void SwChainClearCache(); + + private: + struct SwapChainElement { + std::optional<BufferInfo> bi; + std::shared_ptr<DrmFbIdHandle> fb; + }; + + bool SwChainGetBufferFromCache(BufferUniqueId unique_id); + void SwChainReassemble(BufferUniqueId unique_id); + void SwChainAddCurrentBuffer(BufferUniqueId unique_id); + + std::map<int /*seq_no*/, SwapChainElement> swchain_cache_; + std::map<BufferUniqueId, int /*seq_no*/> swchain_lookup_table_; + bool swchain_reassembled_{}; }; } // namespace android |