You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			370 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
		
		
			
		
	
	
			370 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
| 
								 
											3 years ago
										 
									 | 
							
								// 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-2020 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/any.hpp>
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/util/variant.hpp>
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/util/throw.hpp>
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/util/type_traits.hpp>
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/own/assert.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/gcommon.hpp>  // OpaqueKind
							 | 
						||
| 
								 | 
							
								#include <opencv2/gapi/garray.hpp>  // TypeHintBase
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 GAPI_EXPORTS_W_SIMPLE 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 {};}
							 | 
						||
| 
								 | 
							
								GAPI_EXPORTS_W 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>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <typename T>
							 | 
						||
| 
								 | 
							
								        void storeKind();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void setKind(cv::detail::OpaqueKind);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        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 = util::decay_t<T>;
							 | 
						||
| 
								 | 
							
								        return dynamic_cast<TypeHint<U>*>(m_hint.get()) != nullptr;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <typename T>
							 | 
						||
| 
								 | 
							
								    void GOpaqueU::specifyType(){
							 | 
						||
| 
								 | 
							
								        m_hint.reset(new TypeHint<util::decay_t<T>>);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <typename T>
							 | 
						||
| 
								 | 
							
								    void GOpaqueU::storeKind(){
							 | 
						||
| 
								 | 
							
								        // FIXME: Add assert here on cv::Mat and cv::Scalar?
							 | 
						||
| 
								 | 
							
								        setKind(cv::detail::GOpaqueTraits<T>::kind);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 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;
							 | 
						||
| 
								 | 
							
								        virtual const void* ptr() const = 0;
							 | 
						||
| 
								 | 
							
								        virtual void set(const cv::util::any &a) = 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());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        virtual const void* ptr() const override { return &rref(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        virtual void set(const cv::util::any &a) override {
							 | 
						||
| 
								 | 
							
								            wref() = util::any_cast<T>(a);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 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;
							 | 
						||
| 
								 | 
							
								        cv::detail::OpaqueKind m_kind = cv::detail::OpaqueKind::CV_UNKNOWN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<typename T> inline void check() const
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            GAPI_DbgAssert(dynamic_cast<OpaqueRefT<T>*>(m_ref.get()) != nullptr);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								        OpaqueRef() = default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<
							 | 
						||
| 
								 | 
							
								            typename T,
							 | 
						||
| 
								 | 
							
								            typename = util::are_different_t<OpaqueRef, T>
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								        // FIXME: probably won't work with const object
							 | 
						||
| 
								 | 
							
								        explicit OpaqueRef(T&& obj) :
							 | 
						||
| 
								 | 
							
								            m_ref(new OpaqueRefT<util::decay_t<T>>(std::forward<T>(obj))),
							 | 
						||
| 
								 | 
							
								            m_kind(GOpaqueTraits<util::decay_t<T>>::kind) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        cv::detail::OpaqueKind getKind() const
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return m_kind;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<typename T> void reset()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (!m_ref) m_ref.reset(new OpaqueRefT<T>());
							 | 
						||
| 
								 | 
							
								            check<T>();
							 | 
						||
| 
								 | 
							
								            storeKind<T>();
							 | 
						||
| 
								 | 
							
								            static_cast<OpaqueRefT<T>&>(*m_ref).reset();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <typename T>
							 | 
						||
| 
								 | 
							
								        void storeKind()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            m_kind = cv::detail::GOpaqueTraits<T>::kind;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        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;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // May be used to uniquely identify this object internally
							 | 
						||
| 
								 | 
							
								        const void *ptr() const { return m_ref->ptr(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Introduced for in-graph meta handling
							 | 
						||
| 
								 | 
							
								        OpaqueRef& operator= (const cv::util::any &a)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            m_ref->set(a);
							 | 
						||
| 
								 | 
							
								            return *this;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								} // namespace detail
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** \addtogroup gapi_data_objects
							 | 
						||
| 
								 | 
							
								 * @{
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief `cv::GOpaque<T>` template class represents an object of
							 | 
						||
| 
								 | 
							
								 * class `T` in the graph.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * `cv::GOpaque<T>` describes a functional relationship between operations
							 | 
						||
| 
								 | 
							
								 * consuming and producing object of class `T`. `cv::GOpaque<T>` is
							 | 
						||
| 
								 | 
							
								 * designed to extend G-API with user-defined data types, which are
							 | 
						||
| 
								 | 
							
								 * often required with user-defined operations. G-API can't apply any
							 | 
						||
| 
								 | 
							
								 * optimizations to user-defined types since these types are opaque to
							 | 
						||
| 
								 | 
							
								 * the framework. However, there is a number of G-API operations
							 | 
						||
| 
								 | 
							
								 * declared with `cv::GOpaque<T>` as a return type,
							 | 
						||
| 
								 | 
							
								 * e.g. cv::gapi::streaming::timestamp() or cv::gapi::streaming::size().
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @sa `cv::GArray<T>`
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<typename T> class GOpaque
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    // Host type (or Flat type) - the type this GOpaque is actually
							 | 
						||
| 
								 | 
							
								    // specified to.
							 | 
						||
| 
								 | 
							
								    /// @private
							 | 
						||
| 
								 | 
							
								    using HT = typename detail::flatten_g<util::decay_t<T>>::type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @brief Constructs an empty `cv::GOpaque<T>`
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * Normally, empty G-API data objects denote a starting point of
							 | 
						||
| 
								 | 
							
								     * the graph. When an empty `cv::GOpaque<T>` is assigned to a result
							 | 
						||
| 
								 | 
							
								     * of some operation, it obtains a functional link to this
							 | 
						||
| 
								 | 
							
								     * operation (and is not empty anymore).
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    GOpaque() { putDetails(); }              // Empty constructor
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// @private
							 | 
						||
| 
								 | 
							
								    explicit GOpaque(detail::GOpaqueU &&ref) // GOpaqueU-based constructor
							 | 
						||
| 
								 | 
							
								        : m_ref(ref) { putDetails(); }       // (used by GCall, not for users)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// @private
							 | 
						||
| 
								 | 
							
								    detail::GOpaqueU strip() const {
							 | 
						||
| 
								 | 
							
								        return m_ref;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /// @private
							 | 
						||
| 
								 | 
							
								    static void Ctor(detail::OpaqueRef& ref) {
							 | 
						||
| 
								 | 
							
								        ref.reset<HT>();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    void putDetails() {
							 | 
						||
| 
								 | 
							
								        m_ref.setConstructFcn(&Ctor);
							 | 
						||
| 
								 | 
							
								        m_ref.specifyType<HT>();
							 | 
						||
| 
								 | 
							
								        m_ref.storeKind<HT>();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    detail::GOpaqueU m_ref;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** @} */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace cv
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // OPENCV_GAPI_GOPAQUE_HPP
							 |