Skip to content

Commit

Permalink
Don't buffer any commands to the window server, just process them; yi…
Browse files Browse the repository at this point in the history
…eld between sending/receiving messages; add component destruction
  • Loading branch information
maxdev1 committed Feb 28, 2025
1 parent 516b82a commit 510bacb
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 35 deletions.
5 changes: 4 additions & 1 deletion applications/libwindow/inc/libwindow/component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ class g_component : public g_bounding_component
{
protected:
g_ui_component_id id;
bool destroyed = false;

g_user_mutex listenersLock = g_mutex_initialize_r(true);
std::unordered_map<g_ui_component_event_type, std::vector<g_listener*>> listeners;

~g_component() override = default;
~g_component() override;

template <typename COMPONENT_TYPE, g_ui_component_type COMPONENT_CONSTANT>
static COMPONENT_TYPE* createComponent()
Expand All @@ -58,6 +59,7 @@ class g_component : public g_bounding_component
request.header.id = G_UI_PROTOCOL_CREATE_COMPONENT;
request.type = COMPONENT_CONSTANT;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_create_component_request), tx);
// g_yield_t(g_ui_delegate_tid);

size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_create_component_response);
uint8_t buffer[bufferSize];
Expand Down Expand Up @@ -96,6 +98,7 @@ class g_component : public g_bounding_component
return id;
}

void destroy();
bool addChild(g_component* c);

bool setBounds(const g_rectangle& rect);
Expand Down
10 changes: 10 additions & 0 deletions applications/libwindow/inc/libwindow/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef uint8_t g_ui_protocol_command_id;
#define G_UI_PROTOCOL_SCROLLPANE_SET_CONTENT ((g_ui_protocol_command_id) 18)
#define G_UI_PROTOCOL_SCROLLPANE_SET_FIXED ((g_ui_protocol_command_id) 19)
#define G_UI_PROTOCOL_SET_PREFERRED_SIZE ((g_ui_protocol_command_id) 20)
#define G_UI_PROTOCOL_DESTROY_COMPONENT ((g_ui_protocol_command_id) 21)

/**
* Common status for requests
Expand Down Expand Up @@ -185,6 +186,15 @@ typedef struct
g_ui_component_id id;
} __attribute__((packed)) g_ui_create_component_response;

/**
* Request sent to destroy a component
*/
typedef struct
{
g_ui_message_header header;
g_ui_component_id id;
} __attribute__((packed)) g_ui_destroy_component_request;

/**
* Request/response to focus
*/
Expand Down
2 changes: 1 addition & 1 deletion applications/libwindow/inc/libwindow/metrics/rectangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ struct g_rectangle
*/
void extend(const g_point& p)
{
if (width == -1 || height == -1)
if (width <= 0 || height <= 0)
{
x = p.x;
y = p.y;
Expand Down
1 change: 1 addition & 0 deletions applications/libwindow/src/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,5 @@ void g_canvas::blit(const g_rectangle& rect)
request.id = this->id;
request.area = rect;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_canvas_blit_request), tx);
g_yield_t(g_ui_delegate_tid);
}
26 changes: 26 additions & 0 deletions applications/libwindow/src/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@
#include "libwindow/component.hpp"
#include "libwindow/properties.hpp"

g_component::~g_component()
{
destroy();
}

void g_component::destroy()
{
if(destroyed)
return;
destroyed = true;

g_ui_destroy_component_request request;
request.header.id = G_UI_PROTOCOL_DESTROY_COMPONENT;
request.id = this->id;
g_send_message(g_ui_delegate_tid, &request, sizeof(g_ui_destroy_component_request));
g_yield_t(g_ui_delegate_tid);
}

bool g_component::addChild(g_component* child)
{
if(!g_ui_initialized)
Expand Down Expand Up @@ -66,6 +84,7 @@ bool g_component::setBounds(const g_rectangle& rect)
request.id = this->id;
request.bounds = rect;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_set_bounds_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
Expand All @@ -90,6 +109,7 @@ g_rectangle g_component::getBounds()
request.header.id = G_UI_PROTOCOL_GET_BOUNDS;
request.id = this->id;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_get_bounds_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_get_bounds_response);
Expand Down Expand Up @@ -120,6 +140,7 @@ bool g_component::setNumericProperty(int property, uint32_t value)
request.property = property;
request.value = value;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_set_numeric_property_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_set_numeric_property_response);
Expand Down Expand Up @@ -149,6 +170,7 @@ bool g_component::getNumericProperty(int property, uint32_t* out)
request.id = this->id;
request.property = property;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_get_numeric_property_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_get_numeric_property_response);
Expand Down Expand Up @@ -294,6 +316,7 @@ bool g_component::setPreferredSize(g_dimension size)
request.id = this->id;
request.size = size;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(request), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand All @@ -317,6 +340,7 @@ bool g_component::setFlexOrientation(bool horizontal)
request.id = this->id;
request.horizontal = horizontal;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_flex_set_orientation_request), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand All @@ -343,6 +367,7 @@ bool g_component::setFlexComponentInfo(g_component* child, float grow, float shr
request.shrink = shrink;
request.basis = basis;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_flex_set_component_info), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand All @@ -367,6 +392,7 @@ bool g_component::setFlexPadding(g_insets padding)
request.id = this->id;
request.insets = padding;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_flex_set_padding), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand Down
1 change: 1 addition & 0 deletions applications/libwindow/src/focusable_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ bool g_focusable_component::setFocused(bool focused)
request.header.id = G_UI_PROTOCOL_FOCUS;
request.id = this->id;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_focus_request), tx);
g_yield_t(g_ui_delegate_tid);

