diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp index 5c273c2041..5c5f4bf6ee 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp @@ -85,10 +85,13 @@ public: Priv& priv(); // internal use only const Priv& priv() const; // internal use only - View(Priv* p); + View(std::unique_ptr&& p); + View(View&& v); + View& operator=(View&& v); + ~View(); private: - std::shared_ptr m_priv; + std::unique_ptr m_priv; const Cache* m_cache; }; @@ -139,6 +142,7 @@ public: inline const GMatDesc& meta() const { return m_cache->m_desc; } View mkView(int borderSize, bool ownStorage); + void addView(const View* v); class GAPI_EXPORTS Priv; // internal use only Priv& priv(); // internal use only diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp index 3f7a0f811c..6f6ced4915 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp @@ -172,7 +172,7 @@ template<> struct fluid_get_in { static const cv::gapi::fluid::View& get(const cv::GArgs &in_args, int idx) { - return in_args[idx].unsafe_get(); + return *in_args[idx].unsafe_get(); } }; diff --git a/modules/gapi/src/backends/fluid/gfluidbackend.cpp b/modules/gapi/src/backends/fluid/gfluidbackend.cpp index 5fc9c4e211..9905f6f5a4 100644 --- a/modules/gapi/src/backends/fluid/gfluidbackend.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbackend.cpp @@ -880,10 +880,10 @@ cv::gimpl::GFluidExecutable::GFluidExecutable(const ade::Graph auto inEdge = GModel::getInEdgeByPort(m_g, agent->op_handle, in_idx); auto ownStorage = fg.metadata(inEdge).get().use; - gapi::fluid::View view = buffer.mkView(fu.border_size, ownStorage); // NB: It is safe to keep ptr as view lifetime is buffer lifetime - agent->in_views[in_idx] = view; - agent->in_args[in_idx] = GArg(view); + agent->in_views[in_idx] = buffer.mkView(fu.border_size, ownStorage); + agent->in_args[in_idx] = GArg(&agent->in_views[in_idx]); + buffer.addView(&agent->in_views[in_idx]); } else { diff --git a/modules/gapi/src/backends/fluid/gfluidbuffer.cpp b/modules/gapi/src/backends/fluid/gfluidbuffer.cpp index 8ee2d98a14..1085a480a6 100644 --- a/modules/gapi/src/backends/fluid/gfluidbuffer.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbuffer.cpp @@ -577,7 +577,7 @@ bool fluid::Buffer::Priv::full() const { // reset with maximum possible value and then find minimum slowest_y = m_desc.size.height; - for (const auto &v : m_views) slowest_y = std::min(slowest_y, v.y()); + for (const auto &v : m_views) slowest_y = std::min(slowest_y, v->y()); } return m_write_caret + lpi() - slowest_y > m_storage->rows(); @@ -609,7 +609,7 @@ void fluid::Buffer::Priv::reset() int fluid::Buffer::Priv::size() const { std::size_t view_sz = 0; - for (const auto &v : m_views) view_sz += v.priv().size(); + for (const auto &v : m_views) view_sz += v->priv().size(); auto total = view_sz; if (m_storage) total += m_storage->size(); @@ -693,17 +693,24 @@ int fluid::Buffer::lpi() const return m_priv->lpi(); } -fluid::View::View(Priv* p) - : m_priv(p), m_cache(&p->cache()) +fluid::View::View(std::unique_ptr&& p) + : m_priv(std::move(p)), m_cache(&m_priv->cache()) { /* nothing */ } +fluid::View::View(View&&) = default; +fluid::View& fluid::View::operator=(View&&) = default; +fluid::View::~View() = default; + fluid::View fluid::Buffer::mkView(int borderSize, bool ownStorage) { // FIXME: logic outside of Priv (because View takes pointer to Buffer) - auto view = ownStorage ? View(new ViewPrivWithOwnBorder(this, borderSize)) - : View(new ViewPrivWithoutOwnBorder(this, borderSize)); - m_priv->addView(view); - return view; + return ownStorage ? View(std::unique_ptr(new ViewPrivWithOwnBorder(this, borderSize))) + : View(std::unique_ptr(new ViewPrivWithoutOwnBorder(this, borderSize))); +} + +void fluid::Buffer::addView(const View* v) +{ + m_priv->addView(v); } void fluid::debugBufferPriv(const fluid::Buffer& buffer, std::ostream &os) @@ -717,7 +724,7 @@ void fluid::debugBufferPriv(const fluid::Buffer& buffer, std::ostream &os) <<" (phys " << "[" << p.storage().cols() << " x " << p.storage().rows() << "]" << ") :" << " w: " << p.m_write_caret << ", r: ["; - for (const auto &v : p.m_views) { os << &v.priv() << ":" << v.y() << " "; } + for (const auto &v : p.m_views) { os << &v->priv() << ":" << v->y() << " "; } os << "], avail: " << buffer.linesReady() << std::endl; } diff --git a/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp b/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp index 5925489ddf..5292b035ce 100644 --- a/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp +++ b/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp @@ -239,7 +239,7 @@ class GAPI_EXPORTS Buffer::Priv int m_write_caret = -1; - std::vector m_views; + std::vector m_views; std::unique_ptr m_storage; @@ -265,7 +265,7 @@ public: void allocate(BorderOpt border, int border_size, int line_consumption, int skew); void bindTo(const cv::gapi::own::Mat &data, bool is_input); - inline void addView(const View& view) { m_views.push_back(view); } + inline void addView(const View* view) { m_views.emplace_back(view); } inline const GMatDesc& meta() const { return m_desc; } diff --git a/modules/gapi/test/gapi_kernel_tests.cpp b/modules/gapi/test/gapi_kernel_tests.cpp index 6ed98ad4f4..13e5b21c7b 100644 --- a/modules/gapi/test/gapi_kernel_tests.cpp +++ b/modules/gapi/test/gapi_kernel_tests.cpp @@ -101,7 +101,7 @@ namespace GAPI_FLUID_KERNEL(GClone, I::GClone, false) { static const int Window = 1; - static void run(const cv::gapi::fluid::View&, cv::gapi::fluid::Buffer) + static void run(const cv::gapi::fluid::View&, cv::gapi::fluid::Buffer&) { HeteroGraph::registerCallKernel(KernelTags::FLUID_CUSTOM_CLONE); }