Skip to content

Instantly share code, notes, and snippets.

@X547
Created August 17, 2026 22:53
Show Gist options
  • Select an option

  • Save X547/64089c78a2c26dded30cc90d12c2612a to your computer and use it in GitHub Desktop.

Select an option

Save X547/64089c78a2c26dded30cc90d12c2612a to your computer and use it in GitHub Desktop.
Region scene with 2 swappable buffers redraw algorithm
void
Port::Update(BRegion& updateRgn)
{
if (
!fBackSurf->bitmap.IsSet() ||
fBackSurf->bitmap->Width() != fWidth ||
fBackSurf->bitmap->Height() != fHeight
) {
fBackSurf->bitmap.SetTo(new AppServer::Bitmap(fWidth, fHeight, B_RGBA32, (bitmap_flags)0), true);
fBackSurf->canvas.reset(fPainterAddOn->NewBitmapCanvas(fBackSurf->bitmap.Get()));
fBackSurf->canvas->State().externalInfo = fCanvasExtInfo;
// Newly allocated buffer has undefined contents, so we need to force filling it.
fOldUpdateRgn.Set(clipping_rect{0, 0, fWidth - 1, fHeight - 1});
}
updateRgn.MakeEmpty();
_CalcVisible();
for (Frame* frame = fFrames.Last(); frame != nullptr; frame = fFrames.GetPrevious(frame)) {
IntPoint offset(frame->fCurState.pos.x - frame->fOldState.pos.x, frame->fCurState.pos.y - frame->fOldState.pos.y);
bool isMoved = offset.x != 0 || offset.y != 0;
BRegion oldVisible = frame->fOldState.visible;
oldVisible.OffsetBy(offset.x, offset.y);
BRegion dirty = frame->fCurState.visible;
dirty.Exclude(&oldVisible);
if (isMoved)
updateRgn.Include(&frame->fCurState.visible);
else
updateRgn.Include(&dirty);
BRegion copy = oldVisible;
copy.IntersectWith(&frame->fCurState.visible);
if (!isMoved)
copy.IntersectWith(&fOldUpdateRgn);
Canvas& c = *fBackSurf->canvas;
// copy
if (copy.CountRects() > 0) {
c.PushState();
c.ClipToRegion(false, copy);
c.DrawBitmap(fFrontSurf->bitmap.Get(), (bitmap_drawing_options)0, fFrontSurf->bitmap->Bounds(), fFrontSurf->bitmap->Bounds().OffsetByCopy(-offset.x, -offset.y));
c.PopState();
}
// draw
if (dirty.CountRects() > 0) {
c.PushState();
c.ClipToRegion(false, dirty);
c.State().SetOrigin(frame->fCurState.pos);
c.PushState();
frame->fView->Draw(c, dirty);
c.PopState();
c.PopState();
}
}
for (Frame* frame = fFrames.Last(); frame != nullptr; frame = fFrames.GetPrevious(frame)) {
frame->fOldState.pos = frame->fCurState.pos;
frame->fOldState.visible = frame->fCurState.visible;
}
fOldUpdateRgn = updateRgn;
std::swap(fBackSurf, fFrontSurf);
}
void
Port::_CalcVisible()
{
BRegion remainingVisible;
remainingVisible.Set(clipping_rect{0, 0, fWidth - 1, fHeight - 1});
for (Frame* frame = fFrames.Last(); frame != nullptr; frame = fFrames.GetPrevious(frame)) {
frame->fCurState.visible = remainingVisible;
frame->fCurState.visible.IntersectWith(&frame->fShape);
remainingVisible.Exclude(&frame->fShape);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment