#include "lib_cal_creep_resistance.h" #define CREEP_VALUE 1 #define CREEP_INTERVAL_FRAME 5 uint8_t g_creep_value = 0; uint8_t g_creep_interval_frame = 0; static cal_creep_resistance_t creep_strength_value; cal_creep_resistance_t * svc_creep_strength_value_get(void) { return &creep_strength_value; } void cal_creep_resistance_init(uint8_t creep_strength, uint8_t creep_level) { g_creep_value = creep_strength; g_creep_interval_frame = creep_level; } void cal_creep_resistance(cal_creep_resistance_t *cfg) { static uint64_t frame_count = 0; uint16_t count = cfg->x_max * cfg->y_max; int16_t matrix_deviation = 0; frame_count ++; do{ count--; if (cfg->matrix_real[count] < 2) { cfg->matrix_display[count] = 0; cfg->matrix_creep[count] = 0; continue; } if (!(frame_count % g_creep_interval_frame)) { matrix_deviation = (cfg->matrix_real[count] > cfg->matrix_stab[count]) ? (cfg->matrix_real[count] - cfg->matrix_stab[count]) : (cfg->matrix_stab[count] - cfg->matrix_real[count]); if (matrix_deviation > g_creep_value) { } else { matrix_deviation = (cfg->matrix_real[count] > cfg->matrix_stab[count]) ? matrix_deviation : -matrix_deviation; cfg->matrix_creep[count] += matrix_deviation; } cfg->matrix_stab[count] = cfg->matrix_real[count]; } cfg->matrix_display[count] = (cfg->matrix_real[count] > cfg->matrix_creep[count]) ? (cfg->matrix_real[count] - cfg->matrix_creep[count]) : cfg->matrix_real[count]; if (cfg->matrix_real[count] < cfg->matrix_creep[count]) { cfg->matrix_creep[count] = 0; } } while(count); } /* 四宫格并行入口,兼容原 cal_creep_resistance_t 配置 */ void cal_creep_resistance_4tile(const cal_creep_resistance_t *cfg) { /* 原矩阵参数 */ uint8_t x_max = cfg->x_max; /* 62 */ uint8_t y_max = cfg->y_max; /* 68 */ uint8_t *real = cfg->matrix_real; uint8_t *stab = cfg->matrix_stab; uint8_t *creep = cfg->matrix_creep; uint8_t *disp = cfg->matrix_display; /* 静态变量:四块共享同一帧号(线程安全只读) */ static uint64_t frame_count = 0; #pragma omp atomic update frame_count++; /* 原子+1,防止竞态 */ /* 均分四块 */ uint8_t w2 = x_max / 2; /* 31 */ uint8_t h2 = y_max / 2; /* 34 */ #pragma omp parallel for collapse(2) schedule(static) if(1) for (int by = 0; by < 2; ++by) { for (int bx = 0; bx < 2; ++bx) { /* 本块逻辑区域 */ uint8_t x0 = bx * w2; uint8_t y0 = by * h2; uint8_t x1 = (bx == 1) ? x_max : x0 + w2; uint8_t y1 = (by == 1) ? y_max : y0 + h2; uint8_t bw = x1 - x0; uint8_t bh = y1 - y0; /* 基指针(按行主序) */ uint8_t *b_real = real + y0 * x_max + x0; uint8_t *b_stab = stab + y0 * x_max + x0; uint8_t *b_creep = creep + y0 * x_max + x0; uint8_t *b_disp = disp + y0 * x_max + x0; /* 对这块逐像素跑原算法 */ for (uint8_t yy = 0; yy < bh; ++yy) { for (uint8_t xx = 0; xx < bw; ++xx) { uint16_t idx = yy * x_max + xx; /* 全局跨度 */ uint8_t r = b_real[idx]; if (r < 2) { b_disp[idx] = 0; b_creep[idx] = 0; continue; } /* UPDATE 阶段:只在间隔帧做 */ if ((frame_count % g_creep_interval_frame) == 0) { int16_t s = b_stab[idx]; int16_t dev = (r > s) ? (r - s) : (s - r); if (dev <= g_creep_value) { int16_t c = b_creep[idx]; c += (r > s) ? dev : -dev; b_creep[idx] = (uint8_t)(c < 0 ? 0 : c); } b_stab[idx] = r; } /* DISPLAY 阶段 */ uint8_t c = b_creep[idx]; b_disp[idx] = (r > c) ? r - c : 0; if (r < c) b_creep[idx] = 0; } } } } }