2 Commits
Author SHA1 Message Date
tobid7 daaf473af7 faster rect command creation 2026-09-01 21:21:40 +02:00
tobid7 9ed3ed233d cache ascii chars directly 2026-09-01 21:20:52 +02:00
4 changed files with 46 additions and 9 deletions
+2
View File
@@ -45,6 +45,8 @@ class PD_API Drawlist {
/** Command Allocation */
Command& NewCommand();
bool HasCommands() { return pCommands.size() > 0; }
Command& GetLastCommand() { return pCommands[pCommands.size() - 1]; }
/** Path API */
void PathAdd(const fvec2& point) { pPath.Push(point); }
+2
View File
@@ -92,6 +92,8 @@ class PD_API Font {
* **Now using unordered map**
*/
std::unordered_map<u32, Codepoint> CodeMap;
/** need some performance tweaks */
std::array<Codepoint, 128> pAsciiCache;
/** TMS */
struct TMELEM {
PD::u32 ID;
+2
View File
@@ -9,6 +9,8 @@ class Vertex {
Vertex() {}
Vertex(const fvec2& pos, const fvec2& uv, u32 color)
: pos(pos), uv(uv), color(color) {}
Vertex(float x, float y, float u, float v, u32 color)
: pos(x, y), uv(u, v), color(color) {}
~Vertex() {}
void Reset() {
+40 -9
View File
@@ -136,11 +136,26 @@ PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
if (!empty) {
BakeAndPush(true, font_tex, texszs);
}
for (u32 i = 0; i < 128; i++) {
auto r = CodeMap.find(i);
if (r == CodeMap.end()) {
static Codepoint invalid;
invalid.pInvalid = true;
pAsciiCache[i] = invalid;
} else {
pAsciiCache[i] = CodeMap[i];
}
}
}
PD_API void Font::LoadDefaultFont(int id, int pixel_height) {}
PD_API Font::Codepoint& Font::GetCodepoint(u32 c) {
if (c < 128) {
// Direct Access (~11% improvement)
return pAsciiCache[c];
}
// Check if codepoijt exist or return a static invalid one
auto res = CodeMap.find(c);
if (res == CodeMap.end()) {
@@ -192,6 +207,17 @@ PD_API fvec2 Font::GetTextBounds(const char* text, float scale) {
return res;
}
PD_API void PrimTextQuad(Command& cmd, float x, float y, float w, float h,
const fvec4& uv, const PD::Color& color) {
cmd.Reserve(4, 6);
cmd.Add(2, 1, 0);
cmd.Add(3, 2, 0);
cmd.Add(Vertex(x, y, uv.x, uv.y, color));
cmd.Add(Vertex(x + w, y, uv.z, uv.y, color));
cmd.Add(Vertex(x + w, y + h, uv.z, uv.w, color));
cmd.Add(Vertex(x, y + h, uv.x, uv.w, color));
}
PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
float scale, const char* text, LiTextFlags flags,
const fvec2& box) {
@@ -210,7 +236,7 @@ PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
U8Iterator it(text);
u32 c;
Command* cmd = nullptr;
Command* cmd = dl.HasCommands() ? &dl.GetLastCommand() : nullptr;
while (it.Decode32(c)) {
auto cp = GetCodepoint(c);
if ((cp.pInvalid && c != L'\n' && c != L'\t' && c != L' ') && c != L'\r')
@@ -237,15 +263,20 @@ PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
cmd->Tex = Textures[cp.Tex];
}
if (flags & LiTextFlags_Shaddow) {
Rect rec = Math::PrimRect(rpos + off + fvec2(1, cp.Offset * cfs + 1),
cp.Size * cfs, 0.f);
dl.PrimQuad(*cmd, rec, cp.SimpleUV, 0xff111111);
}
// calculating once and using PrimTextQuad to directly push
// saves ~42% on raw multiline text draw time 6.3 -> 3.7 ms
// and ~25% on the whole frametime 20.3 -> 15.2 ms
// tested with Craftus-Next 0.8.0 commit:
// 33298ccc276bf996d341710e69ecf05f99c57961
float cw = cp.Size.x * cfs;
float ch = cp.Size.y * cfs;
float cx = rpos.x + off.x;
float cy = rpos.y + off.y + (cp.Offset * cfs);
Rect rec = Math::PrimRect(rpos + off + fvec2(0, cp.Offset * cfs),
cp.Size * cfs, 0.f);
dl.PrimQuad(*cmd, rec, cp.SimpleUV, color);
if (flags & LiTextFlags_Shaddow) {
PrimTextQuad(*cmd, cx + 1.f, cy + 1.f, cw, ch, cp.SimpleUV, 0xff111111);
}
PrimTextQuad(*cmd, cx, cy, cw, ch, cp.SimpleUV, color);
off.x += cp.Size.x * cfs + 2 * cfs;
}