summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUmang Jain <umang.jain@ideasonboard.com>2021-05-10 22:52:47 +0530
committerUmang Jain <umang.jain@ideasonboard.com>2021-06-28 17:54:08 +0530
commit12241d3b3be9ef911600194255904fbffeadc377 (patch)
tree2bd9bb8d3ef599b702b2419b82c6e555255f81b1
parent3319e404d494be9fe114958b8250f2b0274cf359 (diff)
stats: Import SharedItemPool for stats' grid buffers
Import the SharedItemPool implementation to managed grid buffers. Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
-rw-r--r--meson.build1
-rw-r--r--stats/meson.build6
-rw-r--r--stats/shared_item_pool.cpp129
-rw-r--r--stats/shared_item_pool.h114
4 files changed, 250 insertions, 0 deletions
diff --git a/meson.build b/meson.build
index ae51789..5516434 100644
--- a/meson.build
+++ b/meson.build
@@ -95,6 +95,7 @@ ipu3_ipa_deps = [
subdir('aiq')
subdir('data')
subdir('src')
+subdir('stats')
mod = shared_module(ipa_name,
[ipu3_ipa_files, libcamera_helpers],
diff --git a/stats/meson.build b/stats/meson.build
new file mode 100644
index 0000000..9707630
--- /dev/null
+++ b/stats/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: CC0-1.0
+
+ipu3_ipa_files += files([
+ 'shared_item_pool.cpp',
+])
+
diff --git a/stats/shared_item_pool.cpp b/stats/shared_item_pool.cpp
new file mode 100644
index 0000000..326a400
--- /dev/null
+++ b/stats/shared_item_pool.cpp
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2014-2018 Intel Corporation
+ *
+ * This implementation is highly derived from ChromeOS:
+ * platform2/camera/hal/intel/ipu3/common/SharedItemPool.cpp
+ */
+
+#include <ia_imaging/ia_aiq_types.h>
+
+#include <libcamera/base/log.h>
+
+#include "shared_item_pool.h"
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(SharedItemPool)
+
+template<class ItemType>
+SharedItemPool<ItemType>::SharedItemPool(const char *name)
+ : allocated_(nullptr), capacity_(0), deleter_(this), poolName_(name),
+ resetter_(nullptr)
+{
+}
+
+template<class ItemType>
+SharedItemPool<ItemType>::~SharedItemPool()
+{
+ deInit();
+}
+
+template<class ItemType>
+int SharedItemPool<ItemType>::init(int32_t capacity, void (*resetter)(ItemType *))
+{
+ if (capacity_ != 0) {
+ LOG(SharedItemPool, Error) << "Pool initialized already";
+ return -ENOSYS;
+ }
+ std::lock_guard<std::mutex> l(mutex_);
+ resetter_ = resetter;
+ capacity_ = capacity;
+ available_.reserve(capacity);
+ allocated_ = new ItemType[capacity];
+
+ for (int32_t i = 0; i < capacity; i++)
+ available_.push_back(&allocated_[i]);
+
+ LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ << "init with " << capacity << " items";
+
+ return 0;
+}
+
+template<class ItemType>
+bool SharedItemPool<ItemType>::isFull()
+{
+ std::lock_guard<std::mutex> l(mutex_);
+ bool ret = (available_.size() == capacity_);
+ return ret;
+}
+
+template<class ItemType>
+int SharedItemPool<ItemType>::deInit()
+{
+ std::lock_guard<std::mutex> l(mutex_);
+ if (capacity_ == 0) {
+ LOG(SharedItemPool, Debug) << "Shared pool " << poolName_
+ << " isn't initialized or already de-initialized";
+ return 0;
+ }
+ if (available_.size() != capacity_) {
+ LOG(SharedItemPool, Error) << "Not all items are returned "
+ << "when destroying pool " << poolName_
+ << "(" << available_.size() << "/" << capacity_ << ")";
+ }
+
+ delete[] allocated_;
+ allocated_ = nullptr;
+ available_.clear();
+ capacity_ = 0;
+ LOG(SharedItemPool, Debug) << "Shared pool " << poolName_
+ << " deinit done";
+
+ return 0;
+}
+
+template<class ItemType>
+int SharedItemPool<ItemType>::acquireItem(std::shared_ptr<ItemType> &item)
+{
+ item.reset();
+ std::lock_guard<std::mutex> l(mutex_);
+ if (available_.empty()) {
+ LOG(SharedItemPool, Error) << "Shared pool " << poolName_
+ << "is empty";
+ return -ENOSYS;
+ }
+
+ std::shared_ptr<ItemType> sh(available_[0], deleter_);
+ available_.erase(available_.begin());
+ item = sh;
+ LOG(SharedItemPool, Debug) << "Shared pool " << poolName_
+ << "acquire items " << sh.get();
+ return 0;
+}
+
+template<class ItemType>
+size_t SharedItemPool<ItemType>::availableItems()
+{
+ std::lock_guard<std::mutex> l(mutex_);
+ size_t ret = available_.size();
+ return ret;
+}
+
+template<class ItemType>
+int SharedItemPool<ItemType>::_releaseItem(ItemType *item)
+{
+ std::lock_guard<std::mutex> l(mutex_);
+ if (resetter_)
+ resetter_(item);
+
+ LOG(SharedItemPool, Debug) << "Shared pool " << poolName_
+ << "returning item " << item;
+
+ available_.push_back(item);
+ return 0;
+}
+
+template class SharedItemPool<ia_aiq_rgbs_grid>;
+template class SharedItemPool<ia_aiq_af_grid>;
+} /* namespace libcamera */
diff --git a/stats/shared_item_pool.h b/stats/shared_item_pool.h
new file mode 100644
index 0000000..89dc9b3
--- /dev/null
+++ b/stats/shared_item_pool.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2014-2018 Intel Corporation
+ *
+ * This implementation is highly derived from ChromeOS:
+ * platform2/camera/hal/intel/ipu3/common/SharedItemPool.h
+ */
+
+#ifndef SHARED_ITEM_POOL_H
+#define SHARED_ITEM_POOL_H
+
+#include <memory>
+#include <mutex>
+#include <pthread.h>
+#include <vector>
+
+/**
+ * \class SharedItemPool
+ *
+ * Pool of ref counted items. This class creates a pool of items and manages
+ * the acquisition of them. When all references to this item have disappeared
+ * The item is returned to the pool.
+ *
+ * This class is thread safe, i.e. it can be called from multiple threads.
+ * When the element is recycled to the pool it can be reset via a client
+ * provided method.
+ *
+ */
+
+namespace libcamera {
+
+template<class ItemType>
+class SharedItemPool
+{
+public:
+ SharedItemPool(const char *name = "Unnamed");
+ ~SharedItemPool();
+
+ /**
+ * Initializes the capacity of the pool. It allocates the objects.
+ * optionally it will take function to reset the item before recycling
+ * it to the pool.
+ * This method is thread safe.
+ *
+ * \param capacity[IN]: Number of items the pool will hold
+ * \param resetter[IN]: Function to reset the item before recycling to the
+ * pool.
+ * \return -ENOSYS if trying to initialize twice
+ * \return 0 If everything went ok.
+ */
+ int init(int32_t capacity, void (*resetter)(ItemType *) = nullptr);
+
+ bool isFull();
+
+ /**
+ * Free the resources of the pool
+ *
+ * \return 0 on success
+ */
+ int deInit();
+
+ /**
+ * Acquire an item from the pool.
+ * This method is thread safe. Access to the internal acquire/release
+ * methods are protected.
+ * BUT the thread-safety for the utilization of the item after it has been
+ * acquired is the user's responsibility.
+ * Be careful not to provide the same item to multiple threads that write
+ * into it.
+ *
+ * \param item[OUT] shared pointer to an item.
+ * \return 0 on success
+ */
+ int acquireItem(std::shared_ptr<ItemType> &item);
+
+ /**
+ * Returns the number of currently available items
+ * It there would be issues acquiring the lock the method returns 0
+ * available items.
+ *
+ * \return item count
+ */
+ size_t availableItems();
+
+private:
+ int _releaseItem(ItemType *item);
+
+ class ItemDeleter
+ {
+ public:
+ ItemDeleter(SharedItemPool *pool)
+ : mPool(pool) {}
+ void operator()(ItemType *item) const
+ {
+ mPool->_releaseItem(item);
+ }
+
+ private:
+ SharedItemPool *mPool;
+ };
+
+ std::vector<ItemType *> available_; /* SharedItemPool doesn't have ownership */
+ ItemType *allocated_;
+ size_t capacity_;
+ ItemDeleter deleter_;
+ std::mutex mutex_; /* protects available_, allocated_, capacity_ */
+ const char *poolName_;
+ void (*resetter_)(ItemType *);
+};
+
+} /* namespace libcamera */
+
+#endif /* SHARED_ITEM_POOL_H */
+