Merge pull request #13215 from rgarnov:rg/overhead

* Added caching of agents execution sequence

* Merged linesRead() and nextWindow() methods on FluidAgent in one method

* Added caching of input lines for fluid::View

* Added caching of output lines for fluid::Buffer

* Fixed GAPI_Assert to work in standalone mode
pull/13233/head
Ruslan Garnov 6 years ago committed by Alexander Alekhin
parent 798e2779f2
commit a3df05d93b
  1. 43
      modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp
  2. 8
      modules/gapi/include/opencv2/gapi/own/assert.hpp
  3. 133
      modules/gapi/src/backends/fluid/gfluidbackend.cpp
  4. 18
      modules/gapi/src/backends/fluid/gfluidbackend.hpp
  5. 103
      modules/gapi/src/backends/fluid/gfluidbuffer.cpp
  6. 22
      modules/gapi/src/backends/fluid/gfluidbuffer_priv.hpp
  7. 5
      modules/gapi/test/gapi_fluid_test.cpp

@ -45,21 +45,37 @@ class GAPI_EXPORTS Buffer;
class GAPI_EXPORTS View
{
public:
struct Cache
{
std::vector<const uint8_t*> 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<typename T> const inline T* InLine(int i) const
{
const uint8_t* ptr = this->InLineB(i);
return reinterpret_cast<const T*>(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<Priv> m_priv;
const Cache* m_cache;
};
class GAPI_EXPORTS Buffer
{
public:
struct Cache
{
std::vector<uint8_t*> 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<typename T> 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<Priv> m_priv;
const Cache* m_cache;
};
} // namespace cv::gapi::fluid

@ -8,7 +8,7 @@
#ifndef OPENCV_GAPI_OWN_ASSERT_HPP
#define OPENCV_GAPI_OWN_ASSERT_HPP
#if 0
#if !defined(GAPI_STANDALONE)
#include <opencv2/core/base.hpp>
#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

@ -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<int,int> 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<int,int> 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<int,int> 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<int,int> 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<int,int> linesReadAndnextWindow() const override;
virtual void setRatio(double ratio) override;
std::unique_ptr<FluidMapper> 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<int>(inCoord(outIdx, ratio) + 1e-3);
}
int windowEnd(int outIdx, double ratio)
inline int windowEnd(int outIdx, double ratio)
{
return static_cast<int>(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<int>(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<int>(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<int,int> 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<int,int> 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<int,int> 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<int,int> 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::own::Rect>
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<InObj> &&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!!!

@ -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<int,int> linesReadAndnextWindow() const = 0;
};
class GFluidExecutable final: public GIslandExecutable
@ -116,6 +102,8 @@ class GFluidExecutable final: public GIslandExecutable
std::vector<std::unique_ptr<FluidAgent>> m_agents;
std::vector<cv::gapi::fluid::Buffer> m_buffers;
std::vector<FluidAgent*> m_script;
using Magazine = detail::magazine<cv::gapi::own::Scalar>;
Magazine m_res;

@ -206,6 +206,23 @@ std::size_t fluid::BorderHandlerT<cv::BORDER_CONSTANT>::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)

@ -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

@ -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<uint8_t>(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)

Loading…
Cancel
Save