Подключил к ББ консольный логгер и посмотрел, как оно работает
При каждом движении окна "bb.open", вызывается InvalidateWin для нижележащих окон "(Host)Ports" и "(Host)Windows". В логе, кстати, заметно небольшое приращение координат области перерисовки для окна "(Host)Windows" - это я аккуратно двигал окно консоли слева направо по горизонтали.
Интересно заметить, что накопление областей перерисовки и сама перерисовка окна разнесены по разным процедурам: w.Restore и w.Update. Это значит, что определение конечной области перерисовки, внутри ББ может происходить в несколько приёмов, и становится понятным назначение структуры модуля Views
Код:
Region = POINTER TO RECORD
n: INTEGER;
r: ARRAY maxN OF Rect
END;
...это буфер! Переменная n здесь обозначает количество накопленных областей. Причём сброс n происходит только в Views.ValidateRoot (и в SetRoot, но это в данный момент неважно).
Здесь есть некоторая тонкость. Views.ValidateRoot использует процедуру Views.RestoreRoot для перерисовки каждой области буфера (к слову, количество этих областей ограничено числом 30, чего вполне достаточно, ведь как правило, перерисовки требует только одна область, вычисленная в Views.AddRect.). А эта процедура публичная, значит - её может нечаянно вызвать клиент, не подозревающий о том, что буфер областей ещё не прошёл обработку с помощью Views.RemoveFrames. Поэтому в RestoreRoot мы видим предусловие
Код:
ASSERT(root.update.n = 0, 22);
..., которое служит причиной возникновения одного неприятного и
таинственного трапа, от которого мы никак не можем избавиться при использовании своих отображений.
Ну и теперь я могу сделать самый для меня важный вывод. Если делать оконную систему на базе SDL, то про частичное обновление экрана можно забыть. Насколько я знаю, там нет возможности определения областей перерисовки для окна. Ну, собственно, это не страшно, сделать полное обновление окна по нынешним временам операция почти незаметная )