From fbe9ef75fbd8896ca527afab610eb49f2db1768e Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Wed, 2 Apr 2014 13:27:00 +0400 Subject: [PATCH] performance fixes --- dlanguilib.visualdproj | 8 +++--- examples/example1/example1.visualdproj | 12 ++++----- src/dlangui/graphics/fonts.d | 33 ++++++++++++++++--------- src/dlangui/graphics/ftfonts.d | 19 +++++++++++--- src/dlangui/platforms/common/platform.d | 8 +++++- src/dlangui/platforms/windows/winapp.d | 2 +- src/dlangui/widgets/controls.d | 6 +++++ 7 files changed, 62 insertions(+), 26 deletions(-) diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj index 94f5d5d5..02718651 100644 --- a/dlanguilib.visualdproj +++ b/dlanguilib.visualdproj @@ -8,12 +8,12 @@ 0 0 0 - 0 + 1 0 0 0 1 - 0 + 1 0 0 0 @@ -29,10 +29,10 @@ 0 0 0 - 0 + 1 0 0 - 0 + 1 0 0 0 diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj index 7927e2b4..8bd9ffdc 100644 --- a/examples/example1/example1.visualdproj +++ b/examples/example1/example1.visualdproj @@ -8,12 +8,12 @@ 0 0 0 - 0 + 1 0 0 0 1 - 0 + 1 0 0 0 @@ -29,10 +29,10 @@ 0 0 0 - 0 + 1 0 0 - 0 + 1 0 0 0 @@ -68,7 +68,7 @@ 0 Unicode USE_OPENGL 0 - 0 + 3 0 @@ -89,7 +89,7 @@ $(OutDir)\$(ProjectName).exe 1 - + -profile *.obj;*.cmd;*.build;*.json;*.dep diff --git a/src/dlangui/graphics/fonts.d b/src/dlangui/graphics/fonts.d index 3fcf3c6a..e4b47a5b 100644 --- a/src/dlangui/graphics/fonts.d +++ b/src/dlangui/graphics/fonts.d @@ -41,21 +41,29 @@ version (USE_OPENGL) { struct GlyphCache { Glyph[ushort] _map; + Glyph[0x10000] _array; // find glyph in cache Glyph * find(ushort glyphIndex) { - Glyph * res = (glyphIndex in _map); - if (res !is null) - res.lastUsage = 1; - return res; + if (_array[glyphIndex].glyphIndex) + return &_array[glyphIndex]; + return null; + + //Glyph * res = (glyphIndex in _map); + //if (res !is null) + // res.lastUsage = 1; + //return res; } /// put glyph to cache Glyph * put(ushort glyphIndex, Glyph * glyph) { - _map[glyphIndex] = *glyph; - Glyph * res = glyphIndex in _map; - res.lastUsage = 1; - return res; + _array[glyphIndex] = *glyph; + return &_array[glyphIndex]; + + //_map[glyphIndex] = *glyph; + //Glyph * res = glyphIndex in _map; + //res.lastUsage = 1; + //return res; } // clear usage flags for all entries @@ -112,13 +120,16 @@ class Font : RefCountedObject { abstract @property bool isNull(); // measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars. abstract int measureText(const dchar[] text, ref int[] widths, int maxWidth); + private int[] _textSizeBuffer; // to avoid GC // measure text string as single line, returns width and height Point textSize(const dchar[] text, int maxWidth = 3000) { - int[] widths = new int[text.length + 1]; - int charsMeasured = measureText(text, widths, maxWidth); + if (_textSizeBuffer.length < text.length + 1) + _textSizeBuffer.length = text.length + 1; + //int[] widths = new int[text.length + 1]; + int charsMeasured = measureText(text, _textSizeBuffer, maxWidth); if (charsMeasured < 1) return Point(0,0); - return Point(widths[charsMeasured - 1], height); + return Point(_textSizeBuffer[charsMeasured - 1], height); } /// draw text string to buffer abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color); diff --git a/src/dlangui/graphics/ftfonts.d b/src/dlangui/graphics/ftfonts.d index 8374ac65..565320bc 100644 --- a/src/dlangui/graphics/ftfonts.d +++ b/src/dlangui/graphics/ftfonts.d @@ -343,9 +343,16 @@ class FreeTypeFont : Font { override Glyph * getCharGlyph(dchar ch, bool withImage = true) { if (ch > 0xFFFF) // do not support unicode chars above 0xFFFF - due to cache limitations return null; + long measureStart = std.datetime.Clock.currStdTime; Glyph * found = _glyphCache.find(cast(ushort)ch); + long measureEnd = std.datetime.Clock.currStdTime; + long duration = measureEnd - measureStart; + //if (duration > 10000) + if (duration > 10000) + Log.d("ft _glyphCache.find took ", duration / 10, " ns"); if (found !is null) return found; + Log.v("Glyph ", ch, " is not found in cache, getting from font"); FT_UInt index; FreeTypeFontFile file; if (!findGlyph(ch, 0, index, file)) { @@ -391,18 +398,24 @@ class FreeTypeFont : Font { uint len = cast(uint)text.length; int x = 0; int charsMeasured = 0; + int * pwidths = widths.ptr; for (int i = 0; i < len; i++) { - Glyph * glyph = getCharGlyph(text[i], true); // TODO: what is better + //auto measureStart = std.datetime.Clock.currAppTick; + Glyph * glyph = getCharGlyph(pstr[i], true); // TODO: what is better + //auto measureEnd = std.datetime.Clock.currAppTick; + //auto duration = measureEnd - measureStart; + //if (duration.length > 10) + // Log.d("ft measureText took ", duration.length, " ticks"); if (glyph is null) { // if no glyph, use previous width - treat as zero width - widths[i] = i > 0 ? widths[i-1] : 0; + pwidths[i] = i > 0 ? pwidths[i-1] : 0; continue; } int w = x + glyph.width; // using advance int w2 = x + glyph.originX + glyph.blackBoxX; // using black box if (w < w2) // choose bigger value w = w2; - widths[i] = w; + pwidths[i] = w; x += glyph.width; charsMeasured = i + 1; if (x > maxWidth) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index cbf20c0a..17aec500 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -32,8 +32,14 @@ class Window { _dx = width; _dy = height; if (_mainWidget !is null) { + Log.d("onResize ", _dx, "x", _dy); + long measureStart = currentTimeMillis; _mainWidget.measure(_dx, _dy); + long measureEnd = currentTimeMillis; + Log.d("measure took ", measureEnd - measureStart, " ms"); _mainWidget.layout(Rect(0, 0, _dx, _dy)); + long layoutEnd = currentTimeMillis; + Log.d("layout took ", layoutEnd - measureEnd, " ms"); } } @@ -80,7 +86,7 @@ class Window { _mainWidget.layout(Rect(0, 0, _dx, _dy)); long layoutEnd = currentTimeMillis; Log.d("layout took ", layoutEnd - measureEnd, " ms"); - checkUpdateNeeded(needDraw, needLayout, animationActive); + //checkUpdateNeeded(needDraw, needLayout, animationActive); } long drawStart = currentTimeMillis; _mainWidget.onDraw(buf); diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 2a26c992..73fa791d 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -561,7 +561,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int Platform.setInstance(platform); - if (false) { + if (true) { /// testing freetype font manager import dlangui.graphics.ftfonts; import win32.shlobj; diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d index 7c21889e..0e4c9d64 100644 --- a/src/dlangui/widgets/controls.d +++ b/src/dlangui/widgets/controls.d @@ -34,7 +34,13 @@ class TextWidget : Widget { override void measure(int parentWidth, int parentHeight) { FontRef font = font(); + auto measureStart = std.datetime.Clock.currAppTick; Point sz = font.textSize(text); + auto measureEnd = std.datetime.Clock.currAppTick; + auto duration = measureEnd - measureStart; + //if (duration > 10000) + if (duration.length > 10) + Log.d("TextWidget measureText took ", duration.length, " ticks"); measuredContent(parentWidth, parentHeight, sz.x, sz.y); }