mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
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
This commit is contained in:
parent
798e2779f2
commit
a3df05d93b
@ -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…
Reference in New Issue
Block a user