From 96e5a7081b697fd088f5365df5f475f16125a22e Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Thu, 1 May 2025 23:49:01 +0100 Subject: [PATCH] clip rect and text drawing that go offscreen. this is already handled by the gpu, but cpu side still has to do some work. this wasn't a performance issue (we only use 4%) but its a free win, so we might as well. --- sphaira/source/ui/nvg_util.cpp | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/sphaira/source/ui/nvg_util.cpp b/sphaira/source/ui/nvg_util.cpp index 03a0169..987cdf4 100644 --- a/sphaira/source/ui/nvg_util.cpp +++ b/sphaira/source/ui/nvg_util.cpp @@ -1,4 +1,5 @@ #include "ui/nvg_util.hpp" +#include "log.hpp" #include #include #include @@ -10,6 +11,9 @@ namespace sphaira::ui::gfx { namespace { +constexpr auto ALIGN_HOR = NVG_ALIGN_LEFT|NVG_ALIGN_CENTER|NVG_ALIGN_RIGHT; +constexpr auto ALIGN_VER = NVG_ALIGN_TOP|NVG_ALIGN_MIDDLE|NVG_ALIGN_BOTTOM|NVG_ALIGN_BASELINE; + constexpr std::array buttons = { std::pair{Button::A, "\uE0E0"}, std::pair{Button::B, "\uE0E1"}, @@ -33,8 +37,29 @@ constexpr std::array buttons = { std::pair{Button::R3, "\uE105"}, }; +// software based clipping, saves a few cpu cycles. +bool ClipRect(float x, float y) { + return x >= SCREEN_WIDTH || y >= SCREEN_HEIGHT; +} + +bool ClipText(float x, float y, int align) { + if ((!(align & ALIGN_HOR) || (align & NVG_ALIGN_LEFT)) && x >= SCREEN_WIDTH) { + return true; + } + + if ((!(align & ALIGN_VER) || (align & NVG_ALIGN_TOP)) && y >= SCREEN_HEIGHT) { + return true; + } + + return false; +} + // NEW --------------------- void drawRectIntenal(NVGcontext* vg, const Vec4& v, const NVGcolor& c, float rounded) { + if (ClipRect(v.x, v.y)) { + return; + } + nvgBeginPath(vg); nvgRoundedRect(vg, v.x, v.y, v.w, v.h, rounded); nvgFillColor(vg, c); @@ -42,6 +67,10 @@ void drawRectIntenal(NVGcontext* vg, const Vec4& v, const NVGcolor& c, float rou } void drawRectIntenal(NVGcontext* vg, const Vec4& v, const NVGpaint& p, float rounded) { + if (ClipRect(v.x, v.y)) { + return; + } + nvgBeginPath(vg); nvgRoundedRect(vg, v.x, v.y, v.w, v.h, rounded); nvgFillPaint(vg, p); @@ -120,6 +149,10 @@ void drawRectOutlineInternal(NVGcontext* vg, const Theme* theme, float size, con } void drawRectOutlineInternal(NVGcontext* vg, const Theme* theme, float size, const Vec4& v, const NVGcolor& c) { + if (ClipRect(v.x, v.y)) { + return; + } + const auto corner_radius = 0.5; drawRectOutlineInternal(vg, theme, size, v); nvgBeginPath(vg); @@ -129,6 +162,10 @@ void drawRectOutlineInternal(NVGcontext* vg, const Theme* theme, float size, con } void drawTextIntenal(NVGcontext* vg, const Vec2& v, float size, const char* str, const char* end, int align, const NVGcolor& c) { + if (ClipText(v.x, v.y, align)) { + return; + } + nvgBeginPath(vg); nvgFontSize(vg, size); nvgTextAlign(vg, align); @@ -166,6 +203,10 @@ void drawImage(NVGcontext* vg, float x, float y, float w, float h, int texture, } void drawTextBox(NVGcontext* vg, float x, float y, float size, float bound, const NVGcolor& c, const char* str, int align, const char* end) { + if (ClipText(x, y, align)) { + return; + } + nvgBeginPath(vg); nvgFontSize(vg, size); nvgTextAlign(vg, align);