size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_focus_response);
uint8_t buffer[bufferSize];
Expand Down
2 changes: 2 additions & 0 deletions applications/libwindow/src/scrollpane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ bool g_scrollpane::setContent(g_component* content)
request.scrollpane = this->id;
request.content = content->getId();
g_send_message_t(g_ui_delegate_tid, &request, sizeof(request), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand All @@ -62,6 +63,7 @@ bool g_scrollpane::setFixed(bool width, bool height)
request.width = width;
request.height = height;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(request), tx);
g_yield_t(g_ui_delegate_tid);

size_t buflen = sizeof(g_message_header) + sizeof(g_ui_simple_response);
uint8_t buffer[buflen];
Expand Down
2 changes: 2 additions & 0 deletions applications/libwindow/src/titled_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ bool g_titled_component::setTitle(std::string title)
request->title[title_len] = 0;

g_send_message_t(g_ui_delegate_tid, request, sizeof(g_ui_component_set_title_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_set_title_response);
Expand Down Expand Up @@ -80,6 +81,7 @@ std::string g_titled_component::getTitle()
request.header.id = G_UI_PROTOCOL_GET_TITLE;
request.id = this->id;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_get_title_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_get_title_response);
Expand Down
4 changes: 4 additions & 0 deletions applications/libwindow/src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ g_ui_open_status g_ui::open()
request.header.id = G_UI_PROTOCOL_INITIALIZATION;
request.event_dispatcher = g_ui_event_dispatcher_tid;
g_send_message_t(windowServerRegistrationTask, &request, sizeof(g_ui_initialize_request), init_tx);
g_yield_t(g_ui_delegate_tid);

// receive initialization response
size_t buflen = sizeof(g_message_header) + sizeof(g_ui_initialize_response);
Expand Down Expand Up @@ -106,6 +107,7 @@ bool g_ui::addListener(g_ui_component_id id, g_ui_component_event_type eventType
request.target_thread = g_ui_event_dispatcher_tid;
request.event_type = eventType;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_add_listener_request), tx);
g_yield_t(g_ui_delegate_tid);

size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_add_listener_response);
uint8_t buffer[bufferSize];
Expand Down Expand Up @@ -169,6 +171,7 @@ bool g_ui::registerDesktopCanvas(g_canvas* c)
request.canvas_id = c->getId();
request.target_thread = g_ui_event_dispatcher_tid;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_register_desktop_canvas_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t buflen = sizeof(g_message_header) + sizeof(g_ui_register_desktop_canvas_response);
Expand Down Expand Up @@ -199,6 +202,7 @@ bool g_ui::getScreenDimension(g_dimension& out)
g_ui_get_screen_dimension_request request;
request.header.id = G_UI_PROTOCOL_GET_SCREEN_DIMENSION;
g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_get_screen_dimension_request), tx);
g_yield_t(g_ui_delegate_tid);

// read response
size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_get_screen_dimension_response);
Expand Down
5 changes: 5 additions & 0 deletions applications/windowserver/src/components/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ void component_t::blit(graphics_t* out, const g_rectangle& parentClip, const g_p
if(!this->visible)
return;

g_mutex_acquire(lock);

g_rectangle clip = getBounds();
clip.x = screenPosition.x;
clip.y = screenPosition.y;
Expand All @@ -179,6 +181,7 @@ void component_t::blit(graphics_t* out, const g_rectangle& parentClip, const g_p
{
graphics.blitTo(out, clip, screenPosition);
}
g_mutex_release(lock);

this->blitChildren(out, clip, screenPosition);
}
Expand Down Expand Up @@ -466,6 +469,7 @@ void component_t::resolveRequirement(component_requirement_t req, int lvl)
g_mutex_release(childrenLock);
}

g_mutex_acquire(lock);
if(requirements & req)
{
if(req == COMPONENT_REQUIREMENT_UPDATE)
Expand All @@ -484,6 +488,7 @@ void component_t::resolveRequirement(component_requirement_t req, int lvl)

requirements &= ~req;
}
g_mutex_release(lock);

