@ -13,6 +13,10 @@
# include <opencv2/gapi/opencv_includes.hpp>
# if !defined(GAPI_STANDALONE)
# include <opencv2/gapi/core.hpp> // GCopy -- FIXME - to be removed!
# endif // GAPI_STANDALONE
# include "api/gproto_priv.hpp" // ptr(GRunArgP)
# include "compiler/passes/passes.hpp"
# include "backends/common/gbackend.hpp" // createMat
@ -80,6 +84,10 @@ struct DataQueue {
std : : shared_ptr < cv : : gimpl : : stream : : Q > q ;
} ;
struct DesyncSpecialCase {
static const char * name ( ) { return " DesyncSpecialCase " ; }
} ;
std : : vector < cv : : gimpl : : stream : : Q * > reader_queues ( ade : : Graph & g ,
const ade : : NodeHandle & obj )
{
@ -936,19 +944,53 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
, isl_exec
} ) ;
// Initialize queues for every operation's input
ade : : TypedGraph < DataQueue > qgr ( * m_island_graph ) ;
ade : : TypedGraph < DataQueue , DesyncSpecialCase > qgr ( * m_island_graph ) ;
bool is_desync_start = false ;
for ( auto eh : nh - > inEdges ( ) )
{
// ...only if the data is not compile-const
if ( const_ins . count ( eh - > srcNode ( ) ) = = 0 ) {
if ( m_gim . metadata ( eh ) . contains < DesyncIslEdge > ( ) ) {
qgr . metadata ( eh ) . set ( DataQueue ( DataQueue : : DESYNC ) ) ;
is_desync_start = true ;
} else if ( qgr . metadata ( eh ) . contains < DesyncSpecialCase > ( ) ) {
// See comment below
// Limit queue size to 1 in this case
qgr . metadata ( eh ) . set ( DataQueue ( 1u ) ) ;
} else {
qgr . metadata ( eh ) . set ( DataQueue ( queue_capacity ) ) ;
}
m_internal_queues . insert ( qgr . metadata ( eh ) . get < DataQueue > ( ) . q . get ( ) ) ;
}
}
// WORKAROUND:
// Since now we always know desync() is followed by copy(),
// copy is always the island with DesyncIslEdge.
// Mark the node's outputs a special way so then its following
// queue sizes will be limited to 1 (to avoid copy reading more
// data in advance - as there's no other way for the underlying
// "slow" part to control it)
if ( is_desync_start ) {
auto isl = m_gim . metadata ( nh ) . get < FusedIsland > ( ) . object ;
// In the current implementation, such islands
// _must_ start with copy
GAPI_Assert ( isl - > in_ops ( ) . size ( ) = = 1u ) ;
# if !defined(GAPI_STANDALONE)
GAPI_Assert ( GModel : : Graph ( * m_orig_graph )
. metadata ( * isl - > in_ops ( ) . begin ( ) )
. get < cv : : gimpl : : Op > ( )
. k . name = = cv : : gapi : : core : : GCopy : : id ( ) ) ;
# endif // GAPI_STANDALONE
for ( auto out_nh : nh - > outNodes ( ) ) {
for ( auto out_eh : out_nh - > outEdges ( ) ) {
qgr . metadata ( out_eh ) . set ( DesyncSpecialCase { } ) ;
}
}
}
// It is ok to do it here since the graph is visited in
// a topologic order and its consumers (those checking
// their input edges & initializing queues) are yet to be
// visited
}
break ;
case NodeKind : : SLOT :