diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj index 02718651..c6afebba 100644 --- a/dlanguilib.visualdproj +++ b/dlanguilib.visualdproj @@ -8,7 +8,7 @@ 0 0 0 - 1 + 0 0 0 0 @@ -29,7 +29,7 @@ 0 0 0 - 1 + 0 0 0 1 diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj index 8bd9ffdc..a058304d 100644 --- a/examples/example1/example1.visualdproj +++ b/examples/example1/example1.visualdproj @@ -8,7 +8,7 @@ 0 0 0 - 1 + 0 0 0 0 @@ -32,7 +32,7 @@ 1 0 0 - 1 + 0 0 0 0 diff --git a/examples/test/main.d b/examples/test/main.d index cdab8252..ad5418bd 100644 --- a/examples/test/main.d +++ b/examples/test/main.d @@ -1,38 +1,24 @@ module main; -import std.stdio; - -//class Foo { -// int _data; -// this(int v) { -// _data = v; -// } -// @property int data() const { return _data; } -//} -// -//struct Bar { -// int _data; -// @property int data() const { return _data; } -//} -// -//class Foo2 { -//} +struct Foo // must be struct to reproduce +{ + uint foo; // any data can be here +} +struct Bar // must be struct to reproduce +{ + // DMD 2.065 hang with 100% CPU load + // works ok if array size is reduced + //Foo[0x20000] _array; + // 0x4000 - < 1 second + // 0x8000 - 5 seconds + // 0xC000 - 15 seconds + // 0xE000 - 20 seconds + // 0x10000 - 25 seconds + // 0x20000 - 1:45 +} + int main(string[] argv) { - //Foo2 foo2 = new Foo2(); - //Foo2 foo22 = new Foo2(); - //const(Foo2) cfoo2 = foo2; - //cfoo2 = foo22; - //Foo obj = new Foo(1); - //Foo obj2 = new Foo(2); - //const Bar bar1; - //writeln("bar1.data=", bar1.data); - //const(Foo) constptr; - //constptr = obj; - //writeln("data=", obj.data); - //writeln("data=", constptr.data); - //constptr = obj2; - //writeln("data=", constptr.data); return 0; } diff --git a/src/dlangui/graphics/fonts.d b/src/dlangui/graphics/fonts.d index e4b47a5b..02c1502e 100644 --- a/src/dlangui/graphics/fonts.d +++ b/src/dlangui/graphics/fonts.d @@ -40,14 +40,22 @@ version (USE_OPENGL) { /// font glyph cache struct GlyphCache { - Glyph[ushort] _map; - Glyph[0x10000] _array; + //Glyph[ushort] _map; + Glyph[][256] _glyphs; + + //Glyph[] _array; // find glyph in cache Glyph * find(ushort glyphIndex) { - if (_array[glyphIndex].glyphIndex) - return &_array[glyphIndex]; - return null; + //if (_array is null) + // _array = new Glyph[0x10000]; + ushort p = glyphIndex >> 8; + if (_glyphs[p] is null) + return null; + return &_glyphs[p][glyphIndex & 0xFF]; + //if (_array[glyphIndex].glyphIndex) + // return &_array[glyphIndex]; + //return null; //Glyph * res = (glyphIndex in _map); //if (res !is null) @@ -57,8 +65,15 @@ struct GlyphCache /// put glyph to cache Glyph * put(ushort glyphIndex, Glyph * glyph) { - _array[glyphIndex] = *glyph; - return &_array[glyphIndex]; + ushort p = glyphIndex >> 8; + ushort i = glyphIndex & 0xFF; + if (_glyphs[p] is null) + _glyphs[p] = new Glyph[256]; + _glyphs[p][i] = *glyph; + return &_glyphs[p][i]; // = *glyph; + + //_array[glyphIndex] = *glyph; + //return &_array[glyphIndex]; //_map[glyphIndex] = *glyph; //Glyph * res = glyphIndex in _map; @@ -68,40 +83,113 @@ struct GlyphCache // clear usage flags for all entries void checkpoint() { - foreach(ref Glyph item; _map) { - item.lastUsage = 0; + //foreach(ref Glyph item; _map) { + // item.lastUsage = 0; + //} + foreach(ref Glyph[] part; _glyphs) { + if (part !is null) + foreach(ref Glyph item; part) { + item.lastUsage = 0; + } } + //foreach(ref Glyph item; _array) { + // item.lastUsage = 0; + //} } /// removes entries not used after last call of checkpoint() or cleanup() void cleanup() { - uint dst = 0; + //uint dst = 0; // notify about destroyed glyphs version (USE_OPENGL) { - if (_glyphDestroyCallback !is null) - foreach(ref Glyph item; _map) { - if (item.lastUsage == 0) - _glyphDestroyCallback(item.id); - } + if (_glyphDestroyCallback !is null) { + foreach(ref Glyph[] part; _glyphs) { + if (part !is null) + foreach(ref Glyph item; part) { + if (item.lastUsage == 0 && item.glyphIndex) + _glyphDestroyCallback(item.id); + } + } + //foreach(ref Glyph item; _map) { + // if (item.lastUsage == 0) + // _glyphDestroyCallback(item.id); + //} + } } - ushort[] forDelete; - foreach(ref Glyph item; _map) - if (item.lastUsage == 0) - forDelete ~= item.glyphIndex; - foreach(ushort index; forDelete) - _map.remove(index); + //ushort[] forDelete; + //foreach(ref Glyph item; _map) + // if (item.lastUsage == 0) + // forDelete ~= item.glyphIndex; + //foreach(ushort index; forDelete) + // _map.remove(index); + foreach(ref Glyph[] part; _glyphs) { + if (part !is null) + foreach(ref Glyph item; part) { + if (item.lastUsage == 0 && item.glyphIndex) { + item.glyphIndex = 0; + item.glyph = null; + version (USE_OPENGL) { + item.id = 0; + } + } + } + } + //foreach(ref Glyph item; _array) { + // if (item.lastUsage == 0 && item.glyphIndex) { + // item.glyphIndex = 0; + // item.glyph = null; + // item.id = 0; + // } + //} } /// removes all entries void clear() { + // notify about destroyed glyphs version (USE_OPENGL) { - if (_glyphDestroyCallback !is null) - foreach(ref Glyph item; _map) { - if (item.lastUsage == 0) - _glyphDestroyCallback(item.id); - } + if (_glyphDestroyCallback !is null) { + foreach(ref Glyph[] part; _glyphs) { + if (part !is null) + foreach(ref Glyph item; part) { + if (item.glyphIndex) + _glyphDestroyCallback(item.id); + } + } + } } - _map.clear(); + foreach(ref Glyph[] part; _glyphs) { + if (part !is null) + foreach(ref Glyph item; part) { + if (item.glyphIndex) { + item.glyphIndex = 0; + item.glyph = null; + version (USE_OPENGL) { + item.id = 0; + } + } + } + } + + //version (USE_OPENGL) { + // if (_glyphDestroyCallback !is null) { + // foreach(ref Glyph item; _array) { + // if (item.glyphIndex) + // _glyphDestroyCallback(item.id); + // } + // //foreach(ref Glyph item; _map) { + // // if (item.lastUsage == 0) + // // _glyphDestroyCallback(item.id); + // //} + // } + //} + ////_map.clear(); + //foreach(ref Glyph item; _array) { + // if (item.glyphIndex) { + // item.glyphIndex = 0; + // item.glyph = null; + // item.id = 0; + // } + //} } ~this() { clear();