diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp index 3a0f02fd4a..8965ec75b6 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp @@ -45,21 +45,37 @@ class GAPI_EXPORTS Buffer; class GAPI_EXPORTS View { public: + struct Cache + { + std::vector m_linePtrs; + GMatDesc m_desc; + int m_border_size = 0; + + inline const uint8_t* linePtr(int index) const + { + return m_linePtrs[index + m_border_size]; + } + }; + View() = default; - const uint8_t* InLineB(int index) const; // -(w-1)/2...0...+(w-1)/2 for Filters + const inline uint8_t* InLineB(int index) const // -(w-1)/2...0...+(w-1)/2 for Filters + { + return m_cache->linePtr(index); + } + template const inline T* InLine(int i) const { const uint8_t* ptr = this->InLineB(i); return reinterpret_cast(ptr); } - operator bool() const; + inline operator bool() const { return m_priv != nullptr; } bool ready() const; - int length() const; + inline int length() const { return m_cache->m_desc.size.width; } int y() const; - const GMatDesc& meta() const; + inline const GMatDesc& meta() const { return m_cache->m_desc; } class GAPI_EXPORTS Priv; // internal use only Priv& priv(); // internal use only @@ -69,11 +85,18 @@ public: private: std::shared_ptr m_priv; + const Cache* m_cache; }; class GAPI_EXPORTS Buffer { public: + struct Cache + { + std::vector m_linePtrs; + GMatDesc m_desc; + }; + // Default constructor (executable creation stage, // all following initialization performed in Priv::init()) Buffer(); @@ -89,7 +112,11 @@ public: // Constructor for in/out buffers (for tests) Buffer(const cv::gapi::own::Mat &data, bool is_input); - uint8_t* OutLineB(int index = 0); + inline uint8_t* OutLineB(int index = 0) + { + return m_cache->m_linePtrs[index]; + } + template inline T* OutLine(int index = 0) { uint8_t* ptr = this->OutLineB(index); @@ -100,10 +127,10 @@ public: int linesReady() const; void debug(std::ostream &os) const; - int length() const; + inline int length() const { return m_cache->m_desc.size.width; } int lpi() const; // LPI for WRITER - const GMatDesc& meta() const; + inline const GMatDesc& meta() const { return m_cache->m_desc; } View mkView(int borderSize, bool ownStorage); @@ -113,7 +140,7 @@ public: private: std::shared_ptr m_priv; - + const Cache* m_cache; }; } // namespace cv::gapi::fluid diff --git a/modules/gapi/include/opencv2/gapi/own/assert.hpp b/modules/gapi/include/opencv2/gapi/own/assert.hpp index 39ad735eaf..8d3feff011 100644 --- a/modules/gapi/include/opencv2/gapi/own/assert.hpp +++ b/modules/gapi/include/opencv2/gapi/own/assert.hpp @@ -8,7 +8,7 @@ #ifndef OPENCV_GAPI_OWN_ASSERT_HPP #define OPENCV_GAPI_OWN_ASSERT_HPP -#if 0 +#if !defined(GAPI_STANDALONE) #include #define GAPI_Assert(expr) CV_Assert(expr) @@ -32,10 +32,10 @@ namespace detail #endif -#ifdef _DEBUG -# define GAPI_DbgAssert(expr) GAPI_Assert(expr) -#else +#ifdef NDEBUG # define GAPI_DbgAssert(expr) +#else +# define GAPI_DbgAssert(expr) GAPI_Assert(expr) #endif #endif // OPENCV_GAPI_OWN_ASSERT_HPP diff --git a/modules/gapi/src/backends/fluid/gfluidbackend.cpp b/modules/gapi/src/backends/fluid/gfluidbackend.cpp index 7e21a4f86d..e6eaaae8c7 100644 --- a/modules/gapi/src/backends/fluid/gfluidbackend.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbackend.cpp @@ -107,19 +107,29 @@ cv::gapi::GBackend cv::gapi::fluid::backend() // FluidAgent implementation /////////////////////////////////////////////////// namespace cv { namespace gimpl { +struct FluidMapper +{ + FluidMapper(double ratio, int lpi) : m_ratio(ratio), m_lpi(lpi) {} + virtual ~FluidMapper() = default; + virtual int firstWindow(int outCoord, int lpi) const = 0; + virtual std::pair linesReadAndNextWindow(int outCoord, int lpi) const = 0; + +protected: + double m_ratio = 0.0; + int m_lpi = 0; +}; + struct FluidDownscaleMapper : public FluidMapper { virtual int firstWindow(int outCoord, int lpi) const override; - virtual int nextWindow(int outCoord, int lpi) const override; - virtual int linesRead(int outCoord) const override; + virtual std::pair linesReadAndNextWindow(int outCoord, int lpi) const override; using FluidMapper::FluidMapper; }; struct FluidUpscaleMapper : public FluidMapper { virtual int firstWindow(int outCoord, int lpi) const override; - virtual int nextWindow(int outCoord, int lpi) const override; - virtual int linesRead(int outCoord) const override; + virtual std::pair linesReadAndNextWindow(int outCoord, int lpi) const override; FluidUpscaleMapper(double ratio, int lpi, int inHeight) : FluidMapper(ratio, lpi), m_inHeight(inHeight) {} private: int m_inHeight = 0; @@ -129,8 +139,7 @@ struct FluidFilterAgent : public FluidAgent { private: virtual int firstWindow() const override; - virtual int nextWindow() const override; - virtual int linesRead() const override; + virtual std::pair linesReadAndnextWindow() const override; virtual void setRatio(double) override { /* nothing */ } public: using FluidAgent::FluidAgent; @@ -140,8 +149,7 @@ struct FluidResizeAgent : public FluidAgent { private: virtual int firstWindow() const override; - virtual int nextWindow() const override; - virtual int linesRead() const override; + virtual std::pair linesReadAndnextWindow() const override; virtual void setRatio(double ratio) override; std::unique_ptr m_mapper; @@ -267,35 +275,35 @@ static int borderSize(const cv::GFluidKernel& k) } } -double inCoord(int outIdx, double ratio) +inline double inCoord(int outIdx, double ratio) { return outIdx * ratio; } -int windowStart(int outIdx, double ratio) +inline int windowStart(int outIdx, double ratio) { return static_cast(inCoord(outIdx, ratio) + 1e-3); } -int windowEnd(int outIdx, double ratio) +inline int windowEnd(int outIdx, double ratio) { return static_cast(std::ceil(inCoord(outIdx + 1, ratio) - 1e-3)); } -double inCoordUpscale(int outCoord, double ratio) +inline double inCoordUpscale(int outCoord, double ratio) { // Calculate the projection of output pixel's center return (outCoord + 0.5) * ratio - 0.5; } -int upscaleWindowStart(int outCoord, double ratio) +inline int upscaleWindowStart(int outCoord, double ratio) { int start = static_cast(inCoordUpscale(outCoord, ratio)); GAPI_DbgAssert(start >= 0); return start; } -int upscaleWindowEnd(int outCoord, double ratio, int inSz) +inline int upscaleWindowEnd(int outCoord, double ratio, int inSz) { int end = static_cast(std::ceil(inCoordUpscale(outCoord, ratio)) + 1); if (end > inSz) @@ -311,16 +319,19 @@ int cv::gimpl::FluidDownscaleMapper::firstWindow(int outCoord, int lpi) const return windowEnd(outCoord + lpi - 1, m_ratio) - windowStart(outCoord, m_ratio); } -int cv::gimpl::FluidDownscaleMapper::nextWindow(int outCoord, int lpi) const +std::pair cv::gimpl::FluidDownscaleMapper::linesReadAndNextWindow(int outCoord, int lpi) const { auto nextStartIdx = outCoord + 1 + m_lpi - 1; auto nextEndIdx = nextStartIdx + lpi - 1; - return windowEnd(nextEndIdx, m_ratio) - windowStart(nextStartIdx, m_ratio); -} -int cv::gimpl::FluidDownscaleMapper::linesRead(int outCoord) const -{ - return windowStart(outCoord + 1 + m_lpi - 1, m_ratio) - windowStart(outCoord, m_ratio); + auto currStart = windowStart(outCoord, m_ratio); + auto nextStart = windowStart(nextStartIdx, m_ratio); + auto nextEnd = windowEnd(nextEndIdx, m_ratio); + + auto lines_read = nextStart - currStart; + auto next_window = nextEnd - nextStart; + + return std::make_pair(lines_read, next_window); } int cv::gimpl::FluidUpscaleMapper::firstWindow(int outCoord, int lpi) const @@ -328,16 +339,19 @@ int cv::gimpl::FluidUpscaleMapper::firstWindow(int outCoord, int lpi) const return upscaleWindowEnd(outCoord + lpi - 1, m_ratio, m_inHeight) - upscaleWindowStart(outCoord, m_ratio); } -int cv::gimpl::FluidUpscaleMapper::nextWindow(int outCoord, int lpi) const +std::pair cv::gimpl::FluidUpscaleMapper::linesReadAndNextWindow(int outCoord, int lpi) const { auto nextStartIdx = outCoord + 1 + m_lpi - 1; auto nextEndIdx = nextStartIdx + lpi - 1; - return upscaleWindowEnd(nextEndIdx, m_ratio, m_inHeight) - upscaleWindowStart(nextStartIdx, m_ratio); -} -int cv::gimpl::FluidUpscaleMapper::linesRead(int outCoord) const -{ - return upscaleWindowStart(outCoord + 1 + m_lpi - 1, m_ratio) - upscaleWindowStart(outCoord, m_ratio); + auto currStart = upscaleWindowStart(outCoord, m_ratio); + auto nextStart = upscaleWindowStart(nextStartIdx, m_ratio); + auto nextEnd = upscaleWindowEnd(nextEndIdx, m_ratio, m_inHeight); + + auto lines_read = nextStart - currStart; + auto next_window = nextEnd - nextStart; + + return std::make_pair(lines_read, next_window); } int cv::gimpl::FluidFilterAgent::firstWindow() const @@ -345,15 +359,10 @@ int cv::gimpl::FluidFilterAgent::firstWindow() const return k.m_window + k.m_lpi - 1; } -int cv::gimpl::FluidFilterAgent::nextWindow() const +std::pair cv::gimpl::FluidFilterAgent::linesReadAndnextWindow() const { int lpi = std::min(k.m_lpi, m_outputLines - m_producedLines - k.m_lpi); - return k.m_window - 1 + lpi; -} - -int cv::gimpl::FluidFilterAgent::linesRead() const -{ - return k.m_lpi; + return std::make_pair(k.m_lpi, k.m_window - 1 + lpi); } int cv::gimpl::FluidResizeAgent::firstWindow() const @@ -363,17 +372,11 @@ int cv::gimpl::FluidResizeAgent::firstWindow() const return m_mapper->firstWindow(outIdx, lpi); } -int cv::gimpl::FluidResizeAgent::nextWindow() const +std::pair cv::gimpl::FluidResizeAgent::linesReadAndnextWindow() const { auto outIdx = out_buffers[0]->priv().y(); auto lpi = std::min(m_outputLines - m_producedLines - k.m_lpi, k.m_lpi); - return m_mapper->nextWindow(outIdx, lpi); -} - -int cv::gimpl::FluidResizeAgent::linesRead() const -{ - auto outIdx = out_buffers[0]->priv().y(); - return m_mapper->linesRead(outIdx); + return m_mapper->linesReadAndNextWindow(outIdx, lpi); } void cv::gimpl::FluidResizeAgent::setRatio(double ratio) @@ -437,7 +440,11 @@ void cv::gimpl::FluidAgent::doWork() for (auto& in_view : in_views) { - if (in_view) in_view.priv().readDone(linesRead(), nextWindow()); + if (in_view) + { + auto pair = linesReadAndnextWindow(); + in_view.priv().readDone(pair.first, pair.second); + }; } for (auto out_buf : out_buffers) @@ -1030,6 +1037,10 @@ void cv::gimpl::GFluidExecutable::makeReshape(const std::vector GAPI_LOG_INFO(NULL, stream.str()); } } + + // FIXME: calculate the size (lpi * ..) + m_script.clear(); + m_script.reserve(10000); } void cv::gimpl::GFluidExecutable::reshape(ade::Graph &g, const GCompileArgs &args) @@ -1134,24 +1145,36 @@ void cv::gimpl::GFluidExecutable::run(std::vector &&input_objs, // and output buffers get "writeDone()" // - if there's not enough data, Agent is skipped // Yes, THAT easy! - bool complete = true; - do { - complete = true; - bool work_done=false; - for (auto &agent : m_agents) - { - // agent->debug(std::cout); - if (!agent->done()) + + if (m_script.empty()) + { + bool complete = true; + do { + complete = true; + bool work_done=false; + for (auto &agent : m_agents) { - if (agent->canWork()) + // agent->debug(std::cout); + if (!agent->done()) { - agent->doWork(); work_done=true; + if (agent->canWork()) + { + agent->doWork(); work_done=true; + m_script.push_back(agent.get()); + } + if (!agent->done()) complete = false; } - if (!agent->done()) complete = false; } + GAPI_Assert(work_done || complete); + } while (!complete); // FIXME: number of iterations can be calculated statically + } + else + { + for (auto &agent : m_script) + { + agent->doWork(); } - GAPI_Assert(work_done || complete); - } while (!complete); // FIXME: number of iterations can be calculated statically + } } // FIXME: these passes operate on graph global level!!! diff --git a/modules/gapi/src/backends/fluid/gfluidbackend.hpp b/modules/gapi/src/backends/fluid/gfluidbackend.hpp index 4e921f2c7f..ba8b9771f8 100644 --- a/modules/gapi/src/backends/fluid/gfluidbackend.hpp +++ b/modules/gapi/src/backends/fluid/gfluidbackend.hpp @@ -49,19 +49,6 @@ struct FluidData gapi::fluid::BorderOpt border; }; -struct FluidMapper -{ - FluidMapper(double ratio, int lpi) : m_ratio(ratio), m_lpi(lpi) {} - virtual ~FluidMapper() = default; - virtual int firstWindow(int outCoord, int lpi) const = 0; - virtual int nextWindow(int outCoord, int lpi) const = 0; - virtual int linesRead(int outCoord) const = 0; - -protected: - double m_ratio = 0.0; - int m_lpi = 0; -}; - struct FluidAgent { public: @@ -104,8 +91,7 @@ private: // FIXME!!! // move to another class virtual int firstWindow() const = 0; - virtual int nextWindow() const = 0; - virtual int linesRead() const = 0; + virtual std::pair linesReadAndnextWindow() const = 0; }; class GFluidExecutable final: public GIslandExecutable @@ -116,6 +102,8 @@ class GFluidExecutable final: public GIslandExecutable std::vector> m_agents; std::vector m_buffers; + std::vector m_script; + using Magazine = detail::magazine; Magazine m_res; diff --git a/modules/gapi/src/backends/fluid/gfluidbuffer.cpp b/modules/gapi/src/backends/fluid/gfluidbuffer.cpp index 741943e6c9..6672ea2724 100644 --- a/modules/gapi/src/backends/fluid/gfluidbuffer.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbuffer.cpp @@ -206,6 +206,23 @@ std::size_t fluid::BorderHandlerT::size() const } // Fluid BufferStorage implementation ////////////////////////////////////////// + +void fluid::BufferStorage::updateInCache(View::Cache& cache, int start_log_idx, int nLines) const +{ + for (int i = 0; i < nLines; i++) + { + cache.m_linePtrs[i] = inLineB(start_log_idx + i, cache.m_desc.size.height); + } +} + +void fluid::BufferStorage::updateOutCache(Buffer::Cache& cache, int start_log_idx, int nLines) +{ + for (int i = 0; i < nLines; i++) + { + cache.m_linePtrs[i] = ptr(start_log_idx + i); + } +} + void fluid::BufferStorageWithBorder::init(int dtype, int border_size, Border border) { switch(border.type) @@ -250,11 +267,6 @@ const uint8_t* fluid::BufferStorageWithBorder::inLineB(int log_idx, int desc_hei } } -const uint8_t* fluid::BufferStorageWithoutBorder::inLineB(int log_idx, int /*desc_height*/) const -{ - return ptr(log_idx); -} - static void copyWithoutBorder(const cv::gapi::own::Mat& src, int src_border_size, cv::gapi::own::Mat& dst, int dst_border_size, int startSrcLine, int startDstLine, int lpi) { auto subSrc = src(cv::gapi::own::Rect{src_border_size, startSrcLine, src.cols - 2*src_border_size, lpi}); @@ -367,7 +379,6 @@ void fluid::View::Priv::readDone(int linesRead, int linesForNextIteration) { GAPI_DbgAssert(m_p); m_read_caret += linesRead; - m_read_caret %= m_p->meta().size.height; m_lines_next_iter = linesForNextIteration; } @@ -405,6 +416,19 @@ const uint8_t* fluid::ViewPrivWithoutOwnBorder::InLineB(int index) const return p_priv.storage().inLineB(log_idx, m_p->meta().size.height); } +void fluid::ViewPrivWithoutOwnBorder::allocate(int lineConsumption, BorderOpt) +{ + initCache(lineConsumption); +} + +void fluid::ViewPrivWithoutOwnBorder::prepareToRead() +{ + const auto &storage = m_p->priv().storage(); + + const int start_log_idx = m_read_caret - m_border_size; + storage.updateInCache(m_cache, start_log_idx, m_lines_next_iter); +} + fluid::ViewPrivWithOwnBorder::ViewPrivWithOwnBorder(const Buffer *parent, int borderSize) { GAPI_Assert(parent); @@ -414,7 +438,9 @@ fluid::ViewPrivWithOwnBorder::ViewPrivWithOwnBorder(const Buffer *parent, int bo void fluid::ViewPrivWithOwnBorder::allocate(int lineConsumption, BorderOpt border) { - auto desc = m_p->meta(); + initCache(lineConsumption); + + const auto& desc = m_cache.m_desc; int type = CV_MAKETYPE(desc.depth, desc.chan); m_own_storage.init(type, m_border_size, border.value()); m_own_storage.create(lineConsumption, desc.size.width, type); @@ -438,6 +464,9 @@ void fluid::ViewPrivWithOwnBorder::prepareToRead() } m_own_storage.updateBeforeRead(startLine, nLines, m_p->priv().storage()); + + const int start_log_idx = m_read_caret - m_border_size; + m_own_storage.updateInCache(m_cache, start_log_idx, m_lines_next_iter); } std::size_t fluid::ViewPrivWithOwnBorder::size() const @@ -457,21 +486,6 @@ const uint8_t* fluid::ViewPrivWithOwnBorder::InLineB(int index) const return m_own_storage.inLineB(log_idx, m_p->meta().size.height); } -const uint8_t* fluid::View::InLineB(int index) const -{ - return m_priv->InLineB(index); -} - -fluid::View::operator bool() const -{ - return m_priv != nullptr && m_priv->m_p != nullptr; -} - -int fluid::View::length() const -{ - return m_priv->m_p->length(); -} - bool fluid::View::ready() const { return m_priv->ready(); @@ -482,12 +496,6 @@ int fluid::View::y() const return m_priv->m_read_caret - m_priv->m_border_size; } -const GMatDesc& fluid::View::meta() const -{ - // FIXME: cover with test! - return m_priv->m_p->meta(); -} - fluid::View::Priv& fluid::View::priv() { return *m_priv; @@ -498,6 +506,13 @@ const fluid::View::Priv& fluid::View::priv() const return *m_priv; } +void fluid::View::Priv::initCache(int lineConsumption) +{ + m_cache.m_linePtrs.resize(lineConsumption); + m_cache.m_desc = m_p->priv().meta(); + m_cache.m_border_size = m_border_size; +} + // Fluid Buffer implementation ///////////////////////////////////////////////// fluid::Buffer::Priv::Priv(int read_start, cv::gapi::own::Rect roi) @@ -515,6 +530,8 @@ void fluid::Buffer::Priv::init(const cv::GMatDesc &desc, m_readStart = readStartPos; m_roi = roi == own::Rect{} ? own::Rect{ 0, 0, desc.size.width, desc.size.height } : roi; + m_cache.m_linePtrs.resize(writer_lpi); + m_cache.m_desc = desc; } void fluid::Buffer::Priv::allocate(BorderOpt border, @@ -536,7 +553,9 @@ void fluid::Buffer::Priv::allocate(BorderOpt border, border); // Finally, initialize carets - m_write_caret = 0; + m_write_caret = writeStart(); + + m_storage->updateOutCache(m_cache, m_write_caret, m_writer_lpi); } void fluid::Buffer::Priv::bindTo(const cv::gapi::own::Mat &data, bool is_input) @@ -557,6 +576,8 @@ void fluid::Buffer::Priv::bindTo(const cv::gapi::own::Mat &data, bool is_input) m_is_input = is_input; m_write_caret = is_input ? writeEnd(): writeStart(); // NB: views remain the same! + + m_storage->updateOutCache(m_cache, m_write_caret, m_writer_lpi); } bool fluid::Buffer::Priv::full() const @@ -585,11 +606,14 @@ void fluid::Buffer::Priv::writeDone() // write caret may exceed logical buffer size m_write_caret += m_writer_lpi; // FIXME: add consistency check! + + m_storage->updateOutCache(m_cache, m_write_caret, m_writer_lpi); } void fluid::Buffer::Priv::reset() { m_write_caret = m_is_input ? writeEnd() : writeStart(); + m_storage->updateOutCache(m_cache, m_write_caret, m_writer_lpi); } int fluid::Buffer::Priv::size() const @@ -633,11 +657,13 @@ int fluid::Buffer::Priv::lpi() const fluid::Buffer::Buffer() : m_priv(new Priv()) + , m_cache(&m_priv->cache()) { } fluid::Buffer::Buffer(const cv::GMatDesc &desc) : m_priv(new Priv()) + , m_cache(&m_priv->cache()) { int lineConsumption = 1; int border = 0, skew = 0, wlpi = 1, readStart = 0; @@ -653,6 +679,7 @@ fluid::Buffer::Buffer(const cv::GMatDesc &desc, int wlpi, BorderOpt border) : m_priv(new Priv()) + , m_cache(&m_priv->cache()) { int readStart = 0; cv::gapi::own::Rect roi = {0, 0, desc.size.width, desc.size.height}; @@ -662,6 +689,7 @@ fluid::Buffer::Buffer(const cv::GMatDesc &desc, fluid::Buffer::Buffer(const cv::gapi::own::Mat &data, bool is_input) : m_priv(new Priv()) + , m_cache(&m_priv->cache()) { int wlpi = 1, readStart = 0; cv::gapi::own::Rect roi{0, 0, data.cols, data.rows}; @@ -669,33 +697,18 @@ fluid::Buffer::Buffer(const cv::gapi::own::Mat &data, bool is_input) m_priv->bindTo(data, is_input); } -uint8_t* fluid::Buffer::Buffer::OutLineB(int index) -{ - return m_priv->OutLineB(index); -} - int fluid::Buffer::linesReady() const { return m_priv->linesReady(); } -int fluid::Buffer::length() const -{ - return meta().size.width; -} - int fluid::Buffer::lpi() const { return m_priv->lpi(); } -const GMatDesc& fluid::Buffer::meta() const -{ - return m_priv->meta(); -} - fluid::View::View(Priv* p) - : m_priv(p) + : m_priv(p), m_cache(&p->cache()) { /* nothing */ } fluid::View fluid::Buffer::mkView(int borderSize, bool ownStorage) diff --git a/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp b/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp index f21b11c5d6..1f3eadc114 100644 --- a/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp +++ b/modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp @@ -68,6 +68,9 @@ protected: cv::gapi::own::Mat m_data; public: + void updateInCache(View::Cache& cache, int start_log_idx, int nLines) const; + void updateOutCache(Buffer::Cache& cache, int start_log_idx, int nLines); + virtual void copyTo(BufferStorageWithBorder &dst, int startLine, int nLines) const = 0; virtual ~BufferStorage() = default; @@ -90,7 +93,7 @@ public: virtual void updateBeforeRead(int startLine, int nLines, const BufferStorage& src) = 0; virtual void updateAfterWrite(int startLine, int nLines) = 0; - virtual int physIdx(int logIdx) const = 0; + virtual inline int physIdx(int logIdx) const = 0; virtual size_t size() const = 0; }; @@ -123,7 +126,7 @@ public: void create(int capacity, int desc_width, int type); - inline virtual const uint8_t* inLineB(int log_idx, int desc_height) const override; + inline virtual const uint8_t* inLineB(int log_idx, int /*desc_height*/) const override { return ptr(log_idx); } virtual void updateBeforeRead(int startLine, int nLines, const BufferStorage& src) override; virtual void updateAfterWrite(int startLine, int nLines) override; @@ -170,6 +173,8 @@ class GAPI_EXPORTS View::Priv { friend class View; protected: + View::Cache m_cache; + const Buffer *m_p = nullptr; // FIXME replace with weak_ptr int m_read_caret = -1; int m_lines_next_iter = -1; @@ -179,6 +184,9 @@ public: virtual ~Priv() = default; // API used by actors/backend + const View::Cache& cache() const { return m_cache; } + void initCache(int lineConsumption); + virtual void allocate(int lineConsumption, BorderOpt border) = 0; virtual void prepareToRead() = 0; @@ -200,8 +208,8 @@ public: // API used by actors/backend ViewPrivWithoutOwnBorder(const Buffer *p, int borderSize); - inline virtual void allocate(int, BorderOpt) override { /* nothing */ } - inline virtual void prepareToRead() override { /* nothing */ } + virtual void allocate(int lineConsumption, BorderOpt) override; + virtual void prepareToRead() override; inline virtual std::size_t size() const override { return 0; } @@ -217,7 +225,7 @@ public: // API used by actors/backend ViewPrivWithOwnBorder(const Buffer *p, int borderSize); - inline virtual void allocate(int lineConsumption, BorderOpt border) override; + virtual void allocate(int lineConsumption, BorderOpt border) override; virtual void prepareToRead() override; virtual std::size_t size() const override; @@ -231,6 +239,8 @@ void debugBufferPriv(const Buffer& buffer, std::ostream &os); // like readDone/writeDone in low-level tests class GAPI_EXPORTS Buffer::Priv { + Buffer::Cache m_cache; + int m_writer_lpi = 1; cv::GMatDesc m_desc = cv::GMatDesc{-1,-1,{-1,-1}}; @@ -287,6 +297,8 @@ public: inline int writeStart() const { return m_roi.y; } inline int writeEnd() const { return m_roi.y + m_roi.height; } inline int outputLines() const { return m_roi.height; } + + inline const Buffer::Cache& cache() const { return m_cache; } }; } // namespace cv::gapi::fluid diff --git a/modules/gapi/test/gapi_fluid_test.cpp b/modules/gapi/test/gapi_fluid_test.cpp index 0951081e97..5b3501175e 100644 --- a/modules/gapi/test/gapi_fluid_test.cpp +++ b/modules/gapi/test/gapi_fluid_test.cpp @@ -51,12 +51,14 @@ TEST(FluidBuffer, InputTest) cv::Mat in_mat = cv::Mat::eye(buffer_size, CV_8U); cv::gapi::fluid::Buffer buffer(to_own(in_mat), true); - cv::gapi::fluid::View view = buffer.mkView(0, {}); + cv::gapi::fluid::View view = buffer.mkView(0, false); + view.priv().allocate(1, {}); view.priv().reset(1); int this_y = 0; while (this_y < buffer_size.height) { + view.priv().prepareToRead(); const uint8_t* rrow = view.InLine(0); ReadFunction1x1(rrow, buffer_size.width); view.priv().readDone(1,1); @@ -76,6 +78,7 @@ TEST(FluidBuffer, CircularTest) util::make_optional(cv::gapi::fluid::Border{cv::BORDER_CONSTANT, cv::gapi::own::Scalar(255)})); cv::gapi::fluid::View view = buffer.mkView(1, {}); view.priv().reset(3); + view.priv().allocate(3, {}); buffer.debug(std::cout); const auto whole_line_is = [](const uint8_t *line, int len, int value)