mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge pull request #16118 from smirnov-alexey:as/gopaque
G-API: GOpaque implementation * Stub initial copypasted solution * Fix mov test and add a couple of others * Fix warnings * More code coverage and tests * fix macos warning * address review comments * Address review comments and fix indentation * Fix build on armv7
This commit is contained in:
@@ -94,9 +94,14 @@ public:
|
||||
{
|
||||
return outVecRef(output).wref<T>();
|
||||
}
|
||||
template<typename T> T& outOpaqueR(int output) // FIXME: the same issue
|
||||
{
|
||||
return outOpaqueRef(output).wref<T>();
|
||||
}
|
||||
|
||||
protected:
|
||||
detail::VectorRef& outVecRef(int output);
|
||||
detail::OpaqueRef& outOpaqueRef(int output);
|
||||
|
||||
std::vector<GArg> m_args;
|
||||
|
||||
@@ -145,12 +150,31 @@ template<typename U> struct get_in<cv::GArray<U> >
|
||||
{
|
||||
static const std::vector<U>& get(GCPUContext &ctx, int idx) { return ctx.inArg<VectorRef>(idx).rref<U>(); }
|
||||
};
|
||||
template<typename U> struct get_in<cv::GOpaque<U> >
|
||||
{
|
||||
static const U& get(GCPUContext &ctx, int idx) { return ctx.inArg<OpaqueRef>(idx).rref<U>(); }
|
||||
};
|
||||
|
||||
//FIXME(dm): GArray<Mat>/GArray<GMat> conversion should be done more gracefully in the system
|
||||
template<> struct get_in<cv::GArray<cv::GMat> >: public get_in<cv::GArray<cv::Mat> >
|
||||
{
|
||||
};
|
||||
|
||||
//FIXME(dm): GArray<Scalar>/GArray<GScalar> conversion should be done more gracefully in the system
|
||||
template<> struct get_in<cv::GArray<cv::GScalar> >: public get_in<cv::GArray<cv::Scalar> >
|
||||
{
|
||||
};
|
||||
|
||||
//FIXME(dm): GOpaque<Mat>/GOpaque<GMat> conversion should be done more gracefully in the system
|
||||
template<> struct get_in<cv::GOpaque<cv::GMat> >: public get_in<cv::GOpaque<cv::Mat> >
|
||||
{
|
||||
};
|
||||
|
||||
//FIXME(dm): GOpaque<Scalar>/GOpaque<GScalar> conversion should be done more gracefully in the system
|
||||
template<> struct get_in<cv::GOpaque<cv::GScalar> >: public get_in<cv::GOpaque<cv::Mat> >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct get_in
|
||||
{
|
||||
static T get(GCPUContext &ctx, int idx) { return ctx.inArg<T>(idx); }
|
||||
@@ -229,6 +253,13 @@ template<typename U> struct get_out<cv::GArray<U>>
|
||||
return ctx.outVecR<U>(idx);
|
||||
}
|
||||
};
|
||||
template<typename U> struct get_out<cv::GOpaque<U>>
|
||||
{
|
||||
static U& get(GCPUContext &ctx, int idx)
|
||||
{
|
||||
return ctx.outOpaqueR<U>(idx);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename, typename, typename>
|
||||
struct OCVCallHelper;
|
||||
|
||||
@@ -200,6 +200,14 @@ template<typename U> struct fluid_get_in<cv::GArray<U>>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename U> struct fluid_get_in<cv::GOpaque<U>>
|
||||
{
|
||||
static const U& get(const cv::GArgs &in_args, int idx)
|
||||
{
|
||||
return in_args.at(idx).unsafe_get<cv::detail::OpaqueRef>().rref<U>();
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct fluid_get_in
|
||||
{
|
||||
static const T& get(const cv::GArgs &in_args, int idx)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <opencv2/gapi/gmat.hpp>
|
||||
#include <opencv2/gapi/gscalar.hpp>
|
||||
#include <opencv2/gapi/garray.hpp>
|
||||
#include <opencv2/gapi/gopaque.hpp>
|
||||
#include <opencv2/gapi/gtype_traits.hpp>
|
||||
#include <opencv2/gapi/gmetaarg.hpp>
|
||||
#include <opencv2/gapi/own/scalar.hpp>
|
||||
@@ -96,7 +97,8 @@ using GRunArg = util::variant<
|
||||
cv::gapi::wip::IStreamSource::Ptr,
|
||||
cv::gapi::own::Mat,
|
||||
cv::gapi::own::Scalar,
|
||||
cv::detail::VectorRef
|
||||
cv::detail::VectorRef,
|
||||
cv::detail::OpaqueRef
|
||||
>;
|
||||
using GRunArgs = std::vector<GRunArg>;
|
||||
|
||||
@@ -128,7 +130,8 @@ using GRunArgP = util::variant<
|
||||
#endif // !defined(GAPI_STANDALONE)
|
||||
cv::gapi::own::Mat*,
|
||||
cv::gapi::own::Scalar*,
|
||||
cv::detail::VectorRef
|
||||
cv::detail::VectorRef,
|
||||
cv::detail::OpaqueRef
|
||||
>;
|
||||
using GRunArgsP = std::vector<GRunArgP>;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <opencv2/gapi/gmat.hpp> // GMat
|
||||
#include <opencv2/gapi/gscalar.hpp> // GScalar
|
||||
#include <opencv2/gapi/garray.hpp> // GArray<T>
|
||||
#include <opencv2/gapi/gopaque.hpp> // GOpaque<T>
|
||||
|
||||
namespace cv {
|
||||
|
||||
@@ -46,6 +47,11 @@ public:
|
||||
return GArray<T>(yieldArray(output));
|
||||
}
|
||||
|
||||
template<class T> GOpaque<T> yieldOpaque(int output = 0)
|
||||
{
|
||||
return GOpaque<T>(yieldOpaque(output));
|
||||
}
|
||||
|
||||
// Internal use only
|
||||
Priv& priv();
|
||||
const Priv& priv() const;
|
||||
@@ -55,8 +61,9 @@ protected:
|
||||
|
||||
void setArgs(std::vector<GArg> &&args);
|
||||
|
||||
// Public version returns a typed array, this one is implementation detail
|
||||
// Public versions return a typed array or opaque, those are implementation details
|
||||
detail::GArrayU yieldArray(int output = 0);
|
||||
detail::GOpaqueU yieldOpaque(int output = 0);
|
||||
};
|
||||
|
||||
} // namespace cv
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class GShape: int
|
||||
GMAT,
|
||||
GSCALAR,
|
||||
GARRAY,
|
||||
GOPAQUE,
|
||||
};
|
||||
|
||||
struct GCompileArg;
|
||||
|
||||
@@ -65,6 +65,16 @@ template<typename U> struct get_compound_in<cv::GArray<U>>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename U> struct get_compound_in<cv::GOpaque<U>>
|
||||
{
|
||||
static cv::GOpaque<U> get(GCompoundContext &ctx, int idx)
|
||||
{
|
||||
auto opaq = cv::GOpaque<U>();
|
||||
ctx.m_args[idx] = GArg(opaq);
|
||||
return opaq;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename, typename, typename>
|
||||
struct GCompoundCallHelper;
|
||||
|
||||
|
||||
@@ -74,6 +74,10 @@ namespace detail
|
||||
{
|
||||
static inline cv::GArray<U> yield(cv::GCall &call, int i) { return call.yieldArray<U>(i); }
|
||||
};
|
||||
template<typename U> struct Yield<cv::GOpaque<U> >
|
||||
{
|
||||
static inline cv::GOpaque<U> yield(cv::GCall &call, int i) { return call.yieldOpaque<U>(i); }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -87,7 +91,8 @@ namespace detail
|
||||
template<> struct MetaType<cv::GMat> { using type = GMatDesc; };
|
||||
template<> struct MetaType<cv::GMatP> { using type = GMatDesc; };
|
||||
template<> struct MetaType<cv::GScalar> { using type = GScalarDesc; };
|
||||
template<typename U> struct MetaType<cv::GArray<U> > { using type = GArrayDesc; };
|
||||
template<typename U> struct MetaType<cv::GArray<U> > { using type = GArrayDesc; };
|
||||
template<typename U> struct MetaType<cv::GOpaque<U> > { using type = GOpaqueDesc; };
|
||||
template<typename T> struct MetaType { using type = T; }; // opaque args passed as-is
|
||||
|
||||
// 2. Hacky test based on MetaType to check if we operate on G-* type or not
|
||||
|
||||
@@ -46,6 +46,7 @@ struct GOrigin;
|
||||
* cv::GMat | cv::Mat
|
||||
* cv::GScalar | cv::Scalar
|
||||
* `cv::GArray<T>` | std::vector<T>
|
||||
* `cv::GOpaque<T>` | T
|
||||
*/
|
||||
class GAPI_EXPORTS GMat
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <opencv2/gapi/gmat.hpp>
|
||||
#include <opencv2/gapi/gscalar.hpp>
|
||||
#include <opencv2/gapi/garray.hpp>
|
||||
#include <opencv2/gapi/gopaque.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -36,6 +37,7 @@ using GMetaArg = util::variant
|
||||
, GMatDesc
|
||||
, GScalarDesc
|
||||
, GArrayDesc
|
||||
, GOpaqueDesc
|
||||
>;
|
||||
GAPI_EXPORTS std::ostream& operator<<(std::ostream& os, const GMetaArg &);
|
||||
|
||||
@@ -52,6 +54,7 @@ namespace detail
|
||||
template<> struct is_meta_descr<GMatDesc> : std::true_type {};
|
||||
template<> struct is_meta_descr<GScalarDesc> : std::true_type {};
|
||||
template<> struct is_meta_descr<GArrayDesc> : std::true_type {};
|
||||
template<> struct is_meta_descr<GOpaqueDesc> : std::true_type {};
|
||||
|
||||
template<typename... Ts>
|
||||
using are_meta_descrs = all_satisfy<is_meta_descr, Ts...>;
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GOPAQUE_HPP
|
||||
#define OPENCV_GAPI_GOPAQUE_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
|
||||
#include <opencv2/gapi/own/exports.hpp>
|
||||
#include <opencv2/gapi/opencv_includes.hpp>
|
||||
|
||||
#include <opencv2/gapi/util/variant.hpp>
|
||||
#include <opencv2/gapi/util/throw.hpp>
|
||||
#include <opencv2/gapi/own/assert.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
// Forward declaration; GNode and GOrigin are an internal
|
||||
// (user-inaccessible) classes.
|
||||
class GNode;
|
||||
struct GOrigin;
|
||||
|
||||
template<typename T> class GOpaque;
|
||||
|
||||
/**
|
||||
* \addtogroup gapi_meta_args
|
||||
* @{
|
||||
*/
|
||||
struct GOpaqueDesc
|
||||
{
|
||||
// FIXME: Body
|
||||
// FIXME: Also implement proper operator== then
|
||||
bool operator== (const GOpaqueDesc&) const { return true; }
|
||||
};
|
||||
template<typename U> GOpaqueDesc descr_of(const U &) { return {};}
|
||||
static inline GOpaqueDesc empty_gopaque_desc() {return {}; }
|
||||
/** @} */
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const cv::GOpaqueDesc &desc);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// ConstructOpaque is a callback which stores information about T and is used by
|
||||
// G-API runtime to construct an object in host memory (T remains opaque for G-API).
|
||||
// ConstructOpaque is carried into G-API internals by GOpaqueU.
|
||||
// Currently it is suitable for Host (CPU) plugins only, real offload may require
|
||||
// more information for manual memory allocation on-device.
|
||||
class OpaqueRef;
|
||||
using ConstructOpaque = std::function<void(OpaqueRef&)>;
|
||||
|
||||
// FIXME: garray.hpp already contains hint classes (for actual T type verification),
|
||||
// need to think where it can be moved (currently opaque uses it from garray)
|
||||
|
||||
// This class strips type information from GOpaque<T> and makes it usable
|
||||
// in the G-API graph compiler (expression unrolling, graph generation, etc).
|
||||
// Part of GProtoArg.
|
||||
class GAPI_EXPORTS GOpaqueU
|
||||
{
|
||||
public:
|
||||
GOpaqueU(const GNode &n, std::size_t out); // Operation result constructor
|
||||
|
||||
template <typename T>
|
||||
bool holds() const; // Check if was created from GOpaque<T>
|
||||
|
||||
GOrigin& priv(); // Internal use only
|
||||
const GOrigin& priv() const; // Internal use only
|
||||
|
||||
protected:
|
||||
GOpaqueU(); // Default constructor
|
||||
template<class> friend class cv::GOpaque; // (available for GOpaque<T> only)
|
||||
|
||||
void setConstructFcn(ConstructOpaque &&cv); // Store T-aware constructor
|
||||
|
||||
template <typename T>
|
||||
void specifyType(); // Store type of initial GOpaque<T>
|
||||
|
||||
std::shared_ptr<GOrigin> m_priv;
|
||||
std::shared_ptr<TypeHintBase> m_hint;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool GOpaqueU::holds() const{
|
||||
GAPI_Assert(m_hint != nullptr);
|
||||
using U = typename std::decay<T>::type;
|
||||
return dynamic_cast<TypeHint<U>*>(m_hint.get()) != nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void GOpaqueU::specifyType(){
|
||||
m_hint.reset(new TypeHint<typename std::decay<T>::type>);
|
||||
};
|
||||
|
||||
// This class represents a typed object reference.
|
||||
// Depending on origins, this reference may be either "just a" reference to
|
||||
// an object created externally, OR actually own the underlying object
|
||||
// (be value holder).
|
||||
class BasicOpaqueRef
|
||||
{
|
||||
public:
|
||||
cv::GOpaqueDesc m_desc;
|
||||
virtual ~BasicOpaqueRef() {}
|
||||
|
||||
virtual void mov(BasicOpaqueRef &ref) = 0;
|
||||
};
|
||||
|
||||
template<typename T> class OpaqueRefT final: public BasicOpaqueRef
|
||||
{
|
||||
using empty_t = util::monostate;
|
||||
using ro_ext_t = const T *;
|
||||
using rw_ext_t = T *;
|
||||
using rw_own_t = T ;
|
||||
util::variant<empty_t, ro_ext_t, rw_ext_t, rw_own_t> m_ref;
|
||||
|
||||
inline bool isEmpty() const { return util::holds_alternative<empty_t>(m_ref); }
|
||||
inline bool isROExt() const { return util::holds_alternative<ro_ext_t>(m_ref); }
|
||||
inline bool isRWExt() const { return util::holds_alternative<rw_ext_t>(m_ref); }
|
||||
inline bool isRWOwn() const { return util::holds_alternative<rw_own_t>(m_ref); }
|
||||
|
||||
void init(const T* obj = nullptr)
|
||||
{
|
||||
if (obj) m_desc = cv::descr_of(*obj);
|
||||
}
|
||||
|
||||
public:
|
||||
OpaqueRefT() { init(); }
|
||||
virtual ~OpaqueRefT() {}
|
||||
|
||||
explicit OpaqueRefT(const T& obj) : m_ref(&obj) { init(&obj); }
|
||||
explicit OpaqueRefT( T& obj) : m_ref(&obj) { init(&obj); }
|
||||
explicit OpaqueRefT( T&& obj) : m_ref(std::move(obj)) { init(&obj); }
|
||||
|
||||
// Reset a OpaqueRefT. Called only for objects instantiated
|
||||
// internally in G-API (e.g. temporary GOpaque<T>'s within a
|
||||
// computation). Reset here means both initialization
|
||||
// (creating an object) and reset (discarding its existing
|
||||
// content before the next execution). Must never be called
|
||||
// for external OpaqueRefTs.
|
||||
void reset()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
T empty_obj{};
|
||||
m_desc = cv::descr_of(empty_obj);
|
||||
m_ref = std::move(empty_obj);
|
||||
GAPI_Assert(isRWOwn());
|
||||
}
|
||||
else if (isRWOwn())
|
||||
{
|
||||
util::get<rw_own_t>(m_ref) = {};
|
||||
}
|
||||
else GAPI_Assert(false); // shouldn't be called in *EXT modes
|
||||
}
|
||||
|
||||
// Obtain a WRITE reference to underlying object
|
||||
// Used by CPU kernel API wrappers when a kernel execution frame
|
||||
// is created
|
||||
T& wref()
|
||||
{
|
||||
GAPI_Assert(isRWExt() || isRWOwn());
|
||||
if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
|
||||
if (isRWOwn()) return util::get<rw_own_t>(m_ref);
|
||||
util::throw_error(std::logic_error("Impossible happened"));
|
||||
}
|
||||
|
||||
// Obtain a READ reference to underlying object
|
||||
// Used by CPU kernel API wrappers when a kernel execution frame
|
||||
// is created
|
||||
const T& rref() const
|
||||
{
|
||||
// ANY object can be accessed for reading, even if it declared for
|
||||
// output. Example -- a GComputation from [in] to [out1,out2]
|
||||
// where [out2] is a result of operation applied to [out1]:
|
||||
//
|
||||
// GComputation boundary
|
||||
// . . . . . . .
|
||||
// . .
|
||||
// [in] ----> foo() ----> [out1]
|
||||
// . . :
|
||||
// . . . .:. . .
|
||||
// . V .
|
||||
// . bar() ---> [out2]
|
||||
// . . . . . . . . . . . .
|
||||
//
|
||||
if (isROExt()) return *util::get<ro_ext_t>(m_ref);
|
||||
if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
|
||||
if (isRWOwn()) return util::get<rw_own_t>(m_ref);
|
||||
util::throw_error(std::logic_error("Impossible happened"));
|
||||
}
|
||||
|
||||
virtual void mov(BasicOpaqueRef &v) override {
|
||||
OpaqueRefT<T> *tv = dynamic_cast<OpaqueRefT<T>*>(&v);
|
||||
GAPI_Assert(tv != nullptr);
|
||||
wref() = std::move(tv->wref());
|
||||
}
|
||||
};
|
||||
|
||||
// This class strips type information from OpaqueRefT<> and makes it usable
|
||||
// in the G-API executables (carrying run-time data/information to kernels).
|
||||
// Part of GRunArg.
|
||||
// Its methods are typed proxies to OpaqueRefT<T>.
|
||||
// OpaqueRef maintains "reference" semantics so two copies of OpaqueRef refer
|
||||
// to the same underlying object.
|
||||
class OpaqueRef
|
||||
{
|
||||
std::shared_ptr<BasicOpaqueRef> m_ref;
|
||||
|
||||
template<typename T> inline void check() const
|
||||
{
|
||||
GAPI_DbgAssert(dynamic_cast<OpaqueRefT<T>*>(m_ref.get()) != nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
OpaqueRef() = default;
|
||||
|
||||
template<typename T> explicit OpaqueRef(T&& obj) :
|
||||
m_ref(new OpaqueRefT<typename std::decay<T>::type>(std::forward<T>(obj))) {}
|
||||
|
||||
template<typename T> void reset()
|
||||
{
|
||||
if (!m_ref) m_ref.reset(new OpaqueRefT<T>());
|
||||
|
||||
check<T>();
|
||||
static_cast<OpaqueRefT<T>&>(*m_ref).reset();
|
||||
}
|
||||
|
||||
template<typename T> T& wref()
|
||||
{
|
||||
check<T>();
|
||||
return static_cast<OpaqueRefT<T>&>(*m_ref).wref();
|
||||
}
|
||||
|
||||
template<typename T> const T& rref() const
|
||||
{
|
||||
check<T>();
|
||||
return static_cast<OpaqueRefT<T>&>(*m_ref).rref();
|
||||
}
|
||||
|
||||
void mov(OpaqueRef &v)
|
||||
{
|
||||
m_ref->mov(*v.m_ref);
|
||||
}
|
||||
|
||||
cv::GOpaqueDesc descr_of() const
|
||||
{
|
||||
return m_ref->m_desc;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/** \addtogroup gapi_data_objects
|
||||
* @{
|
||||
*/
|
||||
|
||||
template<typename T> class GOpaque
|
||||
{
|
||||
public:
|
||||
GOpaque() { putDetails(); } // Empty constructor
|
||||
explicit GOpaque(detail::GOpaqueU &&ref) // GOpaqueU-based constructor
|
||||
: m_ref(ref) { putDetails(); } // (used by GCall, not for users)
|
||||
|
||||
detail::GOpaqueU strip() const { return m_ref; }
|
||||
|
||||
private:
|
||||
// Host type (or Flat type) - the type this GOpaque is actually
|
||||
// specified to.
|
||||
using HT = typename detail::flatten_g<typename std::decay<T>::type>::type;
|
||||
|
||||
static void CTor(detail::OpaqueRef& ref) {
|
||||
ref.reset<HT>();
|
||||
}
|
||||
void putDetails() {
|
||||
m_ref.setConstructFcn(&CTor);
|
||||
m_ref.specifyType<HT>();
|
||||
}
|
||||
|
||||
detail::GOpaqueU m_ref;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_GOPAQUE_HPP
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <opencv2/gapi/gmat.hpp>
|
||||
#include <opencv2/gapi/gscalar.hpp>
|
||||
#include <opencv2/gapi/garray.hpp>
|
||||
#include <opencv2/gapi/gopaque.hpp>
|
||||
#include <opencv2/gapi/garg.hpp>
|
||||
#include <opencv2/gapi/gmetaarg.hpp>
|
||||
|
||||
@@ -36,7 +37,8 @@ using GProtoArg = util::variant
|
||||
< GMat
|
||||
, GMatP
|
||||
, GScalar
|
||||
, detail::GArrayU // instead of GArray<T>
|
||||
, detail::GArrayU // instead of GArray<T>
|
||||
, detail::GOpaqueU // instead of GOpaque<T>
|
||||
>;
|
||||
|
||||
using GProtoArgs = std::vector<GProtoArg>;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <opencv2/gapi/gmat.hpp>
|
||||
#include <opencv2/gapi/gscalar.hpp>
|
||||
#include <opencv2/gapi/garray.hpp>
|
||||
#include <opencv2/gapi/gopaque.hpp>
|
||||
#include <opencv2/gapi/streaming/source.hpp>
|
||||
#include <opencv2/gapi/gcommon.hpp>
|
||||
#include <opencv2/gapi/own/convert.hpp>
|
||||
@@ -36,7 +37,8 @@ namespace detail
|
||||
GMAT, // a cv::GMat
|
||||
GMATP, // a cv::GMatP
|
||||
GSCALAR, // a cv::GScalar
|
||||
GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray<T>!)
|
||||
GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray<T>!)
|
||||
GOPAQUE, // a cv::GOpaqueU (note - exactly GOpaqueU, not GOpaque<T>!)
|
||||
};
|
||||
|
||||
// Describe G-API types (G-types) with traits. Mostly used by
|
||||
@@ -73,6 +75,16 @@ namespace detail
|
||||
static cv::detail::VectorRef wrap_in (const std::vector<T> &t) { return detail::VectorRef(t); }
|
||||
static cv::detail::VectorRef wrap_out ( std::vector<T> &t) { return detail::VectorRef(t); }
|
||||
};
|
||||
template<class T> struct GTypeTraits<cv::GOpaque<T> >
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GOPAQUE;
|
||||
static constexpr const GShape shape = GShape::GOPAQUE;
|
||||
using host_type = T;
|
||||
using strip_type = cv::detail::OpaqueRef;
|
||||
static cv::detail::GOpaqueU wrap_value(const cv::GOpaque<T> &t) { return t.strip();}
|
||||
static cv::detail::OpaqueRef wrap_in (const T &t) { return detail::OpaqueRef(t); }
|
||||
static cv::detail::OpaqueRef wrap_out ( T &t) { return detail::OpaqueRef(t); }
|
||||
};
|
||||
|
||||
// Tests if Trait for type T requires extra marshalling ("custom wrap") or not.
|
||||
// If Traits<T> has wrap_value() defined, it does.
|
||||
@@ -100,6 +112,7 @@ namespace detail
|
||||
template<> struct GTypeOf<cv::gapi::own::Mat> { using type = cv::GMat; };
|
||||
template<> struct GTypeOf<cv::gapi::own::Scalar> { using type = cv::GScalar; };
|
||||
template<typename U> struct GTypeOf<std::vector<U> > { using type = cv::GArray<U>; };
|
||||
template<typename U> struct GTypeOf { using type = cv::GOpaque<U>;};
|
||||
// FIXME: This is not quite correct since IStreamSource may produce not only Mat but also Scalar
|
||||
// and vector data. TODO: Extend the type dispatching on these types too.
|
||||
template<> struct GTypeOf<cv::gapi::wip::IStreamSource::Ptr> { using type = cv::GMat;};
|
||||
@@ -164,7 +177,6 @@ namespace detail
|
||||
|
||||
template<typename T> using wrap_gapi_helper = WrapValue<typename std::decay<T>::type>;
|
||||
template<typename T> using wrap_host_helper = WrapValue<typename std::decay<g_type_of_t<T> >::type>;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
||||
|
||||
@@ -25,13 +25,15 @@ namespace detail
|
||||
template<typename T> struct ProtoToParam;
|
||||
template<> struct ProtoToParam<cv::GMat> { using type = cv::Mat; };
|
||||
template<> struct ProtoToParam<cv::GScalar> { using type = cv::Scalar; };
|
||||
template<typename U> struct ProtoToParam<cv::GArray<U> > { using type = std::vector<U>; };
|
||||
template<typename U> struct ProtoToParam<cv::GArray<U> > { using type = std::vector<U>; };
|
||||
template<typename U> struct ProtoToParam<cv::GOpaque<U> > { using type = U; };
|
||||
template<typename T> using ProtoToParamT = typename ProtoToParam<T>::type;
|
||||
|
||||
template<typename T> struct ProtoToMeta;
|
||||
template<> struct ProtoToMeta<cv::GMat> { using type = cv::GMatDesc; };
|
||||
template<> struct ProtoToMeta<cv::GScalar> { using type = cv::GScalarDesc; };
|
||||
template<typename U> struct ProtoToMeta<cv::GArray<U> > { using type = cv::GArrayDesc; };
|
||||
template<typename U> struct ProtoToMeta<cv::GArray<U> > { using type = cv::GArrayDesc; };
|
||||
template<typename U> struct ProtoToMeta<cv::GOpaque<U> > { using type = cv::GOpaqueDesc; };
|
||||
template<typename T> using ProtoToMetaT = typename ProtoToMeta<T>::type;
|
||||
|
||||
//workaround for MSVC 19.0 bug
|
||||
|
||||
@@ -68,9 +68,14 @@ public:
|
||||
{
|
||||
return outVecRef(output).wref<T>();
|
||||
}
|
||||
template<typename T> T& outOpaqueR(int output) // FIXME: the same issue
|
||||
{
|
||||
return outOpaqueRef(output).wref<T>();
|
||||
}
|
||||
|
||||
protected:
|
||||
detail::VectorRef& outVecRef(int output);
|
||||
detail::VectorRef& outOpaqueRef(int output);
|
||||
|
||||
std::vector<GArg> m_args;
|
||||
std::unordered_map<std::size_t, GRunArgP> m_results;
|
||||
@@ -111,6 +116,10 @@ template<typename U> struct ocl_get_in<cv::GArray<U> >
|
||||
{
|
||||
static const std::vector<U>& get(GOCLContext &ctx, int idx) { return ctx.inArg<VectorRef>(idx).rref<U>(); }
|
||||
};
|
||||
template<typename U> struct ocl_get_in<cv::GOpaque<U> >
|
||||
{
|
||||
static const U& get(GOCLContext &ctx, int idx) { return ctx.inArg<OpaqueRef>(idx).rref<U>(); }
|
||||
};
|
||||
template<class T> struct ocl_get_in
|
||||
{
|
||||
static T get(GOCLContext &ctx, int idx) { return ctx.inArg<T>(idx); }
|
||||
@@ -184,6 +193,10 @@ template<typename U> struct ocl_get_out<cv::GArray<U> >
|
||||
{
|
||||
static std::vector<U>& get(GOCLContext &ctx, int idx) { return ctx.outVecR<U>(idx); }
|
||||
};
|
||||
template<typename U> struct ocl_get_out<cv::GOpaque<U> >
|
||||
{
|
||||
static U& get(GOCLContext &ctx, int idx) { return ctx.outOpaqueR<U>(idx); }
|
||||
};
|
||||
|
||||
template<typename, typename, typename>
|
||||
struct OCLCallHelper;
|
||||
|
||||
Reference in New Issue
Block a user