mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Add fast dword-sized copy and fill to the Painter code.
This commit is contained in:
parent
24b2cadb82
commit
f2551c45ab
Notes:
sideshowbarker
2024-07-19 16:03:47 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/f2551c45ab6
1 changed files with 51 additions and 12 deletions
|
@ -7,6 +7,36 @@
|
||||||
|
|
||||||
#define DEBUG_WIDGET_UNDERDRAW
|
#define DEBUG_WIDGET_UNDERDRAW
|
||||||
|
|
||||||
|
ALWAYS_INLINE void fast_dword_copy(dword* dest, const dword* src, size_t count)
|
||||||
|
{
|
||||||
|
#ifdef SERENITY
|
||||||
|
asm volatile(
|
||||||
|
"rep movsl\n"
|
||||||
|
: "=S"(src), "=D"(dest)
|
||||||
|
: "S"(src), "D"(dest), "c"(count)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
memcpy(dest, src, count * sizeof(dword));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE void fast_dword_fill(dword* dest, dword value, size_t count)
|
||||||
|
{
|
||||||
|
#ifdef SERENITY
|
||||||
|
asm volatile(
|
||||||
|
"rep stosl\n"
|
||||||
|
: "=D"(dest)
|
||||||
|
: "D"(dest), "c"(count), "a"(value)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
for (size_t i = 0; x <= count; ++x) {
|
||||||
|
dest[i] = value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
Painter::Painter(GraphicsBitmap& bitmap)
|
Painter::Painter(GraphicsBitmap& bitmap)
|
||||||
{
|
{
|
||||||
m_font = &Font::defaultFont();
|
m_font = &Font::defaultFont();
|
||||||
|
@ -38,11 +68,13 @@ void Painter::fill_rect(const Rect& rect, Color color)
|
||||||
Rect r = rect;
|
Rect r = rect;
|
||||||
r.moveBy(m_translation);
|
r.moveBy(m_translation);
|
||||||
|
|
||||||
for (int y = max(r.top(), m_clip_rect.top()); y <= min(r.bottom(), m_clip_rect.bottom()); ++y) {
|
int min_y = max(r.top(), m_clip_rect.top());
|
||||||
auto* bits = m_target->scanline(y);
|
int max_y = min(r.bottom(), m_clip_rect.bottom());
|
||||||
for (int x = max(r.left(), m_clip_rect.left()); x <= min(r.right(), m_clip_rect.right()); ++x) {
|
int min_x = max(r.left(), m_clip_rect.left());
|
||||||
bits[x] = color.value();
|
int max_x = min(r.right(), m_clip_rect.right());
|
||||||
}
|
for (int y = min_y; y <= max_y; ++y) {
|
||||||
|
RGBA32* bits = m_target->scanline(y);
|
||||||
|
fast_dword_fill(bits + min_x, color.value(), max_x - min_x + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +83,15 @@ void Painter::draw_rect(const Rect& rect, Color color)
|
||||||
Rect r = rect;
|
Rect r = rect;
|
||||||
r.moveBy(m_translation);
|
r.moveBy(m_translation);
|
||||||
|
|
||||||
for (int y = max(r.top(), m_clip_rect.top()); y <= min(r.bottom(), m_clip_rect.bottom()); ++y) {
|
int min_y = max(r.top(), m_clip_rect.top());
|
||||||
|
int max_y = min(r.bottom(), m_clip_rect.bottom());
|
||||||
|
int min_x = max(r.left(), m_clip_rect.left());
|
||||||
|
int max_x = min(r.right(), m_clip_rect.right());
|
||||||
|
|
||||||
|
for (int y = min_y; y <= max_y; ++y) {
|
||||||
auto* bits = m_target->scanline(y);
|
auto* bits = m_target->scanline(y);
|
||||||
if (y == r.top() || y == r.bottom()) {
|
if (y == r.top() || y == r.bottom()) {
|
||||||
for (int x = max(r.left(), m_clip_rect.left()); x <= min(r.right(), m_clip_rect.right()); ++x) {
|
fast_dword_fill(bits + min_x, color.value(), max_x - min_x + 1);
|
||||||
bits[x] = color.value();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (r.left() >= m_clip_rect.left() && r.left() <= m_clip_rect.right())
|
if (r.left() >= m_clip_rect.left() && r.left() <= m_clip_rect.right())
|
||||||
bits[r.left()] = color.value();
|
bits[r.left()] = color.value();
|
||||||
|
@ -169,8 +204,12 @@ void Painter::draw_line(const Point& p1, const Point& p2, Color color)
|
||||||
int min_x = max(point1.x(), m_clip_rect.left());
|
int min_x = max(point1.x(), m_clip_rect.left());
|
||||||
int max_x = min(point2.x(), m_clip_rect.right());
|
int max_x = min(point2.x(), m_clip_rect.right());
|
||||||
auto* pixels = m_target->scanline(point1.y());
|
auto* pixels = m_target->scanline(point1.y());
|
||||||
for (int x = min_x; x <= max_x; ++x)
|
if (m_draw_op == DrawOp::Copy) {
|
||||||
set_pixel_with_draw_op(pixels[x], color);
|
fast_dword_fill(pixels + min_x, color.value(), max_x - min_x + 1);
|
||||||
|
} else {
|
||||||
|
for (int x = min_x; x <= max_x; ++x)
|
||||||
|
set_pixel_with_draw_op(pixels[x], color);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +252,6 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source)
|
||||||
for (int y = 0; y < dst_rect.height(); ++y) {
|
for (int y = 0; y < dst_rect.height(); ++y) {
|
||||||
auto* dst_scanline = m_target->scanline(position.y() + y);
|
auto* dst_scanline = m_target->scanline(position.y() + y);
|
||||||
auto* src_scanline = source.scanline(y);
|
auto* src_scanline = source.scanline(y);
|
||||||
memcpy(dst_scanline + dst_rect.x(), src_scanline + (dst_rect.x() - position.x()), dst_rect.width() * 4);
|
fast_dword_copy(dst_scanline + dst_rect.x(), src_scanline + (dst_rect.x() - position.x()), dst_rect.width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue