mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08: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:
parent
2ced568d34
commit
0d456f9111
@ -44,6 +44,7 @@ set(gapi_srcs
|
|||||||
src/api/gorigin.cpp
|
src/api/gorigin.cpp
|
||||||
src/api/gmat.cpp
|
src/api/gmat.cpp
|
||||||
src/api/garray.cpp
|
src/api/garray.cpp
|
||||||
|
src/api/gopaque.cpp
|
||||||
src/api/gscalar.cpp
|
src/api/gscalar.cpp
|
||||||
src/api/gkernel.cpp
|
src/api/gkernel.cpp
|
||||||
src/api/gbackend.cpp
|
src/api/gbackend.cpp
|
||||||
|
@ -94,9 +94,14 @@ public:
|
|||||||
{
|
{
|
||||||
return outVecRef(output).wref<T>();
|
return outVecRef(output).wref<T>();
|
||||||
}
|
}
|
||||||
|
template<typename T> T& outOpaqueR(int output) // FIXME: the same issue
|
||||||
|
{
|
||||||
|
return outOpaqueRef(output).wref<T>();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
detail::VectorRef& outVecRef(int output);
|
detail::VectorRef& outVecRef(int output);
|
||||||
|
detail::OpaqueRef& outOpaqueRef(int output);
|
||||||
|
|
||||||
std::vector<GArg> m_args;
|
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>(); }
|
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
|
//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> >
|
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
|
template<class T> struct get_in
|
||||||
{
|
{
|
||||||
static T get(GCPUContext &ctx, int idx) { return ctx.inArg<T>(idx); }
|
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);
|
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>
|
template<typename, typename, typename>
|
||||||
struct OCVCallHelper;
|
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
|
template<class T> struct fluid_get_in
|
||||||
{
|
{
|
||||||
static const T& get(const cv::GArgs &in_args, int idx)
|
static const T& get(const cv::GArgs &in_args, int idx)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <opencv2/gapi/gmat.hpp>
|
#include <opencv2/gapi/gmat.hpp>
|
||||||
#include <opencv2/gapi/gscalar.hpp>
|
#include <opencv2/gapi/gscalar.hpp>
|
||||||
#include <opencv2/gapi/garray.hpp>
|
#include <opencv2/gapi/garray.hpp>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
#include <opencv2/gapi/gtype_traits.hpp>
|
#include <opencv2/gapi/gtype_traits.hpp>
|
||||||
#include <opencv2/gapi/gmetaarg.hpp>
|
#include <opencv2/gapi/gmetaarg.hpp>
|
||||||
#include <opencv2/gapi/own/scalar.hpp>
|
#include <opencv2/gapi/own/scalar.hpp>
|
||||||
@ -96,7 +97,8 @@ using GRunArg = util::variant<
|
|||||||
cv::gapi::wip::IStreamSource::Ptr,
|
cv::gapi::wip::IStreamSource::Ptr,
|
||||||
cv::gapi::own::Mat,
|
cv::gapi::own::Mat,
|
||||||
cv::gapi::own::Scalar,
|
cv::gapi::own::Scalar,
|
||||||
cv::detail::VectorRef
|
cv::detail::VectorRef,
|
||||||
|
cv::detail::OpaqueRef
|
||||||
>;
|
>;
|
||||||
using GRunArgs = std::vector<GRunArg>;
|
using GRunArgs = std::vector<GRunArg>;
|
||||||
|
|
||||||
@ -128,7 +130,8 @@ using GRunArgP = util::variant<
|
|||||||
#endif // !defined(GAPI_STANDALONE)
|
#endif // !defined(GAPI_STANDALONE)
|
||||||
cv::gapi::own::Mat*,
|
cv::gapi::own::Mat*,
|
||||||
cv::gapi::own::Scalar*,
|
cv::gapi::own::Scalar*,
|
||||||
cv::detail::VectorRef
|
cv::detail::VectorRef,
|
||||||
|
cv::detail::OpaqueRef
|
||||||
>;
|
>;
|
||||||
using GRunArgsP = std::vector<GRunArgP>;
|
using GRunArgsP = std::vector<GRunArgP>;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <opencv2/gapi/gmat.hpp> // GMat
|
#include <opencv2/gapi/gmat.hpp> // GMat
|
||||||
#include <opencv2/gapi/gscalar.hpp> // GScalar
|
#include <opencv2/gapi/gscalar.hpp> // GScalar
|
||||||
#include <opencv2/gapi/garray.hpp> // GArray<T>
|
#include <opencv2/gapi/garray.hpp> // GArray<T>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp> // GOpaque<T>
|
||||||
|
|
||||||
namespace cv {
|
namespace cv {
|
||||||
|
|
||||||
@ -46,6 +47,11 @@ public:
|
|||||||
return GArray<T>(yieldArray(output));
|
return GArray<T>(yieldArray(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> GOpaque<T> yieldOpaque(int output = 0)
|
||||||
|
{
|
||||||
|
return GOpaque<T>(yieldOpaque(output));
|
||||||
|
}
|
||||||
|
|
||||||
// Internal use only
|
// Internal use only
|
||||||
Priv& priv();
|
Priv& priv();
|
||||||
const Priv& priv() const;
|
const Priv& priv() const;
|
||||||
@ -55,8 +61,9 @@ protected:
|
|||||||
|
|
||||||
void setArgs(std::vector<GArg> &&args);
|
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::GArrayU yieldArray(int output = 0);
|
||||||
|
detail::GOpaqueU yieldOpaque(int output = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
@ -44,6 +44,7 @@ enum class GShape: int
|
|||||||
GMAT,
|
GMAT,
|
||||||
GSCALAR,
|
GSCALAR,
|
||||||
GARRAY,
|
GARRAY,
|
||||||
|
GOPAQUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GCompileArg;
|
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>
|
template<typename, typename, typename>
|
||||||
struct GCompoundCallHelper;
|
struct GCompoundCallHelper;
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ namespace detail
|
|||||||
{
|
{
|
||||||
static inline cv::GArray<U> yield(cv::GCall &call, int i) { return call.yieldArray<U>(i); }
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -87,7 +91,8 @@ namespace detail
|
|||||||
template<> struct MetaType<cv::GMat> { using type = GMatDesc; };
|
template<> struct MetaType<cv::GMat> { using type = GMatDesc; };
|
||||||
template<> struct MetaType<cv::GMatP> { using type = GMatDesc; };
|
template<> struct MetaType<cv::GMatP> { using type = GMatDesc; };
|
||||||
template<> struct MetaType<cv::GScalar> { using type = GScalarDesc; };
|
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
|
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
|
// 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::GMat | cv::Mat
|
||||||
* cv::GScalar | cv::Scalar
|
* cv::GScalar | cv::Scalar
|
||||||
* `cv::GArray<T>` | std::vector<T>
|
* `cv::GArray<T>` | std::vector<T>
|
||||||
|
* `cv::GOpaque<T>` | T
|
||||||
*/
|
*/
|
||||||
class GAPI_EXPORTS GMat
|
class GAPI_EXPORTS GMat
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <opencv2/gapi/gmat.hpp>
|
#include <opencv2/gapi/gmat.hpp>
|
||||||
#include <opencv2/gapi/gscalar.hpp>
|
#include <opencv2/gapi/gscalar.hpp>
|
||||||
#include <opencv2/gapi/garray.hpp>
|
#include <opencv2/gapi/garray.hpp>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
@ -36,6 +37,7 @@ using GMetaArg = util::variant
|
|||||||
, GMatDesc
|
, GMatDesc
|
||||||
, GScalarDesc
|
, GScalarDesc
|
||||||
, GArrayDesc
|
, GArrayDesc
|
||||||
|
, GOpaqueDesc
|
||||||
>;
|
>;
|
||||||
GAPI_EXPORTS std::ostream& operator<<(std::ostream& os, const GMetaArg &);
|
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<GMatDesc> : std::true_type {};
|
||||||
template<> struct is_meta_descr<GScalarDesc> : 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<GArrayDesc> : std::true_type {};
|
||||||
|
template<> struct is_meta_descr<GOpaqueDesc> : std::true_type {};
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
using are_meta_descrs = all_satisfy<is_meta_descr, Ts...>;
|
using are_meta_descrs = all_satisfy<is_meta_descr, Ts...>;
|
||||||
|
289
modules/gapi/include/opencv2/gapi/gopaque.hpp
Normal file
289
modules/gapi/include/opencv2/gapi/gopaque.hpp
Normal file
@ -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/gmat.hpp>
|
||||||
#include <opencv2/gapi/gscalar.hpp>
|
#include <opencv2/gapi/gscalar.hpp>
|
||||||
#include <opencv2/gapi/garray.hpp>
|
#include <opencv2/gapi/garray.hpp>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
#include <opencv2/gapi/garg.hpp>
|
#include <opencv2/gapi/garg.hpp>
|
||||||
#include <opencv2/gapi/gmetaarg.hpp>
|
#include <opencv2/gapi/gmetaarg.hpp>
|
||||||
|
|
||||||
@ -36,7 +37,8 @@ using GProtoArg = util::variant
|
|||||||
< GMat
|
< GMat
|
||||||
, GMatP
|
, GMatP
|
||||||
, GScalar
|
, GScalar
|
||||||
, detail::GArrayU // instead of GArray<T>
|
, detail::GArrayU // instead of GArray<T>
|
||||||
|
, detail::GOpaqueU // instead of GOpaque<T>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using GProtoArgs = std::vector<GProtoArg>;
|
using GProtoArgs = std::vector<GProtoArg>;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <opencv2/gapi/gmat.hpp>
|
#include <opencv2/gapi/gmat.hpp>
|
||||||
#include <opencv2/gapi/gscalar.hpp>
|
#include <opencv2/gapi/gscalar.hpp>
|
||||||
#include <opencv2/gapi/garray.hpp>
|
#include <opencv2/gapi/garray.hpp>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
#include <opencv2/gapi/streaming/source.hpp>
|
#include <opencv2/gapi/streaming/source.hpp>
|
||||||
#include <opencv2/gapi/gcommon.hpp>
|
#include <opencv2/gapi/gcommon.hpp>
|
||||||
#include <opencv2/gapi/own/convert.hpp>
|
#include <opencv2/gapi/own/convert.hpp>
|
||||||
@ -36,7 +37,8 @@ namespace detail
|
|||||||
GMAT, // a cv::GMat
|
GMAT, // a cv::GMat
|
||||||
GMATP, // a cv::GMatP
|
GMATP, // a cv::GMatP
|
||||||
GSCALAR, // a cv::GScalar
|
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
|
// 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_in (const std::vector<T> &t) { return detail::VectorRef(t); }
|
||||||
static cv::detail::VectorRef wrap_out ( 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.
|
// Tests if Trait for type T requires extra marshalling ("custom wrap") or not.
|
||||||
// If Traits<T> has wrap_value() defined, it does.
|
// 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::Mat> { using type = cv::GMat; };
|
||||||
template<> struct GTypeOf<cv::gapi::own::Scalar> { using type = cv::GScalar; };
|
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<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
|
// 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.
|
// and vector data. TODO: Extend the type dispatching on these types too.
|
||||||
template<> struct GTypeOf<cv::gapi::wip::IStreamSource::Ptr> { using type = cv::GMat;};
|
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_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>;
|
template<typename T> using wrap_host_helper = WrapValue<typename std::decay<g_type_of_t<T> >::type>;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|
||||||
|
@ -25,13 +25,15 @@ namespace detail
|
|||||||
template<typename T> struct ProtoToParam;
|
template<typename T> struct ProtoToParam;
|
||||||
template<> struct ProtoToParam<cv::GMat> { using type = cv::Mat; };
|
template<> struct ProtoToParam<cv::GMat> { using type = cv::Mat; };
|
||||||
template<> struct ProtoToParam<cv::GScalar> { using type = cv::Scalar; };
|
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> using ProtoToParamT = typename ProtoToParam<T>::type;
|
||||||
|
|
||||||
template<typename T> struct ProtoToMeta;
|
template<typename T> struct ProtoToMeta;
|
||||||
template<> struct ProtoToMeta<cv::GMat> { using type = cv::GMatDesc; };
|
template<> struct ProtoToMeta<cv::GMat> { using type = cv::GMatDesc; };
|
||||||
template<> struct ProtoToMeta<cv::GScalar> { using type = cv::GScalarDesc; };
|
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;
|
template<typename T> using ProtoToMetaT = typename ProtoToMeta<T>::type;
|
||||||
|
|
||||||
//workaround for MSVC 19.0 bug
|
//workaround for MSVC 19.0 bug
|
||||||
|
@ -68,9 +68,14 @@ public:
|
|||||||
{
|
{
|
||||||
return outVecRef(output).wref<T>();
|
return outVecRef(output).wref<T>();
|
||||||
}
|
}
|
||||||
|
template<typename T> T& outOpaqueR(int output) // FIXME: the same issue
|
||||||
|
{
|
||||||
|
return outOpaqueRef(output).wref<T>();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
detail::VectorRef& outVecRef(int output);
|
detail::VectorRef& outVecRef(int output);
|
||||||
|
detail::VectorRef& outOpaqueRef(int output);
|
||||||
|
|
||||||
std::vector<GArg> m_args;
|
std::vector<GArg> m_args;
|
||||||
std::unordered_map<std::size_t, GRunArgP> m_results;
|
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>(); }
|
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
|
template<class T> struct ocl_get_in
|
||||||
{
|
{
|
||||||
static T get(GOCLContext &ctx, int idx) { return ctx.inArg<T>(idx); }
|
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); }
|
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>
|
template<typename, typename, typename>
|
||||||
struct OCLCallHelper;
|
struct OCLCallHelper;
|
||||||
|
@ -168,6 +168,10 @@ void bindInArg(Mag& mag, const RcDesc &rc, const GRunArg &arg, bool is_umat)
|
|||||||
mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
|
mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GShape::GOPAQUE:
|
||||||
|
mag.template slot<cv::detail::OpaqueRef>()[rc.id] = util::get<cv::detail::OpaqueRef>(arg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
}
|
}
|
||||||
@ -233,6 +237,10 @@ void bindOutArg(Mag& mag, const RcDesc &rc, const GRunArgP &arg, bool is_umat)
|
|||||||
mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
|
mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GShape::GOPAQUE:
|
||||||
|
mag.template slot<cv::detail::OpaqueRef>()[rc.id] = util::get<cv::detail::OpaqueRef>(arg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
@ -251,6 +259,11 @@ void resetInternalData(Mag& mag, const Data &d)
|
|||||||
(mag.template slot<cv::detail::VectorRef>()[d.rc]);
|
(mag.template slot<cv::detail::VectorRef>()[d.rc]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GShape::GOPAQUE:
|
||||||
|
util::get<cv::detail::ConstructOpaque>(d.ctor)
|
||||||
|
(mag.template slot<cv::detail::OpaqueRef>()[d.rc]);
|
||||||
|
break;
|
||||||
|
|
||||||
case GShape::GSCALAR:
|
case GShape::GSCALAR:
|
||||||
mag.template slot<cv::gapi::own::Scalar>()[d.rc] = cv::gapi::own::Scalar();
|
mag.template slot<cv::gapi::own::Scalar>()[d.rc] = cv::gapi::own::Scalar();
|
||||||
break;
|
break;
|
||||||
@ -272,9 +285,10 @@ cv::GRunArg getArg(const Mag& mag, const RcDesc &ref)
|
|||||||
{
|
{
|
||||||
case GShape::GMAT: return GRunArg(mag.template slot<cv::gapi::own::Mat>().at(ref.id));
|
case GShape::GMAT: return GRunArg(mag.template slot<cv::gapi::own::Mat>().at(ref.id));
|
||||||
case GShape::GSCALAR: return GRunArg(mag.template slot<cv::gapi::own::Scalar>().at(ref.id));
|
case GShape::GSCALAR: return GRunArg(mag.template slot<cv::gapi::own::Scalar>().at(ref.id));
|
||||||
// Note: .at() is intentional for GArray as object MUST be already there
|
// Note: .at() is intentional for GArray and GOpaque as objects MUST be already there
|
||||||
// (and constructed by either bindIn/Out or resetInternal)
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
case GShape::GARRAY: return GRunArg(mag.template slot<cv::detail::VectorRef>().at(ref.id));
|
case GShape::GARRAY: return GRunArg(mag.template slot<cv::detail::VectorRef>().at(ref.id));
|
||||||
|
case GShape::GOPAQUE: return GRunArg(mag.template slot<cv::detail::OpaqueRef>().at(ref.id));
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
@ -297,7 +311,7 @@ cv::GRunArgP getObjPtr(Mag& mag, const RcDesc &rc, bool is_umat)
|
|||||||
else
|
else
|
||||||
return GRunArgP(&mag.template slot<cv::gapi::own::Mat>()[rc.id]);
|
return GRunArgP(&mag.template slot<cv::gapi::own::Mat>()[rc.id]);
|
||||||
case GShape::GSCALAR: return GRunArgP(&mag.template slot<cv::gapi::own::Scalar>()[rc.id]);
|
case GShape::GSCALAR: return GRunArgP(&mag.template slot<cv::gapi::own::Scalar>()[rc.id]);
|
||||||
// Note: .at() is intentional for GArray as object MUST be already there
|
// Note: .at() is intentional for GArray and GOpaque as objects MUST be already there
|
||||||
// (and constructor by either bindIn/Out or resetInternal)
|
// (and constructor by either bindIn/Out or resetInternal)
|
||||||
case GShape::GARRAY:
|
case GShape::GARRAY:
|
||||||
// FIXME(DM): For some absolutely unknown to me reason, move
|
// FIXME(DM): For some absolutely unknown to me reason, move
|
||||||
@ -307,6 +321,14 @@ cv::GRunArgP getObjPtr(Mag& mag, const RcDesc &rc, bool is_umat)
|
|||||||
// debugging this!!!1
|
// debugging this!!!1
|
||||||
return GRunArgP(const_cast<const Mag&>(mag)
|
return GRunArgP(const_cast<const Mag&>(mag)
|
||||||
.template slot<cv::detail::VectorRef>().at(rc.id));
|
.template slot<cv::detail::VectorRef>().at(rc.id));
|
||||||
|
case GShape::GOPAQUE:
|
||||||
|
// FIXME(DM): For some absolutely unknown to me reason, move
|
||||||
|
// semantics is involved here without const_cast to const (and
|
||||||
|
// value from map is moved into return value GRunArgP, leaving
|
||||||
|
// map with broken value I've spent few late Friday hours
|
||||||
|
// debugging this!!!1
|
||||||
|
return GRunArgP(const_cast<const Mag&>(mag)
|
||||||
|
.template slot<cv::detail::OpaqueRef>().at(rc.id));
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
@ -320,6 +342,9 @@ void writeBack(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg, bool is_umat)
|
|||||||
case GShape::GARRAY:
|
case GShape::GARRAY:
|
||||||
// Do nothing - should we really do anything here?
|
// Do nothing - should we really do anything here?
|
||||||
break;
|
break;
|
||||||
|
case GShape::GOPAQUE:
|
||||||
|
// Do nothing - should we really do anything here?
|
||||||
|
break;
|
||||||
|
|
||||||
case GShape::GMAT:
|
case GShape::GMAT:
|
||||||
{
|
{
|
||||||
|
@ -64,6 +64,11 @@ cv::detail::GArrayU cv::GCall::yieldArray(int output)
|
|||||||
return cv::detail::GArrayU(m_priv->m_node, output);
|
return cv::detail::GArrayU(m_priv->m_node, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::detail::GOpaqueU cv::GCall::yieldOpaque(int output)
|
||||||
|
{
|
||||||
|
return cv::detail::GOpaqueU(m_priv->m_node, output);
|
||||||
|
}
|
||||||
|
|
||||||
cv::GCall::Priv& cv::GCall::priv()
|
cv::GCall::Priv& cv::GCall::priv()
|
||||||
{
|
{
|
||||||
return *m_priv;
|
return *m_priv;
|
||||||
|
45
modules/gapi/src/api/gopaque.cpp
Normal file
45
modules/gapi/src/api/gopaque.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
|
||||||
|
#include "precomp.hpp"
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
|
#include "api/gorigin.hpp"
|
||||||
|
|
||||||
|
// cv::detail::GOpaqueU public implementation ///////////////////////////////////
|
||||||
|
cv::detail::GOpaqueU::GOpaqueU()
|
||||||
|
: m_priv(new GOrigin(GShape::GOPAQUE, cv::GNode::Param()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::detail::GOpaqueU::GOpaqueU(const GNode &n, std::size_t out)
|
||||||
|
: m_priv(new GOrigin(GShape::GOPAQUE, n, out))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::GOrigin& cv::detail::GOpaqueU::priv()
|
||||||
|
{
|
||||||
|
return *m_priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cv::GOrigin& cv::detail::GOpaqueU::priv() const
|
||||||
|
{
|
||||||
|
return *m_priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::detail::GOpaqueU::setConstructFcn(ConstructOpaque &&co)
|
||||||
|
{
|
||||||
|
m_priv->ctor = std::move(co);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace cv {
|
||||||
|
std::ostream& operator<<(std::ostream& os, const cv::GOpaqueDesc &)
|
||||||
|
{
|
||||||
|
// FIXME: add type information here
|
||||||
|
os << "(Opaque)";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,9 @@ const cv::GOrigin& cv::gimpl::proto::origin_of(const cv::GProtoArg &arg)
|
|||||||
case cv::GProtoArg::index_of<cv::detail::GArrayU>():
|
case cv::GProtoArg::index_of<cv::detail::GArrayU>():
|
||||||
return util::get<cv::detail::GArrayU>(arg).priv();
|
return util::get<cv::detail::GArrayU>(arg).priv();
|
||||||
|
|
||||||
|
case cv::GProtoArg::index_of<cv::detail::GOpaqueU>():
|
||||||
|
return util::get<cv::detail::GOpaqueU>(arg).priv();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GProtoArg type"));
|
util::throw_error(std::logic_error("Unsupported GProtoArg type"));
|
||||||
}
|
}
|
||||||
@ -59,6 +62,7 @@ bool cv::gimpl::proto::is_dynamic(const cv::GArg& arg)
|
|||||||
case detail::ArgKind::GMATP:
|
case detail::ArgKind::GMATP:
|
||||||
case detail::ArgKind::GSCALAR:
|
case detail::ArgKind::GSCALAR:
|
||||||
case detail::ArgKind::GARRAY:
|
case detail::ArgKind::GARRAY:
|
||||||
|
case detail::ArgKind::GOPAQUE:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -85,6 +89,7 @@ cv::GProtoArg cv::gimpl::proto::rewrap(const cv::GArg &arg)
|
|||||||
case detail::ArgKind::GMATP: return GProtoArg(arg.get<cv::GMatP>());
|
case detail::ArgKind::GMATP: return GProtoArg(arg.get<cv::GMatP>());
|
||||||
case detail::ArgKind::GSCALAR: return GProtoArg(arg.get<cv::GScalar>());
|
case detail::ArgKind::GSCALAR: return GProtoArg(arg.get<cv::GScalar>());
|
||||||
case detail::ArgKind::GARRAY: return GProtoArg(arg.get<cv::detail::GArrayU>());
|
case detail::ArgKind::GARRAY: return GProtoArg(arg.get<cv::detail::GArrayU>());
|
||||||
|
case detail::ArgKind::GOPAQUE: return GProtoArg(arg.get<cv::detail::GOpaqueU>());
|
||||||
default: util::throw_error(std::logic_error("Unsupported GArg type"));
|
default: util::throw_error(std::logic_error("Unsupported GArg type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,6 +115,9 @@ cv::GMetaArg cv::descr_of(const cv::GRunArg &arg)
|
|||||||
case GRunArg::index_of<cv::detail::VectorRef>():
|
case GRunArg::index_of<cv::detail::VectorRef>():
|
||||||
return cv::GMetaArg(util::get<cv::detail::VectorRef>(arg).descr_of());
|
return cv::GMetaArg(util::get<cv::detail::VectorRef>(arg).descr_of());
|
||||||
|
|
||||||
|
case GRunArg::index_of<cv::detail::OpaqueRef>():
|
||||||
|
return cv::GMetaArg(util::get<cv::detail::OpaqueRef>(arg).descr_of());
|
||||||
|
|
||||||
case GRunArg::index_of<cv::gapi::wip::IStreamSource::Ptr>():
|
case GRunArg::index_of<cv::gapi::wip::IStreamSource::Ptr>():
|
||||||
return cv::util::get<cv::gapi::wip::IStreamSource::Ptr>(arg)->descr_of();
|
return cv::util::get<cv::gapi::wip::IStreamSource::Ptr>(arg)->descr_of();
|
||||||
|
|
||||||
@ -136,6 +144,7 @@ cv::GMetaArg cv::descr_of(const cv::GRunArgP &argp)
|
|||||||
case GRunArgP::index_of<cv::gapi::own::Mat*>(): return GMetaArg(descr_of(*util::get<cv::gapi::own::Mat*>(argp)));
|
case GRunArgP::index_of<cv::gapi::own::Mat*>(): return GMetaArg(descr_of(*util::get<cv::gapi::own::Mat*>(argp)));
|
||||||
case GRunArgP::index_of<cv::gapi::own::Scalar*>(): return GMetaArg(descr_of(*util::get<cv::gapi::own::Scalar*>(argp)));
|
case GRunArgP::index_of<cv::gapi::own::Scalar*>(): return GMetaArg(descr_of(*util::get<cv::gapi::own::Scalar*>(argp)));
|
||||||
case GRunArgP::index_of<cv::detail::VectorRef>(): return GMetaArg(util::get<cv::detail::VectorRef>(argp).descr_of());
|
case GRunArgP::index_of<cv::detail::VectorRef>(): return GMetaArg(util::get<cv::detail::VectorRef>(argp).descr_of());
|
||||||
|
case GRunArgP::index_of<cv::detail::OpaqueRef>(): return GMetaArg(util::get<cv::detail::OpaqueRef>(argp).descr_of());
|
||||||
default: util::throw_error(std::logic_error("Unsupported GRunArgP type"));
|
default: util::throw_error(std::logic_error("Unsupported GRunArgP type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,6 +163,7 @@ bool cv::can_describe(const GMetaArg& meta, const GRunArgP& argp)
|
|||||||
util::get<GMatDesc>(meta).canDescribe(*util::get<cv::gapi::own::Mat*>(argp));
|
util::get<GMatDesc>(meta).canDescribe(*util::get<cv::gapi::own::Mat*>(argp));
|
||||||
case GRunArgP::index_of<cv::gapi::own::Scalar*>(): return meta == GMetaArg(descr_of(*util::get<cv::gapi::own::Scalar*>(argp)));
|
case GRunArgP::index_of<cv::gapi::own::Scalar*>(): return meta == GMetaArg(descr_of(*util::get<cv::gapi::own::Scalar*>(argp)));
|
||||||
case GRunArgP::index_of<cv::detail::VectorRef>(): return meta == GMetaArg(util::get<cv::detail::VectorRef>(argp).descr_of());
|
case GRunArgP::index_of<cv::detail::VectorRef>(): return meta == GMetaArg(util::get<cv::detail::VectorRef>(argp).descr_of());
|
||||||
|
case GRunArgP::index_of<cv::detail::OpaqueRef>(): return meta == GMetaArg(util::get<cv::detail::OpaqueRef>(argp).descr_of());
|
||||||
default: util::throw_error(std::logic_error("Unsupported GRunArgP type"));
|
default: util::throw_error(std::logic_error("Unsupported GRunArgP type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,6 +182,7 @@ bool cv::can_describe(const GMetaArg& meta, const GRunArg& arg)
|
|||||||
util::get<GMatDesc>(meta).canDescribe(util::get<cv::gapi::own::Mat>(arg));
|
util::get<GMatDesc>(meta).canDescribe(util::get<cv::gapi::own::Mat>(arg));
|
||||||
case GRunArg::index_of<cv::gapi::own::Scalar>(): return meta == cv::GMetaArg(descr_of(util::get<cv::gapi::own::Scalar>(arg)));
|
case GRunArg::index_of<cv::gapi::own::Scalar>(): return meta == cv::GMetaArg(descr_of(util::get<cv::gapi::own::Scalar>(arg)));
|
||||||
case GRunArg::index_of<cv::detail::VectorRef>(): return meta == cv::GMetaArg(util::get<cv::detail::VectorRef>(arg).descr_of());
|
case GRunArg::index_of<cv::detail::VectorRef>(): return meta == cv::GMetaArg(util::get<cv::detail::VectorRef>(arg).descr_of());
|
||||||
|
case GRunArg::index_of<cv::detail::OpaqueRef>(): return meta == cv::GMetaArg(util::get<cv::detail::OpaqueRef>(arg).descr_of());
|
||||||
case GRunArg::index_of<cv::gapi::wip::IStreamSource::Ptr>(): return util::holds_alternative<GMatDesc>(meta); // FIXME(?) may be not the best option
|
case GRunArg::index_of<cv::gapi::wip::IStreamSource::Ptr>(): return util::holds_alternative<GMatDesc>(meta); // FIXME(?) may be not the best option
|
||||||
default: util::throw_error(std::logic_error("Unsupported GRunArg type"));
|
default: util::throw_error(std::logic_error("Unsupported GRunArg type"));
|
||||||
}
|
}
|
||||||
@ -207,6 +218,10 @@ std::ostream& operator<<(std::ostream& os, const cv::GMetaArg &arg)
|
|||||||
case cv::GMetaArg::index_of<cv::GArrayDesc>():
|
case cv::GMetaArg::index_of<cv::GArrayDesc>():
|
||||||
os << util::get<cv::GArrayDesc>(arg);
|
os << util::get<cv::GArrayDesc>(arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cv::GMetaArg::index_of<cv::GOpaqueDesc>():
|
||||||
|
os << util::get<cv::GOpaqueDesc>(arg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GAPI_Assert(false);
|
GAPI_Assert(false);
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ namespace magazine {
|
|||||||
|
|
||||||
} // namespace magazine
|
} // namespace magazine
|
||||||
#if !defined(GAPI_STANDALONE)
|
#if !defined(GAPI_STANDALONE)
|
||||||
using Mag = magazine::Class<cv::gapi::own::Mat, cv::UMat, cv::gapi::own::Scalar, cv::detail::VectorRef>;
|
using Mag = magazine::Class<cv::gapi::own::Mat, cv::UMat, cv::gapi::own::Scalar, cv::detail::VectorRef, cv::detail::OpaqueRef>;
|
||||||
#else
|
#else
|
||||||
using Mag = magazine::Class<cv::gapi::own::Mat, cv::gapi::own::Scalar, cv::detail::VectorRef>;
|
using Mag = magazine::Class<cv::gapi::own::Mat, cv::gapi::own::Scalar, cv::detail::VectorRef, cv::detail::OpaqueRef>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace magazine
|
namespace magazine
|
||||||
|
@ -113,7 +113,8 @@ cv::GArg cv::gimpl::GCPUExecutable::packArg(const GArg &arg)
|
|||||||
// FIXME: this check has to be done somewhere in compilation stage.
|
// FIXME: this check has to be done somewhere in compilation stage.
|
||||||
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
||||||
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
||||||
&& arg.kind != cv::detail::ArgKind::GARRAY);
|
&& arg.kind != cv::detail::ArgKind::GARRAY
|
||||||
|
&& arg.kind != cv::detail::ArgKind::GOPAQUE);
|
||||||
|
|
||||||
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
||||||
{
|
{
|
||||||
@ -129,9 +130,10 @@ cv::GArg cv::gimpl::GCPUExecutable::packArg(const GArg &arg)
|
|||||||
{
|
{
|
||||||
case GShape::GMAT: return GArg(m_res.slot<cv::gapi::own::Mat>() [ref.id]);
|
case GShape::GMAT: return GArg(m_res.slot<cv::gapi::own::Mat>() [ref.id]);
|
||||||
case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
|
case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
|
||||||
// Note: .at() is intentional for GArray as object MUST be already there
|
// Note: .at() is intentional for GArray and GOpaque as objects MUST be already there
|
||||||
// (and constructed by either bindIn/Out or resetInternal)
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
||||||
|
case GShape::GOPAQUE: return GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id));
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
|
@ -36,6 +36,11 @@ cv::detail::VectorRef& cv::GCPUContext::outVecRef(int output)
|
|||||||
return util::get<cv::detail::VectorRef>(m_results.at(output));
|
return util::get<cv::detail::VectorRef>(m_results.at(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::detail::OpaqueRef& cv::GCPUContext::outOpaqueRef(int output)
|
||||||
|
{
|
||||||
|
return util::get<cv::detail::OpaqueRef>(m_results.at(output));
|
||||||
|
}
|
||||||
|
|
||||||
cv::GCPUKernel::GCPUKernel()
|
cv::GCPUKernel::GCPUKernel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1250,6 +1250,7 @@ void cv::gimpl::GFluidExecutable::bindInArg(const cv::gimpl::RcDesc &rc, const G
|
|||||||
case GShape::GMAT: m_buffers[m_id_map.at(rc.id)].priv().bindTo(util::get<cv::gapi::own::Mat>(arg), true); break;
|
case GShape::GMAT: m_buffers[m_id_map.at(rc.id)].priv().bindTo(util::get<cv::gapi::own::Mat>(arg), true); break;
|
||||||
case GShape::GSCALAR: m_res.slot<cv::gapi::own::Scalar>()[rc.id] = util::get<cv::gapi::own::Scalar>(arg); break;
|
case GShape::GSCALAR: m_res.slot<cv::gapi::own::Scalar>()[rc.id] = util::get<cv::gapi::own::Scalar>(arg); break;
|
||||||
case GShape::GARRAY: m_res.slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg); break;
|
case GShape::GARRAY: m_res.slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg); break;
|
||||||
|
case GShape::GOPAQUE: m_res.slot<cv::detail::OpaqueRef>()[rc.id] = util::get<cv::detail::OpaqueRef>(arg); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1292,7 +1293,8 @@ void cv::gimpl::GFluidExecutable::packArg(cv::GArg &in_arg, const cv::GArg &op_a
|
|||||||
{
|
{
|
||||||
GAPI_Assert(op_arg.kind != cv::detail::ArgKind::GMAT
|
GAPI_Assert(op_arg.kind != cv::detail::ArgKind::GMAT
|
||||||
&& op_arg.kind != cv::detail::ArgKind::GSCALAR
|
&& op_arg.kind != cv::detail::ArgKind::GSCALAR
|
||||||
&& op_arg.kind != cv::detail::ArgKind::GARRAY);
|
&& op_arg.kind != cv::detail::ArgKind::GARRAY
|
||||||
|
&& op_arg.kind != cv::detail::ArgKind::GOPAQUE);
|
||||||
|
|
||||||
if (op_arg.kind == cv::detail::ArgKind::GOBJREF)
|
if (op_arg.kind == cv::detail::ArgKind::GOBJREF)
|
||||||
{
|
{
|
||||||
@ -1305,6 +1307,10 @@ void cv::gimpl::GFluidExecutable::packArg(cv::GArg &in_arg, const cv::GArg &op_a
|
|||||||
{
|
{
|
||||||
in_arg = GArg(m_res.slot<cv::detail::VectorRef>()[ref.id]);
|
in_arg = GArg(m_res.slot<cv::detail::VectorRef>()[ref.id]);
|
||||||
}
|
}
|
||||||
|
else if (ref.shape == GShape::GOPAQUE)
|
||||||
|
{
|
||||||
|
in_arg = GArg(m_res.slot<cv::detail::OpaqueRef>()[ref.id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class GFluidExecutable final: public GIslandExecutable
|
|||||||
|
|
||||||
std::vector<FluidAgent*> m_script;
|
std::vector<FluidAgent*> m_script;
|
||||||
|
|
||||||
using Magazine = detail::magazine<cv::gapi::own::Scalar, cv::detail::VectorRef>;
|
using Magazine = detail::magazine<cv::gapi::own::Scalar, cv::detail::VectorRef, cv::detail::OpaqueRef>;
|
||||||
Magazine m_res;
|
Magazine m_res;
|
||||||
|
|
||||||
std::size_t m_num_int_buffers; // internal buffers counter (m_buffers - num_scratch)
|
std::size_t m_num_int_buffers; // internal buffers counter (m_buffers - num_scratch)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <opencv2/gapi/gcommon.hpp>
|
#include <opencv2/gapi/gcommon.hpp>
|
||||||
#include <opencv2/gapi/garray.hpp>
|
#include <opencv2/gapi/garray.hpp>
|
||||||
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
#include <opencv2/gapi/util/any.hpp>
|
#include <opencv2/gapi/util/any.hpp>
|
||||||
#include <opencv2/gapi/gtype_traits.hpp>
|
#include <opencv2/gapi/gtype_traits.hpp>
|
||||||
#include <opencv2/gapi/infer.hpp>
|
#include <opencv2/gapi/infer.hpp>
|
||||||
@ -396,6 +397,10 @@ cv::GArg cv::gimpl::ie::GIEExecutable::packArg(const cv::GArg &arg) {
|
|||||||
// (and constructed by either bindIn/Out or resetInternal)
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
||||||
|
|
||||||
|
// Note: .at() is intentional for GOpaque as object MUST be already there
|
||||||
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
|
case GShape::GOPAQUE: return GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
|
@ -113,7 +113,8 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
|
|||||||
// FIXME: this check has to be done somewhere in compilation stage.
|
// FIXME: this check has to be done somewhere in compilation stage.
|
||||||
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
||||||
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
||||||
&& arg.kind != cv::detail::ArgKind::GARRAY);
|
&& arg.kind != cv::detail::ArgKind::GARRAY
|
||||||
|
&& arg.kind != cv::detail::ArgKind::GOPAQUE);
|
||||||
|
|
||||||
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
||||||
{
|
{
|
||||||
@ -129,9 +130,12 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
|
|||||||
{
|
{
|
||||||
case GShape::GMAT: return GArg(m_res.slot<cv::UMat>()[ref.id]);
|
case GShape::GMAT: return GArg(m_res.slot<cv::UMat>()[ref.id]);
|
||||||
case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
|
case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
|
||||||
// Note: .at() is intentional for GArray as object MUST be already there
|
// Note: .at() is intentional for GArray as object MUST be already there
|
||||||
// (and constructed by either bindIn/Out or resetInternal)
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
case GShape::GARRAY: return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
|
||||||
|
// Note: .at() is intentional for GOpaque as object MUST be already there
|
||||||
|
// (and constructed by either bindIn/Out or resetInternal)
|
||||||
|
case GShape::GOPAQUE: return GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id));
|
||||||
default:
|
default:
|
||||||
util::throw_error(std::logic_error("Unsupported GShape type"));
|
util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||||
break;
|
break;
|
||||||
|
@ -276,7 +276,8 @@ cv::GArg cv::gimpl::GPlaidMLExecutable::packArg(const GArg &arg)
|
|||||||
{
|
{
|
||||||
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
|
||||||
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
&& arg.kind != cv::detail::ArgKind::GSCALAR
|
||||||
&& arg.kind != cv::detail::ArgKind::GARRAY);
|
&& arg.kind != cv::detail::ArgKind::GARRAY
|
||||||
|
&& arg.kind != cv::detail::ArgKind::GOPAQUE);
|
||||||
|
|
||||||
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
if (arg.kind != cv::detail::ArgKind::GOBJREF)
|
||||||
{
|
{
|
||||||
|
@ -332,6 +332,9 @@ void cv::gimpl::GCompiler::validateInputMeta()
|
|||||||
case GProtoArg::index_of<cv::detail::GArrayU>():
|
case GProtoArg::index_of<cv::detail::GArrayU>():
|
||||||
return util::holds_alternative<cv::GArrayDesc>(meta);
|
return util::holds_alternative<cv::GArrayDesc>(meta);
|
||||||
|
|
||||||
|
case GProtoArg::index_of<cv::detail::GOpaqueU>():
|
||||||
|
return util::holds_alternative<cv::GOpaqueDesc>(meta);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GAPI_Assert(false);
|
GAPI_Assert(false);
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,14 @@ namespace cv
|
|||||||
|
|
||||||
namespace gimpl
|
namespace gimpl
|
||||||
{
|
{
|
||||||
// Union type for various user-defined type constructors (GArray<T>, etc)
|
// Union type for various user-defined type constructors (GArray<T>, GOpaque<T>, etc)
|
||||||
// FIXME: Replace construct-only API with a more generic one
|
// FIXME: Replace construct-only API with a more generic one
|
||||||
// (probably with bits of introspection)
|
// (probably with bits of introspection)
|
||||||
// Not required for non-user-defined types (GMat, GScalar, etc)
|
// Not required for non-user-defined types (GMat, GScalar, etc)
|
||||||
using HostCtor = util::variant
|
using HostCtor = util::variant
|
||||||
< util::monostate
|
< util::monostate
|
||||||
, detail::ConstructVec
|
, detail::ConstructVec
|
||||||
|
, detail::ConstructOpaque
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using ConstVal = util::variant
|
using ConstVal = util::variant
|
||||||
|
@ -32,6 +32,7 @@ void dumpDot(const ade::Graph &g, std::ostream& os)
|
|||||||
{cv::GShape::GMAT, "GMat"},
|
{cv::GShape::GMAT, "GMat"},
|
||||||
{cv::GShape::GSCALAR, "GScalar"},
|
{cv::GShape::GSCALAR, "GScalar"},
|
||||||
{cv::GShape::GARRAY, "GArray"},
|
{cv::GShape::GARRAY, "GArray"},
|
||||||
|
{cv::GShape::GOPAQUE, "GOpaque"},
|
||||||
};
|
};
|
||||||
|
|
||||||
auto format_op_label = [&gr](ade::NodeHandle nh) -> std::string {
|
auto format_op_label = [&gr](ade::NodeHandle nh) -> std::string {
|
||||||
|
197
modules/gapi/test/gapi_opaque_tests.cpp
Normal file
197
modules/gapi/test/gapi_opaque_tests.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
#include "test_precomp.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace opencv_test
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ThisTest
|
||||||
|
{
|
||||||
|
using GPointOpaque = cv::GOpaque<cv::Point>;
|
||||||
|
|
||||||
|
G_TYPED_KERNEL(GeneratePoint, <GPointOpaque(GMat)>, "test.opaque.gen_point")
|
||||||
|
{
|
||||||
|
static GOpaqueDesc outMeta(const GMatDesc&) { return empty_gopaque_desc(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
G_TYPED_KERNEL(FillMat, <GMat(cv::GOpaque<int>, int, int, cv::Size)>, "test.opaque.fill_mat")
|
||||||
|
{
|
||||||
|
static GMatDesc outMeta(const GOpaqueDesc&, int depth, int chan, cv::Size size)
|
||||||
|
{
|
||||||
|
return cv::GMatDesc{depth, chan, size};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
G_TYPED_KERNEL(PaintPoint, <GMat(GPointOpaque, int, int, cv::Size)>, "test.opaque.paint_point")
|
||||||
|
{
|
||||||
|
static GMatDesc outMeta(const GOpaqueDesc&, int depth, int chan, cv::Size size)
|
||||||
|
{
|
||||||
|
return cv::GMatDesc{depth, chan, size};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MyCustomType{
|
||||||
|
int num;
|
||||||
|
std::string s;
|
||||||
|
};
|
||||||
|
|
||||||
|
using GOpaq2 = std::tuple<GOpaque<MyCustomType>,GOpaque<MyCustomType>>;
|
||||||
|
|
||||||
|
G_TYPED_KERNEL_M(GenerateOpaque, <GOpaq2(GMat, GMat, std::string)>, "test.opaque.gen_point_multy")
|
||||||
|
{
|
||||||
|
static std::tuple<GOpaqueDesc, GOpaqueDesc> outMeta(const GMatDesc&, const GMatDesc&, std::string)
|
||||||
|
{
|
||||||
|
return std::make_tuple(empty_gopaque_desc(), empty_gopaque_desc());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ThisTest
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
GAPI_OCV_KERNEL(OCVGeneratePoint, ThisTest::GeneratePoint)
|
||||||
|
{
|
||||||
|
static void run(const cv::Mat&, cv::Point& out)
|
||||||
|
{
|
||||||
|
out = cv::Point(42, 42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_OCV_KERNEL(OCVFillMat, ThisTest::FillMat)
|
||||||
|
{
|
||||||
|
static void run(int a, int, int, cv::Size, cv::Mat& out)
|
||||||
|
{
|
||||||
|
out = cv::Scalar(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_OCV_KERNEL(OCVPaintPoint, ThisTest::PaintPoint)
|
||||||
|
{
|
||||||
|
static void run(cv::Point a, int, int, cv::Size, cv::Mat& out)
|
||||||
|
{
|
||||||
|
out.at<uint8_t>(a) = 77;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_OCV_KERNEL(OCVGenerateOpaque, ThisTest::GenerateOpaque)
|
||||||
|
{
|
||||||
|
static void run(const cv::Mat& a, const cv::Mat& b, const std::string& s,
|
||||||
|
ThisTest::MyCustomType &out1, ThisTest::MyCustomType &out2)
|
||||||
|
{
|
||||||
|
out1.num = a.size().width * a.size().height;
|
||||||
|
out1.s = s;
|
||||||
|
|
||||||
|
out2.num = b.size().width * b.size().height;
|
||||||
|
auto s2 = s;
|
||||||
|
std::reverse(s2.begin(), s2.end());
|
||||||
|
out2.s = s2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // (anonymous namespace)
|
||||||
|
|
||||||
|
TEST(GOpaque, TestOpaqueOut)
|
||||||
|
{
|
||||||
|
cv::Mat input = cv::Mat(52, 52, CV_8U);
|
||||||
|
cv::Point point;
|
||||||
|
|
||||||
|
cv::GMat in;
|
||||||
|
auto out = ThisTest::GeneratePoint::on(in);
|
||||||
|
|
||||||
|
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||||
|
c.apply(cv::gin(input), cv::gout(point), cv::compile_args(cv::gapi::kernels<OCVGeneratePoint>()));
|
||||||
|
|
||||||
|
EXPECT_TRUE(point == cv::Point(42, 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GOpaque, TestOpaqueIn)
|
||||||
|
{
|
||||||
|
cv::Size sz = {42, 42};
|
||||||
|
int depth = CV_8U;
|
||||||
|
int chan = 1;
|
||||||
|
cv::Mat mat = cv::Mat(sz, CV_MAKETYPE(depth, chan));
|
||||||
|
int fill = 0;
|
||||||
|
|
||||||
|
cv::GOpaque<int> in;
|
||||||
|
auto out = ThisTest::FillMat::on(in, depth, chan, sz);
|
||||||
|
|
||||||
|
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||||
|
c.apply(cv::gin(fill), cv::gout(mat), cv::compile_args(cv::gapi::kernels<OCVFillMat>()));
|
||||||
|
|
||||||
|
auto diff = cv::Mat(sz, CV_MAKETYPE(depth, chan), cv::Scalar(fill)) - mat;
|
||||||
|
EXPECT_EQ(cv::countNonZero(diff), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GOpaque, TestOpaqueBetween)
|
||||||
|
{
|
||||||
|
cv::Size sz = {50, 50};
|
||||||
|
int depth = CV_8U;
|
||||||
|
int chan = 1;
|
||||||
|
cv::Mat mat_in = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
|
||||||
|
cv::Mat mat_out = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
|
||||||
|
|
||||||
|
cv::GMat in, out;
|
||||||
|
auto betw = ThisTest::GeneratePoint::on(in);
|
||||||
|
out = ThisTest::PaintPoint::on(betw, depth, chan, sz);
|
||||||
|
|
||||||
|
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||||
|
c.apply(cv::gin(mat_in), cv::gout(mat_out), cv::compile_args(cv::gapi::kernels<OCVGeneratePoint, OCVPaintPoint>()));
|
||||||
|
|
||||||
|
int painted = mat_out.at<uint8_t>(42, 42);
|
||||||
|
EXPECT_EQ(painted, 77);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GOpaque, TestOpaqueCustomOut2)
|
||||||
|
{
|
||||||
|
cv::Mat input1 = cv::Mat(52, 52, CV_8U);
|
||||||
|
cv::Mat input2 = cv::Mat(42, 42, CV_8U);
|
||||||
|
std::string str = "opaque";
|
||||||
|
std::string str2 = str;
|
||||||
|
std::reverse(str2.begin(), str2.end());
|
||||||
|
|
||||||
|
ThisTest::MyCustomType out1, out2;
|
||||||
|
|
||||||
|
cv::GMat in1, in2;
|
||||||
|
auto out = ThisTest::GenerateOpaque::on(in1, in2, str);
|
||||||
|
|
||||||
|
cv::GComputation c(cv::GIn(in1, in2), cv::GOut(std::get<0>(out), std::get<1>(out)));
|
||||||
|
c.apply(cv::gin(input1, input2), cv::gout(out1, out2), cv::compile_args(cv::gapi::kernels<OCVGenerateOpaque>()));
|
||||||
|
|
||||||
|
EXPECT_EQ(out1.num, input1.size().width * input1.size().height);
|
||||||
|
EXPECT_EQ(out1.s, str);
|
||||||
|
|
||||||
|
EXPECT_EQ(out2.num, input2.size().width * input2.size().height);
|
||||||
|
EXPECT_EQ(out2.s, str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GOpaque_OpaqueRef, TestMov)
|
||||||
|
{
|
||||||
|
// Warning: this test is testing some not-very-public APIs
|
||||||
|
// Test how OpaqueRef's mov() (aka poor man's move()) is working.
|
||||||
|
|
||||||
|
using I = std::string;
|
||||||
|
|
||||||
|
std::string str = "this string must be long due to short string optimization";
|
||||||
|
const I gold(str);
|
||||||
|
|
||||||
|
I test = gold;
|
||||||
|
const char* ptr = test.data();
|
||||||
|
|
||||||
|
cv::detail::OpaqueRef ref(test);
|
||||||
|
cv::detail::OpaqueRef mov;
|
||||||
|
mov.reset<I>();
|
||||||
|
|
||||||
|
EXPECT_EQ(gold, ref.rref<I>()); // ref = gold
|
||||||
|
|
||||||
|
mov.mov(ref);
|
||||||
|
EXPECT_EQ(gold, mov.rref<I>()); // mov obtained the data
|
||||||
|
EXPECT_EQ(ptr, mov.rref<I>().data()); // pointer is unchanged (same data)
|
||||||
|
EXPECT_EQ(test, ref.rref<I>()); // ref = test
|
||||||
|
EXPECT_NE(test, mov.rref<I>()); // ref lost the data
|
||||||
|
}
|
||||||
|
} // namespace opencv_test
|
@ -22,10 +22,27 @@ using GMat2 = std::tuple<GMat, GMat>;
|
|||||||
using GMat3 = std::tuple<GMat, GMat, GMat>;
|
using GMat3 = std::tuple<GMat, GMat, GMat>;
|
||||||
using GScalar = cv::GScalar;
|
using GScalar = cv::GScalar;
|
||||||
template <typename T> using GArray = cv::GArray<T>;
|
template <typename T> using GArray = cv::GArray<T>;
|
||||||
|
template <typename T> using GOpaque = cv::GOpaque<T>;
|
||||||
|
|
||||||
using ArrayT = int;
|
using ArrayT = int;
|
||||||
using WrongArrayT = char;
|
using WrongArrayT = char;
|
||||||
|
|
||||||
|
struct CustomType{
|
||||||
|
cv::Mat mat;
|
||||||
|
int i;
|
||||||
|
void *v;
|
||||||
|
CustomType* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnotherCustomType{
|
||||||
|
cv::Mat mat;
|
||||||
|
int i;
|
||||||
|
void *v;
|
||||||
|
};
|
||||||
|
|
||||||
|
using OpaqueT = CustomType;
|
||||||
|
using WrongOpaqueT = AnotherCustomType;
|
||||||
|
|
||||||
GAPI_TRANSFORM(gmat_in_gmat_out, <GMat(GMat)>, "gmat_in_gmat_out")
|
GAPI_TRANSFORM(gmat_in_gmat_out, <GMat(GMat)>, "gmat_in_gmat_out")
|
||||||
{
|
{
|
||||||
static GMat pattern(GMat) { return {}; }
|
static GMat pattern(GMat) { return {}; }
|
||||||
@ -92,6 +109,36 @@ GAPI_TRANSFORM(gmat_gsc_garray_in_gmat2_out, <GMat2(GMat, GScalar, GArray<ArrayT
|
|||||||
static GMat2 substitute(GMat, GScalar, GArray<ArrayT>) { return {}; }
|
static GMat2 substitute(GMat, GScalar, GArray<ArrayT>) { return {}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GAPI_TRANSFORM(gop_in_gmat_out, <GMat(GOpaque<OpaqueT>)>, "gop_in_gmat_out")
|
||||||
|
{
|
||||||
|
static GMat pattern(GOpaque<OpaqueT>) { return {}; }
|
||||||
|
static GMat substitute(GOpaque<OpaqueT>) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_TRANSFORM(gmat_in_gop_out, <GOpaque<OpaqueT>(GMat)>, "gmat_in_gop_out")
|
||||||
|
{
|
||||||
|
static GOpaque<OpaqueT> pattern(GMat) { return {}; }
|
||||||
|
static GOpaque<OpaqueT> substitute(GMat) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_TRANSFORM(gop_in_gscalar_out, <GScalar(GOpaque<OpaqueT>)>, "gop_in_gscalar_out")
|
||||||
|
{
|
||||||
|
static GScalar pattern(GOpaque<OpaqueT>) { return {}; }
|
||||||
|
static GScalar substitute(GOpaque<OpaqueT>) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_TRANSFORM(gscalar_in_gop_out, <GOpaque<OpaqueT>(GScalar)>, "gscalar_in_gop_out")
|
||||||
|
{
|
||||||
|
static GOpaque<OpaqueT> pattern(GScalar) { return {}; }
|
||||||
|
static GOpaque<OpaqueT> substitute(GScalar) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
GAPI_TRANSFORM(gmat_gsc_gopaque_in_gmat2_out, <GMat2(GMat, GScalar, GOpaque<OpaqueT>)>, "gmat_gsc_gopaque_in_gmat2_out")
|
||||||
|
{
|
||||||
|
static GMat2 pattern(GMat, GScalar, GOpaque<OpaqueT>) { return {}; }
|
||||||
|
static GMat2 substitute(GMat, GScalar, GOpaque<OpaqueT>) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
TEST(KernelPackageTransform, CreatePackage)
|
TEST(KernelPackageTransform, CreatePackage)
|
||||||
@ -108,10 +155,15 @@ TEST(KernelPackageTransform, CreatePackage)
|
|||||||
, garr_in_gscalar_out
|
, garr_in_gscalar_out
|
||||||
, gscalar_in_garr_out
|
, gscalar_in_garr_out
|
||||||
, gmat_gsc_garray_in_gmat2_out
|
, gmat_gsc_garray_in_gmat2_out
|
||||||
|
, gop_in_gmat_out
|
||||||
|
, gmat_in_gop_out
|
||||||
|
, gop_in_gscalar_out
|
||||||
|
, gscalar_in_gop_out
|
||||||
|
, gmat_gsc_gopaque_in_gmat2_out
|
||||||
>();
|
>();
|
||||||
|
|
||||||
auto tr = pkg.get_transformations();
|
auto tr = pkg.get_transformations();
|
||||||
EXPECT_EQ(11u, tr.size());
|
EXPECT_EQ(16u, tr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(KernelPackageTransform, Include)
|
TEST(KernelPackageTransform, Include)
|
||||||
@ -164,6 +216,29 @@ TEST(KernelPackageTransform, gmat_gsc_garray_in_gmat2_out)
|
|||||||
check(tr.substitute());
|
check(tr.substitute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(KernelPackageTransform, gmat_gsc_gopaque_in_gmat2_out)
|
||||||
|
{
|
||||||
|
auto tr = gmat_gsc_gopaque_in_gmat2_out::transformation();
|
||||||
|
|
||||||
|
auto check = [](const cv::GComputation &comp){
|
||||||
|
const auto &p = comp.priv();
|
||||||
|
EXPECT_EQ(3u, p.m_ins.size());
|
||||||
|
EXPECT_EQ(2u, p.m_outs.size());
|
||||||
|
|
||||||
|
EXPECT_TRUE(ProtoContainsT<GMat>(p.m_ins[0]));
|
||||||
|
EXPECT_TRUE(ProtoContainsT<GScalar>(p.m_ins[1]));
|
||||||
|
EXPECT_TRUE(ProtoContainsT<cv::detail::GOpaqueU>(p.m_ins[2]));
|
||||||
|
EXPECT_TRUE(cv::util::get<cv::detail::GOpaqueU>(p.m_ins[2]).holds<OpaqueT>());
|
||||||
|
EXPECT_FALSE(cv::util::get<cv::detail::GOpaqueU>(p.m_ins[2]).holds<WrongOpaqueT>());
|
||||||
|
|
||||||
|
EXPECT_TRUE(ProtoContainsT<GMat>(p.m_outs[0]));
|
||||||
|
EXPECT_TRUE(ProtoContainsT<GMat>(p.m_outs[1]));
|
||||||
|
};
|
||||||
|
|
||||||
|
check(tr.pattern());
|
||||||
|
check(tr.substitute());
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template<typename ArgT>
|
template<typename ArgT>
|
||||||
@ -176,7 +251,17 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename ArgT>
|
template<typename ArgT>
|
||||||
typename std::enable_if<(cv::detail::GTypeTraits<ArgT>::kind != cv::detail::ArgKind::GARRAY), void>::type
|
typename std::enable_if<(cv::detail::GTypeTraits<ArgT>::kind == cv::detail::ArgKind::GOPAQUE), void>::type
|
||||||
|
arg_check(const cv::GProtoArg &arg)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(ProtoContainsT<cv::detail::GOpaqueU>(arg));
|
||||||
|
EXPECT_TRUE(cv::util::get<cv::detail::GOpaqueU>(arg).holds<OpaqueT>());
|
||||||
|
EXPECT_FALSE(cv::util::get<cv::detail::GOpaqueU>(arg).holds<WrongOpaqueT>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ArgT>
|
||||||
|
typename std::enable_if<(cv::detail::GTypeTraits<ArgT>::kind != cv::detail::ArgKind::GARRAY &&
|
||||||
|
cv::detail::GTypeTraits<ArgT>::kind != cv::detail::ArgKind::GOPAQUE), void>::type
|
||||||
arg_check(const cv::GProtoArg &arg)
|
arg_check(const cv::GProtoArg &arg)
|
||||||
{
|
{
|
||||||
EXPECT_TRUE(ProtoContainsT<ArgT>(arg));
|
EXPECT_TRUE(ProtoContainsT<ArgT>(arg));
|
||||||
@ -242,4 +327,24 @@ TEST(KernelPackageTransform, gscalar_in_garr_out)
|
|||||||
transformTest<gscalar_in_garr_out, GScalar, GArray<ArrayT>>();
|
transformTest<gscalar_in_garr_out, GScalar, GArray<ArrayT>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(KernelPackageTransform, gop_in_gmat_out)
|
||||||
|
{
|
||||||
|
transformTest<gop_in_gmat_out, GOpaque<OpaqueT>, GMat>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(KernelPackageTransform, gmat_in_gop_out)
|
||||||
|
{
|
||||||
|
transformTest<gmat_in_gop_out, GMat, GOpaque<OpaqueT>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(KernelPackageTransform, gop_in_gscalar_out)
|
||||||
|
{
|
||||||
|
transformTest<gop_in_gscalar_out, GOpaque<OpaqueT>, GScalar>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(KernelPackageTransform, gscalar_in_gop_out)
|
||||||
|
{
|
||||||
|
transformTest<gscalar_in_gop_out, GScalar, GOpaque<OpaqueT>>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace opencv_test
|
} // namespace opencv_test
|
||||||
|
@ -37,6 +37,10 @@ using GArg_Test_Types = ::testing::Types
|
|||||||
, Expected<cv::GArray<float>, cv::detail::ArgKind::GARRAY>
|
, Expected<cv::GArray<float>, cv::detail::ArgKind::GARRAY>
|
||||||
, Expected<cv::GArray<cv::Point>, cv::detail::ArgKind::GARRAY>
|
, Expected<cv::GArray<cv::Point>, cv::detail::ArgKind::GARRAY>
|
||||||
, Expected<cv::GArray<cv::Rect>, cv::detail::ArgKind::GARRAY>
|
, Expected<cv::GArray<cv::Rect>, cv::detail::ArgKind::GARRAY>
|
||||||
|
, Expected<cv::GOpaque<int>, cv::detail::ArgKind::GOPAQUE>
|
||||||
|
, Expected<cv::GOpaque<float>, cv::detail::ArgKind::GOPAQUE>
|
||||||
|
, Expected<cv::GOpaque<cv::Point>, cv::detail::ArgKind::GOPAQUE>
|
||||||
|
, Expected<cv::GOpaque<cv::Rect>, cv::detail::ArgKind::GOPAQUE>
|
||||||
|
|
||||||
// Built-in types
|
// Built-in types
|
||||||
, Expected<int, cv::detail::ArgKind::OPAQUE_VAL>
|
, Expected<int, cv::detail::ArgKind::OPAQUE_VAL>
|
||||||
@ -85,6 +89,11 @@ TEST(GArg, HasWrap)
|
|||||||
"GArray<int> has custom marshalling logic");
|
"GArray<int> has custom marshalling logic");
|
||||||
static_assert(cv::detail::has_custom_wrap<cv::GArray<std::string> >::value,
|
static_assert(cv::detail::has_custom_wrap<cv::GArray<std::string> >::value,
|
||||||
"GArray<int> has custom marshalling logic");
|
"GArray<int> has custom marshalling logic");
|
||||||
|
|
||||||
|
static_assert(cv::detail::has_custom_wrap<cv::GOpaque<int> >::value,
|
||||||
|
"GOpaque<int> has custom marshalling logic");
|
||||||
|
static_assert(cv::detail::has_custom_wrap<cv::GOpaque<std::string> >::value,
|
||||||
|
"GOpaque<int> has custom marshalling logic");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GArg, GArrayU)
|
TEST(GArg, GArrayU)
|
||||||
@ -97,5 +106,15 @@ TEST(GArg, GArrayU)
|
|||||||
EXPECT_NO_THROW(arg2.get<cv::detail::GArrayU>());
|
EXPECT_NO_THROW(arg2.get<cv::detail::GArrayU>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GArg, GOpaqueU)
|
||||||
|
{
|
||||||
|
// Placing a GOpaque<T> into GArg automatically strips it to GOpaqueU
|
||||||
|
cv::GArg arg1 = cv::GArg(cv::GOpaque<int>());
|
||||||
|
EXPECT_NO_THROW(arg1.get<cv::detail::GOpaqueU>());
|
||||||
|
|
||||||
|
cv::GArg arg2 = cv::GArg(cv::GOpaque<cv::Point>());
|
||||||
|
EXPECT_NO_THROW(arg2.get<cv::detail::GOpaqueU>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace opencv_test
|
} // namespace opencv_test
|
||||||
|
Loading…
Reference in New Issue
Block a user