reuse pango layouts for text nodes

This commit is contained in:
hippoz 2023-04-13 04:57:54 +03:00
parent 68211499e8
commit 9aac4865dc
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
2 changed files with 23 additions and 9 deletions

View file

@ -30,8 +30,10 @@ int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p)
if (n->pending_text) { if (n->pending_text) {
if (n->layout) { if (n->layout) {
g_object_unref(n->layout); pango_layout_set_text(n->layout, n->pending_text, -1);
} pango_cairo_update_layout(node->drw, n->layout);
n->pending_text = NULL;
} else {
PangoLayout *layout = pango_cairo_create_layout(n->node.drw); PangoLayout *layout = pango_cairo_create_layout(n->node.drw);
pango_layout_set_font_description(layout, n->desc); pango_layout_set_font_description(layout, n->desc);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
@ -39,6 +41,7 @@ int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p)
n->layout = layout; n->layout = layout;
n->pending_text = NULL; n->pending_text = NULL;
} }
}
switch (ev) { switch (ev) {
case UI_EVENT_REPAINT: { case UI_EVENT_REPAINT: {

View file

@ -3,7 +3,7 @@
#include "timeutil.h" #include "timeutil.h"
#include "window.h" #include "window.h"
#include "node.h" #include "node.h"
//#define PROF #define PROF
#include "prof.c" #include "prof.c"
#include "time.h" #include "time.h"
#include <stdint.h> #include <stdint.h>
@ -170,14 +170,17 @@ void _window_process_xcb_event(UIWindow *window, xcb_generic_event_t *event)
uint8_t event_type = event->response_type & ~0x80; uint8_t event_type = event->response_type & ~0x80;
switch (event_type) { switch (event_type) {
case XCB_EXPOSE: { case XCB_EXPOSE: {
begin_clock("XCB_EXPOSE");
xcb_expose_event_t *ev = (xcb_expose_event_t*)event; xcb_expose_event_t *ev = (xcb_expose_event_t*)event;
UIRect region = { ev->x, ev->y, ev->width, ev->height }; UIRect region = { ev->x, ev->y, ev->width, ev->height };
window->invalid_region = ui_rect_united(&window->invalid_region, &region); window->invalid_region = ui_rect_united(&window->invalid_region, &region);
window_invalidate_node(window, window->root); window_invalidate_node(window, window->root);
end_clock();
break; break;
} }
case XCB_CONFIGURE_NOTIFY: { case XCB_CONFIGURE_NOTIFY: {
begin_clock("XCB_CONFIGURE_NOTIFY");
xcb_configure_notify_event_t *ev = (xcb_configure_notify_event_t*)event; xcb_configure_notify_event_t *ev = (xcb_configure_notify_event_t*)event;
UIRect new_rect = { 0, 0, ev->width, ev->height }; UIRect new_rect = { 0, 0, ev->width, ev->height };
if (!ui_rect_equals(&window->root->rect, &new_rect)) { if (!ui_rect_equals(&window->root->rect, &new_rect)) {
@ -189,10 +192,12 @@ void _window_process_xcb_event(UIWindow *window, xcb_generic_event_t *event)
node_dispatch(window->root, UI_EVENT_RELAYOUT, 0, NULL); node_dispatch(window->root, UI_EVENT_RELAYOUT, 0, NULL);
node_dump(window->root, 0); node_dump(window->root, 0);
} }
end_clock();
break; break;
} }
case XCB_MOTION_NOTIFY: { case XCB_MOTION_NOTIFY: {
begin_clock("XCB_MOTION_NOTIFY");
xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t*)event; xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t*)event;
UINode *node = node_by_point(window->root, ev->event_x, ev->event_y); UINode *node = node_by_point(window->root, ev->event_x, ev->event_y);
if (node && node != window->hovered) { if (node && node != window->hovered) {
@ -203,11 +208,13 @@ void _window_process_xcb_event(UIWindow *window, xcb_generic_event_t *event)
} }
node_dispatch(node, UI_EVENT_HOVERED, 0, NULL); node_dispatch(node, UI_EVENT_HOVERED, 0, NULL);
} }
end_clock();
break; break;
} }
case XCB_BUTTON_RELEASE: /* through */ case XCB_BUTTON_RELEASE: /* through */
case XCB_BUTTON_PRESS: { case XCB_BUTTON_PRESS: {
begin_clock("XCB_BUTTON_PRESS");
xcb_button_press_event_t *ev = (xcb_button_press_event_t*)event; xcb_button_press_event_t *ev = (xcb_button_press_event_t*)event;
UINode *node = node_by_point(window->root, ev->event_x, ev->event_y); UINode *node = node_by_point(window->root, ev->event_x, ev->event_y);
if (node) { if (node) {
@ -258,6 +265,7 @@ void _window_process_xcb_event(UIWindow *window, xcb_generic_event_t *event)
} }
} }
} }
end_clock();
break; break;
} }
@ -329,6 +337,7 @@ int window_turn(UIWindow *window)
clear_summary(); clear_summary();
begin_clock("Frame");
int64_t frame_start_ms = time_current_ms(); int64_t frame_start_ms = time_current_ms();
for (int i = 0; i < UI_WINDOW_MAX_POLL; i++) { for (int i = 0; i < UI_WINDOW_MAX_POLL; i++) {
if (fds[i].revents & POLLNVAL) { if (fds[i].revents & POLLNVAL) {
@ -393,7 +402,9 @@ int window_turn(UIWindow *window)
printf("peak frametime: %ldms\n", frame_peak_ms); printf("peak frametime: %ldms\n", frame_peak_ms);
} }
dump_summary(); end_clock();
dump_summary(stdout);
} }
return 0; return 0;
} }