06fb4235f0
atlas_image ради двух байт записи каталога переключает W3 туда и обратно, хотя вызывающий сразу после этого мапит ту же страницу в W0 — и каталог там доступен по тому же смещению. Новый atlas_image_w0 (libbgi) читает его из W0; в pop_blit_b порядок стал «сначала gfx_w0_map, потом каталог». ОЖИДАНИЕ НЕ ОПРАВДАЛОСЬ. По раскладке блита atlas_image стоил 672 такта, и я рассчитывал снять их целиком: 8 блитов зелёной фазы это 5 400 за кадр. Фактически цена блита 16 107 -> 16 005 (-102), на кадре -408. Причина: 672 — это почти целиком вызов функции и арифметика idx*8, а не переключение окна. Замер после правки: gfx_w0_map 324, «каталог + шапка + клип» 2 694 — работа просто переехала из одной статьи в другую. Правку оставляю: она не вредит, убирает лишнее переключение W3 и делает контракт честнее (страница мапится один раз). Но как способ снять накладные блита она не работает — фиксированная часть 6 765 -> 6 663. Замеры: лёгкая позиция 438 978 -> 438 570; тяжёлая 602 574 (прошлый замер 617 487 снят до P16, поэтому напрямую не сравним). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
26 lines
1.5 KiB
C
26 lines
1.5 KiB
C
/*
|
|
* atlas_image_w0 — адрес ленты idx для страницы, УЖЕ ПОДКЛЮЧЁННОЙ В W0.
|
|
*
|
|
* Отличие от atlas_image: тот читает каталог через временный мап страницы
|
|
* в W3 и потому платит двумя переключениями окна. А вызывающий, который
|
|
* собирается блитить, страницу в W0 мапит всё равно — и каталог там уже
|
|
* лежит по тому же смещению. Значит переключать W3 незачем.
|
|
*
|
|
* КОНТРАКТ: страница a->page обязана быть подключена в W0 (gfx_w0_map)
|
|
* ДО вызова и оставаться подключённой, пока используется результат.
|
|
* Возвращает W0-адрес ленты (как atlas_image).
|
|
*
|
|
* Замер PoP 2026-08-19: atlas_image в горячем пути блита фона стоил 672
|
|
* такта на КАЖДЫЙ блит, а блитов в кадре до двенадцати.
|
|
*/
|
|
#include <sprinter.h>
|
|
#include <sprite.h>
|
|
#include "../_bgi.h"
|
|
|
|
const void *atlas_image_w0(const atlas_t *a, uint8_t idx)
|
|
{
|
|
const uint8_t *e = (const uint8_t *)(_ATL_DIR_OFF + (uint16_t)idx * 8);
|
|
(void)a; /* страница уже в W0 — сам атлас не нужен */
|
|
return (const void *)(e[0] | (uint16_t)(e[1] << 8));
|
|
}
|