if((childRequirements & req) && req == COMPONENT_REQUIREMENT_LAYOUT)
{
Expand Down
46 changes: 18 additions & 28 deletions applications/windowserver/src/interface/interface_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@
#include "interface/interface_receiver.hpp"
#include "layout/flex_layout_manager.hpp"

g_user_mutex eventBufferLock = g_mutex_initialize();
std::vector<g_message_header*> eventBuffer;

void interfaceReceiverThread()
{
while(true)
Expand All @@ -52,20 +49,8 @@ void interfaceReceiverThread()
if(stat == G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL)
{
auto message = (g_message_header*) buf;
auto content = (g_ui_message_header*) G_MESSAGE_CONTENT(message);

if(content->id == G_UI_PROTOCOL_GET_BOUNDS || content->id == G_UI_PROTOCOL_SET_BOUNDS)
{
interfaceReceiverProcessCommand(message);
}
else
{
g_mutex_acquire(eventBufferLock);
eventBuffer.push_back(message);
g_mutex_release(eventBufferLock);
windowserver_t::instance()->requestUpdate();
deferred = true;
}
interfaceReceiverProcessCommand(message);
}
else if(stat == G_MESSAGE_RECEIVE_STATUS_EXCEEDS_BUFFER_SIZE)
{
Expand All @@ -81,18 +66,6 @@ void interfaceReceiverThread()
}
}

void interfaceReceiverProcessBufferedCommands()
{
g_mutex_acquire(eventBufferLock);
for(auto& entry: eventBuffer)
{
interfaceReceiverProcessCommand(entry);
delete entry;
}
eventBuffer.clear();
g_mutex_release(eventBufferLock);
}

void interfaceReceiverProcessCommand(g_message_header* requestMessage)
{
auto requestUiMessage = (g_ui_message_header*) G_MESSAGE_CONTENT(requestMessage);
Expand Down Expand Up @@ -181,6 +154,19 @@ void interfaceReceiverProcessCommand(g_message_header* requestMessage)
responseMessage = response;
responseLength = sizeof(g_ui_component_add_child_response);
}
else if(requestUiMessage->id == G_UI_PROTOCOL_DESTROY_COMPONENT)
{
auto request = (g_ui_destroy_component_request*) requestUiMessage;
component_t* component = component_registry_t::get(request->id);

if(component)
{
auto parent = component->getParent();
if(parent)
parent->removeChild(component);
// TODO deferred component deletion
}
}
else if(requestUiMessage->id == G_UI_PROTOCOL_SET_BOUNDS)
{
auto request = (g_ui_component_set_bounds_request*) requestUiMessage;
Expand Down Expand Up @@ -540,7 +526,11 @@ void interfaceReceiverProcessCommand(g_message_header* requestMessage)
responseLength = sizeof(g_ui_simple_response);
}

windowserver_t::instance()->requestUpdate();

if(responseMessage)
{
g_send_message_t(requestMessage->sender, responseMessage, responseLength, requestMessage->transaction);
g_yield_t(requestMessage->sender);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@

void interfaceReceiverThread();
void interfaceReceiverProcessCommand(g_message_header* requestMessage);
void interfaceReceiverProcessBufferedCommands();

#endif
18 changes: 14 additions & 4 deletions applications/windowserver/src/windowserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,24 +155,30 @@ void windowserver_t::updateLoop()
{
g_task_register_id("windowserver/updater");

int timesUpdated = 0;

g_mutex_acquire(updateLock);
while(true)
{
++timesUpdated;
eventProcessor->process();
interfaceReceiverProcessBufferedCommands();

screen->resolveRequirement(COMPONENT_REQUIREMENT_UPDATE, 0);
screen->resolveRequirement(COMPONENT_REQUIREMENT_LAYOUT, 0);
screen->resolveRequirement(COMPONENT_REQUIREMENT_PAINT, 0);

requestRender();
g_mutex_acquire_to(updateLock, 1000);

if(!g_mutex_acquire_to(updateLock, 1000))
{
klog("Times updated: %i", timesUpdated);
}
}
}

void windowserver_t::requestUpdate() const
{
g_mutex_release(updateLock);
g_yield_t(updateTask);
}


Expand Down Expand Up @@ -223,7 +229,11 @@ void windowserver_t::output(graphics_t* graphics) const
cairo_save(cr);
cairo_set_line_width(cr, 2);
cairo_rectangle(cr, invalid.x, invalid.y, invalid.width, invalid.height);
cairo_set_source_rgba(cr, 0, ((double) (debugBorderCycle + 100)) / 255, 0, 1);
cairo_set_source_rgba(cr,
debugBorderCycle % 3 == 0 ? ((double) (debugBorderCycle + 100)) / 255 : 0,
debugBorderCycle % 2 == 0 ? ((double) (debugBorderCycle + 100)) / 255 : 0,
debugBorderCycle % 2 == 1 ? ((double) (debugBorderCycle + 100)) / 255 : 0,
1);
cairo_stroke(cr);
cairo_restore(cr);
graphics->releaseContext();
Expand Down

0 comments on commit 510bacb

Please sign in to comment.