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