From 3ba01fa09d2d0c6702269a0eab0c696435c0cbdd Mon Sep 17 00:00:00 2001
From: nakst <>
Date: Fri, 21 Jan 2022 09:32:59 +0000
Subject: [PATCH] faster painting of partially opaque windows

---
 kernel/windows.cpp | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/kernel/windows.cpp b/kernel/windows.cpp
index 199efa3..2d43d32 100644
--- a/kernel/windows.cpp
+++ b/kernel/windows.cpp
@@ -1034,15 +1034,28 @@ void WindowManager::Redraw(EsPoint position, int width, int height, Window *exce
 
 		if (!ES_RECT_VALID(rectangle)) continue;
 
-		EsPoint point = ES_POINT(window->position.x + rectangle.l, window->position.y + rectangle.t);
 		Surface *surface = &window->surface;
 
-		if (window->opaqueBounds.l <= rectangle.l && window->opaqueBounds.r >= rectangle.r 
-				&& window->opaqueBounds.t <= rectangle.t && window->opaqueBounds.b >= rectangle.b) {
-			graphics.frameBuffer.Copy(surface, point, rectangle, addToModifiedRegion);
-		} else {
-			EsRectangle blurRegion = Translate(EsRectangleIntersection(window->blurBounds, rectangle), window->position.x, window->position.y);
-			graphics.frameBuffer.BlendWindow(surface, point, rectangle, window->material, window->alpha, blurRegion);
+		EsRectangle transparentRegions[] = {
+			EsRectangleIntersection(rectangle, ES_RECT_4(0, window->opaqueBounds.l, 0, window->height)),
+			EsRectangleIntersection(rectangle, ES_RECT_4(window->opaqueBounds.r, window->width, 0, window->height)),
+			EsRectangleIntersection(rectangle, ES_RECT_4(window->opaqueBounds.l, window->opaqueBounds.r, 0, window->opaqueBounds.t)),
+			EsRectangleIntersection(rectangle, ES_RECT_4(window->opaqueBounds.l, window->opaqueBounds.r, window->opaqueBounds.b, window->height)),
+		};
+
+		EsRectangle opaqueRegion = EsRectangleIntersection(rectangle, window->opaqueBounds);
+		EsRectangle blurRegion = Translate(EsRectangleIntersection(window->blurBounds, rectangle), window->position.x, window->position.y);
+
+		for (uintptr_t i = 0; i < 4; i++) {
+			if (ES_RECT_VALID(transparentRegions[i])) {
+				EsPoint point = ES_POINT(window->position.x + transparentRegions[i].l, window->position.y + transparentRegions[i].t);
+				graphics.frameBuffer.BlendWindow(surface, point, transparentRegions[i], window->material, window->alpha, blurRegion);
+			}
+		}
+
+		if (ES_RECT_VALID(opaqueRegion)) {
+			EsPoint point = ES_POINT(window->position.x + opaqueRegion.l, window->position.y + opaqueRegion.t);
+			graphics.frameBuffer.Copy(surface, point, opaqueRegion, addToModifiedRegion);
 		}
 	}
 }