perf(effects): cull off-screen card effects and sample border by arc
Glass cards scrolled out of view still ran their full effect path, and the rainbow border always used a segment count derived from a fixed per-pixel budget, so wide cards drew far more line segments than their slowly changing gradient needed. - A glass panel whose rectangle lies wholly outside the draw list's clip rect now returns early, so a scrolled-out card draws nothing (its border and ember passes are skipped along with the fill). - The rainbow border is split into segments by perimeter arc length: straight edges get one segment per ~32 dp, corner arcs get a few chords each to stay round, and a fully transparent border is skipped outright. A wide card now draws tens of segments instead of a couple hundred, with no visible change. Tests: the segment fractions are ascending and bounded, each corner arc keeps at least three chords, and the rect-cull margin test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,8 @@
|
||||
#include "ui/node_status_banner.h"
|
||||
#include "ui/staleness_badge.h"
|
||||
#include "ui/effects/effect_clock.h"
|
||||
#include "ui/effects/border_sampling.h"
|
||||
#include "ui/material/rect_cull.h"
|
||||
#include "ui/notifications.h"
|
||||
#include "data/seed_migration_resume.h"
|
||||
#include "data/pin_vault_policy.h"
|
||||
@@ -13513,6 +13515,30 @@ void testEffectClock() {
|
||||
EXPECT_NEAR(radSin(1e6, 0.0, 1.5707963267948966), 1.0f, 1e-6f);
|
||||
}
|
||||
|
||||
void testBorderSampling() {
|
||||
using namespace dragonx::ui::effects; float fr[129];
|
||||
int n = BorderSampleFractions(500, 150, 8, 32, fr, 129);
|
||||
EXPECT_TRUE(n >= 40 && n <= 80); // old formula: ~210
|
||||
EXPECT_EQ(fr[0], 0.0f); EXPECT_EQ(fr[n], 1.0f);
|
||||
for (int i = 1; i <= n; ++i) EXPECT_TRUE(fr[i] > fr[i - 1]);
|
||||
n = BorderSampleFractions(3000, 800, 12, 32, fr, 129); EXPECT_TRUE(n <= 128); // old: 256
|
||||
n = BorderSampleFractions(300, 100, 0, 32, fr, 129); EXPECT_TRUE(n >= 4 && n <= 40); // r=0 rectangle
|
||||
// each corner arc keeps >= 3 chords: top-right arc spans [s1/P, s2/P]
|
||||
{ float r = 12, w = 400, h = 120, P = 2*(w-2*r) + 2*(h-2*r) + 4*(3.14159265f*r*0.5f);
|
||||
n = BorderSampleFractions(w, h, r, 32, fr, 129);
|
||||
float lo = (w-2*r)/P, hi = lo + 3.14159265f*r*0.5f/P; int c = 0;
|
||||
for (int i = 1; i <= n; ++i) if (fr[i] > lo + 1e-5f && fr[i] <= hi + 1e-5f) ++c;
|
||||
EXPECT_TRUE(c >= 3); }
|
||||
n = BorderSampleFractions(0, 50, 4, 32, fr, 129); EXPECT_EQ(n, 1); // degenerate
|
||||
}
|
||||
void testRectCull() {
|
||||
using namespace dragonx::ui::material; ImVec2 a(0,0), b(100,100);
|
||||
EXPECT_TRUE(!RectOutsideRect(ImVec2(10,10), ImVec2(50,50), a, b, 0));
|
||||
EXPECT_TRUE(RectOutsideRect(ImVec2(0,150), ImVec2(80,250), a, b, 16)); // below
|
||||
EXPECT_TRUE(!RectOutsideRect(ImVec2(0,110), ImVec2(80,250), a, b, 16)); // inside margin
|
||||
EXPECT_TRUE(RectOutsideRect(ImVec2(-90,0), ImVec2(-20,50), a, b, 16)); // left
|
||||
}
|
||||
|
||||
// The effective pool list = official pools ∪ saved favorites ∪ current custom pool,
|
||||
// endpoint-deduped, with synthetic user rows flagged official=false.
|
||||
void testEffectivePools()
|
||||
@@ -18249,6 +18275,8 @@ int main()
|
||||
testPoolFeeParsing();
|
||||
testEffectivePools();
|
||||
testEffectClock();
|
||||
testBorderSampling();
|
||||
testRectCull();
|
||||
testFormatFeePercent();
|
||||
testPoolWeightedSelection();
|
||||
testCoalescingWriter();
|
||||
|
||||
Reference in New Issue
Block a user