Skip to content

Commit

Permalink
platform: Properly check if it is necessary to copy data in DisplayBu…
Browse files Browse the repository at this point in the history
…ffer::screenWrite
  • Loading branch information
magiblot committed Oct 15, 2024
1 parent 5a9d715 commit c757578
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions source/platform/dispbuff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,22 @@ void DisplayBuffer::setCaretPosition(int x, int y) noexcept

void DisplayBuffer::screenWrite(int x, int y, TScreenCell *buf, int len) noexcept
{
if (inBounds(x, y) && len)
if (inBounds(x, y) && len > 0)
{
len = min(len, size.x - x);
// Since 'buffer' is used as 'TScreen::screenBuffer' and is written to
// directly, we can avoid a copy operation in most cases.
if (buf < buffer.data() || buf >= buffer.data() + buffer.size())
memcpy(&buffer[y*size.x + x], buf, len*sizeof(TScreenCell));
TScreenCell *dst = &buffer[y*size.x + x];
// Since 'buffer' is also used as 'TScreen::screenBuffer' and is
// directly written into by 'TView::writeView', we can avoid a copy
// operation in most cases because the data is already there.
if (buf == dst)
; // No need to copy anything.
// But since 'TScreen::screenBuffer' is public, it is also possible
// (theoretically) that the source and destination regions overlap each
// other. Turbo Vision does not do this, but handle this case anyway.
else if (max(buf, dst) <= min(&buf[len], &dst[len]))
memmove(dst, buf, len*sizeof(TScreenCell)); // Copy between overlapping regions.
else
memcpy(dst, buf, len*sizeof(TScreenCell));

setDirty(x, y, len);
screenTouched = true;
Expand Down

0 comments on commit c757578

Please sign in to comment.