mirror of https://github.com/buggins/dlangui.git
performance fixes
This commit is contained in:
parent
970928d5f6
commit
fbe9ef75fb
|
@ -8,12 +8,12 @@
|
|||
<multiobj>0</multiobj>
|
||||
<singleFileCompilation>0</singleFileCompilation>
|
||||
<oneobj>0</oneobj>
|
||||
<trace>0</trace>
|
||||
<trace>1</trace>
|
||||
<quiet>0</quiet>
|
||||
<verbose>0</verbose>
|
||||
<vtls>0</vtls>
|
||||
<symdebug>1</symdebug>
|
||||
<optimize>0</optimize>
|
||||
<optimize>1</optimize>
|
||||
<cpu>0</cpu>
|
||||
<isX86_64>0</isX86_64>
|
||||
<isLinux>0</isLinux>
|
||||
|
@ -29,10 +29,10 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useInline>0</useInline>
|
||||
<useInline>1</useInline>
|
||||
<release>0</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
<warnings>0</warnings>
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
<multiobj>0</multiobj>
|
||||
<singleFileCompilation>0</singleFileCompilation>
|
||||
<oneobj>0</oneobj>
|
||||
<trace>0</trace>
|
||||
<trace>1</trace>
|
||||
<quiet>0</quiet>
|
||||
<verbose>0</verbose>
|
||||
<vtls>0</vtls>
|
||||
<symdebug>1</symdebug>
|
||||
<optimize>0</optimize>
|
||||
<optimize>1</optimize>
|
||||
<cpu>0</cpu>
|
||||
<isX86_64>0</isX86_64>
|
||||
<isLinux>0</isLinux>
|
||||
|
@ -29,10 +29,10 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useInline>0</useInline>
|
||||
<useInline>1</useInline>
|
||||
<release>0</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
<warnings>0</warnings>
|
||||
|
@ -68,7 +68,7 @@
|
|||
<versionlevel>0</versionlevel>
|
||||
<versionids>Unicode USE_OPENGL</versionids>
|
||||
<dump_source>0</dump_source>
|
||||
<mapverbosity>0</mapverbosity>
|
||||
<mapverbosity>3</mapverbosity>
|
||||
<createImplib>0</createImplib>
|
||||
<defaultlibname />
|
||||
<debuglibname />
|
||||
|
@ -89,7 +89,7 @@
|
|||
<resfile />
|
||||
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||
<useStdLibPath>1</useStdLibPath>
|
||||
<additionalOptions />
|
||||
<additionalOptions>-profile</additionalOptions>
|
||||
<preBuildCommand />
|
||||
<postBuildCommand />
|
||||
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue