Optimizing realtime vis.
This commit is contained in:
parent
7fb2c4b831
commit
e8c748d159
|
@ -57,14 +57,17 @@ float FrustumMetric::GetError(unsigned int cell) {
|
||||||
if(dist < 0) return 1e20f;
|
if(dist < 0) return 1e20f;
|
||||||
float error = entry.error/frustum.Resolution(dist);
|
float error = entry.error/frustum.Resolution(dist);
|
||||||
if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
||||||
error /= 256;
|
error /= 32;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NexusMt::Expand(TNode &node) {
|
bool NexusMt::Expand(TNode &tnode) {
|
||||||
//expand if node error > target error
|
//expand if node error > target error
|
||||||
if(extraction_used >= extraction_max) return false;
|
if(extraction_used >= extraction_max) return false;
|
||||||
return node.error > target_error;
|
if(draw_used >= draw_max) return false;
|
||||||
|
if(disk_used >= disk_max) return false;
|
||||||
|
|
||||||
|
return tnode.error > target_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NexusMt::NodeVisited(Node *node) {
|
void NexusMt::NodeVisited(Node *node) {
|
||||||
|
@ -75,8 +78,15 @@ void NexusMt::NodeVisited(Node *node) {
|
||||||
assert(!(node->out[i]->visited));
|
assert(!(node->out[i]->visited));
|
||||||
Frag &frag = node->frags[i];
|
Frag &frag = node->frags[i];
|
||||||
for(unsigned int k = 0; k < frag.size(); k++) {
|
for(unsigned int k = 0; k < frag.size(); k++) {
|
||||||
PServer::Entry &entry = patches.entries[frag[k]];
|
unsigned int patch = frag[k];
|
||||||
extraction_used += entry.ram_size;
|
PServer::Entry &entry = patches.entries[patch];
|
||||||
|
unsigned int ram_size = entry.ram_size;
|
||||||
|
extraction_used += ram_size;
|
||||||
|
PatchInfo &info = index[patch];
|
||||||
|
if(!frustum.IsOutside(info.sphere.Center(), info.sphere.Radius()))
|
||||||
|
draw_used += ram_size;
|
||||||
|
if(!patches.entries[patch].patch)
|
||||||
|
disk_used += ram_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +98,14 @@ void NexusMt::NodeVisited(Node *node) {
|
||||||
if((*from)->out[i] == node) {
|
if((*from)->out[i] == node) {
|
||||||
vector<unsigned int> &frag = frags[i];
|
vector<unsigned int> &frag = frags[i];
|
||||||
for(unsigned int k = 0; k < frag.size(); k++) {
|
for(unsigned int k = 0; k < frag.size(); k++) {
|
||||||
PServer::Entry &entry = patches.entries[frag[k]];
|
unsigned int patch = frag[k];
|
||||||
extraction_used -= entry.ram_size;
|
PServer::Entry &entry = patches.entries[patch];
|
||||||
|
extraction_used -= entry.ram_size;
|
||||||
|
PatchInfo &info = index[patch];
|
||||||
|
if(!frustum.IsOutside(info.sphere.Center(), info.sphere.Radius()))
|
||||||
|
draw_used -= entry.ram_size;
|
||||||
|
if(!patches.entries[patch].patch)
|
||||||
|
disk_used -= entry.ram_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +117,10 @@ NexusMt::NexusMt(): vbo_mode(VBO_AUTO),
|
||||||
metric = new FrustumMetric();
|
metric = new FrustumMetric();
|
||||||
metric->index = &index;
|
metric->index = &index;
|
||||||
target_error = 4.0f;
|
target_error = 4.0f;
|
||||||
extraction_max = 640000000;
|
extraction_max = 64000000000;
|
||||||
|
draw_max = 12000; //1M triangles (ZSN)
|
||||||
|
disk_max = 300;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusMt::~NexusMt() {
|
NexusMt::~NexusMt() {
|
||||||
|
@ -180,7 +199,7 @@ bool NexusMt::Load(const string &filename) {
|
||||||
|
|
||||||
SetPrefetchSize(patches.ram_max/2);
|
SetPrefetchSize(patches.ram_max/2);
|
||||||
cerr << "Start!\n";
|
cerr << "Start!\n";
|
||||||
prefetch.start();
|
|
||||||
cerr << "Started\n";
|
cerr << "Started\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +218,8 @@ bool NexusMt::InitGL(Vbo mode, unsigned int vbosize) {
|
||||||
patches.vbo_max = vbosize / chunk_size;
|
patches.vbo_max = vbosize / chunk_size;
|
||||||
if(vbo_mode == VBO_OFF)
|
if(vbo_mode == VBO_OFF)
|
||||||
patches.vbo_max = 0;
|
patches.vbo_max = 0;
|
||||||
|
|
||||||
|
prefetch.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,13 +233,23 @@ void NexusMt::Render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NexusMt::Draw(vector<unsigned int> &cells) {
|
void NexusMt::Draw(vector<unsigned int> &cells) {
|
||||||
prefetch.init(this, cells, visited);
|
|
||||||
tri_total = 0;
|
tri_total = 0;
|
||||||
tri_rendered = 0;
|
tri_rendered = 0;
|
||||||
|
|
||||||
Frustumf frustum;
|
|
||||||
frustum.GetView();
|
frustum.GetView();
|
||||||
|
|
||||||
|
vector<unsigned int> draw;
|
||||||
|
for(unsigned int i = 0; i < cells.size(); i++) {
|
||||||
|
PatchInfo &entry = index[cells[i]];
|
||||||
|
tri_total += entry.nface;
|
||||||
|
|
||||||
|
if(!frustum.IsOutside(entry.sphere.Center(), entry.sphere.Radius())) {
|
||||||
|
draw.push_back(cells[i]);
|
||||||
|
tri_rendered += entry.nface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefetch.init(this, draw, visited);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
if(use_colors)
|
if(use_colors)
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
@ -226,37 +257,36 @@ void NexusMt::Draw(vector<unsigned int> &cells) {
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
//TODO textures and data.
|
//TODO textures and data.
|
||||||
|
|
||||||
unsigned int count = cells.size();
|
unsigned int count = draw.size();
|
||||||
while(count) {
|
while(count > 0 || prefetch.draw.get_count()) {
|
||||||
// cerr << "Getting message: " << count << endl;
|
if(todraw.size()) {
|
||||||
pt::message *msg = patches.queue.getmessage();
|
QueuePServer::Data *data = todraw.back();
|
||||||
QueuePServer::Data *data = (QueuePServer::Data *)(msg->param);
|
todraw.pop_back();
|
||||||
if(msg->id == QueuePServer::FLUSH) {
|
Draw((unsigned int)(data->patch), *data);
|
||||||
// cerr << "Flush...\n";
|
} else {
|
||||||
if(data->vbo_element) {
|
// cerr << "Getting message: " << count << endl;
|
||||||
glDeleteBuffersARB(1, &(data->vbo_element));
|
pt::message *msg = prefetch.draw.getmessage();
|
||||||
glDeleteBuffersARB(1, &(data->vbo_array));
|
QueuePServer::Data *data = (QueuePServer::Data *)(msg->param);
|
||||||
|
if(msg->id == QueuePServer::FLUSH) {
|
||||||
|
if(data->vbo_element) {
|
||||||
|
glDeleteBuffersARB(1, &(data->vbo_element));
|
||||||
|
glDeleteBuffersARB(1, &(data->vbo_array));
|
||||||
|
}
|
||||||
|
delete data;
|
||||||
|
delete msg;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
delete data;
|
|
||||||
|
if(msg->id != QueuePServer::DRAW) {
|
||||||
|
cerr << "Unknown message!\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int cell = msg->result;
|
||||||
|
Draw(cell, *data);
|
||||||
|
|
||||||
delete msg;
|
delete msg;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(msg->id != QueuePServer::DRAW) {
|
|
||||||
cerr << "Unknown message!\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int cell = msg->result;
|
|
||||||
PatchInfo &entry = index[cell];
|
|
||||||
tri_total += entry.nface;
|
|
||||||
//frustum culling
|
|
||||||
if(!frustum.IsOutside(entry.sphere.Center(), entry.sphere.Radius())) {
|
|
||||||
tri_rendered += entry.nface;
|
|
||||||
Draw(cell, *data);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete msg;
|
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
@ -455,7 +485,7 @@ void NexusMt::LoadHistory() {
|
||||||
Node &oldnode = nodes[floor_node];
|
Node &oldnode = nodes[floor_node];
|
||||||
oldnode.frags.push_back(fr);
|
oldnode.frags.push_back(fr);
|
||||||
if(node.error < max_err)
|
if(node.error < max_err)
|
||||||
node.error = max_err;
|
node.error = max_err;
|
||||||
|
|
||||||
//Update in and out of the nodes.
|
//Update in and out of the nodes.
|
||||||
node.in.push_back(&oldnode);
|
node.in.push_back(&oldnode);
|
||||||
|
@ -502,18 +532,24 @@ void NexusMt::ClearHistory() {
|
||||||
|
|
||||||
void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
||||||
extraction_used = 0;
|
extraction_used = 0;
|
||||||
|
draw_used = 0;
|
||||||
|
disk_used = 0;
|
||||||
visited.clear();
|
visited.clear();
|
||||||
|
|
||||||
|
float bestcost = -1;
|
||||||
|
int best = -1;
|
||||||
|
float cost = 0;
|
||||||
|
|
||||||
std::vector<Node>::iterator n;
|
std::vector<Node>::iterator n;
|
||||||
for(n = nodes.begin(); n != nodes.end(); n++) {
|
for(n = nodes.begin(); n != nodes.end(); n++)
|
||||||
(*n).visited = false;
|
(*n).visited = false;
|
||||||
// (*n).pushed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TNode> heap;
|
std::vector<TNode> heap;
|
||||||
Node *root = &nodes[0];
|
Node *root = &nodes[0];
|
||||||
VisitNode(root, heap);
|
VisitNode(root, heap);
|
||||||
|
|
||||||
|
sequence.clear();
|
||||||
|
//vector<Node *> sequence;
|
||||||
while(heap.size()) {
|
while(heap.size()) {
|
||||||
pop_heap(heap.begin(), heap.end());
|
pop_heap(heap.begin(), heap.end());
|
||||||
TNode tnode = heap.back();
|
TNode tnode = heap.back();
|
||||||
|
@ -524,9 +560,40 @@ void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
||||||
|
|
||||||
bool expand = Expand(tnode);
|
bool expand = Expand(tnode);
|
||||||
|
|
||||||
if(expand)
|
if(expand) //{
|
||||||
VisitNode(node, heap);
|
VisitNode(node, heap);
|
||||||
|
|
||||||
|
/* float cost = disk_used * 100;
|
||||||
|
if(draw_used > draw_max)
|
||||||
|
cost += 1 * (draw_used - draw_max);
|
||||||
|
if(tnode.error > target_error)
|
||||||
|
cost += 1000 * (tnode.error - target_error) * (tnode.error - target_error);
|
||||||
|
if(best == -1 || cost < bestcost) {
|
||||||
|
bestcost = cost;
|
||||||
|
best = sequence.size();
|
||||||
|
}
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cerr << "best: " << best << " tot: " << sequence.size() << endl;
|
||||||
|
/*for(n = nodes.begin(); n != nodes.end(); n++)
|
||||||
|
(*n).visited = false;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < best; i++) {
|
||||||
|
Node *node = sequence[i];
|
||||||
|
node->visited = true;
|
||||||
|
for(unsigned int n = 0; n < node->out.size(); n++) {
|
||||||
|
Node *outnode = node->out[n];
|
||||||
|
for(unsigned int k = 0; k < outnode->frags.size(); k++) {
|
||||||
|
for(unsigned int j = 0; j < outnode->frags[k].size(); j++) {
|
||||||
|
unsigned int patch = outnode->frags[k][j];
|
||||||
|
float error = metric->GetError(patch);
|
||||||
|
visited.push_back(PServer::Item(patch, fabs(error - target_error)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
Select(selected);
|
Select(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +623,7 @@ void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Select(selected);
|
Select(selected);
|
||||||
}*/
|
} */
|
||||||
|
|
||||||
void NexusMt::Select(vector<unsigned int> &selected) {
|
void NexusMt::Select(vector<unsigned int> &selected) {
|
||||||
selected.clear();
|
selected.clear();
|
||||||
|
@ -579,18 +646,38 @@ void NexusMt::Select(vector<unsigned int> &selected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*bool NexusMt::TestCurrent(Node *node) {
|
||||||
|
if(!visited) return;
|
||||||
|
for(unsigned int i = 0; i < node->out.size(); i++)
|
||||||
|
if(!node->out[k].visited) {
|
||||||
|
node->current = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
node->current = false;
|
||||||
|
return false;
|
||||||
|
} */
|
||||||
|
|
||||||
void NexusMt::VisitNode(Node *node, vector<TNode> &heap) {
|
void NexusMt::VisitNode(Node *node, vector<TNode> &heap) {
|
||||||
if(node->visited) return;
|
//TestCurrent(*i);
|
||||||
|
|
||||||
|
if(node->visited) return;
|
||||||
|
node->visited = true;
|
||||||
|
|
||||||
|
|
||||||
vector<Node *>::iterator i;
|
vector<Node *>::iterator i;
|
||||||
for(i = node->in.begin(); i != node->in.end(); i++)
|
for(i = node->in.begin(); i != node->in.end(); i++) {
|
||||||
VisitNode(*i, heap);
|
VisitNode(*i, heap);
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned int k = 0; k < node->out.size(); k++) {
|
for(unsigned int k = 0; k < node->out.size(); k++) {
|
||||||
Node *outnode = node->out[k];
|
Node *outnode = node->out[k];
|
||||||
float max_error = 0;
|
float max_error = metric->GetError(outnode);
|
||||||
|
/* for(unsigned int j = 0; j < node->frags[k].size(); j++) {
|
||||||
|
unsigned int patch = node->frags[k][j];
|
||||||
|
PServer::Entry &entry = patches.entries[patch];
|
||||||
|
if(!entry.patch)
|
||||||
|
max_error /= 2;
|
||||||
|
}*/
|
||||||
|
|
||||||
for(unsigned int j = 0; j < node->frags[k].size(); j++) {
|
for(unsigned int j = 0; j < node->frags[k].size(); j++) {
|
||||||
unsigned int patch = node->frags[k][j];
|
unsigned int patch = node->frags[k][j];
|
||||||
|
@ -598,13 +685,23 @@ void NexusMt::VisitNode(Node *node, vector<TNode> &heap) {
|
||||||
if(max_error < error) max_error = error;
|
if(max_error < error) max_error = error;
|
||||||
visited.push_back(PServer::Item(patch, fabs(error - target_error)));
|
visited.push_back(PServer::Item(patch, fabs(error - target_error)));
|
||||||
// push_heap(visited.begin(), visited.end());
|
// push_heap(visited.begin(), visited.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
heap.push_back(TNode(outnode, max_error));
|
heap.push_back(TNode(outnode, max_error));
|
||||||
push_heap(heap.begin(), heap.end());
|
push_heap(heap.begin(), heap.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
node->visited = true;
|
sequence.push_back(node);
|
||||||
NodeVisited(node);
|
NodeVisited(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void NexusMt::UnvisitNode(Node *node, vector<TNode> &heap) {
|
||||||
|
node->current = false;
|
||||||
|
vector<Node *>::iterator i;
|
||||||
|
for(i = node->in.begin(); i != node->in.end(); i++)
|
||||||
|
if(TestCurrent(*i)) {
|
||||||
|
float error = metric->GetError(*i);
|
||||||
|
heap.push_back(TNode(*i, error));
|
||||||
|
push_heap(heap.begin(), heap.end());
|
||||||
|
}
|
||||||
|
} */
|
|
@ -19,7 +19,8 @@ namespace nxs {
|
||||||
std::vector<Node *> out;
|
std::vector<Node *> out;
|
||||||
std::vector<Frag> frags;
|
std::vector<Frag> frags;
|
||||||
float error;
|
float error;
|
||||||
bool visited;
|
bool visited;
|
||||||
|
bool current;
|
||||||
// bool pushed;
|
// bool pushed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,9 +103,15 @@ class NexusMt: public NexusBase {
|
||||||
|
|
||||||
Metric *metric;
|
Metric *metric;
|
||||||
float target_error;
|
float target_error;
|
||||||
|
|
||||||
int extraction_max;
|
vcg::Frustumf frustum;
|
||||||
int extraction_used;
|
|
||||||
|
unsigned int extraction_max; //total extraxtion (even culled parts)
|
||||||
|
unsigned int extraction_used;
|
||||||
|
unsigned int draw_max; //only visible parts
|
||||||
|
unsigned int draw_used;
|
||||||
|
unsigned int disk_max; //max not in ram loadable size
|
||||||
|
unsigned int disk_used;
|
||||||
|
|
||||||
|
|
||||||
Mode mode;
|
Mode mode;
|
||||||
|
@ -119,7 +126,9 @@ class NexusMt: public NexusBase {
|
||||||
unsigned int tri_rendered;
|
unsigned int tri_rendered;
|
||||||
unsigned int tri_total;
|
unsigned int tri_total;
|
||||||
|
|
||||||
|
vector<QueuePServer::Data *> todraw;
|
||||||
std::vector<PServer::Item> visited;
|
std::vector<PServer::Item> visited;
|
||||||
|
std::vector<Node *> sequence;
|
||||||
|
|
||||||
QueuePServer patches;
|
QueuePServer patches;
|
||||||
BorderServer borders;
|
BorderServer borders;
|
||||||
|
@ -160,6 +169,7 @@ class NexusMt: public NexusBase {
|
||||||
void LoadHistory();
|
void LoadHistory();
|
||||||
void ClearHistory();
|
void ClearHistory();
|
||||||
void VisitNode(Node *node, std::vector<TNode> &heap);
|
void VisitNode(Node *node, std::vector<TNode> &heap);
|
||||||
|
void UnvisitNode(Node *node, std::vector<TNode> &heap);
|
||||||
void Select(std::vector<unsigned int> &selected);
|
void Select(std::vector<unsigned int> &selected);
|
||||||
Patch &LoadPatch(unsigned int p);
|
Patch &LoadPatch(unsigned int p);
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.24 2004/12/13 00:44:48 ponchio
|
||||||
|
Lotsa changes...
|
||||||
|
|
||||||
Revision 1.23 2004/12/01 18:46:21 ponchio
|
Revision 1.23 2004/12/01 18:46:21 ponchio
|
||||||
Microchanges.
|
Microchanges.
|
||||||
|
|
||||||
|
@ -209,14 +212,17 @@ int main(int argc, char *argv[]) {
|
||||||
" q: quit\n"
|
" q: quit\n"
|
||||||
" s: screen error extraction\n"
|
" s: screen error extraction\n"
|
||||||
" g: geometry error extraction\n"
|
" g: geometry error extraction\n"
|
||||||
" p: draw points\n"
|
|
||||||
" t: show statistics\n"
|
" t: show statistics\n"
|
||||||
" r: toggle realtime mode (TODO)\n"
|
|
||||||
" b: increase memory buffer\n"
|
" b: increase memory buffer\n"
|
||||||
" B: decrease memory buffer\n"
|
" B: decrease memory buffer\n"
|
||||||
|
|
||||||
" d: debug mode (show patches colored)\n"
|
" d: debug mode (show patches colored)\n"
|
||||||
" f: flas shading mode\n"
|
" f: flas shading mode\n"
|
||||||
" m: smooth mode\n"
|
" m: smooth mode\n"
|
||||||
|
" p: draw points\n"
|
||||||
|
|
||||||
" c: show colors\n"
|
" c: show colors\n"
|
||||||
" n: show normals\n"
|
" n: show normals\n"
|
||||||
" u: rotate model\n"
|
" u: rotate model\n"
|
||||||
|
@ -233,11 +239,9 @@ int main(int argc, char *argv[]) {
|
||||||
bool extract = true;
|
bool extract = true;
|
||||||
|
|
||||||
NexusMt::MetricKind metric;
|
NexusMt::MetricKind metric;
|
||||||
NexusMt::Mode mode = NexusMt::SMOOTH;
|
NexusMt::Mode mode = NexusMt::SMOOTH;
|
||||||
unsigned int ram_size = 640000;
|
|
||||||
|
|
||||||
nexus.SetError(error);
|
nexus.SetError(error);
|
||||||
nexus.SetExtractionSize(ram_size);
|
|
||||||
nexus.SetMetric(NexusMt::FRUSTUM);
|
nexus.SetMetric(NexusMt::FRUSTUM);
|
||||||
if(!nexus.InitGL()) {
|
if(!nexus.InitGL()) {
|
||||||
cerr << "Could not init glew.\n";
|
cerr << "Could not init glew.\n";
|
||||||
|
@ -256,100 +260,99 @@ int main(int argc, char *argv[]) {
|
||||||
bool redraw = false;
|
bool redraw = false;
|
||||||
float fps = 0;
|
float fps = 0;
|
||||||
float tframe = 0;
|
float tframe = 0;
|
||||||
|
bool keepdrawing = true;
|
||||||
|
|
||||||
while( !quit ) {
|
while( !quit ) {
|
||||||
bool first = true;
|
unsigned int anything = SDL_PollEvent(&event);
|
||||||
SDL_WaitEvent(&event);
|
if(!anything && !keepdrawing) {
|
||||||
while( first || SDL_PollEvent( &event ) ){
|
SDL_WaitEvent(&event);
|
||||||
first = false;
|
anything = true;
|
||||||
switch( event.type ) {
|
}
|
||||||
case SDL_QUIT: quit = 1; break;
|
if(anything) {
|
||||||
case SDL_KEYDOWN:
|
switch( event.type ) {
|
||||||
switch(event.key.keysym.sym) {
|
case SDL_QUIT: quit = 1; break;
|
||||||
case SDLK_RCTRL:
|
case SDL_KEYDOWN:
|
||||||
case SDLK_LCTRL:
|
switch(event.key.keysym.sym) {
|
||||||
track.ButtonDown(Trackball::KEY_CTRL); break;
|
case SDLK_RCTRL:
|
||||||
case SDLK_q: exit(0); break;
|
case SDLK_LCTRL: track.ButtonDown(Trackball::KEY_CTRL); break;
|
||||||
case SDLK_b: show_borders = !show_borders; break;
|
case SDLK_q: exit(0); break;
|
||||||
case SDLK_e: extract = !extract; break;
|
case SDLK_k: keepdrawing = !keepdrawing; break;
|
||||||
case SDLK_c: show_colors = !show_colors; break;
|
case SDLK_e: extract = !extract; break;
|
||||||
case SDLK_n: show_normals = !show_normals; break;
|
case SDLK_c: show_colors = !show_colors; break;
|
||||||
// case SDLK_9: nexus.patches->ram_size *= 0.8f; break;
|
case SDLK_n: show_normals = !show_normals; break;
|
||||||
// case SDLK_0: nexus.patches->ram_size *= 1.2f; break;
|
|
||||||
|
case SDLK_LEFT: nexus.extraction_max *= 0.7; break;
|
||||||
case SDLK_LEFT:
|
case SDLK_RIGHT: nexus.extraction_max *= 1.5; break;
|
||||||
ram_size *= 0.7;
|
case SDLK_UP: nexus.draw_max *= 1.5; break;
|
||||||
nexus.SetExtractionSize(ram_size);
|
case SDLK_DOWN: nexus.draw_max *= 0.7; break;
|
||||||
cerr << "Max extraction ram size: " << ram_size << endl; break;
|
case SDLK_PAGEUP: nexus.disk_max *= 1.5; break;
|
||||||
case SDLK_RIGHT:
|
case SDLK_PAGEDOWN: nexus.disk_max *= 0.7; break;
|
||||||
ram_size *= 1.5;
|
|
||||||
nexus.SetExtractionSize(ram_size);
|
|
||||||
cerr << "Max extraction ram size: " << ram_size << endl; break;
|
|
||||||
|
|
||||||
case SDLK_s: metric = NexusMt::FRUSTUM; break;
|
case SDLK_s: metric = NexusMt::FRUSTUM; break;
|
||||||
case SDLK_p: mode = NexusMt::POINTS; nexus.SetMode(mode); break;
|
case SDLK_p: mode = NexusMt::POINTS; nexus.SetMode(mode); break;
|
||||||
case SDLK_d: mode = NexusMt::PATCHES; nexus.SetMode(mode); break;
|
case SDLK_d: mode = NexusMt::PATCHES; nexus.SetMode(mode); break;
|
||||||
case SDLK_f: mode = NexusMt::FLAT; nexus.SetMode(mode); break;
|
case SDLK_f: mode = NexusMt::FLAT; nexus.SetMode(mode); break;
|
||||||
case SDLK_m: mode = NexusMt::SMOOTH; nexus.SetMode(mode); break;
|
case SDLK_m: mode = NexusMt::SMOOTH; nexus.SetMode(mode); break;
|
||||||
|
|
||||||
case SDLK_r:
|
case SDLK_r:
|
||||||
case SDLK_SPACE: rotate = !rotate; break;
|
case SDLK_SPACE: rotate = !rotate; break;
|
||||||
|
|
||||||
case SDLK_MINUS:
|
case SDLK_MINUS:
|
||||||
error *= 0.9f;
|
error *= 0.9f;
|
||||||
nexus.SetError(error);
|
nexus.SetError(error);
|
||||||
cerr << "Error: " << error << endl; break;
|
cerr << "Error: " << error << endl; break;
|
||||||
|
|
||||||
case SDLK_EQUALS:
|
case SDLK_EQUALS:
|
||||||
case SDLK_PLUS:
|
case SDLK_PLUS:
|
||||||
error *= 1.1f;
|
error *= 1.1f;
|
||||||
nexus.SetError(error);
|
nexus.SetError(error);
|
||||||
cerr << "Error: " << error << endl; break;
|
cerr << "Error: " << error << endl; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
switch(event.key.keysym.sym) {
|
switch(event.key.keysym.sym) {
|
||||||
case SDLK_RCTRL:
|
case SDLK_RCTRL:
|
||||||
case SDLK_LCTRL:
|
case SDLK_LCTRL:
|
||||||
track.ButtonUp(Trackball::KEY_CTRL); break;
|
track.ButtonUp(Trackball::KEY_CTRL); break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
x = event.button.x;
|
x = event.button.x;
|
||||||
y = height - event.button.y;
|
y = height - event.button.y;
|
||||||
#ifdef SDL_BUTTON_WHEELUP
|
#ifdef SDL_BUTTON_WHEELUP
|
||||||
if(event.button.button == SDL_BUTTON_WHEELUP)
|
if(event.button.button == SDL_BUTTON_WHEELUP)
|
||||||
track.MouseWheel(1);
|
track.MouseWheel(1);
|
||||||
else if(event.button.button == SDL_BUTTON_WHEELDOWN)
|
else if(event.button.button == SDL_BUTTON_WHEELDOWN)
|
||||||
track.MouseWheel(-1);
|
track.MouseWheel(-1);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(event.button.button == SDL_BUTTON_LEFT)
|
if(event.button.button == SDL_BUTTON_LEFT)
|
||||||
track.MouseDown(x, y, Trackball::BUTTON_LEFT);
|
track.MouseDown(x, y, Trackball::BUTTON_LEFT);
|
||||||
else if(event.button.button == SDL_BUTTON_RIGHT)
|
else if(event.button.button == SDL_BUTTON_RIGHT)
|
||||||
track.MouseDown(x, y, Trackball::BUTTON_RIGHT);
|
track.MouseDown(x, y, Trackball::BUTTON_RIGHT);
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
x = event.button.x;
|
x = event.button.x;
|
||||||
y = height - event.button.y;
|
y = height - event.button.y;
|
||||||
if(event.button.button == SDL_BUTTON_LEFT)
|
if(event.button.button == SDL_BUTTON_LEFT)
|
||||||
track.MouseUp(x, y, Trackball::BUTTON_LEFT);
|
track.MouseUp(x, y, Trackball::BUTTON_LEFT);
|
||||||
else if(event.button.button == SDL_BUTTON_RIGHT)
|
else if(event.button.button == SDL_BUTTON_RIGHT)
|
||||||
track.MouseUp(x, y, Trackball::BUTTON_RIGHT);
|
track.MouseUp(x, y, Trackball::BUTTON_RIGHT);
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
|
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
|
||||||
x = event.motion.x;
|
x = event.motion.x;
|
||||||
y = height - event.motion.y;
|
y = height - event.motion.y;
|
||||||
track.MouseMove(x, y);
|
track.MouseMove(x, y);
|
||||||
break;
|
break;
|
||||||
case SDL_VIDEOEXPOSE:
|
case SDL_VIDEOEXPOSE:
|
||||||
default: break;
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
redraw = true;
|
redraw = true;
|
||||||
}
|
|
||||||
|
|
||||||
if(!redraw) continue;
|
//if(!redraw && !keepdrawing) continue;
|
||||||
redraw = false;
|
redraw = false;
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -363,9 +366,11 @@ int main(int argc, char *argv[]) {
|
||||||
if(rotate) {
|
if(rotate) {
|
||||||
alpha++;
|
alpha++;
|
||||||
if(alpha > 360) alpha = 0;
|
if(alpha > 360) alpha = 0;
|
||||||
SDL_Event redraw;
|
if(!keepdrawing) {
|
||||||
redraw.type = SDL_VIDEOEXPOSE;
|
SDL_Event redraw;
|
||||||
SDL_PushEvent(&redraw);
|
redraw.type = SDL_VIDEOEXPOSE;
|
||||||
|
SDL_PushEvent(&redraw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -440,8 +445,8 @@ int main(int argc, char *argv[]) {
|
||||||
gl_print(0.03, 0.12, buffer);*/
|
gl_print(0.03, 0.12, buffer);*/
|
||||||
|
|
||||||
sprintf(buffer, "Extr size: %.3fMb(max) %.3fMb(cur)",
|
sprintf(buffer, "Extr size: %.3fMb(max) %.3fMb(cur)",
|
||||||
nexus.extraction_max * nexus.chunk_size/(float)(1<<20),
|
nexus.patches.ram_max * nexus.chunk_size/(float)(1<<20),
|
||||||
nexus.extraction_used * nexus.chunk_size/(float)(1<<20));
|
nexus.patches.ram_used * nexus.chunk_size/(float)(1<<20));
|
||||||
gl_print(0.03, 0.09, buffer);
|
gl_print(0.03, 0.09, buffer);
|
||||||
|
|
||||||
sprintf(buffer, "Vbo size : %.3fMb(max) %.3fMb(cur)",
|
sprintf(buffer, "Vbo size : %.3fMb(max) %.3fMb(cur)",
|
||||||
|
@ -455,12 +460,7 @@ int main(int argc, char *argv[]) {
|
||||||
nexus.tri_rendered/(float)(1<<10),
|
nexus.tri_rendered/(float)(1<<10),
|
||||||
tframe, 1/tframe);
|
tframe, 1/tframe);
|
||||||
gl_print(0.03, 0.03, buffer);
|
gl_print(0.03, 0.03, buffer);
|
||||||
|
|
||||||
|
|
||||||
/* cerr << "Ram flushed: " << nexus.patches.ram_flushed << endl;
|
|
||||||
cerr << "Ram readed: " << nexus.patches.ram_readed << endl;*/
|
|
||||||
nexus.patches.ram_flushed = 0;
|
|
||||||
nexus.patches.ram_readed = 0;
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "prefetch.h"
|
#include "prefetch.h"
|
||||||
#include "nexusmt.h"
|
#include "nexusmt.h"
|
||||||
|
|
||||||
|
@ -13,18 +15,30 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
safety.lock();
|
safety.lock();
|
||||||
mt = m;
|
mt = m;
|
||||||
missing.clear();
|
missing.clear();
|
||||||
|
mt->todraw.clear();
|
||||||
|
|
||||||
unsigned int notloaded = 0;
|
unsigned int notloaded = 0;
|
||||||
std::map<unsigned int, float> tmp;
|
set<unsigned int> tmp;
|
||||||
|
//std::map<unsigned int, float> tmp;
|
||||||
|
vector<QueuePServer::Data> flush;
|
||||||
for(unsigned int i = 0; i < selected.size(); i++) {
|
for(unsigned int i = 0; i < selected.size(); i++) {
|
||||||
unsigned int patch = selected[i];
|
unsigned int patch = selected[i];
|
||||||
tmp[patch] = 0.0f;
|
tmp.insert(patch);
|
||||||
if(!mt->patches.IsLoaded(patch))
|
//tmp[patch] = 0.0f;
|
||||||
notloaded++;
|
if(!mt->patches.entries[patch].patch) {
|
||||||
// if(mt->patches.IsLoaded(patch))
|
//cerr << "miss: " << patch << endl;
|
||||||
// mt->todraw.push_back(make_pair(patch, (Patch *)NULL));
|
load.post(patch);
|
||||||
// else
|
notloaded++;
|
||||||
missing.push_back(PServer::Item(patch, 0.0f));
|
} else {
|
||||||
|
PatchInfo &info = mt->index[patch];
|
||||||
|
QueuePServer::Data &data = mt->patches.Lookup(patch, info.nvert, info.nface, 0.0f, flush);
|
||||||
|
if(flush.size() != 0) {
|
||||||
|
cerr << "Flushing!\n";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
mt->todraw.push_back(&data);
|
||||||
|
}
|
||||||
|
//missing.push_back(PServer::Item(patch, 0.0f));
|
||||||
}
|
}
|
||||||
if(notloaded)
|
if(notloaded)
|
||||||
cerr << "Patches to load: " << notloaded << endl;
|
cerr << "Patches to load: " << notloaded << endl;
|
||||||
|
@ -32,52 +46,84 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
for(unsigned int i = 0; i < visited.size(); i++) {
|
for(unsigned int i = 0; i < visited.size(); i++) {
|
||||||
PServer::Item &item = visited[i];
|
PServer::Item &item = visited[i];
|
||||||
if(tmp.count(item.patch)) continue;
|
if(tmp.count(item.patch)) continue;
|
||||||
if(mt->patches.IsLoaded(item.patch))
|
// if(mt->patches.entries[item.patch].patch)
|
||||||
tmp[item.patch] = item.priority;
|
// tmp[item.patch] = item.priority;
|
||||||
|
if(item.priority != 0.0f)
|
||||||
missing.push_back(item);
|
missing.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuePServer &ps = mt->patches;
|
QueuePServer &ps = mt->patches;
|
||||||
for(unsigned int i = 0; i < ps.heap.size(); i++) {
|
for(unsigned int i = 0; i < ps.heap.size(); i++) {
|
||||||
PServer::Item &item = ps.heap[i];
|
PServer::Item &item = ps.heap[i];
|
||||||
if(tmp.count(item.patch))
|
if(tmp.count(item.patch))
|
||||||
|
item.priority = 0;
|
||||||
|
else {
|
||||||
|
if(item.priority == 0)
|
||||||
|
item.priority = 1;
|
||||||
|
item.priority *= 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(tmp.count(item.patch))
|
||||||
item.priority = tmp[item.patch];
|
item.priority = tmp[item.patch];
|
||||||
else
|
else
|
||||||
item.priority = 1e40;
|
item.priority = 1e30;*/
|
||||||
}
|
}
|
||||||
make_heap(ps.heap.begin(), ps.heap.end());
|
make_heap(ps.heap.begin(), ps.heap.end());
|
||||||
|
|
||||||
sort(missing.begin(), missing.end()); //CRITICAL reverse pero'!
|
sort(missing.begin(), missing.end()); //CRITICAL reverse pero'!
|
||||||
reverse(missing.begin(), missing.end());
|
reverse(missing.begin(), missing.end());
|
||||||
|
load.post(0xffffffff);
|
||||||
|
|
||||||
safety.unlock();
|
safety.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Prefetch::execute() {
|
void Prefetch::execute() {
|
||||||
while(1) {
|
|
||||||
if(get_signaled()) return;
|
|
||||||
while(1) {
|
while(1) {
|
||||||
safety.lock();
|
if(get_signaled()) return;
|
||||||
if(missing.size() == 0) {
|
vector<QueuePServer::Data> flush;
|
||||||
safety.unlock();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PServer::Item item = missing.back();
|
|
||||||
missing.pop_back();
|
|
||||||
|
|
||||||
if(item.priority > 0 &&
|
|
||||||
mt->patches.ram_used > mt->patches.ram_max &&
|
|
||||||
item.priority >= mt->patches.MaxPriority()) {
|
|
||||||
safety.unlock();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PatchInfo &info = mt->index[item.patch];
|
|
||||||
|
|
||||||
// cerr << "prefetching: " << item.patch << endl;
|
if(load.get_count() || missing.size() == 0) {
|
||||||
mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority);
|
pt::message *msg = load.getmessage();
|
||||||
|
if(msg->id != 0xffffffff) {
|
||||||
|
safety.lock();
|
||||||
|
PatchInfo &info = mt->index[msg->id];
|
||||||
|
|
||||||
safety.unlock();
|
//posting draw message
|
||||||
}
|
QueuePServer::Data &data = mt->patches.Lookup(msg->id, info.nvert, info.nface, 0.0f, flush);
|
||||||
relax(5);
|
pt::message *msg = new pt::message(QueuePServer::DRAW, (unsigned int)&data);
|
||||||
}
|
msg->result = msg->id;
|
||||||
|
draw.post(msg);
|
||||||
|
|
||||||
|
//p;osting flush messages
|
||||||
|
for(unsigned int i = 0; i < flush.size(); i++) {
|
||||||
|
QueuePServer::Data *data = new QueuePServer::Data;
|
||||||
|
*data = flush[i];
|
||||||
|
draw.post(QueuePServer::FLUSH, (unsigned int)data);
|
||||||
|
}
|
||||||
|
safety.unlock();
|
||||||
|
}
|
||||||
|
delete msg;
|
||||||
|
} else {
|
||||||
|
safety.lock();
|
||||||
|
if(missing.size() != 0) {
|
||||||
|
PServer::Item item = missing.back();
|
||||||
|
missing.pop_back();
|
||||||
|
|
||||||
|
if(item.priority > mt->patches.MaxPriority()) {
|
||||||
|
missing.clear();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PatchInfo &info = mt->index[item.patch];
|
||||||
|
//cerr << "prefetching: " << item.patch << endl;
|
||||||
|
mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority, flush);
|
||||||
|
for(unsigned int i = 0; i < flush.size(); i++) {
|
||||||
|
QueuePServer::Data *data = new QueuePServer::Data;
|
||||||
|
*data = flush[i];
|
||||||
|
draw.post(QueuePServer::FLUSH, (unsigned int)data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safety.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,15 @@ class Prefetch: public pt::thread{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
pt::mutex safety;
|
pt::mutex safety;
|
||||||
unsigned int ram_max;
|
//unsigned int ram_max;
|
||||||
unsigned int ram_used;
|
//unsigned int ram_used;
|
||||||
|
|
||||||
NexusMt *mt;
|
NexusMt *mt;
|
||||||
std::vector<PServer::Item> missing;
|
std::vector<PServer::Item> missing;
|
||||||
|
pt::jobqueue draw;
|
||||||
|
pt::jobqueue load;
|
||||||
|
|
||||||
|
Prefetch(): thread(false), draw(20000), load(64000) {}
|
||||||
Prefetch(): thread(false) {}
|
|
||||||
~Prefetch() {
|
~Prefetch() {
|
||||||
waitfor();
|
waitfor();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,6 @@ bool PServer::Create(const std::string &filename,
|
||||||
ram_max = rsize/chunk_size + 1;
|
ram_max = rsize/chunk_size + 1;
|
||||||
ram_used = 0;
|
ram_used = 0;
|
||||||
|
|
||||||
ram_readed = 0;
|
|
||||||
ram_flushed = 0;
|
|
||||||
|
|
||||||
return MFile::Create(filename);
|
return MFile::Create(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +28,6 @@ bool PServer::Load(const std::string &filename, Signature sig,
|
||||||
ram_max = rsize/chunk_size + 1;
|
ram_max = rsize/chunk_size + 1;
|
||||||
ram_used = 0;
|
ram_used = 0;
|
||||||
|
|
||||||
ram_readed = 0;
|
|
||||||
ram_flushed = 0;
|
|
||||||
|
|
||||||
return MFile::Load(filename, readonly);
|
return MFile::Load(filename, readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +45,7 @@ bool PServer::ReadEntries(FILE *fp) {
|
||||||
fread(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
|
fread(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
|
||||||
fread(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
|
fread(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
|
||||||
fread(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
|
fread(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
|
||||||
|
entries[i].patch = NULL;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +76,7 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
|
|
||||||
assert(idx < entries.size());
|
assert(idx < entries.size());
|
||||||
Entry &entry = entries[idx];
|
Entry &entry = entries[idx];
|
||||||
|
if(entry.patch) return entry.patch;
|
||||||
|
|
||||||
char *ram = new char[entry.ram_size * chunk_size];
|
char *ram = new char[entry.ram_size * chunk_size];
|
||||||
#ifdef CONTROLS
|
#ifdef CONTROLS
|
||||||
|
@ -108,15 +104,17 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
delete []disk;
|
delete []disk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ram_used += entry.ram_size;
|
ram_used += entry.ram_size;
|
||||||
ram_readed += entry.ram_size;
|
entry.patch = patch;
|
||||||
|
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
||||||
|
//TODO move this into an assert!!!!
|
||||||
|
if(!patch) return;
|
||||||
Entry &entry = entries[id];
|
Entry &entry = entries[id];
|
||||||
|
assert(entry.patch == patch);
|
||||||
|
entry.patch = NULL;
|
||||||
|
|
||||||
if(!readonly) { //write back patch
|
if(!readonly) { //write back patch
|
||||||
if((signature & NXS_COMPRESSED)) {
|
if((signature & NXS_COMPRESSED)) {
|
||||||
|
@ -147,10 +145,8 @@ void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [](patch->start);
|
delete [](patch->start);
|
||||||
delete patch;
|
delete patch;
|
||||||
|
ram_used -= entry.ram_size;
|
||||||
ram_used -= entry.ram_size;
|
|
||||||
ram_flushed += entry.ram_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::MaxRamBuffer(unsigned int r_buffer) {
|
void PServer::MaxRamBuffer(unsigned int r_buffer) {
|
||||||
|
|
|
@ -16,6 +16,7 @@ class PServer: public MFile {
|
||||||
unsigned int patch_start; //granularita' Chunk
|
unsigned int patch_start; //granularita' Chunk
|
||||||
unsigned short ram_size; //in chunks
|
unsigned short ram_size; //in chunks
|
||||||
unsigned short disk_size; // in chunks (used when compressed)
|
unsigned short disk_size; // in chunks (used when compressed)
|
||||||
|
Patch *patch;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct Data {
|
/* struct Data {
|
||||||
|
@ -42,17 +43,8 @@ class PServer: public MFile {
|
||||||
|
|
||||||
unsigned int ram_max;
|
unsigned int ram_max;
|
||||||
unsigned int ram_used;
|
unsigned int ram_used;
|
||||||
|
|
||||||
//statistics:
|
|
||||||
unsigned int ram_readed;
|
|
||||||
unsigned int ram_flushed;
|
|
||||||
|
|
||||||
//pt::rwlock ramlock; //read only thread safety...
|
|
||||||
//pt::rwlock disklock; //read only thread safety...
|
|
||||||
|
|
||||||
std::vector<Entry> entries;
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<Entry> entries;
|
||||||
|
|
||||||
PServer(): chunk_size(1024),
|
PServer(): chunk_size(1024),
|
||||||
ram_max(128000000),
|
ram_max(128000000),
|
||||||
|
|
|
@ -7,6 +7,42 @@ using namespace nxs;
|
||||||
using namespace pt;
|
using namespace pt;
|
||||||
|
|
||||||
|
|
||||||
|
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
|
unsigned short nv, unsigned short nf,
|
||||||
|
float priority,
|
||||||
|
vector<QueuePServer::Data> &flush) {
|
||||||
|
flush.clear();
|
||||||
|
if(index.count(patch)) {
|
||||||
|
return index[patch];
|
||||||
|
} else {
|
||||||
|
while(ram_used > ram_max) {
|
||||||
|
if(MaxPriority() == 0) break;
|
||||||
|
pop_heap(heap.begin(), heap.end());
|
||||||
|
Item item = heap.back();
|
||||||
|
heap.pop_back();
|
||||||
|
assert(item.priority != 0);
|
||||||
|
Data &data = index[item.patch];
|
||||||
|
flush.push_back(data);
|
||||||
|
FlushPatch(item.patch, data.patch);
|
||||||
|
index.erase(item.patch);
|
||||||
|
}
|
||||||
|
Item item(patch, priority);
|
||||||
|
heap.push_back(item);
|
||||||
|
push_heap(heap.begin(), heap.end());
|
||||||
|
Data &data = index[patch];
|
||||||
|
// cerr << "Loading: " << patch << endl;
|
||||||
|
data.patch = LoadPatch(patch, nv, nf);
|
||||||
|
|
||||||
|
/*if(priority == 0) {
|
||||||
|
message *msg = new message(DRAW, (unsigned int)&data);
|
||||||
|
msg->result = patch;
|
||||||
|
queue.post(msg);
|
||||||
|
} */
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
unsigned short nv, unsigned short nf,
|
unsigned short nv, unsigned short nf,
|
||||||
float priority) {
|
float priority) {
|
||||||
|
@ -48,8 +84,8 @@ QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
/*QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
Patch *mem,
|
Patch *mem,
|
||||||
float priority) {
|
float priority) {
|
||||||
if(index.count(patch)) {
|
if(index.count(patch)) {
|
||||||
|
@ -75,7 +111,7 @@ QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
LoadVbo(data);
|
LoadVbo(data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
bool QueuePServer::IsLoaded(unsigned int patch) {
|
bool QueuePServer::IsLoaded(unsigned int patch) {
|
||||||
return index.count(patch);
|
return index.count(patch);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define NXS_QUEUE_PSERVER_H
|
#define NXS_QUEUE_PSERVER_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <hash_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -29,11 +30,15 @@ class QueuePServer: public PServer {
|
||||||
|
|
||||||
std::map<unsigned int, Data> index;
|
std::map<unsigned int, Data> index;
|
||||||
std::vector<Item> heap;
|
std::vector<Item> heap;
|
||||||
|
|
||||||
Data &Lookup(unsigned int patch, unsigned short nv, unsigned short nf,
|
|
||||||
float priority = 0.0f);
|
|
||||||
|
|
||||||
Data &Lookup(unsigned int patch, Patch *mem, float priority = 0.0f);
|
QueuePServer(): queue(64000) {}
|
||||||
|
|
||||||
|
//Data &Lookup(unsigned int patch, unsigned short nv, unsigned short nf,
|
||||||
|
// float priority = 0.0f);
|
||||||
|
|
||||||
|
//return flushing too.
|
||||||
|
Data &Lookup(unsigned int patch, unsigned short nv, unsigned short nf, float priority,
|
||||||
|
std::vector<QueuePServer::Data> &data);
|
||||||
|
|
||||||
bool IsLoaded(unsigned int patch);
|
bool IsLoaded(unsigned int patch);
|
||||||
float MaxPriority();
|
float MaxPriority();
|
||||||
|
|
Loading…
Reference in New Issue