diff --git a/modules/gapi/include/opencv2/gapi/garray.hpp b/modules/gapi/include/opencv2/gapi/garray.hpp index d7b365f7f9..17b03332e0 100644 --- a/modules/gapi/include/opencv2/gapi/garray.hpp +++ b/modules/gapi/include/opencv2/gapi/garray.hpp @@ -236,7 +236,7 @@ namespace detail class VectorRef { std::shared_ptr m_ref; - cv::detail::OpaqueKind m_kind; + cv::detail::OpaqueKind m_kind = cv::detail::OpaqueKind::CV_UNKNOWN; template inline void check() const { diff --git a/modules/gapi/include/opencv2/gapi/gopaque.hpp b/modules/gapi/include/opencv2/gapi/gopaque.hpp index 979a9db8c4..f77795c506 100644 --- a/modules/gapi/include/opencv2/gapi/gopaque.hpp +++ b/modules/gapi/include/opencv2/gapi/gopaque.hpp @@ -232,7 +232,7 @@ namespace detail class OpaqueRef { std::shared_ptr m_ref; - cv::detail::OpaqueKind m_kind; + cv::detail::OpaqueKind m_kind = cv::detail::OpaqueKind::CV_UNKNOWN; template inline void check() const { diff --git a/modules/gapi/include/opencv2/gapi/own/cvdefs.hpp b/modules/gapi/include/opencv2/gapi/own/cvdefs.hpp index 9ec0f89ed8..b0c91d3530 100644 --- a/modules/gapi/include/opencv2/gapi/own/cvdefs.hpp +++ b/modules/gapi/include/opencv2/gapi/own/cvdefs.hpp @@ -84,6 +84,16 @@ typedef unsigned short ushort; // cvdef.h: +#ifndef CV_ALWAYS_INLINE +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define CV_ALWAYS_INLINE inline __attribute__((always_inline)) +# elif defined(_MSC_VER) +# define CV_ALWAYS_INLINE __forceinline +# else +# define CV_ALWAYS_INLINE inline +# endif +#endif + #define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) #define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) #define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1) diff --git a/modules/gapi/include/opencv2/gapi/own/saturate.hpp b/modules/gapi/include/opencv2/gapi/own/saturate.hpp index 5b232479ea..74eaecf57e 100644 --- a/modules/gapi/include/opencv2/gapi/own/saturate.hpp +++ b/modules/gapi/include/opencv2/gapi/own/saturate.hpp @@ -11,9 +11,9 @@ #include #include -#include #include +#include namespace cv { namespace gapi { namespace own { //----------------------------- @@ -22,16 +22,12 @@ namespace cv { namespace gapi { namespace own { // //----------------------------- -template -static inline DST saturate(SRC x) +template::value && + std::is_integral::value && + std::is_integral::value> > +static CV_ALWAYS_INLINE DST saturate(SRC x) { - // only integral types please! - GAPI_DbgAssert(std::is_integral::value && - std::is_integral::value); - - if (std::is_same::value) - return static_cast(x); - if (sizeof(DST) > sizeof(SRC)) return static_cast(x); @@ -44,38 +40,35 @@ static inline DST saturate(SRC x) std::numeric_limits::max(): static_cast(x); } +template +static CV_ALWAYS_INLINE T saturate(T x) +{ + return x; +} +template::value, bool> = true > +static CV_ALWAYS_INLINE DST saturate(SRC x, R) +{ + return static_cast(x); +} +template::value && + std::is_integral::value , bool> = true > +static CV_ALWAYS_INLINE DST saturate(SRC x, R) +{ + return saturate(x); +} // Note, that OpenCV rounds differently: // - like std::round() for add, subtract // - like std::rint() for multiply, divide -template -static inline DST saturate(SRC x, R round) +template::value && + std::is_floating_point::value, bool> = true > +static CV_ALWAYS_INLINE DST saturate(SRC x, R round) { - if (std::is_floating_point::value) - { - return static_cast(x); - } - else if (std::is_integral::value) - { - GAPI_DbgAssert(std::is_integral::value && - std::is_integral::value); - return saturate(x); - } - else - { - GAPI_DbgAssert(std::is_integral::value && - std::is_floating_point::value); -#ifdef _WIN32 -// Suppress warning about converting x to floating-point -// Note that x is already floating-point at this point -#pragma warning(disable: 4244) -#endif - int ix = static_cast(round(x)); -#ifdef _WIN32 -#pragma warning(default: 4244) -#endif - return saturate(ix); - } + int ix = static_cast(round(x)); + return saturate(ix); } // explicit suffix 'd' for double type diff --git a/modules/gapi/src/backends/common/serialization.cpp b/modules/gapi/src/backends/common/serialization.cpp index 619b2feb74..638ce2f025 100644 --- a/modules/gapi/src/backends/common/serialization.cpp +++ b/modules/gapi/src/backends/common/serialization.cpp @@ -928,7 +928,7 @@ IIStream& ByteMemoryInStream::operator>> (std::string& str) { if (sz == 0u) { str.clear(); } else { - str.resize(sz); + str.resize(static_cast(sz)); for (auto &&i : ade::util::iota(sz)) { *this >> str[i]; } } return *this; diff --git a/modules/gapi/src/backends/fluid/gfluidcore.cpp b/modules/gapi/src/backends/fluid/gfluidcore.cpp index d68ae733dd..7a3d90acc7 100644 --- a/modules/gapi/src/backends/fluid/gfluidcore.cpp +++ b/modules/gapi/src/backends/fluid/gfluidcore.cpp @@ -1955,93 +1955,122 @@ GAPI_FLUID_KERNEL(GFluidLUT, cv::gapi::core::GLUT, false) // //------------------------- +#if CV_SIMD128 +template +CV_ALWAYS_INLINE int run_convertto_simd(DST*, const SRC*, int) +{ + return 0; +} +CV_ALWAYS_INLINE int run_convertto_simd(uchar *out, const float *in, const int length) +{ + int l = 0; + for (; l <= length - 16; l += 16) + { + v_int32x4 i0, i1, i2, i3; + i0 = v_round( v_load( (float*)& in[l ] ) ); + i1 = v_round( v_load( (float*)& in[l + 4] ) ); + i2 = v_round( v_load( (float*)& in[l + 8] ) ); + i3 = v_round( v_load( (float*)& in[l + 12] ) ); + + v_uint16x8 us0, us1; + us0 = v_pack_u(i0, i1); + us1 = v_pack_u(i2, i3); + + v_uint8x16 uc; + uc = v_pack(us0, us1); + v_store((uchar*)& out[l], uc); + } + return l; +} +CV_ALWAYS_INLINE int run_convertto_simd(ushort *out, const float *in, const int length) +{ + int l = 0; + for (; l <= length - 8; l += 8) + { + v_int32x4 i0, i1; + i0 = v_round( v_load( (float*)& in[l ] ) ); + i1 = v_round( v_load( (float*)& in[l + 4] ) ); + + v_uint16x8 us; + us = v_pack_u(i0, i1); + v_store((ushort*)& out[l], us); + } + return l; +} +#endif + +template::value && + std::is_floating_point::value, bool> = true > +CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length) +{ + // manual SIMD if need rounding + static_assert(std::is_same::value, "64-bit floating-point source is not supported"); + int l = 0; // cycle index +#if CV_SIMD128 + l = run_convertto_simd(out, in, length); +#endif + // tail of SIMD cycle + for (; l < length; l++) + { + out[l] = saturate(in[l], rintf); + } +} +template::value && + std::is_integral::value , bool> = true > +CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length) +{ + for (int l = 0; l < length; l++) + { + out[l] = saturate(in[l]); + } +} +template::value, bool> = true > +CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length) +{ + static_assert(!std::is_same::value, "64-bit floating-point source is not supported"); + for (int l = 0; l < length; l++) + { + out[l] = static_cast(in[l]); + } +} + +template +CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const float alpha, const float beta, + const int length) +{ + static_assert(!std::is_same::value, "64-bit floating-point source is not supported"); + // TODO: optimize if alpha and beta and data are integral + for (int l = 0; l < length; l++) + { + out[l] = saturate(in[l] * alpha + beta, rintf); + } +} + template static void run_convertto(Buffer &dst, const View &src, double _alpha, double _beta) { const auto *in = src.InLine(0); auto *out = dst.OutLine(); - int width = dst.length(); - int chan = dst.meta().chan; - int length = width * chan; + const int width = dst.length(); + const int chan = dst.meta().chan; + const int length = width * chan; // NB: don't do this if SRC or DST is 64-bit - auto alpha = static_cast( _alpha ); - auto beta = static_cast( _beta ); + const auto alpha = static_cast( _alpha ); + const auto beta = static_cast( _beta ); // compute faster if no alpha no beta - if (alpha == 1 && beta == 0) + if (1.f == alpha && 0.f == beta) { - // manual SIMD if need rounding - if (std::is_integral::value && std::is_floating_point::value) - { - GAPI_Assert(( std::is_same::value )); - - int l = 0; // cycle index - - #if CV_SIMD128 - if (std::is_same::value) - { - for (; l <= length-16; l+=16) - { - v_int32x4 i0, i1, i2, i3; - i0 = v_round( v_load( (float*)& in[l ] ) ); - i1 = v_round( v_load( (float*)& in[l + 4] ) ); - i2 = v_round( v_load( (float*)& in[l + 8] ) ); - i3 = v_round( v_load( (float*)& in[l + 12] ) ); - - v_uint16x8 us0, us1; - us0 = v_pack_u(i0, i1); - us1 = v_pack_u(i2, i3); - - v_uint8x16 uc; - uc = v_pack(us0, us1); - v_store((uchar*)& out[l], uc); - } - } - if (std::is_same::value) - { - for (; l <= length-8; l+=8) - { - v_int32x4 i0, i1; - i0 = v_round( v_load( (float*)& in[l ] ) ); - i1 = v_round( v_load( (float*)& in[l + 4] ) ); - - v_uint16x8 us; - us = v_pack_u(i0, i1); - v_store((ushort*)& out[l], us); - } - } - #endif - - // tail of SIMD cycle - for (; l < length; l++) - { - out[l] = saturate(in[l], rintf); - } - } - else if (std::is_integral::value) // here SRC is integral - { - for (int l=0; l < length; l++) - { - out[l] = saturate(in[l]); - } - } - else // DST is floating-point, SRC is any - { - for (int l=0; l < length; l++) - { - out[l] = static_cast(in[l]); - } - } + run_convertto(out, in, length); } else // if alpha or beta is non-trivial { - // TODO: optimize if alpha and beta and data are integral - for (int l=0; l < length; l++) - { - out[l] = saturate(in[l]*alpha + beta, rintf); - } + run_convertto(out, in, alpha, beta, length); } } diff --git a/modules/gapi/src/executor/gstreamingexecutor.cpp b/modules/gapi/src/executor/gstreamingexecutor.cpp index ef93833143..d15e17ea28 100644 --- a/modules/gapi/src/executor/gstreamingexecutor.cpp +++ b/modules/gapi/src/executor/gstreamingexecutor.cpp @@ -24,6 +24,8 @@ #include "backends/streaming/gstreamingbackend.hpp" // GCopy #include "compiler/gcompiler.hpp" // for compileIslands +#include + #include "executor/gstreamingexecutor.hpp" #include @@ -1382,8 +1384,16 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr && cv::gimpl::GStreamingExecutor::~GStreamingExecutor() { - if (state == State::READY || state == State::RUNNING) - stop(); + // FIXME: this is a temporary try-catch exception hadling. + // Need to eliminate throwings from stop() + try { + if (state == State::READY || state == State::RUNNING) + stop(); + } catch (const std::exception& e) { + std::stringstream message; + message << "~GStreamingExecutor() threw exception with message '" << e.what() << "'\n"; + GAPI_LOG_WARNING(NULL, message.str()); + } } void cv::gimpl::GStreamingExecutor::setSource(GRunArgs &&ins)