aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hwc2_device/HwcDisplay.cpp1
-rw-r--r--hwc2_device/HwcLayer.cpp80
-rw-r--r--hwc2_device/HwcLayer.h19
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