mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
Stop recomposing the window hierarchy after every dang widget paint.
This commit is contained in:
parent
f3ec96a1b9
commit
cfd76ade73
Notes:
sideshowbarker
2024-07-19 16:05:35 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/cfd76ade73d
8 changed files with 34 additions and 41 deletions
|
@ -21,8 +21,6 @@ Painter::Painter(Widget& widget)
|
|||
|
||||
Painter::~Painter()
|
||||
{
|
||||
if (m_window)
|
||||
m_window->did_paint();
|
||||
}
|
||||
|
||||
void Painter::fillRect(const Rect& rect, Color color)
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
RootWidget::RootWidget()
|
||||
{
|
||||
m_backing = GraphicsBitmap::create_wrapper(FrameBufferSDL::the().size(), (byte*)FrameBufferSDL::the().scanline(0));
|
||||
setWindowRelativeRect(FrameBufferSDL::the().rect());
|
||||
m_backing = GraphicsBitmap::create_wrapper(size(), (byte*)FrameBufferSDL::the().scanline(0));
|
||||
}
|
||||
|
||||
RootWidget::~RootWidget()
|
||||
|
|
|
@ -19,16 +19,18 @@ Widget::~Widget()
|
|||
{
|
||||
}
|
||||
|
||||
void Widget::setWindowRelativeRect(const Rect& rect)
|
||||
void Widget::setWindowRelativeRect(const Rect& rect, bool should_update)
|
||||
{
|
||||
// FIXME: Make some kind of event loop driven ResizeEvent?
|
||||
m_relativeRect = rect;
|
||||
update();
|
||||
if (should_update)
|
||||
update();
|
||||
}
|
||||
|
||||
void Widget::repaint(const Rect& rect)
|
||||
{
|
||||
event(*make<PaintEvent>(rect));
|
||||
if (auto* w = window())
|
||||
w->repaint(rect);
|
||||
}
|
||||
|
||||
void Widget::event(Event& event)
|
||||
|
@ -109,10 +111,13 @@ void Widget::mouseMoveEvent(MouseEvent&)
|
|||
|
||||
void Widget::update()
|
||||
{
|
||||
auto* w = window();
|
||||
if (!w)
|
||||
return;
|
||||
if (m_hasPendingPaintEvent)
|
||||
return;
|
||||
m_hasPendingPaintEvent = true;
|
||||
EventLoop::main().postEvent(this, make<PaintEvent>(rect()));
|
||||
EventLoop::main().postEvent(w, make<PaintEvent>(rect()));
|
||||
}
|
||||
|
||||
Widget::HitTestResult Widget::hitTest(int x, int y)
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
int height() const { return m_relativeRect.height(); }
|
||||
|
||||
Rect rect() const { return { 0, 0, width(), height() }; }
|
||||
Size size() const { return m_relativeRect.size(); }
|
||||
|
||||
void update();
|
||||
void repaint(const Rect&);
|
||||
|
@ -50,7 +51,7 @@ public:
|
|||
|
||||
virtual const char* class_name() const override { return "Widget"; }
|
||||
|
||||
void setWindowRelativeRect(const Rect&);
|
||||
void setWindowRelativeRect(const Rect&, bool should_update = true);
|
||||
|
||||
Color backgroundColor() const { return m_backgroundColor; }
|
||||
Color foregroundColor() const { return m_foregroundColor; }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Window.h"
|
||||
#include "WindowManager.h"
|
||||
#include "Event.h"
|
||||
#include "EventLoop.h"
|
||||
#include "Widget.h"
|
||||
|
||||
Window::Window(Object* parent)
|
||||
|
@ -46,9 +47,14 @@ void Window::setRect(const Rect& rect)
|
|||
WindowManager::the().notifyRectChanged(*this, oldRect, m_rect);
|
||||
}
|
||||
|
||||
void Window::repaint()
|
||||
void Window::repaint(const Rect& rect)
|
||||
{
|
||||
event(*make<PaintEvent>());
|
||||
event(*make<PaintEvent>(rect));
|
||||
}
|
||||
|
||||
void Window::update(const Rect& rect)
|
||||
{
|
||||
EventLoop::main().postEvent(this, make<PaintEvent>(rect));
|
||||
}
|
||||
|
||||
void Window::event(Event& event)
|
||||
|
@ -80,9 +86,11 @@ void Window::event(Event& event)
|
|||
}
|
||||
if (m_mainWidget) {
|
||||
if (pe.rect().is_empty())
|
||||
return m_mainWidget->event(*make<PaintEvent>(m_mainWidget->rect()));
|
||||
m_mainWidget->event(*make<PaintEvent>(m_mainWidget->rect()));
|
||||
else
|
||||
return m_mainWidget->event(event);
|
||||
m_mainWidget->event(event);
|
||||
WindowManager::the().did_paint(*this);
|
||||
return;
|
||||
}
|
||||
return Object::event(event);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ public:
|
|||
bool isBeingDragged() const { return m_isBeingDragged; }
|
||||
void setIsBeingDragged(bool b) { m_isBeingDragged = b; }
|
||||
|
||||
void repaint();
|
||||
void repaint(const Rect& = Rect());
|
||||
void update(const Rect& = Rect());
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
|
|
|
@ -136,9 +136,10 @@ void WindowManager::repaint()
|
|||
void WindowManager::did_paint(Window& window)
|
||||
{
|
||||
auto& framebuffer = FrameBufferSDL::the();
|
||||
if (m_windows_in_order.head() == &window) {
|
||||
if (m_windows_in_order.tail() == &window) {
|
||||
ASSERT(window.backing());
|
||||
framebuffer.blit(window.position(), *window.backing());
|
||||
printf("[WM] frontmost_only_compose_count: %u\n", ++m_frontmost_only_compose_count);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -167,7 +168,7 @@ void WindowManager::notifyTitleChanged(Window& window)
|
|||
void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height());
|
||||
repaintAfterMove(oldRect, newRect);
|
||||
recompose();
|
||||
}
|
||||
|
||||
void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
|
||||
|
@ -190,28 +191,6 @@ void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
|
|||
#endif
|
||||
}
|
||||
|
||||
void WindowManager::repaintAfterMove(const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
printf("[WM] repaint: [%d,%d %dx%d] -> [%d,%d %dx%d]\n",
|
||||
oldRect.x(),
|
||||
oldRect.y(),
|
||||
oldRect.width(),
|
||||
oldRect.height(),
|
||||
newRect.x(),
|
||||
newRect.y(),
|
||||
newRect.width(),
|
||||
newRect.height());
|
||||
|
||||
m_rootWidget->repaint(oldRect);
|
||||
m_rootWidget->repaint(newRect);
|
||||
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||
if (outerRectForWindow(*window).intersects(oldRect) || outerRectForWindow(*window).intersects(newRect)) {
|
||||
paintWindowFrame(*window);
|
||||
window->repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::processMouseEvent(MouseEvent& event)
|
||||
{
|
||||
if (event.type() == Event::MouseUp) {
|
||||
|
@ -220,8 +199,7 @@ void WindowManager::processMouseEvent(MouseEvent& event)
|
|||
m_dragWindow->setIsBeingDragged(false);
|
||||
m_dragEndRect = outerRectForWindow(*m_dragWindow);
|
||||
m_dragWindow = nullptr;
|
||||
|
||||
repaintAfterMove(m_dragStartRect, m_dragEndRect);
|
||||
recompose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +259,8 @@ void WindowManager::recompose()
|
|||
{
|
||||
printf("[WM] recompose_count: %u\n", ++m_recompose_count);
|
||||
auto& framebuffer = FrameBufferSDL::the();
|
||||
m_rootWidget->repaint(m_rootWidget->rect());
|
||||
PaintEvent dummy_event(m_rootWidget->rect());
|
||||
m_rootWidget->paintEvent(dummy_event);
|
||||
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||
if (!window->backing())
|
||||
continue;
|
||||
|
|
|
@ -41,7 +41,6 @@ private:
|
|||
void processMouseEvent(MouseEvent&);
|
||||
void handleTitleBarMouseEvent(Window&, MouseEvent&);
|
||||
void handlePaintEvent(PaintEvent&);
|
||||
void repaintAfterMove(const Rect& oldRect, const Rect& newRect);
|
||||
|
||||
virtual void event(Event&) override;
|
||||
|
||||
|
@ -68,4 +67,5 @@ private:
|
|||
Rect m_dragEndRect;
|
||||
|
||||
unsigned m_recompose_count { 0 };
|
||||
unsigned m_frontmost_only_compose_count { 0 };
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue