sdm: Configure RMFB delay based on whether it is refcounted
Configure RMFB delay based on whether it is refcounted. If it is,
fb_id should be released immediately from userspace and driver will
free it when its usage is over. If not refcounted userspace needs
to defer freeing fb_id until a time where driver usage will be over.
Change-Id: I162723a5426c7e7c041d444ba50a73475858e96f
CRs-fixed: 1114808
diff --git a/libdrmutils/drm_master.cpp b/libdrmutils/drm_master.cpp
index 09e0729..ff7770b 100644
--- a/libdrmutils/drm_master.cpp
+++ b/libdrmutils/drm_master.cpp
@@ -146,4 +146,11 @@
return ret;
}
+bool DRMMaster::IsRmFbRefCounted() {
+#ifdef DRM_IOCTL_MSM_RMFB2
+ return true;
+#endif
+ return false;
+}
+
} // namespace drm_utils
diff --git a/libdrmutils/drm_master.h b/libdrmutils/drm_master.h
index 52a8b02..18f51eb 100644
--- a/libdrmutils/drm_master.h
+++ b/libdrmutils/drm_master.h
@@ -71,6 +71,8 @@
* fd: Pointer to store master fd into
*/
void GetHandle(int *fd) { *fd = dev_fd_; }
+ /* Returns true if the ref counted version of rmfb is being used */
+ bool IsRmFbRefCounted();
/* Creates an instance of DRMMaster if it doesn't exist and initializes it. Threadsafe.
* Input:
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 9e99361..ff25295 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -216,6 +216,27 @@
}
}
+HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
+ buffer_allocator_(buffer_allocator) {
+ DRMMaster *master = nullptr;
+ DRMMaster::GetInstance(&master);
+
+ if (!master) {
+ DLOGE("Failed to acquire DRM Master instance");
+ return;
+ }
+
+ // If RMFB is ref-counted, we should immediately make a call to clean up fb_id after commit.
+ // Driver will release fb_id after its usage. Otherwise speculatively free up fb_id after 3
+ // cycles assuming driver is done with it.
+ rmfb_delay_ = master->IsRmFbRefCounted() ? 1 : 3;
+ hashmap_ = new std::unordered_map<int, uint32_t>[rmfb_delay_];
+}
+
+HWDeviceDRM::Registry::~Registry() {
+ delete [] hashmap_;
+}
+
void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
@@ -276,7 +297,7 @@
return;
}
- current_index_ = (current_index_ + 1) % kCycleDelay;
+ current_index_ = (current_index_ + 1) % rmfb_delay_;
auto &curr_map = hashmap_[current_index_];
for (auto &pair : curr_map) {
uint32_t fb_id = pair.second;
@@ -290,7 +311,7 @@
}
void HWDeviceDRM::Registry::Clear() {
- for (int i = 0; i < kCycleDelay; i++) {
+ for (int i = 0; i < rmfb_delay_; i++) {
UnregisterNext();
}
current_index_ = 0;
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index bbdd69d..c602bb6 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -128,7 +128,8 @@
class Registry {
public:
- explicit Registry(BufferAllocator *buffer_allocator) : buffer_allocator_(buffer_allocator) {}
+ explicit Registry(BufferAllocator *buffer_allocator);
+ ~Registry();
// Call on each validate and commit to register layer buffers
void RegisterCurrent(HWLayers *hw_layers);
// Call at the end of draw cycle to clear the next slot for business
@@ -141,10 +142,10 @@
uint32_t GetFbId(int fd);
private:
- static const int kCycleDelay = 3; // N cycle delay before destroy
+ uint8_t rmfb_delay_ = 1; // N cycle delay before destroy
// fd to fb_id map. fd is used as key only for a single draw cycle between
// prepare and commit. It should not be used for caching in future due to fd recycling
- std::unordered_map<int, uint32_t> hashmap_[kCycleDelay] {};
+ std::unordered_map<int, uint32_t> *hashmap_ {};
int current_index_ = 0;
BufferAllocator *buffer_allocator_ = {};
};