Оптимизация каскада плит: -27% работы за кадр (пять правок с замерами)
Сцена — ур.13 комната 23, шесть плит с потолка (docs/perf_l13_room23.md).
Все замеры сняты одним и тем же прогоном «ESC -> зонды -> roomtest».
было стало
работа за кадр 1 437 150 1 051 332 -27%
зелёная (фон) 805 000 575 730 -28%
циан (спрайты) 631 800 438 546 -31%
синяя 142 830 142 830 в бюджете
Цена одной перерисовки:
RDA_CEIL_GONE (запечь колодец) 251 335 -> 137 975 -45%
RD_FLOOR (щебень на посадке) 198 805 -> 182 124 -8%
RDA_CEIL (дрожащая плита) 48 785 -> 43 543 -11%
C1. Пометки «фон трогали» в mob_render ПОДАВЛЕНЫ (pop_cd_mute): коридор
куска уже помечен одним вызовом в pop_loose_mob_tick, а три блита метили
подмножества того же прямоугольника по 4 502 такта. Плюс пометка в
mob_spawn_copy — кусок, рождённый внутри тика, свою мог не получить
(слот выдаётся с начала таблицы, то есть уже пройденный). -55 тыс.
G2. Контекст тайла — file-scope, а не локали draw_tile (порт
load_curr_and_left_tile, seg008:0339). В функции 57 вызовов, и каждое
живое через вызов значение спиливалось: 26 байт кадра и 513 обращений
`-N(ix)`. Стало 33 обращения, кадра нет, банк 7 -703 Б. -55 тыс.
G1. Окно клипа для точечной перерисовки (pop_t_win_set/clear). В
pop_ceil_bake_empty куски ряда 0 высотой 63 px рисовались целиком, хотя
восстановить надо девять строк: блит стоил 21 447, стал 7 619. -90 тыс.
В pop_floor_bake окно попробовано и ОТКАЧЕНО (там нет клипа, блиты шли
быстрым путём, а окно уводило их в blit_b_clip и не отсеивало ничего:
187 266 -> 198 279) — вернуться после G3, запись в коде.
G3. blit_b_clip: байтовый габарит + file-scope вместо локалей. Одного
байтового габарита НЕ ХВАТИЛО (кадр остался, 211 -> 173 обращений) —
значений, живых через шесть вызовов ядер libbgi, больше, чем регистров.
С file-scope: 51 обращение, кадр 22 -> 12 Б. Клипованный блит подешевел.
C4. Падающий кусок КЛИПУЕТСЯ сам, вместо чистки бортов после. Раньше он
рисовался в борт целиком и взводил border_dirty, а pop_room_clip_borders
стирал две полосы 320x28 — 150 978 тактов в каждом кадре, пока хоть один
кусок торчит выше поля (гряда 13-го рождается ровно у потолка, y=2), то
есть почти весь каскад. Стало 1 722. -138 тыс.
Заодно blit_b_oversize больше не ходит через blit_b_clip (у того габарит
теперь байтовый) — рисует напрямую gfx_blit_part. Это путь под
полноэкранные подложки интро/финала (320x200, docs/perf_l13_room23.md §5).
Проверено: 8 наборов tests-host зелёные; в MAME каскад рисуется корректно
(кадр с летящими плитами, чистые борта, итоговая картинка как до правок).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,25 @@ extern int pop_t_fclip_x0, pop_t_fclip_y0, pop_t_fclip_x1, pop_t_fclip_y1;
|
||||
extern int pop_t_fclip_ly0, pop_t_fclip_ly1;
|
||||
extern uint8_t pop_t_fclip_on;
|
||||
|
||||
/* Поставить то же окно под ТОЧЕЧНУЮ ПЕРЕРИСОВКУ / ЗАПЕЧКУ. Прямоугольник —
|
||||
* тот, который восстанавливаем (heal или бар-в-чёрный), в ЛОГИЧЕСКИХ
|
||||
* экранных координатах (с POP_YOFF, но до переворота); экранную пару
|
||||
* функция считает сама.
|
||||
*
|
||||
* Зачем: точечная перерисовка зовёт draw_tile, а тот честно рисует ВЕСЬ тайл.
|
||||
* У полосы кладки у потолка это особенно дорого: куски ряда 0 высотой 63 px
|
||||
* рисуются целиком, хотя восстановить надо девять верхних строк (замер
|
||||
* 2026-08-17: блит в pop_ceil_bake_empty стоит 21 447 против 14 384 в
|
||||
* pop_floor_bake — ровно разница в высоте). Окно и отсеивает куски, вовсе не
|
||||
* попавшие в прямоугольник (предфильтр pop_blit_b — ДО atlas_image и
|
||||
* gfx_w0_map), и режет остальные по нему.
|
||||
*
|
||||
* ВАЖНО: пока окно стоит, pop_blit_b НЕ ставит пометку «фон трогали» (признак
|
||||
* fore-прохода) — вызывающий обязан пометить прямоугольник САМ (pop_cd_touch
|
||||
* или pop_bar_black, который метит сам). */
|
||||
void pop_t_win_set(int x, int ytop, int w, int h);
|
||||
void pop_t_win_clear(void);
|
||||
|
||||
/* ---- Таблица тайлов (piece, seg008.c:27) ---------------------------- */
|
||||
typedef struct {
|
||||
uint8_t base_id, floor_left; int8_t base_y;
|
||||
|
||||
Reference in New Issue
Block a user