tightens memory use

This commit is contained in:
tosh 2013-04-04 11:59:16 +02:00
parent de4734d6fb
commit 284530f7d6
2 changed files with 52 additions and 13 deletions

View file

@ -96,10 +96,14 @@ namespace starfield {
Tiling tiling(k);
size_t nTiles = tiling.getTileCount();
// REVISIT: could coalesce allocation for faster rebuild
// REVISIT: batch arrays are probably oversized, but - hey - they
// are not very large (unless for insane tiling) and we're better
// off safe than sorry
_arrData = new GpuVertex[n];
_arrTile = new Tile[nTiles + 1];
_arrBatchOffs = new GLint[nTiles];
_arrBatchCount = new GLsizei[nTiles];
_arrBatchOffs = new GLint[nTiles * 2];
_arrBatchCount = new GLsizei[nTiles * 2];
prepareVertexData(src, n, tiling, b, bMin);
@ -290,21 +294,31 @@ namespace starfield {
bool select(Tile* t) {
if (t < _arrTile || t >= _itrTilesEnd ||
!! (t->flags & Tile::visited)) {
!! (t->flags & Tile::checked)) {
return false;
// out of bounds or been here already
return false;
}
if (! (t->flags & Tile::checked)) {
if (_refRenderer.visitTile(t))
t->flags |= Tile::render;
// will check now and never again
t->flags |= Tile::checked;
if (_refRenderer.visitTile(t)) {
// good one -> remember (for batching) and propagate
t->flags |= Tile::render;
return true;
}
return !! (t->flags & Tile::render);
return false;
}
void process(Tile* t) {
bool process(Tile* t) {
t->flags |= Tile::visited;
if (! (t->flags & Tile::visited)) {
t->flags |= Tile::visited;
return true;
}
return false;
}
void right(Tile*& cursor) const { cursor += 1; }

View file

@ -11,6 +11,29 @@
/**
* Line scanning, iterative flood fill algorithm.
*
* The strategy must obey the following contract:
*
* There is an associated cursor that represents a position on the image.
* The member functions 'left(C&)', 'right(C&)', 'up(C&)', and 'down(C&)'
* move it.
* The state of a cursor can be deferred to temporary storage (typically a
* stack or a queue) using the 'defer(C const&)' member function.
* Calling 'deferred(C&)' restores a cursor's state from temporary storage
* and removes it there.
* The 'select(C const&)' and 'process(C const&)' functions control the
* algorithm. The former is called to determine where to go. It may be
* called multiple times but does not have to (and should not) return
* 'true' more than once for a pixel to be selected (will cause memory
* overuse, otherwise). The latter will never be called for a given pixel
* unless previously selected. It may be called multiple times, in which
* case it should return 'true' upon successful processing and 'false'
* when an already processed pixel has been visited.
*
* Note: The terms "image" and "pixel" are used for illustratory purposes
* and mean "undirected graph with 4-connected 2D grid topology" and "node",
* respectively.
*
*/
template< class Strategy, typename Cursor >
void floodFill(Cursor const& position,
@ -35,16 +58,18 @@ struct floodFill_impl : Strategy {
void go(Cursor position) {
if (! select(position)) {
return;
}
Cursor higher, lower, h,l, i;
bool higherFound, lowerFound, hf, lf;
do {
if (! select(position)) {
if (! process(position)) {
continue;
}
process(position);
higher = position; higherFound = false;
up(higher); yTest(higher, higherFound);
lower = position; lowerFound = false;