Commit 9f41643359 for aom

commit 9f4164335928afb9b17a9f762d8cf540ebfc6834
Author: Frank Galligan <fgalligan@google.com>
Date:   Sat Oct 31 09:54:05 2026 -0700

    av1: Optimize ssim_rdmult and intra_mode_search

    Avoid calling pow(x, 1.0) in av1_set_ssim_rdmult for blocks <= 16x16,
    skip inter-only buffer allocations in allintra mode, copy only the
    active portion of WinnerModeStats in store_winner_mode_stats, hoist
    allowed_mode_mask in av1_rd_pick_intra_sby_mode, and broadcast cached
    CfL DC prediction rows from scalar registers.

    Benchmarking results (incremental vs prev CL / cumulative vs baseline):
    - Stock avifenc still-image (Default 1T): -1.67% / -25.98% encode time
    - Stock avifenc still-image (Default 8T): -2.47% / -21.16% encode time
    - 48-image multi-rate corpus (Full Suite 1T): -1.18% / -26.10% time
    - Bit-exact output (1T and 8T)

    TAG=agy
    CONV=b929a630-a6cd-45a0-979c-1767c30178ee
    Change-Id: I22ee84baa4fa3b6fd5aa84f4ae6400a9c9dd5ef8

diff --git a/av1/common/cfl.c b/av1/common/cfl.c
index 7d4f07f863..25d557d3f9 100644
--- a/av1/common/cfl.c
+++ b/av1/common/cfl.c
@@ -46,18 +46,110 @@ void cfl_store_dc_pred(MACROBLOCKD *const xd, const uint8_t *input,

 static void cfl_load_dc_pred_lbd(const int16_t *dc_pred_cache, uint8_t *dst,
                                  int dst_stride, int width, int height) {
-  for (int j = 0; j < height; j++) {
-    memcpy(dst, dc_pred_cache, width);
-    dst += dst_stride;
+  // Load the cached 1D row into scalar registers once and broadcast across all
+  // height rows to avoid repeated memory reads per row.
+  switch (width) {
+    case 4: {
+      uint32_t v;
+      memcpy(&v, dc_pred_cache, 4);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v, 4);
+        dst += dst_stride;
+      }
+      return;
+    }
+    case 8: {
+      uint64_t v;
+      memcpy(&v, dc_pred_cache, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    case 16: {
+      uint64_t v0, v1;
+      memcpy(&v0, (const uint8_t *)dc_pred_cache, 8);
+      memcpy(&v1, (const uint8_t *)dc_pred_cache + 8, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v0, 8);
+        memcpy(dst + 8, &v1, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    case 32: {
+      uint64_t v0, v1, v2, v3;
+      memcpy(&v0, (const uint8_t *)dc_pred_cache, 8);
+      memcpy(&v1, (const uint8_t *)dc_pred_cache + 8, 8);
+      memcpy(&v2, (const uint8_t *)dc_pred_cache + 16, 8);
+      memcpy(&v3, (const uint8_t *)dc_pred_cache + 24, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v0, 8);
+        memcpy(dst + 8, &v1, 8);
+        memcpy(dst + 16, &v2, 8);
+        memcpy(dst + 24, &v3, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    default:
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, dc_pred_cache, width);
+        dst += dst_stride;
+      }
+      return;
   }
 }

 static void cfl_load_dc_pred_hbd(const int16_t *dc_pred_cache, uint16_t *dst,
                                  int dst_stride, int width, int height) {
-  const size_t num_bytes = width << 1;
-  for (int j = 0; j < height; j++) {
-    memcpy(dst, dc_pred_cache, num_bytes);
-    dst += dst_stride;
+  // Load the cached 1D row into scalar registers once and broadcast across all
+  // height rows to avoid repeated memory reads per row.
+  switch (width) {
+    case 4: {
+      uint64_t v;
+      memcpy(&v, dc_pred_cache, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    case 8: {
+      uint64_t v0, v1;
+      memcpy(&v0, dc_pred_cache, 8);
+      memcpy(&v1, dc_pred_cache + 4, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v0, 8);
+        memcpy(dst + 4, &v1, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    case 16: {
+      uint64_t v0, v1, v2, v3;
+      memcpy(&v0, dc_pred_cache, 8);
+      memcpy(&v1, dc_pred_cache + 4, 8);
+      memcpy(&v2, dc_pred_cache + 8, 8);
+      memcpy(&v3, dc_pred_cache + 12, 8);
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, &v0, 8);
+        memcpy(dst + 4, &v1, 8);
+        memcpy(dst + 8, &v2, 8);
+        memcpy(dst + 12, &v3, 8);
+        dst += dst_stride;
+      }
+      return;
+    }
+    default: {
+      const size_t num_bytes = width << 1;
+      for (int j = 0; j < height; j++) {
+        memcpy(dst, dc_pred_cache, num_bytes);
+        dst += dst_stride;
+      }
+      return;
+    }
   }
 }
 void cfl_load_dc_pred(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 16862d408f..6a49c1127f 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -119,10 +119,10 @@ typedef struct {
   int rate_y;
   //! Chroma rate of the winner mode.
   int rate_uv;
-  //! The color map needed to reconstruct palette mode.
-  uint8_t color_index_map[MAX_SB_SQUARE];
   //! The current winner mode.
   THR_MODES mode_index;
+  //! The color map needed to reconstruct palette mode.
+  uint8_t color_index_map[MAX_SB_SQUARE];
 } WinnerModeStats;

 /*! \brief Each source plane of the current macroblock
@@ -1478,21 +1478,12 @@ static inline void zero_winner_mode_stats(BLOCK_SIZE bsize, int n_stats,
                                           WinnerModeStats *stats) {
   // When winner mode stats are not required, the memory allocation is avoided
   // for x->winner_mode_stats. The stats pointer will be NULL in such cases.
+  (void)bsize;
   if (stats == NULL) return;

-  const int block_height = block_size_high[bsize];
-  const int block_width = block_size_wide[bsize];
   for (int i = 0; i < n_stats; ++i) {
     WinnerModeStats *const stat = &stats[i];
-    memset(&stat->mbmi, 0, sizeof(stat->mbmi));
-    memset(&stat->rd_cost, 0, sizeof(stat->rd_cost));
-    memset(&stat->rd, 0, sizeof(stat->rd));
-    memset(&stat->rate_y, 0, sizeof(stat->rate_y));
-    memset(&stat->rate_uv, 0, sizeof(stat->rate_uv));
-    // Do not reset the whole array as it is CPU intensive.
-    memset(&stat->color_index_map, 0,
-           block_width * block_height * sizeof(stat->color_index_map[0]));
-    memset(&stat->mode_index, 0, sizeof(stat->mode_index));
+    memset(stat, 0, offsetof(WinnerModeStats, color_index_map));
   }
 }

diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index 8e3f387bba..c14a2f783d 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -30,12 +30,7 @@ void av1_set_ssim_rdmult(const AV1_COMP *const cpi, int *errorperbit,
   const int num_mi_w = mi_size_wide[bsize_base];
   const int num_mi_h = mi_size_high[bsize_base];
   const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
-  const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
-  const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
-  int row, col;
-  double num_of_mi = 0.0;
-  double geom_mean_of_scale = 1.0;
+  double geom_mean_of_scale;

   // To avoid overflow of 'geom_mean_of_scale', bsize_base must be at least
   // BLOCK_8X8.
@@ -52,17 +47,30 @@ void av1_set_ssim_rdmult(const AV1_COMP *const cpi, int *errorperbit,
          cpi->oxcf.tune_cfg.tuning == AOM_TUNE_IQ ||
          cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2);

-  for (row = mi_row / num_mi_w;
-       row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
-    for (col = mi_col / num_mi_h;
-         col < num_cols && col < mi_col / num_mi_h + num_bcols; ++col) {
-      const int index = row * num_cols + col;
-      assert(cpi->ssim_rdmult_scaling_factors[index] != 0.0);
-      geom_mean_of_scale *= cpi->ssim_rdmult_scaling_factors[index];
-      num_of_mi += 1.0;
+  if (mi_size_wide[bsize] <= 4 && mi_size_high[bsize] <= 4) {
+    geom_mean_of_scale =
+        cpi->ssim_rdmult_scaling_factors[(mi_row >> 2) * num_cols +
+                                         (mi_col >> 2)];
+  } else {
+    const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
+    const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
+    const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
+    double num_of_mi = 0.0;
+    geom_mean_of_scale = 1.0;
+    for (int row = mi_row / num_mi_w;
+         row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
+      for (int col = mi_col / num_mi_h;
+           col < num_cols && col < mi_col / num_mi_h + num_bcols; ++col) {
+        const int index = row * num_cols + col;
+        assert(cpi->ssim_rdmult_scaling_factors[index] != 0.0);
+        geom_mean_of_scale *= cpi->ssim_rdmult_scaling_factors[index];
+        num_of_mi += 1.0;
+      }
+    }
+    if (num_of_mi > 1.0) {
+      geom_mean_of_scale = pow(geom_mean_of_scale, (1.0 / num_of_mi));
     }
   }
-  geom_mean_of_scale = pow(geom_mean_of_scale, (1.0 / num_of_mi));

   *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
   *rdmult = AOMMAX(*rdmult, 0);
diff --git a/av1/encoder/encodeframe_utils.h b/av1/encoder/encodeframe_utils.h
index c988e018d1..72ae44fea0 100644
--- a/av1/encoder/encodeframe_utils.h
+++ b/av1/encoder/encodeframe_utils.h
@@ -483,9 +483,11 @@ static inline void av1_alloc_mb_data(const AV1_COMP *cpi,

   av1_alloc_src_diff_buf(cm, mb);

-  CHECK_MEM_ERROR(cm, mb->e_mbd.seg_mask,
-                  (uint8_t *)aom_memalign(
-                      16, 2 * MAX_SB_SQUARE * sizeof(mb->e_mbd.seg_mask[0])));
+  if (!frame_is_intra_only(cm)) {
+    CHECK_MEM_ERROR(cm, mb->e_mbd.seg_mask,
+                    (uint8_t *)aom_memalign(
+                        16, 2 * MAX_SB_SQUARE * sizeof(mb->e_mbd.seg_mask[0])));
+  }

   allocate_winner_mode_stats(cpi, mb);

diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 0795123ee3..cd836c578e 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -964,12 +964,27 @@ void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
                     aom_memalign(16, sizeof(*x->palette_buffer)));
   }

-  if (x->tmp_conv_dst == NULL) {
-    CHECK_MEM_ERROR(
-        cm, x->tmp_conv_dst,
-        aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(*x->tmp_conv_dst)));
-    x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
+  if (cpi->oxcf.mode != ALLINTRA) {
+    if (x->tmp_conv_dst == NULL) {
+      CHECK_MEM_ERROR(cm, x->tmp_conv_dst,
+                      aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
+                                           sizeof(*x->tmp_conv_dst)));
+      x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
+    }
+
+    if (x->upsample_pred == NULL) {
+      // The buffer 'upsampled_pred' is used to store the output of horizontal
+      // filtering in aom_(highbd_)upsampled_pred() function. As the length of
+      // the interpolation filter used is SUBPEL_TAPS a buffer size of
+      // (MAX_SB_SIZE + SUBPEL_TAPS) * MAX_SB_SIZE is allocated.
+      CHECK_MEM_ERROR(
+          cm, x->upsample_pred,
+          aom_memalign(16, (1 + is_highbitdepth) * (MAX_SB_SIZE + SUBPEL_TAPS) *
+                               MAX_SB_SIZE * sizeof(*x->upsample_pred)));
+      x->e_mbd.tmp_upsample_pred = x->upsample_pred;
+    }
   }
+
   // The buffers 'tmp_pred_bufs[]' and 'comp_rd_buffer' are used in inter frames
   // to store intermediate inter mode prediction results and are not required
   // for allintra encoding mode. Hence, the memory allocations for these buffers
@@ -988,18 +1003,6 @@ void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
     }
   }

-  if (x->upsample_pred == NULL) {
-    // The buffer 'upsampled_pred' is used to store the output of horizontal
-    // filtering in aom_(highbd_)upsampled_pred() function. As the length of the
-    // interpolation filter used is SUBPEL_TAPS a buffer size of (MAX_SB_SIZE +
-    // SUBPEL_TAPS) * MAX_SB_SIZE is allocated.
-    CHECK_MEM_ERROR(
-        cm, x->upsample_pred,
-        aom_memalign(16, (1 + is_highbitdepth) * (MAX_SB_SIZE + SUBPEL_TAPS) *
-                             MAX_SB_SIZE * sizeof(*x->upsample_pred)));
-    x->e_mbd.tmp_upsample_pred = x->upsample_pred;
-  }
-
   av1_reset_segment_features(cm);

   av1_set_high_precision_mv(cpi, 1, 0);
@@ -1434,15 +1437,17 @@ AV1_PRIMARY *av1_create_primary_compressor(
     enc_set_mb_mi(&mi_params, oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height,
                   BLOCK_4X4);

-    const BLOCK_SIZE bsize = BLOCK_16X16;
-    const int w = mi_size_wide[bsize];
-    const int h = mi_size_high[bsize];
-    const int num_cols = (mi_params.mi_cols + w - 1) / w;
-    const int num_rows = (mi_params.mi_rows + h - 1) / h;
-    AOM_CHECK_MEM_ERROR(
-        &ppi->error, ppi->tpl_sb_rdmult_scaling_factors,
-        aom_calloc(num_rows * num_cols,
-                   sizeof(*ppi->tpl_sb_rdmult_scaling_factors)));
+    if (oxcf->mode != ALLINTRA) {
+      const BLOCK_SIZE bsize = BLOCK_16X16;
+      const int w = mi_size_wide[bsize];
+      const int h = mi_size_high[bsize];
+      const int num_cols = (mi_params.mi_cols + w - 1) / w;
+      const int num_rows = (mi_params.mi_rows + h - 1) / h;
+      AOM_CHECK_MEM_ERROR(
+          &ppi->error, ppi->tpl_sb_rdmult_scaling_factors,
+          aom_calloc(num_rows * num_cols,
+                     sizeof(*ppi->tpl_sb_rdmult_scaling_factors)));
+    }

 #if CONFIG_INTERNAL_STATS
     ppi->b_calculate_blockiness = 1;
@@ -1642,11 +1647,13 @@ AV1_COMP *av1_create_compressor(AV1_PRIMARY *ppi, const AV1EncoderConfig *oxcf,
     max_mi_rows = size_in_mi(oxcf->frm_dim_cfg.forced_max_frame_height);
   }

-  const int consec_zero_mv_alloc_size = (max_mi_rows * max_mi_cols) >> 2;
-  CHECK_MEM_ERROR(
-      cm, cpi->consec_zero_mv,
-      aom_calloc(consec_zero_mv_alloc_size, sizeof(*cpi->consec_zero_mv)));
-  cpi->consec_zero_mv_alloc_size = consec_zero_mv_alloc_size;
+  if (cpi->oxcf.mode != ALLINTRA) {
+    const int consec_zero_mv_alloc_size = (max_mi_rows * max_mi_cols) >> 2;
+    CHECK_MEM_ERROR(
+        cm, cpi->consec_zero_mv,
+        aom_calloc(consec_zero_mv_alloc_size, sizeof(*cpi->consec_zero_mv)));
+    cpi->consec_zero_mv_alloc_size = consec_zero_mv_alloc_size;
+  }

   cpi->mb_weber_stats = NULL;
   cpi->mb_weber_stats_alloc_size = 0;
@@ -3046,11 +3053,13 @@ static int encode_without_recode(AV1_COMP *cpi) {
   cpi->source = av1_realloc_and_scale_if_required(
       cm, unscaled, &cpi->scaled_source, filter_scaler, phase_scaler, true,
       false, cpi->oxcf.border_in_pixels, cpi->alloc_pyramid);
-  if (frame_is_intra_only(cm) || resize_pending != 0) {
+  if (cpi->oxcf.mode != ALLINTRA &&
+      (frame_is_intra_only(cm) || resize_pending != 0 ||
+       cpi->consec_zero_mv == NULL)) {
     const int current_size =
         (cm->mi_params.mi_rows * cm->mi_params.mi_cols) >> 2;
-    if (cpi->consec_zero_mv &&
-        (cpi->consec_zero_mv_alloc_size < current_size)) {
+    if (cpi->consec_zero_mv == NULL ||
+        cpi->consec_zero_mv_alloc_size < current_size) {
       aom_free(cpi->consec_zero_mv);
       cpi->consec_zero_mv_alloc_size = 0;
       CHECK_MEM_ERROR(cm, cpi->consec_zero_mv,
diff --git a/av1/encoder/encoder_alloc.h b/av1/encoder/encoder_alloc.h
index 4ee8301d37..ac1a6508a9 100644
--- a/av1/encoder/encoder_alloc.h
+++ b/av1/encoder/encoder_alloc.h
@@ -82,11 +82,13 @@ static inline void alloc_compressor_data(AV1_COMP *cpi) {
     aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
                        "Failed to allocate SMS tree");
   }
-  cpi->td.firstpass_ctx =
-      av1_alloc_pmc(cpi, BLOCK_16X16, &cpi->td.shared_coeff_buf);
-  if (!cpi->td.firstpass_ctx)
-    aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
-                       "Failed to allocate PICK_MODE_CONTEXT");
+  if (is_stat_generation_stage(cpi) || cpi->ppi->lap_enabled) {
+    cpi->td.firstpass_ctx =
+        av1_alloc_pmc(cpi, BLOCK_16X16, &cpi->td.shared_coeff_buf);
+    if (!cpi->td.firstpass_ctx)
+      aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
+                         "Failed to allocate PICK_MODE_CONTEXT");
+  }
 }

 // Allocate mbmi buffers which are used to store mode information at block
@@ -155,14 +157,16 @@ static inline void alloc_rdmult_scaling_factors(AV1_COMP *cpi) {

   aom_free(cpi->ssim_rdmult_scaling_factors);
   cpi->ssim_rdmult_scaling_factors = NULL;
-  aom_free(cpi->tpl_rdmult_scaling_factors);
-  cpi->tpl_rdmult_scaling_factors = NULL;
   CHECK_MEM_ERROR(cm, cpi->ssim_rdmult_scaling_factors,
-                  aom_calloc(num_rows * num_cols,
+                  aom_malloc(num_rows * num_cols *
                              sizeof(*cpi->ssim_rdmult_scaling_factors)));
-  CHECK_MEM_ERROR(cm, cpi->tpl_rdmult_scaling_factors,
-                  aom_calloc(num_rows * num_cols,
-                             sizeof(*cpi->tpl_rdmult_scaling_factors)));
+  aom_free(cpi->tpl_rdmult_scaling_factors);
+  cpi->tpl_rdmult_scaling_factors = NULL;
+  if (cpi->oxcf.mode != ALLINTRA) {
+    CHECK_MEM_ERROR(cm, cpi->tpl_rdmult_scaling_factors,
+                    aom_calloc(num_rows * num_cols,
+                               sizeof(*cpi->tpl_rdmult_scaling_factors)));
+  }

 #if CONFIG_TUNE_VMAF
   {
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 5a1e8a5627..1690e21878 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -979,11 +979,14 @@ void av1_init_tile_thread_data(AV1_PRIMARY *ppi, int is_first_pass) {
       // Set up shared coeff buffers.
       av1_setup_shared_coeff_buffer(&ppi->seq_params, &td->shared_coeff_buf,
                                     &ppi->error);
-      AOM_CHECK_MEM_ERROR(&ppi->error, td->tmp_conv_dst,
-                          aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
-                                               sizeof(*td->tmp_conv_dst)));
+      if (ppi->cpi->oxcf.mode != ALLINTRA) {
+        AOM_CHECK_MEM_ERROR(&ppi->error, td->tmp_conv_dst,
+                            aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
+                                                 sizeof(*td->tmp_conv_dst)));
+      }

-      if (i < p_mt_info->num_mod_workers[MOD_FP]) {
+      if ((is_first_pass || ppi->lap_enabled) &&
+          i < p_mt_info->num_mod_workers[MOD_FP]) {
         // Set up firstpass PICK_MODE_CONTEXT.
         td->firstpass_ctx =
             av1_alloc_pmc(ppi->cpi, BLOCK_16X16, &td->shared_coeff_buf);
@@ -992,10 +995,13 @@ void av1_init_tile_thread_data(AV1_PRIMARY *ppi, int is_first_pass) {
                              "Failed to allocate PICK_MODE_CONTEXT");
       }

-      AOM_CHECK_MEM_ERROR(
-          &ppi->error, td->upsample_pred,
-          aom_memalign(16, (1 + is_highbitdepth) * (MAX_SB_SIZE + SUBPEL_TAPS) *
-                               MAX_SB_SIZE * sizeof(*td->upsample_pred)));
+      if (ppi->cpi->oxcf.mode != ALLINTRA) {
+        AOM_CHECK_MEM_ERROR(
+            &ppi->error, td->upsample_pred,
+            aom_memalign(16, (1 + is_highbitdepth) *
+                                 (MAX_SB_SIZE + SUBPEL_TAPS) * MAX_SB_SIZE *
+                                 sizeof(*td->upsample_pred)));
+      }

       if (!is_first_pass && i < num_enc_workers) {
         // Set up sms_tree.
diff --git a/av1/encoder/intra_mode_search.c b/av1/encoder/intra_mode_search.c
index 8c6cade9cc..5cfa8bede4 100644
--- a/av1/encoder/intra_mode_search.c
+++ b/av1/encoder/intra_mode_search.c
@@ -25,15 +25,6 @@
 // the rd threshold check to prune -3 and 3 delta angles.
 #define SIZE_OF_ANGLE_DELTA_RD_COST_ARRAY (2 * MAX_ANGLE_DELTA + 3)

-// The order for evaluating delta angles while processing the luma directional
-// intra modes. Currently, this order of evaluation is applicable only when
-// speed feature prune_luma_odd_delta_angles_in_intra is enabled. In this case,
-// even angles are evaluated first in order to facilitate the pruning of odd
-// delta angles based on the rd costs of the neighboring delta angles.
-static const int8_t luma_delta_angles_order[2 * MAX_ANGLE_DELTA] = {
-  -2, 2, -3, -1, 1, 3,
-};
-
 /*!\cond */
 static const PREDICTION_MODE intra_rd_search_mode_order[INTRA_MODES] = {
   DC_PRED,       H_PRED,        V_PRED,    SMOOTH_PRED, PAETH_PRED,
@@ -406,17 +397,34 @@ void set_y_mode_and_delta_angle(const int mode_idx, MB_MODE_INFO *const mbmi,
     mbmi->mode = intra_rd_search_mode_order[mode_idx];
     mbmi->angle_delta[PLANE_TYPE_Y] = 0;
   } else {
-    mbmi->mode = (mode_idx - INTRA_MODE_END) / (MAX_ANGLE_DELTA * 2) + V_PRED;
-    int delta_angle_eval_idx =
-        (mode_idx - INTRA_MODE_END) % (MAX_ANGLE_DELTA * 2);
-    if (reorder_delta_angle_eval) {
-      mbmi->angle_delta[PLANE_TYPE_Y] =
-          luma_delta_angles_order[delta_angle_eval_idx];
-    } else {
-      mbmi->angle_delta[PLANE_TYPE_Y] =
-          (delta_angle_eval_idx < 3 ? (delta_angle_eval_idx - 3)
-                                    : (delta_angle_eval_idx - 2));
-    }
+    // Precomputed lookup tables for directional mode and delta angle indexed by
+    // (mode_idx - INTRA_MODE_END) to avoid division/modulo by 6.
+    static const uint8_t mode_div6[48] = {
+      V_PRED,    V_PRED,    V_PRED,    V_PRED,    V_PRED,    V_PRED,
+      H_PRED,    H_PRED,    H_PRED,    H_PRED,    H_PRED,    H_PRED,
+      D45_PRED,  D45_PRED,  D45_PRED,  D45_PRED,  D45_PRED,  D45_PRED,
+      D135_PRED, D135_PRED, D135_PRED, D135_PRED, D135_PRED, D135_PRED,
+      D113_PRED, D113_PRED, D113_PRED, D113_PRED, D113_PRED, D113_PRED,
+      D157_PRED, D157_PRED, D157_PRED, D157_PRED, D157_PRED, D157_PRED,
+      D203_PRED, D203_PRED, D203_PRED, D203_PRED, D203_PRED, D203_PRED,
+      D67_PRED,  D67_PRED,  D67_PRED,  D67_PRED,  D67_PRED,  D67_PRED,
+    };
+    static const int8_t angle_mod6[2][48] = {
+      {
+          -3, -2, -1, 1,  2,  3,  -3, -2, -1, 1,  2,  3,  -3, -2, -1, 1,
+          2,  3,  -3, -2, -1, 1,  2,  3,  -3, -2, -1, 1,  2,  3,  -3, -2,
+          -1, 1,  2,  3,  -3, -2, -1, 1,  2,  3,  -3, -2, -1, 1,  2,  3,
+      },
+      {
+          -2, 2,  -3, -1, 1,  3,  -2, 2,  -3, -1, 1,  3,  -2, 2,  -3, -1,
+          1,  3,  -2, 2,  -3, -1, 1,  3,  -2, 2,  -3, -1, 1,  3,  -2, 2,
+          -3, -1, 1,  3,  -2, 2,  -3, -1, 1,  3,  -2, 2,  -3, -1, 1,  3,
+      },
+    };
+    const int offset = mode_idx - INTRA_MODE_END;
+    mbmi->mode = (PREDICTION_MODE)mode_div6[offset];
+    mbmi->angle_delta[PLANE_TYPE_Y] =
+        angle_mod6[reorder_delta_angle_eval != 0][offset];
   }
 }

@@ -1488,7 +1496,6 @@ int64_t av1_rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
   MB_MODE_INFO *const mbmi = xd->mi[0];
   assert(!is_inter_block(mbmi));
   int64_t best_model_rd = INT64_MAX;
-  int is_directional_mode;
   uint8_t directional_mode_skip_mask[INTRA_MODES] = { 0 };
   // Flag to check rd of any intra mode is better than best_rd passed to this
   // function
@@ -1529,9 +1536,6 @@ int64_t av1_rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
   set_mode_eval_params(cpi, x, MODE_EVAL);

   MB_MODE_INFO best_mbmi = *mbmi;
-  const int max_winner_mode_count =
-      winner_mode_count_allowed[cpi->sf.winner_mode_sf.multi_winner_mode_type];
-  zero_winner_mode_stats(bsize, max_winner_mode_count, x->winner_mode_stats);
   x->winner_mode_count = 0;

   // Searches the intra-modes except for intrabc, palette, and filter_intra.
@@ -1540,74 +1544,64 @@ int64_t av1_rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
     top_intra_model_rd[i] = INT64_MAX;
   }

-  // Initialize the rdcost corresponding to all the directional and
-  // non-directional intra modes.
-  // 1. For directional modes, it stores the rdcost values for delta angles -4,
-  // -3, ..., 3, 4.
-  // 2. The rdcost value for luma_delta_angle is stored at index
-  // luma_delta_angle + MAX_ANGLE_DELTA + 1.
-  // 3. The rdcost values for fictitious/nonexistent luma_delta_angle -4 and 4
-  // (array indices 0 and 8) are always set to INT64_MAX (the initial value).
+  const int use_angle_delta =
+      av1_use_angle_delta(bsize) && intra_mode_cfg->enable_angle_delta;
+  const int max_mode_idx =
+      (use_angle_delta && intra_mode_cfg->enable_directional_intra)
+          ? LUMA_MODE_COUNT
+          : INTRA_MODE_END;
+
+  uint16_t allowed_mode_mask =
+      intra_sf->intra_y_mode_mask[max_txsize_lookup[bsize]];
+  if (!intra_mode_cfg->enable_diagonal_intra)
+    allowed_mode_mask &=
+        ~((1 << D45_PRED) | (1 << D135_PRED) | (1 << D113_PRED) |
+          (1 << D157_PRED) | (1 << D203_PRED) | (1 << D67_PRED));
+  if (!intra_mode_cfg->enable_directional_intra)
+    allowed_mode_mask &=
+        ~((1 << V_PRED) | (1 << H_PRED) | (1 << D45_PRED) | (1 << D135_PRED) |
+          (1 << D113_PRED) | (1 << D157_PRED) | (1 << D203_PRED) |
+          (1 << D67_PRED));
+  if (!intra_mode_cfg->enable_smooth_intra || intra_sf->disable_smooth_intra) {
+    allowed_mode_mask &= ~((1 << SMOOTH_H_PRED) | (1 << SMOOTH_V_PRED));
+    if (!intra_mode_cfg->enable_smooth_intra ||
+        intra_sf->prune_filter_intra_level == 0)
+      allowed_mode_mask &= ~(1 << SMOOTH_PRED);
+  }
+  if (!intra_mode_cfg->enable_paeth_intra)
+    allowed_mode_mask &= ~(1 << PAETH_PRED);
+  if (x->use_mb_mode_cache)
+    allowed_mode_mask &= (uint16_t)(1u << x->mb_mode_cache->mode);
+  if (intra_sf->intra_pruning_with_hog) {
+    for (int m = V_PRED; m <= D67_PRED; ++m) {
+      if (directional_mode_skip_mask[m]) allowed_mode_mask &= ~(1 << m);
+    }
+  }
+
+  // Initialize the rdcost corresponding to directional intra modes when odd
+  // delta angle pruning is active.
   int64_t intra_modes_rd_cost[INTRA_MODE_END]
                              [SIZE_OF_ANGLE_DELTA_RD_COST_ARRAY];
-  for (int i = 0; i < INTRA_MODE_END; i++) {
-    for (int j = 0; j < SIZE_OF_ANGLE_DELTA_RD_COST_ARRAY; j++) {
-      intra_modes_rd_cost[i][j] = INT64_MAX;
+  if (use_angle_delta && intra_sf->prune_luma_odd_delta_angles_in_intra) {
+    for (int i = V_PRED; i <= D67_PRED; i++) {
+      for (int j = 0; j < SIZE_OF_ANGLE_DELTA_RD_COST_ARRAY; j++) {
+        intra_modes_rd_cost[i][j] = INT64_MAX;
+      }
     }
   }

-  for (int mode_idx = INTRA_MODE_START; mode_idx < LUMA_MODE_COUNT;
-       ++mode_idx) {
+  for (int mode_idx = INTRA_MODE_START; mode_idx < max_mode_idx; ++mode_idx) {
     set_y_mode_and_delta_angle(mode_idx, mbmi,
                                intra_sf->prune_luma_odd_delta_angles_in_intra);
+    if (!(allowed_mode_mask & (1 << mbmi->mode))) continue;
+
     RD_STATS this_rd_stats;
     int this_rate, this_rate_tokenonly, s;
-    int is_diagonal_mode;
     int64_t this_distortion, this_rd;
     const int luma_delta_angle = mbmi->angle_delta[PLANE_TYPE_Y];

-    is_diagonal_mode = av1_is_diagonal_mode(mbmi->mode);
-    if (is_diagonal_mode && !intra_mode_cfg->enable_diagonal_intra) continue;
-    if (av1_is_directional_mode(mbmi->mode) &&
-        !intra_mode_cfg->enable_directional_intra)
-      continue;
-
-    // The smooth prediction mode appears to be more frequently picked
-    // than horizontal / vertical smooth prediction modes. Hence treat
-    // them differently in speed features.
-    if ((!intra_mode_cfg->enable_smooth_intra ||
-         intra_sf->disable_smooth_intra) &&
-        (mbmi->mode == SMOOTH_H_PRED || mbmi->mode == SMOOTH_V_PRED))
-      continue;
-    if (!intra_mode_cfg->enable_smooth_intra && mbmi->mode == SMOOTH_PRED)
-      continue;
-
-    // The functionality of filter intra modes and smooth prediction
-    // overlap. Hence smooth prediction is pruned only if all the
-    // filter intra modes are enabled.
-    if (intra_sf->disable_smooth_intra &&
-        intra_sf->prune_filter_intra_level == 0 && mbmi->mode == SMOOTH_PRED)
-      continue;
-    if (!intra_mode_cfg->enable_paeth_intra && mbmi->mode == PAETH_PRED)
-      continue;
-
-    // Skip the evaluation of modes that do not match with the winner mode in
-    // x->mb_mode_cache.
-    if (x->use_mb_mode_cache && mbmi->mode != x->mb_mode_cache->mode) continue;
-
-    is_directional_mode = av1_is_directional_mode(mbmi->mode);
-    if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
-    if (is_directional_mode &&
-        !(av1_use_angle_delta(bsize) && intra_mode_cfg->enable_angle_delta) &&
-        luma_delta_angle != 0)
-      continue;
-
-    // Use intra_y_mode_mask speed feature to skip intra mode evaluation.
-    if (!(intra_sf->intra_y_mode_mask[max_txsize_lookup[bsize]] &
-          (1 << mbmi->mode)))
-      continue;
-
-    if (prune_luma_odd_delta_angles_using_rd_cost(
+    if ((luma_delta_angle & 1) &&
+        prune_luma_odd_delta_angles_using_rd_cost(
             mbmi, intra_modes_rd_cost[mbmi->mode], best_rd,
             intra_sf->prune_luma_odd_delta_angles_in_intra))
       continue;
diff --git a/av1/encoder/rdopt_utils.h b/av1/encoder/rdopt_utils.h
index 208216327d..37475a501b 100644
--- a/av1/encoder/rdopt_utils.h
+++ b/av1/encoder/rdopt_utils.h
@@ -812,10 +812,26 @@ static inline void store_winner_mode_stats(
       // No mode has higher rd cost than this_rd
       return;
     } else if (mode_idx < max_winner_mode_count - 1) {
-      // Create a slot for current mode and move others to the next slot
-      memmove(
-          &winner_mode_stats[mode_idx + 1], &winner_mode_stats[mode_idx],
-          (max_winner_mode_count - mode_idx - 1) * sizeof(*winner_mode_stats));
+      // Create a slot for current mode and move others to the next slot.
+      // Only copy the active fields up to color_index_map, and copy the active
+      // portion of color_index_map only when palette mode is used.
+      const int move_end =
+          AOMMIN(x->winner_mode_count, max_winner_mode_count - 1);
+      for (int j = move_end; j > mode_idx; --j) {
+        memcpy(&winner_mode_stats[j], &winner_mode_stats[j - 1],
+               offsetof(WinnerModeStats, color_index_map));
+        if (winner_mode_stats[j - 1]
+                .mbmi.palette_mode_info.palette_size[PLANE_TYPE_Y] > 0) {
+          const MACROBLOCKD *const xd = &x->e_mbd;
+          int block_width, block_height;
+          av1_get_block_dimensions(bsize, AOM_PLANE_Y, xd, &block_width,
+                                   &block_height, NULL, NULL);
+          memcpy(winner_mode_stats[j].color_index_map,
+                 winner_mode_stats[j - 1].color_index_map,
+                 block_width * block_height *
+                     sizeof(winner_mode_stats[0].color_index_map[0]));
+        }
+      }
     }
   }
   // Add a mode stat for winner mode processing