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>
|
<multiobj>0</multiobj>
|
||||||
<singleFileCompilation>0</singleFileCompilation>
|
<singleFileCompilation>0</singleFileCompilation>
|
||||||
<oneobj>0</oneobj>
|
<oneobj>0</oneobj>
|
||||||
<trace>0</trace>
|
<trace>1</trace>
|
||||||
<quiet>0</quiet>
|
<quiet>0</quiet>
|
||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
<vtls>0</vtls>
|
<vtls>0</vtls>
|
||||||
<symdebug>1</symdebug>
|
<symdebug>1</symdebug>
|
||||||
<optimize>0</optimize>
|
<optimize>1</optimize>
|
||||||
<cpu>0</cpu>
|
<cpu>0</cpu>
|
||||||
<isX86_64>0</isX86_64>
|
<isX86_64>0</isX86_64>
|
||||||
<isLinux>0</isLinux>
|
<isLinux>0</isLinux>
|
||||||
|
@ -29,10 +29,10 @@
|
||||||
<useIn>0</useIn>
|
<useIn>0</useIn>
|
||||||
<useOut>0</useOut>
|
<useOut>0</useOut>
|
||||||
<useArrayBounds>0</useArrayBounds>
|
<useArrayBounds>0</useArrayBounds>
|
||||||
<noboundscheck>0</noboundscheck>
|
<noboundscheck>1</noboundscheck>
|
||||||
<useSwitchError>0</useSwitchError>
|
<useSwitchError>0</useSwitchError>
|
||||||
<useUnitTests>0</useUnitTests>
|
<useUnitTests>0</useUnitTests>
|
||||||
<useInline>0</useInline>
|
<useInline>1</useInline>
|
||||||
<release>0</release>
|
<release>0</release>
|
||||||
<preservePaths>0</preservePaths>
|
<preservePaths>0</preservePaths>
|
||||||
<warnings>0</warnings>
|
<warnings>0</warnings>
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
<multiobj>0</multiobj>
|
<multiobj>0</multiobj>
|
||||||
<singleFileCompilation>0</singleFileCompilation>
|
<singleFileCompilation>0</singleFileCompilation>
|
||||||
<oneobj>0</oneobj>
|
<oneobj>0</oneobj>
|
||||||
<trace>0</trace>
|
<trace>1</trace>
|
||||||
<quiet>0</quiet>
|
<quiet>0</quiet>
|
||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
<vtls>0</vtls>
|
<vtls>0</vtls>
|
||||||
<symdebug>1</symdebug>
|
<symdebug>1</symdebug>
|
||||||
<optimize>0</optimize>
|
<optimize>1</optimize>
|
||||||
<cpu>0</cpu>
|
<cpu>0</cpu>
|
||||||
<isX86_64>0</isX86_64>
|
<isX86_64>0</isX86_64>
|
||||||
<isLinux>0</isLinux>
|
<isLinux>0</isLinux>
|
||||||
|
@ -29,10 +29,10 @@
|
||||||
<useIn>0</useIn>
|
<useIn>0</useIn>
|
||||||
<useOut>0</useOut>
|
<useOut>0</useOut>
|
||||||
<useArrayBounds>0</useArrayBounds>
|
<useArrayBounds>0</useArrayBounds>
|
||||||
<noboundscheck>0</noboundscheck>
|
<noboundscheck>1</noboundscheck>
|
||||||
<useSwitchError>0</useSwitchError>
|
<useSwitchError>0</useSwitchError>
|
||||||
<useUnitTests>0</useUnitTests>
|
<useUnitTests>0</useUnitTests>
|
||||||
<useInline>0</useInline>
|
<useInline>1</useInline>
|
||||||
<release>0</release>
|
<release>0</release>
|
||||||
<preservePaths>0</preservePaths>
|
<preservePaths>0</preservePaths>
|
||||||
<warnings>0</warnings>
|
<warnings>0</warnings>
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>Unicode USE_OPENGL</versionids>
|
<versionids>Unicode USE_OPENGL</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>3</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
<defaultlibname />
|
<defaultlibname />
|
||||||
<debuglibname />
|
<debuglibname />
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
<resfile />
|
<resfile />
|
||||||
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||||
<useStdLibPath>1</useStdLibPath>
|
<useStdLibPath>1</useStdLibPath>
|
||||||
<additionalOptions />
|
<additionalOptions>-profile</additionalOptions>
|
||||||
<preBuildCommand />
|
<preBuildCommand />
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
||||||
|
|
|
@ -41,21 +41,29 @@ version (USE_OPENGL) {
|
||||||
struct GlyphCache
|
struct GlyphCache
|
||||||
{
|
{
|
||||||
Glyph[ushort] _map;
|
Glyph[ushort] _map;
|
||||||
|
Glyph[0x10000] _array;
|
||||||
|
|
||||||
// find glyph in cache
|
// find glyph in cache
|
||||||
Glyph * find(ushort glyphIndex) {
|
Glyph * find(ushort glyphIndex) {
|
||||||
Glyph * res = (glyphIndex in _map);
|
if (_array[glyphIndex].glyphIndex)
|
||||||
if (res !is null)
|
return &_array[glyphIndex];
|
||||||
res.lastUsage = 1;
|
return null;
|
||||||
return res;
|
|
||||||
|
//Glyph * res = (glyphIndex in _map);
|
||||||
|
//if (res !is null)
|
||||||
|
// res.lastUsage = 1;
|
||||||
|
//return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// put glyph to cache
|
/// put glyph to cache
|
||||||
Glyph * put(ushort glyphIndex, Glyph * glyph) {
|
Glyph * put(ushort glyphIndex, Glyph * glyph) {
|
||||||
_map[glyphIndex] = *glyph;
|
_array[glyphIndex] = *glyph;
|
||||||
Glyph * res = glyphIndex in _map;
|
return &_array[glyphIndex];
|
||||||
res.lastUsage = 1;
|
|
||||||
return res;
|
//_map[glyphIndex] = *glyph;
|
||||||
|
//Glyph * res = glyphIndex in _map;
|
||||||
|
//res.lastUsage = 1;
|
||||||
|
//return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear usage flags for all entries
|
// clear usage flags for all entries
|
||||||
|
@ -112,13 +120,16 @@ class Font : RefCountedObject {
|
||||||
abstract @property bool isNull();
|
abstract @property bool isNull();
|
||||||
// measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars.
|
// 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);
|
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
|
// measure text string as single line, returns width and height
|
||||||
Point textSize(const dchar[] text, int maxWidth = 3000) {
|
Point textSize(const dchar[] text, int maxWidth = 3000) {
|
||||||
int[] widths = new int[text.length + 1];
|
if (_textSizeBuffer.length < text.length + 1)
|
||||||
int charsMeasured = measureText(text, widths, maxWidth);
|
_textSizeBuffer.length = text.length + 1;
|
||||||
|
//int[] widths = new int[text.length + 1];
|
||||||
|
int charsMeasured = measureText(text, _textSizeBuffer, maxWidth);
|
||||||
if (charsMeasured < 1)
|
if (charsMeasured < 1)
|
||||||
return Point(0,0);
|
return Point(0,0);
|
||||||
return Point(widths[charsMeasured - 1], height);
|
return Point(_textSizeBuffer[charsMeasured - 1], height);
|
||||||
}
|
}
|
||||||
/// draw text string to buffer
|
/// draw text string to buffer
|
||||||
abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color);
|
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) {
|
override Glyph * getCharGlyph(dchar ch, bool withImage = true) {
|
||||||
if (ch > 0xFFFF) // do not support unicode chars above 0xFFFF - due to cache limitations
|
if (ch > 0xFFFF) // do not support unicode chars above 0xFFFF - due to cache limitations
|
||||||
return null;
|
return null;
|
||||||
|
long measureStart = std.datetime.Clock.currStdTime;
|
||||||
Glyph * found = _glyphCache.find(cast(ushort)ch);
|
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)
|
if (found !is null)
|
||||||
return found;
|
return found;
|
||||||
|
Log.v("Glyph ", ch, " is not found in cache, getting from font");
|
||||||
FT_UInt index;
|
FT_UInt index;
|
||||||
FreeTypeFontFile file;
|
FreeTypeFontFile file;
|
||||||
if (!findGlyph(ch, 0, index, file)) {
|
if (!findGlyph(ch, 0, index, file)) {
|
||||||
|
@ -391,18 +398,24 @@ class FreeTypeFont : Font {
|
||||||
uint len = cast(uint)text.length;
|
uint len = cast(uint)text.length;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int charsMeasured = 0;
|
int charsMeasured = 0;
|
||||||
|
int * pwidths = widths.ptr;
|
||||||
for (int i = 0; i < len; i++) {
|
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 (glyph is null) {
|
||||||
// if no glyph, use previous width - treat as zero width
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
int w = x + glyph.width; // using advance
|
int w = x + glyph.width; // using advance
|
||||||
int w2 = x + glyph.originX + glyph.blackBoxX; // using black box
|
int w2 = x + glyph.originX + glyph.blackBoxX; // using black box
|
||||||
if (w < w2) // choose bigger value
|
if (w < w2) // choose bigger value
|
||||||
w = w2;
|
w = w2;
|
||||||
widths[i] = w;
|
pwidths[i] = w;
|
||||||
x += glyph.width;
|
x += glyph.width;
|
||||||
charsMeasured = i + 1;
|
charsMeasured = i + 1;
|
||||||
if (x > maxWidth)
|
if (x > maxWidth)
|
||||||
|
|
|
@ -32,8 +32,14 @@ class Window {
|
||||||
_dx = width;
|
_dx = width;
|
||||||
_dy = height;
|
_dy = height;
|
||||||
if (_mainWidget !is null) {
|
if (_mainWidget !is null) {
|
||||||
|
Log.d("onResize ", _dx, "x", _dy);
|
||||||
|
long measureStart = currentTimeMillis;
|
||||||
_mainWidget.measure(_dx, _dy);
|
_mainWidget.measure(_dx, _dy);
|
||||||
|
long measureEnd = currentTimeMillis;
|
||||||
|
Log.d("measure took ", measureEnd - measureStart, " ms");
|
||||||
_mainWidget.layout(Rect(0, 0, _dx, _dy));
|
_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));
|
_mainWidget.layout(Rect(0, 0, _dx, _dy));
|
||||||
long layoutEnd = currentTimeMillis;
|
long layoutEnd = currentTimeMillis;
|
||||||
Log.d("layout took ", layoutEnd - measureEnd, " ms");
|
Log.d("layout took ", layoutEnd - measureEnd, " ms");
|
||||||
checkUpdateNeeded(needDraw, needLayout, animationActive);
|
//checkUpdateNeeded(needDraw, needLayout, animationActive);
|
||||||
}
|
}
|
||||||
long drawStart = currentTimeMillis;
|
long drawStart = currentTimeMillis;
|
||||||
_mainWidget.onDraw(buf);
|
_mainWidget.onDraw(buf);
|
||||||
|
|
|
@ -561,7 +561,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
|
||||||
Platform.setInstance(platform);
|
Platform.setInstance(platform);
|
||||||
|
|
||||||
|
|
||||||
if (false) {
|
if (true) {
|
||||||
/// testing freetype font manager
|
/// testing freetype font manager
|
||||||
import dlangui.graphics.ftfonts;
|
import dlangui.graphics.ftfonts;
|
||||||
import win32.shlobj;
|
import win32.shlobj;
|
||||||
|
|
|
@ -34,7 +34,13 @@ class TextWidget : Widget {
|
||||||
|
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
|
auto measureStart = std.datetime.Clock.currAppTick;
|
||||||
Point sz = font.textSize(text);
|
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);
|
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue