Optimizing realtime vis.
This commit is contained in:
parent
b2f3d4f49e
commit
45154f0716
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
#include "pserver.h"
|
#include "pserver.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
@ -19,7 +20,7 @@ class LruPServer: public PServer {
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
Patch &Lookup(unsigned int patch, unsigned short nv, unsigned short nf) {
|
Patch &Lookup(unsigned int patch, unsigned short nv, unsigned short nf) {
|
||||||
if(index.count(patch)) {
|
if(index.count(patch)) {
|
||||||
Items::iterator &i = index[patch];
|
Items::iterator &i = index[patch];
|
||||||
Item item = *i;
|
Item item = *i;
|
||||||
|
@ -27,10 +28,11 @@ class LruPServer: public PServer {
|
||||||
items.push_front(item);
|
items.push_front(item);
|
||||||
i = items.begin();
|
i = items.begin();
|
||||||
return *((*i).second);
|
return *((*i).second);
|
||||||
} else {
|
} else {
|
||||||
while(ram_used > ram_max) {
|
while(ram_used > ram_max) {
|
||||||
index.erase(items.back().first);
|
Item item = items.back();
|
||||||
FlushPatch(patch, items.back().second);
|
index.erase(item.first);
|
||||||
|
FlushPatch(item.first, item.second);
|
||||||
items.pop_back();
|
items.pop_back();
|
||||||
}
|
}
|
||||||
Item item;
|
Item item;
|
||||||
|
|
|
@ -65,8 +65,11 @@ 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;
|
||||||
if(draw_used >= draw_max) return false;
|
if(draw_used >= draw_max) return false;
|
||||||
if(disk_used >= disk_max) return false;
|
if(disk_used >= disk_max) {
|
||||||
|
float ratio = disk_max / (float)disk_used;
|
||||||
|
float error = tnode.error * ratio;
|
||||||
|
return error > target_error;
|
||||||
|
}
|
||||||
return tnode.error > target_error;
|
return tnode.error > target_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.26 2004/12/15 13:50:32 ponchio
|
||||||
|
Optimizing realtime vis.
|
||||||
|
|
||||||
Revision 1.25 2004/12/15 08:46:16 ponchio
|
Revision 1.25 2004/12/15 08:46:16 ponchio
|
||||||
Optimizing realtime vis.
|
Optimizing realtime vis.
|
||||||
|
|
||||||
|
@ -459,8 +462,9 @@ int main(int argc, char *argv[]) {
|
||||||
nexus.patches.ram_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(cur)",
|
sprintf(buffer, "Vbo size : %.3fMb(cur) Load: %.4fK Pref: %.4fK",
|
||||||
nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20));
|
nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20),
|
||||||
|
nexus.prefetch.loading, nexus.prefetch.prefetching);
|
||||||
gl_print(0.03, 0.06, buffer);
|
gl_print(0.03, 0.06, buffer);
|
||||||
|
|
||||||
sprintf(buffer, "Triangles: %.2fK (tot) %.2fK (vis) "
|
sprintf(buffer, "Triangles: %.2fK (tot) %.2fK (vis) "
|
||||||
|
|
|
@ -211,11 +211,12 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
|
||||||
Nexus nexus;
|
Nexus nexus;
|
||||||
nexus.MaxRamBuffer(ram_size);
|
|
||||||
if(!nexus.Load(input, true)) {
|
if(!nexus.Load(input, true)) {
|
||||||
cerr << "Could not open nexus file: " << input << "\n";
|
cerr << "Could not open nexus file: " << input << "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
nexus.MaxRamBuffer(ram_size);
|
||||||
|
|
||||||
|
|
||||||
//Sanity tests
|
//Sanity tests
|
||||||
|
@ -312,7 +313,7 @@ int main(int argc, char *argv[]) {
|
||||||
cout << "Writing to nexus: " << output << endl;
|
cout << "Writing to nexus: " << output << endl;
|
||||||
|
|
||||||
Nexus out;
|
Nexus out;
|
||||||
out.MaxRamBuffer(ram_size);
|
|
||||||
if(!chunk_size)
|
if(!chunk_size)
|
||||||
chunk_size = nexus.patches.chunk_size;
|
chunk_size = nexus.patches.chunk_size;
|
||||||
|
|
||||||
|
@ -320,6 +321,7 @@ int main(int argc, char *argv[]) {
|
||||||
cerr << "Could not open output: " << output << endl;
|
cerr << "Could not open output: " << output << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
out.MaxRamBuffer(ram_size);
|
||||||
|
|
||||||
//TODO set rambuffer low (or even direct access!)
|
//TODO set rambuffer low (or even direct access!)
|
||||||
|
|
||||||
|
@ -397,9 +399,9 @@ int main(int argc, char *argv[]) {
|
||||||
Border dst_border = out.GetBorder(patch);
|
Border dst_border = out.GetBorder(patch);
|
||||||
out.borders.ResizeBorder(patch, src_border.Size());
|
out.borders.ResizeBorder(patch, src_border.Size());
|
||||||
memcpy(dst_border.Start(), src_border.Start(),
|
memcpy(dst_border.Start(), src_border.Start(),
|
||||||
src_border.Size() * sizeof(Link));
|
src_border.Size() * sizeof(Link));
|
||||||
}
|
}
|
||||||
report.Finish();
|
report.Finish();
|
||||||
|
|
||||||
//TODO this is ok only if we have faces still!
|
//TODO this is ok only if we have faces still!
|
||||||
if(add_normals) {
|
if(add_normals) {
|
||||||
|
@ -429,7 +431,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
out.sphere = nexus.sphere;
|
out.sphere = nexus.sphere;
|
||||||
out.history = nexus.history;
|
out.history = nexus.history;
|
||||||
|
|
||||||
out.Close();
|
out.Close();
|
||||||
nexus.Close();
|
nexus.Close();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -16,19 +16,19 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
mt = m;
|
mt = m;
|
||||||
missing.clear();
|
missing.clear();
|
||||||
mt->todraw.clear();
|
mt->todraw.clear();
|
||||||
|
float loaded = 0;
|
||||||
unsigned int notloaded = 0;
|
unsigned int notloaded = 0;
|
||||||
set<unsigned int> tmp;
|
set<unsigned int> tmp;
|
||||||
//std::map<unsigned int, float> tmp;
|
//std::map<unsigned int, float> tmp;
|
||||||
vector<QueuePServer::Data> flush;
|
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.insert(patch);
|
tmp.insert(patch);
|
||||||
//tmp[patch] = 0.0f;
|
|
||||||
if(!mt->patches.entries[patch].patch) {
|
if(!mt->patches.entries[patch].patch) {
|
||||||
//cerr << "miss: " << patch << endl;
|
PServer::Entry &entry = mt->patches.entries[patch];
|
||||||
load.post(patch);
|
load.post(patch);
|
||||||
notloaded++;
|
loaded += entry.disk_size;
|
||||||
} else {
|
} else {
|
||||||
PatchInfo &info = mt->index[patch];
|
PatchInfo &info = mt->index[patch];
|
||||||
//WORKING QueuePServer::Data &data = mt->patches.Lookup(patch, info.nvert, info.nface, 0.0f, flush);
|
//WORKING QueuePServer::Data &data = mt->patches.Lookup(patch, info.nvert, info.nface, 0.0f, flush);
|
||||||
|
@ -46,8 +46,7 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
}
|
}
|
||||||
//missing.push_back(PServer::Item(patch, 0.0f));
|
//missing.push_back(PServer::Item(patch, 0.0f));
|
||||||
}
|
}
|
||||||
if(notloaded)
|
loading = 0.2 * loaded + 0.8 * loading;
|
||||||
cerr << "Patches to load: " << notloaded << endl;
|
|
||||||
|
|
||||||
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];
|
||||||
|
@ -78,22 +77,23 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
safety.unlock();
|
safety.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Prefetch::execute() {
|
void Prefetch::execute() {
|
||||||
unsigned int prefetched = 0;
|
|
||||||
|
float prefetch;
|
||||||
|
prefetching = 0;
|
||||||
|
loading = 0;
|
||||||
while(1) {
|
while(1) {
|
||||||
if(get_signaled()) return;
|
if(get_signaled()) return;
|
||||||
vector<QueuePServer::Data> flush;
|
vector<QueuePServer::Data> flush;
|
||||||
|
|
||||||
if(load.get_count() || missing.size() == 0) {
|
if(load.get_count() || missing.size() == 0) {
|
||||||
if(prefetched)
|
prefetch = 0;
|
||||||
cerr << "Prefetched: " << prefetched << endl;
|
|
||||||
prefetched = 0;
|
|
||||||
|
|
||||||
pt::message *msg = load.getmessage();
|
pt::message *msg = load.getmessage();
|
||||||
if(msg->id != 0xffffffff) {
|
if(msg->id != 0xffffffff) {
|
||||||
safety.lock();
|
safety.lock();
|
||||||
PatchInfo &info = mt->index[msg->id];
|
PatchInfo &info = mt->index[msg->id];
|
||||||
|
PServer::Entry &entry = mt->patches.entries[msg->id];
|
||||||
|
loading += entry.disk_size;
|
||||||
//posting draw message
|
//posting draw message
|
||||||
//WORKING QueuePServer::Data &data = mt->patches.Lookup(msg->id, info.nvert, info.nface, 0.0f, flush);
|
//WORKING QueuePServer::Data &data = mt->patches.Lookup(msg->id, info.nvert, info.nface, 0.0f, flush);
|
||||||
QueuePServer::Data &data = mt->patches.Lookup(msg->id, info.nvert, info.nface, flush);
|
QueuePServer::Data &data = mt->patches.Lookup(msg->id, info.nvert, info.nface, flush);
|
||||||
|
@ -108,6 +108,8 @@ void Prefetch::execute() {
|
||||||
draw.post(QueuePServer::FLUSH, (unsigned int)data);
|
draw.post(QueuePServer::FLUSH, (unsigned int)data);
|
||||||
}
|
}
|
||||||
safety.unlock();
|
safety.unlock();
|
||||||
|
} else {
|
||||||
|
prefetching = 0.2 * prefetch + 0.8 * prefetching;
|
||||||
}
|
}
|
||||||
delete msg;
|
delete msg;
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,8 +126,10 @@ void Prefetch::execute() {
|
||||||
//cerr << "prefetching: " << item.patch << endl;
|
//cerr << "prefetching: " << item.patch << endl;
|
||||||
//WORKING mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority, flush);
|
//WORKING mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority, flush);
|
||||||
if(!mt->patches.entries[item.patch].patch) {
|
if(!mt->patches.entries[item.patch].patch) {
|
||||||
mt->patches.Lookup(item.patch, info.nvert, info.nface, flush);
|
PServer::Entry &entry = mt->patches.entries[item.patch];
|
||||||
prefetched++;
|
prefetch += entry.disk_size;
|
||||||
|
|
||||||
|
mt->patches.Lookup(item.patch, info.nvert, info.nface, flush);
|
||||||
for(unsigned int i = 0; i < flush.size(); i++) {
|
for(unsigned int i = 0; i < flush.size(); i++) {
|
||||||
QueuePServer::Data *data = new QueuePServer::Data;
|
QueuePServer::Data *data = new QueuePServer::Data;
|
||||||
*data = flush[i];
|
*data = flush[i];
|
||||||
|
|
|
@ -24,6 +24,8 @@ class Prefetch: public pt::thread{
|
||||||
std::vector<PServer::Item> missing;
|
std::vector<PServer::Item> missing;
|
||||||
pt::jobqueue draw;
|
pt::jobqueue draw;
|
||||||
pt::jobqueue load;
|
pt::jobqueue load;
|
||||||
|
float prefetching;
|
||||||
|
float loading;
|
||||||
|
|
||||||
Prefetch(): thread(false), draw(20000), load(64000) {}
|
Prefetch(): thread(false), draw(20000), load(64000) {}
|
||||||
~Prefetch() {
|
~Prefetch() {
|
||||||
|
|
|
@ -31,7 +31,7 @@ bool PServer::Load(const std::string &filename, Signature sig,
|
||||||
return MFile::Load(filename, readonly);
|
return MFile::Load(filename, readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::Close() {
|
void PServer::Close() {
|
||||||
Flush();
|
Flush();
|
||||||
MFile::Close();
|
MFile::Close();
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
// ramlock.rdlock();
|
// ramlock.rdlock();
|
||||||
|
|
||||||
assert(idx < entries.size());
|
assert(idx < entries.size());
|
||||||
Entry &entry = entries[idx];
|
Entry &entry = entries[idx];
|
||||||
if(entry.patch) return entry.patch;
|
if(entry.patch) return entry.patch;
|
||||||
|
|
||||||
char *ram = new char[entry.ram_size * chunk_size];
|
char *ram = new char[entry.ram_size * chunk_size];
|
||||||
|
@ -111,10 +111,10 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
||||||
//TODO move this into an assert!!!!
|
//TODO move this into an assert!!!!
|
||||||
if(!patch) return;
|
if(!patch) return;
|
||||||
Entry &entry = entries[id];
|
Entry &entry = entries[id];
|
||||||
assert(entry.patch == patch);
|
// cerr << "entry: " << (void *)(entry.patch) << " patch: " << (void *)patch << endl;
|
||||||
entry.patch = NULL;
|
entry.patch = NULL;
|
||||||
|
|
||||||
if(!readonly) { //write back patch
|
if(!readonly) { //write back patch
|
||||||
|
@ -150,6 +150,6 @@ void PServer::FlushPatch(unsigned int id, Patch *patch) {
|
||||||
ram_used -= entry.ram_size;
|
ram_used -= entry.ram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::MaxRamBuffer(unsigned int r_buffer) {
|
void PServer::MaxRamBuffer(unsigned int r_buffer) {
|
||||||
ram_max = (unsigned int)(r_buffer/chunk_size) + 1;
|
ram_max = (unsigned int)(r_buffer/chunk_size) + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,7 @@ class PServer: public MFile {
|
||||||
PServer(): chunk_size(1024),
|
PServer(): chunk_size(1024),
|
||||||
ram_max(128000000),
|
ram_max(128000000),
|
||||||
ram_used(0) {}
|
ram_used(0) {}
|
||||||
virtual ~PServer() {
|
virtual ~PServer() {
|
||||||
std::cerr << "Closing pserver" << std::endl;
|
|
||||||
MFile::Close();
|
MFile::Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ class QueuePServer: public PServer {
|
||||||
Data &data = items.back().second;
|
Data &data = items.back().second;
|
||||||
//TODO i should not flush current extraction!
|
//TODO i should not flush current extraction!
|
||||||
index.erase(items.back().first);
|
index.erase(items.back().first);
|
||||||
FlushPatch(patch, data.patch);
|
FlushPatch(items.back().first, data.patch);
|
||||||
flush.push_back(data);
|
flush.push_back(data);
|
||||||
items.pop_back();
|
items.pop_back();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue