Allintra: Delay top-right sync for row-mt

When row-mt is enabled, a thread waits for the encoding of
the top-right superblock to be complete before encoding the
current superblock. This wait time is reduced in allintra
mode, by delaying the sync wait until the data from top-right
superblock is needed. This change is applicable for
resolutions < 4k in speed >= 9 as cost update frequencies
are set to COST_UPD_OFF for these resolutions.

For AVIF still-image encode, an average encode time reduction
of ~6.12% is observed for 360p-720p resolutions with speed=9
and 4 threads.

Change-Id: I3cdeb7ad58df976788cc6bd058184dfc65b63593
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 0e6baae..80eb7f3 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -734,11 +734,36 @@
   }
 }
 
-static AOM_INLINE int is_rtc_mode(const CostUpdateFreq *cost_upd_freq,
-                                  MODE mode) {
-  return ((mode == REALTIME) && cost_upd_freq->coeff >= 2 &&
-          cost_upd_freq->mode >= 2 && cost_upd_freq->mv >= 2 &&
-          cost_upd_freq->dv >= 2);
+// Check if the cost update of symbols mode, coeff and dv are tile or off.
+static AOM_INLINE int is_mode_coeff_dv_upd_freq_tile_or_off(
+    const AV1_COMP *const cpi, const CostUpdateFreq *const cost_upd_freq) {
+  const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
+
+  return ((cost_upd_freq->coeff >= COST_UPD_TILE ||
+           inter_sf->coeff_cost_upd_level == INTERNAL_COST_UPD_OFF) &&
+          (cost_upd_freq->mode >= COST_UPD_TILE ||
+           inter_sf->mode_cost_upd_level == INTERNAL_COST_UPD_OFF) &&
+          (cost_upd_freq->dv >= COST_UPD_TILE ||
+           cpi->sf.intra_sf.dv_cost_upd_level == INTERNAL_COST_UPD_OFF));
+}
+
+// When row-mt is enabled and cost update frequencies are set to off/tile,
+// processing of current SB can start even before processing of top-right SB
+// is finished. This function checks if it is sufficient to wait for top SB
+// to finish processing before current SB starts processing.
+static AOM_INLINE int delay_wait_for_top_right_sb(const AV1_COMP *const cpi) {
+  const MODE mode = cpi->oxcf.mode;
+  if (mode == GOOD) return 0;
+
+  const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq;
+  if (mode == ALLINTRA)
+    return is_mode_coeff_dv_upd_freq_tile_or_off(cpi, cost_upd_freq);
+  else if (mode == REALTIME)
+    return (is_mode_coeff_dv_upd_freq_tile_or_off(cpi, cost_upd_freq) &&
+            (cost_upd_freq->mv >= COST_UPD_TILE ||
+             cpi->sf.inter_sf.mv_cost_upd_level == INTERNAL_COST_UPD_OFF));
+  else
+    return 0;
 }
 
 /*!\brief Encode a superblock row by breaking it into superblocks
@@ -766,8 +791,6 @@
   const int mib_size_log2 = cm->seq_params->mib_size_log2;
   const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
   const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
-  const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq;
-  const int rtc_mode = is_rtc_mode(cost_upd_freq, cpi->oxcf.mode);
 
 #if CONFIG_COLLECT_COMPONENT_TIMING
   start_timing(cpi, encode_sb_row_time);
@@ -790,11 +813,11 @@
   // Code each SB in the row
   for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0;
        mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) {
-    // In realtime mode and when frequency of cost updates is off/tile, wait for
-    // the top superblock to finish encoding. Otherwise, wait for the top-right
-    // superblock to finish encoding.
-    (*(enc_row_mt->sync_read_ptr))(row_mt_sync, sb_row,
-                                   sb_col_in_tile - rtc_mode);
+    // In realtime/allintra mode and when frequency of cost updates is off/tile,
+    // wait for the top superblock to finish encoding. Otherwise, wait for the
+    // top-right superblock to finish encoding.
+    (*(enc_row_mt->sync_read_ptr))(
+        row_mt_sync, sb_row, sb_col_in_tile - delay_wait_for_top_right_sb(cpi));
     const int update_cdf = tile_data->allow_update_cdf && row_mt_enabled;
     if (update_cdf && (tile_info->mi_row_start != mi_row)) {
       if ((tile_info->mi_col_start == mi_col)) {
@@ -904,8 +927,6 @@
   TokenList *tplist = token_info->tplist[0][0];
   unsigned int tile_tok = 0;
   int tplist_count = 0;
-  const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq;
-  const int rtc_mode = is_rtc_mode(cost_upd_freq, cpi->oxcf.mode);
 
   if (!is_stat_generation_stage(cpi) &&
       cm->features.allow_screen_content_tools) {
@@ -949,7 +970,7 @@
       tile_data->allow_update_cdf = !cm->tiles.large_scale;
       tile_data->allow_update_cdf = tile_data->allow_update_cdf &&
                                     !cm->features.disable_cdf_update &&
-                                    !rtc_mode;
+                                    !delay_wait_for_top_right_sb(cpi);
       tile_data->tctx = *cm->fc;
     }
   }
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index f010a20..61aa878 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -713,9 +713,9 @@
     av1_nonrd_pick_intra_mode(cpi, x, rd_cost, bsize, ctx);
 }
 
-// For real time row-mt enabled multi-threaded encoding with cost update
-// frequency set to COST_UPD_TILE/COST_UPD_OFF, tile ctxt is not updated at
-// superblock level. Thus, it is not required for the encoding of top-right
+// For real time/allintra row-mt enabled multi-threaded encoding with cost
+// update frequency set to COST_UPD_TILE/COST_UPD_OFF, tile ctxt is not updated
+// at superblock level. Thus, it is not required for the encoding of top-right
 // superblock be complete for updating tile ctxt. However, when encoding a block
 // whose right edge is also the superblock edge, intra and inter mode evaluation
 // (ref mv list population) require the encoding of the top-right superblock to
@@ -812,8 +812,8 @@
 
   int i;
 
-  // This is only needed for real time row-mt enabled multi-threaded encoding
-  // with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF.
+  // This is only needed for real time/allintra row-mt enabled multi-threaded
+  // encoding with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF.
   wait_for_top_right_sb(&cpi->mt_info.enc_row_mt, &tile_data->row_mt_sync,
                         &tile_data->tile_info, cm->seq_params->sb_size,
                         cm->seq_params->mib_size_log2, bsize, mi_row, mi_col);
@@ -2148,8 +2148,8 @@
   TxfmSearchInfo *txfm_info = &x->txfm_search_info;
   int i;
 
-  // This is only needed for real time row-mt enabled multi-threaded encoding
-  // with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF.
+  // This is only needed for real time/allintra row-mt enabled multi-threaded
+  // encoding with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF.
   wait_for_top_right_sb(&cpi->mt_info.enc_row_mt, &tile_data->row_mt_sync,
                         &tile_data->tile_info, cm->seq_params->sb_size,
                         cm->seq_params->mib_size_log2, bsize, mi_row, mi_col);