From b8eda519d0701f2700976ab71d58cd96f35b0181 Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Wed, 8 Feb 2023 10:44:12 +0300 Subject: [PATCH] Optimize `draw_dashed_line()` and `draw_rect()` --- scene/main/canvas_item.cpp | 51 ++++++++++++++------------------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 906b478eb34..e5dcdd2afd3 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -530,10 +530,18 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons if (p_aligned) { off += (p_to - p_from).normalized() * (length - steps * p_dash) / 2.0; } + + Vector points; + points.resize(steps + 1); for (int i = 0; i < steps; i += 2) { - RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, (i == 0) ? p_from : off, (p_aligned && i == steps - 1) ? p_to : (off + step), p_color, p_width); + points.write[i] = (i == 0) ? p_from : off; + points.write[i + 1] = (p_aligned && i == steps - 1) ? p_to : (off + step); off += step * 2; } + + Vector colors = { p_color }; + + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width); } void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, bool p_antialiased) { @@ -599,38 +607,17 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil } else if (p_width >= rect.size.width || p_width >= rect.size.height) { RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color); } else { - // Thick lines are offset depending on their width to avoid partial overlapping. - // Thin lines are drawn without offset. The result may not be perfect. - real_t offset = (p_width >= 0) ? 0.5f * p_width : 0.0f; + Vector points; + points.resize(5); + points.write[0] = rect.position; + points.write[1] = rect.position + Vector2(rect.size.x, 0); + points.write[2] = rect.position + rect.size; + points.write[3] = rect.position + Vector2(0, rect.size.y); + points.write[4] = rect.position; - // Top line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(-offset, 0), - rect.position + Size2(-offset + rect.size.width, 0), - p_color, - p_width); - // Right line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(rect.size.width, -offset), - rect.position + Size2(rect.size.width, -offset + rect.size.height), - p_color, - p_width); - // Bottom line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(offset + rect.size.width, rect.size.height), - rect.position + Size2(offset, rect.size.height), - p_color, - p_width); - // Left line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(0, offset + rect.size.height), - rect.position + Size2(0, offset), - p_color, - p_width); + Vector colors = { p_color }; + + RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width); } }