glyph cache fixes

This commit is contained in:
Vadim Lopatin 2014-04-04 09:08:04 +04:00
parent 912961b48e
commit dd13b36bc3
4 changed files with 136 additions and 62 deletions

View File

@ -8,7 +8,7 @@
<multiobj>0</multiobj> <multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation> <singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj> <oneobj>0</oneobj>
<trace>1</trace> <trace>0</trace>
<quiet>0</quiet> <quiet>0</quiet>
<verbose>0</verbose> <verbose>0</verbose>
<vtls>0</vtls> <vtls>0</vtls>
@ -29,7 +29,7 @@
<useIn>0</useIn> <useIn>0</useIn>
<useOut>0</useOut> <useOut>0</useOut>
<useArrayBounds>0</useArrayBounds> <useArrayBounds>0</useArrayBounds>
<noboundscheck>1</noboundscheck> <noboundscheck>0</noboundscheck>
<useSwitchError>0</useSwitchError> <useSwitchError>0</useSwitchError>
<useUnitTests>0</useUnitTests> <useUnitTests>0</useUnitTests>
<useInline>1</useInline> <useInline>1</useInline>

View File

@ -8,7 +8,7 @@
<multiobj>0</multiobj> <multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation> <singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj> <oneobj>0</oneobj>
<trace>1</trace> <trace>0</trace>
<quiet>0</quiet> <quiet>0</quiet>
<verbose>0</verbose> <verbose>0</verbose>
<vtls>0</vtls> <vtls>0</vtls>
@ -32,7 +32,7 @@
<noboundscheck>1</noboundscheck> <noboundscheck>1</noboundscheck>
<useSwitchError>0</useSwitchError> <useSwitchError>0</useSwitchError>
<useUnitTests>0</useUnitTests> <useUnitTests>0</useUnitTests>
<useInline>1</useInline> <useInline>0</useInline>
<release>0</release> <release>0</release>
<preservePaths>0</preservePaths> <preservePaths>0</preservePaths>
<warnings>0</warnings> <warnings>0</warnings>

View File

@ -1,38 +1,24 @@
module main; module main;
import std.stdio; struct Foo // must be struct to reproduce
{
uint foo; // any data can be here
}
//class Foo { struct Bar // must be struct to reproduce
// int _data; {
// this(int v) { // DMD 2.065 hang with 100% CPU load
// _data = v; // works ok if array size is reduced
// } //Foo[0x20000] _array;
// @property int data() const { return _data; } // 0x4000 - < 1 second
//} // 0x8000 - 5 seconds
// // 0xC000 - 15 seconds
//struct Bar { // 0xE000 - 20 seconds
// int _data; // 0x10000 - 25 seconds
// @property int data() const { return _data; } // 0x20000 - 1:45
//} }
//
//class Foo2 {
//}
int main(string[] argv) 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; return 0;
} }

View File

@ -40,14 +40,22 @@ version (USE_OPENGL) {
/// font glyph cache /// font glyph cache
struct GlyphCache struct GlyphCache
{ {
Glyph[ushort] _map; //Glyph[ushort] _map;
Glyph[0x10000] _array; Glyph[][256] _glyphs;
//Glyph[] _array;
// find glyph in cache // find glyph in cache
Glyph * find(ushort glyphIndex) { Glyph * find(ushort glyphIndex) {
if (_array[glyphIndex].glyphIndex) //if (_array is null)
return &_array[glyphIndex]; // _array = new Glyph[0x10000];
ushort p = glyphIndex >> 8;
if (_glyphs[p] is null)
return null; return null;
return &_glyphs[p][glyphIndex & 0xFF];
//if (_array[glyphIndex].glyphIndex)
// return &_array[glyphIndex];
//return null;
//Glyph * res = (glyphIndex in _map); //Glyph * res = (glyphIndex in _map);
//if (res !is null) //if (res !is null)
@ -57,8 +65,15 @@ struct GlyphCache
/// put glyph to cache /// put glyph to cache
Glyph * put(ushort glyphIndex, Glyph * glyph) { Glyph * put(ushort glyphIndex, Glyph * glyph) {
_array[glyphIndex] = *glyph; ushort p = glyphIndex >> 8;
return &_array[glyphIndex]; 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; //_map[glyphIndex] = *glyph;
//Glyph * res = glyphIndex in _map; //Glyph * res = glyphIndex in _map;
@ -68,40 +83,113 @@ struct GlyphCache
// clear usage flags for all entries // clear usage flags for all entries
void checkpoint() { void checkpoint() {
foreach(ref Glyph item; _map) { //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; item.lastUsage = 0;
} }
} }
//foreach(ref Glyph item; _array) {
// item.lastUsage = 0;
//}
}
/// removes entries not used after last call of checkpoint() or cleanup() /// removes entries not used after last call of checkpoint() or cleanup()
void cleanup() { void cleanup() {
uint dst = 0; //uint dst = 0;
// notify about destroyed glyphs // notify about destroyed glyphs
version (USE_OPENGL) { version (USE_OPENGL) {
if (_glyphDestroyCallback !is null) if (_glyphDestroyCallback !is null) {
foreach(ref Glyph item; _map) { foreach(ref Glyph[] part; _glyphs) {
if (item.lastUsage == 0) if (part !is null)
foreach(ref Glyph item; part) {
if (item.lastUsage == 0 && item.glyphIndex)
_glyphDestroyCallback(item.id); _glyphDestroyCallback(item.id);
} }
} }
ushort[] forDelete; //foreach(ref Glyph item; _map) {
foreach(ref Glyph item; _map) // if (item.lastUsage == 0)
if (item.lastUsage == 0) // _glyphDestroyCallback(item.id);
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 /// removes all entries
void clear() { void clear() {
// notify about destroyed glyphs
version (USE_OPENGL) { version (USE_OPENGL) {
if (_glyphDestroyCallback !is null) if (_glyphDestroyCallback !is null) {
foreach(ref Glyph item; _map) { foreach(ref Glyph[] part; _glyphs) {
if (item.lastUsage == 0) if (part !is null)
foreach(ref Glyph item; part) {
if (item.glyphIndex)
_glyphDestroyCallback(item.id); _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() { ~this() {
clear(); clear();