1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:47:36 +00:00

WindowServer: Support windows with alpha channels. And per-WSWindow opacity.

This patch also adds a Format concept to GraphicsBitmap. For now there are
only two formats: RGB32 and RGBA32. Windows with alpha channel have their
backing stores created in the RGBA32 format.

Use this to make Terminal windows semi-transparent for that comfy rice look.
There is one problem here, in that window compositing overdraw incurs
multiple passes of blending of the same pixels. This leads to a mismatch in
opacity which is obviously not good. I will work on this in a later patch.

The alpha blending is currently straight C++. It should be relatively easy
to optimize this using SSE instructions.

For now I'm just happy with the cute effect. :^)
This commit is contained in:
Andreas Kling 2019-02-19 01:42:53 +01:00
parent d4973842c9
commit 9b71307d49
25 changed files with 244 additions and 71 deletions

View file

@ -79,14 +79,14 @@ void WSClientConnection::post_message(const WSAPI_ServerMessage& message)
ASSERT(nwritten == sizeof(message));
}
RetainPtr<GraphicsBitmap> WSClientConnection::create_shared_bitmap(const Size& size)
RetainPtr<GraphicsBitmap> WSClientConnection::create_shared_bitmap(GraphicsBitmap::Format format, const Size& size)
{
RGBA32* buffer;
int shared_buffer_id = create_shared_buffer(m_pid, size.area() * sizeof(RGBA32), (void**)&buffer);
ASSERT(shared_buffer_id >= 0);
ASSERT(buffer);
ASSERT(buffer != (void*)-1);
return GraphicsBitmap::create_with_shared_buffer(shared_buffer_id, size, buffer);
return GraphicsBitmap::create_with_shared_buffer(format, shared_buffer_id, size, buffer);
}
void WSClientConnection::on_message(WSMessage& message)
@ -236,6 +236,18 @@ void WSClientConnection::handle_request(WSAPIAddMenuSeparatorRequest& request)
post_message(response);
}
void WSClientConnection::handle_request(WSAPISetWindowOpacityRequest& request)
{
int window_id = request.window_id();
auto it = m_windows.find(window_id);
if (it == m_windows.end()) {
post_error("Bad window ID");
return;
}
auto& window = *(*it).value;
window.set_opacity(request.opacity());
}
void WSClientConnection::handle_request(WSAPISetWindowTitleRequest& request)
{
int window_id = request.window_id();
@ -298,8 +310,10 @@ void WSClientConnection::handle_request(WSAPICreateWindowRequest& request)
{
int window_id = m_next_window_id++;
auto window = make<WSWindow>(*this, window_id);
window->set_has_alpha_channel(request.has_alpha_channel());
window->set_title(request.title());
window->set_rect(request.rect());
window->set_opacity(request.opacity());
m_windows.set(window_id, move(window));
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::DidCreateWindow;
@ -364,6 +378,7 @@ void WSClientConnection::handle_request(WSAPIGetWindowBackingStoreRequest& reque
response.backing.bpp = sizeof(RGBA32);
response.backing.pitch = backing_store->pitch();
response.backing.size = backing_store->size();
response.backing.has_alpha_channel = backing_store->has_alpha_channel();
response.backing.shared_buffer_id = backing_store->shared_buffer_id();
post_message(response);
}
@ -419,6 +434,8 @@ void WSClientConnection::on_request(WSAPIClientRequest& request)
return handle_request(static_cast<WSAPIGetWindowBackingStoreRequest&>(request));
case WSMessage::APISetGlobalCursorTrackingRequest:
return handle_request(static_cast<WSAPISetGlobalCursorTrackingRequest&>(request));
case WSMessage::APISetWindowOpacityRequest:
return handle_request(static_cast<WSAPISetWindowOpacityRequest&>(request));
default:
break;
}