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();