github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/gopaque.hpp (about)

     1  // This file is part of OpenCV project.
     2  // It is subject to the license terms in the LICENSE file found in the top-level directory
     3  // of this distribution and at http://opencv.org/license.html.
     4  //
     5  // Copyright (C) 2019-2020 Intel Corporation
     6  
     7  
     8  #ifndef OPENCV_GAPI_GOPAQUE_HPP
     9  #define OPENCV_GAPI_GOPAQUE_HPP
    10  
    11  #include <functional>
    12  #include <ostream>
    13  #include <memory>
    14  
    15  #include <opencv2/gapi/own/exports.hpp>
    16  #include <opencv2/gapi/opencv_includes.hpp>
    17  
    18  #include <opencv2/gapi/util/any.hpp>
    19  #include <opencv2/gapi/util/variant.hpp>
    20  #include <opencv2/gapi/util/throw.hpp>
    21  #include <opencv2/gapi/util/type_traits.hpp>
    22  #include <opencv2/gapi/own/assert.hpp>
    23  
    24  #include <opencv2/gapi/gcommon.hpp>  // OpaqueKind
    25  #include <opencv2/gapi/garray.hpp>  // TypeHintBase
    26  
    27  namespace cv
    28  {
    29  // Forward declaration; GNode and GOrigin are an internal
    30  // (user-inaccessible) classes.
    31  class GNode;
    32  struct GOrigin;
    33  template<typename T> class GOpaque;
    34  
    35  /**
    36   * \addtogroup gapi_meta_args
    37   * @{
    38   */
    39  struct GAPI_EXPORTS_W_SIMPLE GOpaqueDesc
    40  {
    41      // FIXME: Body
    42      // FIXME: Also implement proper operator== then
    43      bool operator== (const GOpaqueDesc&) const { return true; }
    44  };
    45  template<typename U> GOpaqueDesc descr_of(const U &) { return {};}
    46  GAPI_EXPORTS_W inline GOpaqueDesc empty_gopaque_desc() {return {}; }
    47  /** @} */
    48  
    49  std::ostream& operator<<(std::ostream& os, const cv::GOpaqueDesc &desc);
    50  
    51  namespace detail
    52  {
    53      // ConstructOpaque is a callback which stores information about T and is used by
    54      // G-API runtime to construct an object in host memory (T remains opaque for G-API).
    55      // ConstructOpaque is carried into G-API internals by GOpaqueU.
    56      // Currently it is suitable for Host (CPU) plugins only, real offload may require
    57      // more information for manual memory allocation on-device.
    58      class OpaqueRef;
    59      using ConstructOpaque = std::function<void(OpaqueRef&)>;
    60  
    61      // FIXME: garray.hpp already contains hint classes (for actual T type verification),
    62      // need to think where it can be moved (currently opaque uses it from garray)
    63  
    64      // This class strips type information from GOpaque<T> and makes it usable
    65      // in the G-API graph compiler (expression unrolling, graph generation, etc).
    66      // Part of GProtoArg.
    67      class GAPI_EXPORTS GOpaqueU
    68      {
    69      public:
    70          GOpaqueU(const GNode &n, std::size_t out); // Operation result constructor
    71  
    72          template <typename T>
    73          bool holds() const;                       // Check if was created from GOpaque<T>
    74  
    75          GOrigin& priv();                          // Internal use only
    76          const GOrigin& priv() const;              // Internal use only
    77  
    78      protected:
    79          GOpaqueU();                                // Default constructor
    80          template<class> friend class cv::GOpaque;  // (available for GOpaque<T> only)
    81  
    82          void setConstructFcn(ConstructOpaque &&cv);  // Store T-aware constructor
    83  
    84          template <typename T>
    85          void specifyType();                       // Store type of initial GOpaque<T>
    86  
    87          template <typename T>
    88          void storeKind();
    89  
    90          void setKind(cv::detail::OpaqueKind);
    91  
    92          std::shared_ptr<GOrigin> m_priv;
    93          std::shared_ptr<TypeHintBase> m_hint;
    94      };
    95  
    96      template <typename T>
    97      bool GOpaqueU::holds() const{
    98          GAPI_Assert(m_hint != nullptr);
    99          using U = util::decay_t<T>;
   100          return dynamic_cast<TypeHint<U>*>(m_hint.get()) != nullptr;
   101      };
   102  
   103      template <typename T>
   104      void GOpaqueU::specifyType(){
   105          m_hint.reset(new TypeHint<util::decay_t<T>>);
   106      };
   107  
   108      template <typename T>
   109      void GOpaqueU::storeKind(){
   110          // FIXME: Add assert here on cv::Mat and cv::Scalar?
   111          setKind(cv::detail::GOpaqueTraits<T>::kind);
   112      };
   113  
   114      // This class represents a typed object reference.
   115      // Depending on origins, this reference may be either "just a" reference to
   116      // an object created externally, OR actually own the underlying object
   117      // (be value holder).
   118      class BasicOpaqueRef
   119      {
   120      public:
   121          cv::GOpaqueDesc m_desc;
   122          virtual ~BasicOpaqueRef() {}
   123  
   124          virtual void mov(BasicOpaqueRef &ref) = 0;
   125          virtual const void* ptr() const = 0;
   126          virtual void set(const cv::util::any &a) = 0;
   127      };
   128  
   129      template<typename T> class OpaqueRefT final: public BasicOpaqueRef
   130      {
   131          using empty_t  = util::monostate;
   132          using ro_ext_t = const T *;
   133          using rw_ext_t =       T *;
   134          using rw_own_t =       T  ;
   135          util::variant<empty_t, ro_ext_t, rw_ext_t, rw_own_t> m_ref;
   136  
   137          inline bool isEmpty() const { return util::holds_alternative<empty_t>(m_ref);  }
   138          inline bool isROExt() const { return util::holds_alternative<ro_ext_t>(m_ref); }
   139          inline bool isRWExt() const { return util::holds_alternative<rw_ext_t>(m_ref); }
   140          inline bool isRWOwn() const { return util::holds_alternative<rw_own_t>(m_ref); }
   141  
   142          void init(const T* obj = nullptr)
   143          {
   144              if (obj) m_desc = cv::descr_of(*obj);
   145          }
   146  
   147      public:
   148          OpaqueRefT() { init(); }
   149          virtual ~OpaqueRefT() {}
   150  
   151          explicit OpaqueRefT(const T&  obj) : m_ref(&obj)           { init(&obj); }
   152          explicit OpaqueRefT(      T&  obj) : m_ref(&obj)           { init(&obj); }
   153          explicit OpaqueRefT(      T&& obj) : m_ref(std::move(obj)) { init(&obj); }
   154  
   155          // Reset a OpaqueRefT. Called only for objects instantiated
   156          // internally in G-API (e.g. temporary GOpaque<T>'s within a
   157          // computation).  Reset here means both initialization
   158          // (creating an object) and reset (discarding its existing
   159          // content before the next execution). Must never be called
   160          // for external OpaqueRefTs.
   161          void reset()
   162          {
   163              if (isEmpty())
   164              {
   165                  T empty_obj{};
   166                  m_desc = cv::descr_of(empty_obj);
   167                  m_ref  = std::move(empty_obj);
   168                  GAPI_Assert(isRWOwn());
   169              }
   170              else if (isRWOwn())
   171              {
   172                  util::get<rw_own_t>(m_ref) = {};
   173              }
   174              else GAPI_Assert(false); // shouldn't be called in *EXT modes
   175          }
   176  
   177          // Obtain a WRITE reference to underlying object
   178          // Used by CPU kernel API wrappers when a kernel execution frame
   179          // is created
   180          T& wref()
   181          {
   182              GAPI_Assert(isRWExt() || isRWOwn());
   183              if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
   184              if (isRWOwn()) return  util::get<rw_own_t>(m_ref);
   185              util::throw_error(std::logic_error("Impossible happened"));
   186          }
   187  
   188          // Obtain a READ reference to underlying object
   189          // Used by CPU kernel API wrappers when a kernel execution frame
   190          // is created
   191          const T& rref() const
   192          {
   193              // ANY object can be accessed for reading, even if it declared for
   194              // output. Example -- a GComputation from [in] to [out1,out2]
   195              // where [out2] is a result of operation applied to [out1]:
   196              //
   197              //            GComputation boundary
   198              //            . . . . . . .
   199              //            .           .
   200              //     [in] ----> foo() ----> [out1]
   201              //            .           .    :
   202              //            .           . . .:. . .
   203              //            .                V    .
   204              //            .              bar() ---> [out2]
   205              //            . . . . . . . . . . . .
   206              //
   207              if (isROExt()) return *util::get<ro_ext_t>(m_ref);
   208              if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
   209              if (isRWOwn()) return  util::get<rw_own_t>(m_ref);
   210              util::throw_error(std::logic_error("Impossible happened"));
   211          }
   212  
   213          virtual void mov(BasicOpaqueRef &v) override {
   214              OpaqueRefT<T> *tv = dynamic_cast<OpaqueRefT<T>*>(&v);
   215              GAPI_Assert(tv != nullptr);
   216              wref() = std::move(tv->wref());
   217          }
   218  
   219          virtual const void* ptr() const override { return &rref(); }
   220  
   221          virtual void set(const cv::util::any &a) override {
   222              wref() = util::any_cast<T>(a);
   223          }
   224      };
   225  
   226      // This class strips type information from OpaqueRefT<> and makes it usable
   227      // in the G-API executables (carrying run-time data/information to kernels).
   228      // Part of GRunArg.
   229      // Its methods are typed proxies to OpaqueRefT<T>.
   230      // OpaqueRef maintains "reference" semantics so two copies of OpaqueRef refer
   231      // to the same underlying object.
   232      class OpaqueRef
   233      {
   234          std::shared_ptr<BasicOpaqueRef> m_ref;
   235          cv::detail::OpaqueKind m_kind;
   236  
   237          template<typename T> inline void check() const
   238          {
   239              GAPI_DbgAssert(dynamic_cast<OpaqueRefT<T>*>(m_ref.get()) != nullptr);
   240          }
   241  
   242      public:
   243          OpaqueRef() = default;
   244  
   245          template<
   246              typename T,
   247              typename = util::are_different_t<OpaqueRef, T>
   248          >
   249          // FIXME: probably won't work with const object
   250          explicit OpaqueRef(T&& obj) :
   251              m_ref(new OpaqueRefT<util::decay_t<T>>(std::forward<T>(obj))),
   252              m_kind(GOpaqueTraits<util::decay_t<T>>::kind) {}
   253  
   254          cv::detail::OpaqueKind getKind() const
   255          {
   256              return m_kind;
   257          }
   258  
   259          template<typename T> void reset()
   260          {
   261              if (!m_ref) m_ref.reset(new OpaqueRefT<T>());
   262              check<T>();
   263              storeKind<T>();
   264              static_cast<OpaqueRefT<T>&>(*m_ref).reset();
   265          }
   266  
   267          template <typename T>
   268          void storeKind()
   269          {
   270              m_kind = cv::detail::GOpaqueTraits<T>::kind;
   271          }
   272  
   273          template<typename T> T& wref()
   274          {
   275              check<T>();
   276              return static_cast<OpaqueRefT<T>&>(*m_ref).wref();
   277          }
   278  
   279          template<typename T> const T& rref() const
   280          {
   281              check<T>();
   282              return static_cast<OpaqueRefT<T>&>(*m_ref).rref();
   283          }
   284  
   285          void mov(OpaqueRef &v)
   286          {
   287              m_ref->mov(*v.m_ref);
   288          }
   289  
   290          cv::GOpaqueDesc descr_of() const
   291          {
   292              return m_ref->m_desc;
   293          }
   294  
   295          // May be used to uniquely identify this object internally
   296          const void *ptr() const { return m_ref->ptr(); }
   297  
   298          // Introduced for in-graph meta handling
   299          OpaqueRef& operator= (const cv::util::any &a)
   300          {
   301              m_ref->set(a);
   302              return *this;
   303          }
   304      };
   305  } // namespace detail
   306  
   307  /** \addtogroup gapi_data_objects
   308   * @{
   309   */
   310  /**
   311   * @brief `cv::GOpaque<T>` template class represents an object of
   312   * class `T` in the graph.
   313   *
   314   * `cv::GOpaque<T>` describes a functional relationship between operations
   315   * consuming and producing object of class `T`. `cv::GOpaque<T>` is
   316   * designed to extend G-API with user-defined data types, which are
   317   * often required with user-defined operations. G-API can't apply any
   318   * optimizations to user-defined types since these types are opaque to
   319   * the framework. However, there is a number of G-API operations
   320   * declared with `cv::GOpaque<T>` as a return type,
   321   * e.g. cv::gapi::streaming::timestamp() or cv::gapi::streaming::size().
   322   *
   323   * @sa `cv::GArray<T>`
   324   */
   325  template<typename T> class GOpaque
   326  {
   327  public:
   328      // Host type (or Flat type) - the type this GOpaque is actually
   329      // specified to.
   330      /// @private
   331      using HT = typename detail::flatten_g<util::decay_t<T>>::type;
   332  
   333      /**
   334       * @brief Constructs an empty `cv::GOpaque<T>`
   335       *
   336       * Normally, empty G-API data objects denote a starting point of
   337       * the graph. When an empty `cv::GOpaque<T>` is assigned to a result
   338       * of some operation, it obtains a functional link to this
   339       * operation (and is not empty anymore).
   340       */
   341      GOpaque() { putDetails(); }              // Empty constructor
   342  
   343      /// @private
   344      explicit GOpaque(detail::GOpaqueU &&ref) // GOpaqueU-based constructor
   345          : m_ref(ref) { putDetails(); }       // (used by GCall, not for users)
   346  
   347      /// @private
   348      detail::GOpaqueU strip() const {
   349          return m_ref;
   350      }
   351      /// @private
   352      static void Ctor(detail::OpaqueRef& ref) {
   353          ref.reset<HT>();
   354      }
   355  private:
   356      void putDetails() {
   357          m_ref.setConstructFcn(&Ctor);
   358          m_ref.specifyType<HT>();
   359          m_ref.storeKind<HT>();
   360      }
   361  
   362      detail::GOpaqueU m_ref;
   363  };
   364  
   365  /** @} */
   366  
   367  } // namespace cv
   368  
   369  #endif // OPENCV_GAPI_GOPAQUE_HPP