Переглянути джерело

Optimize WindowManager::flush() with fast_dword_copy().

Andreas Kling 6 роки тому
батько
коміт
edc827077e
5 змінених файлів з 40 додано та 35 видалено
  1. 30 0
      AK/StdLibExtras.h
  2. 1 1
      Kernel/init.cpp
  3. 1 0
      Widgets/GraphicsBitmap.h
  4. 0 30
      Widgets/Painter.cpp
  5. 8 4
      Widgets/WindowManager.cpp

+ 30 - 0
AK/StdLibExtras.h

@@ -13,6 +13,36 @@
 #include <utility>
 #endif
 
+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
+}
+
 namespace AK {
 
 template<typename T>

+ 1 - 1
Kernel/init.cpp

@@ -22,7 +22,7 @@
 #include "Scheduler.h"
 #include "PS2MouseDevice.h"
 
-#define SPAWN_MULTIPLE_SHELLS
+//#define SPAWN_MULTIPLE_SHELLS
 //#define STRESS_TEST_SPAWNING
 
 system_t system;

+ 1 - 0
Widgets/GraphicsBitmap.h

@@ -17,6 +17,7 @@ public:
     Size size() const { return m_size; }
     int width() const { return m_size.width(); }
     int height() const { return m_size.height(); }
+    size_t pitch() const { return m_pitch; }
 
 private:
     explicit GraphicsBitmap(const Size&);

+ 0 - 30
Widgets/Painter.cpp

@@ -7,36 +7,6 @@
 
 #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)
 {
     m_font = &Font::defaultFont();

+ 8 - 4
Widgets/WindowManager.cpp

@@ -346,10 +346,14 @@ void WindowManager::flush(const Rect& a_rect)
 {
     auto rect = Rect::intersection(a_rect, m_screen_rect);
 
-    for (int y = rect.top(); y <= rect.bottom(); ++y) {
-        auto* front_scanline = m_front_bitmap->scanline(y);
-        auto* back_scanline = m_back_bitmap->scanline(y);
-        memcpy(front_scanline + rect.x(), back_scanline + rect.x(), rect.width() * sizeof(RGBA32));
+    RGBA32* front_ptr = m_front_bitmap->scanline(rect.y()) + rect.x();
+    const RGBA32* back_ptr = m_back_bitmap->scanline(rect.y()) + rect.x();
+    size_t pitch = m_back_bitmap->pitch();
+
+    for (int y = 0; y < rect.height(); ++y) {
+        fast_dword_copy(front_ptr, back_ptr, rect.width());
+        front_ptr = (RGBA32*)((byte*)front_ptr + pitch);
+        back_ptr = (const RGBA32*)((const byte*)back_ptr + pitch);
     }
 
     m_framebuffer.flush();