PaintBrush: Speed up the bucket tool with smarter use of Vector.

Put together a pretty well-performing queue using a Vector and an offset.
By using the new Vector::shift_left(int) instead of Vector::take_first()
we can avoid shifting the vector contents every time and instead only
do it every so often.

Maybe this could be generalized into a separate class, I'm not sure if it's
the best algorithm though, it's just what I came up with right now. :^)
This commit is contained in:
Andreas Kling 2019-06-14 21:46:35 +02:00
parent e9c021de92
commit 9443957c14
Notes: sideshowbarker 2024-07-19 13:36:14 +09:00
2 changed files with 34 additions and 8 deletions

View File

@ -298,6 +298,19 @@ public:
m_capacity = new_capacity;
}
void shift_left(int count)
{
ASSERT(count <= m_size);
if (count == m_size) {
clear();
return;
}
for (int i = 0; i < m_size - count; ++i) {
at(i) = move(at(i + count));
}
m_size -= count;
}
void resize(int new_size)
{
if (new_size == size())

View File

@ -15,21 +15,34 @@ BucketTool::~BucketTool()
static void flood_fill(GraphicsBitmap& bitmap, const Point& start_position, Color target_color, Color fill_color)
{
SinglyLinkedList<Point> queue;
Vector<Point> queue;
queue.append(start_position);
int queue_pos = 0;
while (queue_pos != queue.size()) {
auto position = queue[queue_pos++];
if (queue_pos > 4096) {
queue.shift_left(4096);
queue_pos = 0;
}
queue.append(Point(start_position));
while (!queue.is_empty()) {
auto position = queue.take_first();
if (!bitmap.rect().contains(position))
continue;
if (bitmap.get_pixel(position) != target_color)
continue;
bitmap.set_pixel(position, fill_color);
queue.append(position.translated(0, -1));
queue.append(position.translated(0, 1));
queue.append(position.translated(1, 0));
queue.append(position.translated(-1, 0));
if (position.x() != 0)
queue.append(position.translated(0, -1));
if (position.x() != bitmap.width() - 1)
queue.append(position.translated(0, 1));
if (position.y() != 0)
queue.append(position.translated(-1, 0));
if (position.y() != bitmap.height() - 1)
queue.append(position.translated(1, 0));
}
}