// check for pending tiles in the background BOOLINT datacloud::loadpendingtile(int background) { float prio,p; tilecacheelem *tile,*scan; double time; // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); time=gettime(); prio=0.0f; tile=NULL; scan=TILECACHETAIL; // scan tiles while (scan!=NULL) { if (MAXDELAY>0.0) if (!scan->isavailable && !scan->isloading && !scan->isdelayed) if (time-scan->access>MAXDELAY) scan->isdelayed=TRUE; if (!scan->isavailable && !scan->isloading && !scan->isdelayed) { p=getpriority(scan); if (p>=prio) { prio=p; tile=scan; } } scan=scan->prev; } // trigger loading if (tile!=NULL) { // load in background loadtile(tile,background); // decrease pending tile count PENDINGTILES--; } // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); if (tile!=NULL) return(TRUE); else return(FALSE); }
// delete a tile from the cache void datacloud::deletetile(tilecacheelem *tile) { // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // delete tile from hash map TILECACHEMAP->removedata(tile->tileid,NULL,NULL); // decrease pending tile count if (!tile->isavailable) PENDINGTILES--; // release tile identifier free(tile->tileid); // release memory chunk if (CONFIGURE_DONTFREE==0) tile->tile->release(); // release databuf object delete tile->tile; // delete from head if (tile==TILECACHE) { TILECACHE=tile->next; if (TILECACHE!=NULL) TILECACHE->prev=NULL; else TILECACHETAIL=NULL; delete tile; } // delete from tail else if (tile==TILECACHETAIL) { TILECACHETAIL=tile->prev; if (TILECACHETAIL!=NULL) TILECACHETAIL->next=NULL; else TILECACHE=NULL; delete tile; } // delete from queue else { tilecacheelem *prev=tile->prev; tilecacheelem *next=tile->next; prev->next=next; next->prev=prev; delete tile; } // one tile less TILECOUNT--; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); }
// insert a tile into the cache after a given element void datacloud::inserttile(tilecacheelem *tile,tilecacheelem *newtile) { // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // insert tile into hash map TILECACHEMAP->insertdata(newtile->tileid,NULL,NULL,(void *)newtile); // increase pending tile count if (!newtile->isavailable) PENDINGTILES++; // insert in empty cache if (TILECACHE==NULL) { TILECACHE=TILECACHETAIL=newtile; newtile->prev=newtile->next=NULL; } // insert at cache head else if (tile==NULL) { newtile->prev=NULL; newtile->next=TILECACHE; TILECACHE->prev=newtile; TILECACHE=newtile; } // insert at cache tail else if (tile==TILECACHETAIL) { newtile->prev=TILECACHETAIL; newtile->next=NULL; TILECACHETAIL->next=newtile; TILECACHETAIL=newtile; } // insert after given element else { newtile->prev=tile; newtile->next=tile->next; tile->next=newtile; newtile->next->prev=newtile; } // one more tile TILECOUNT++; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); }
// load a pending tile in the background void datacloud::loadtile(tilecacheelem *tile,int background) { // signal loading tile->isloading=TRUE; tile->background=background; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // lock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) LOCKIO_CALLBACK(START_DATA); // load data REQUEST_CALLBACK(tile->tileid,tile->tile,tile->istexture,background,REQUEST_DATA); // auto mip-map textures in the background if (CONFIGURE_AUTOMIPMAP!=0) if (CONFIGURE_DONTFREE==0) tile->tile->automipmap(); // autocompress textures in the background if (CONFIGURE_AUTOCOMPRESS!=0) if (CONFIGURE_DONTFREE==0) if (CONFIGURE_LOD0UNCOMPRESSED==0 || tile->lod>0) tile->tile->autocompress(); // unlock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) UNLOCKIO_CALLBACK(START_DATA); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // set access time tile->access=gettime(); // signal availability tile->isloading=FALSE; tile->isavailable=TRUE; }
// insert a tile into the cache tilecacheelem *datacloud::inserttile(const unsigned char *tileid,int col,int row,BOOLINT istexture,BOOLINT immediate,BOOLINT loprio,int lod) { tilecacheelem *oldtile,*newtile; // check for already existing tile oldtile=checktile(tileid,col,row,istexture,immediate,loprio,lod); // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // already existing tile if (oldtile!=NULL) { oldtile->refcount++; newtile=oldtile; } // allocate and initialize new tile else { newtile=new tilecacheelem; newtile->tileid=(unsigned char *)strdup((char *)tileid); newtile->tile=new databuf; newtile->col=col; newtile->row=row; newtile->istexture=istexture; newtile->loprio=loprio; newtile->lod=lod; newtile->refcount=1; newtile->isavailable=FALSE; newtile->isloading=FALSE; newtile->background=0; } // load immediate data if (immediate && !newtile->isavailable) { // signal background thread to finish signalthread(); // check if actual tile is already being loaded in the background if (newtile->isloading) { // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // wait for background thread to finish loading stopthread(newtile->background); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); } // load actual tile directly if (!newtile->isavailable) { // load in foreground loadtile(newtile); // decrease pending tile count if (oldtile!=NULL) PENDINGTILES--; } } // reset access time newtile->access=gettime(); newtile->isdelayed=FALSE; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // insert tile at cache tail if (oldtile==NULL) inserttile(TILECACHETAIL,newtile); return(newtile); }
// unlock background thread void datacloud::unlockthread() {if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA);}
// load a pending tile in the background BOOLINT datacloud::loadpendingtile(int background) { float prio,p; tilecacheelem *tile,*scan; // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); prio=0.0f; tile=NULL; scan=TILECACHE; // scan for tile with highest priority while (scan!=NULL) { if (!scan->loprio && !scan->isavailable && !scan->isloading) { p=getpriority(scan); if (p>prio) { prio=p; tile=scan; } } scan=scan->next; } // check hi prio tile with highest priority first if (tile!=NULL) { // signal loading tile->isloading=TRUE; tile->background=background; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // lock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) LOCKIO_CALLBACK(START_DATA); // load data REQUEST_CALLBACK(tile->tileid,tile->tile,tile->istexture,background,REQUEST_DATA); // autocompress textures in the background if (CONFIGURE_AUTOCOMPRESS!=0) tile->tile->autocompress(); // unlock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) UNLOCKIO_CALLBACK(START_DATA); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // signal availability tile->isavailable=TRUE; tile->isloading=FALSE; // decrease pending tile count PENDINGTILES--; // set access time tile->access=minitime(); // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); return(TRUE); } tile=TILECACHE; // check for lo prio tiles next while (tile!=NULL) { if (tile->loprio && !tile->isavailable && !tile->isloading) { // signal loading tile->isloading=TRUE; tile->background=background; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // lock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) LOCKIO_CALLBACK(START_DATA); // load data REQUEST_CALLBACK(tile->tileid,tile->tile,tile->istexture,background,REQUEST_DATA); // autocompress textures in the background if (CONFIGURE_AUTOCOMPRESS!=0) tile->tile->autocompress(); // unlock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) UNLOCKIO_CALLBACK(START_DATA); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // signal availability tile->isavailable=TRUE; tile->isloading=FALSE; // decrease pending tile count PENDINGTILES--; // set access time tile->access=minitime(); // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); return(TRUE); } tile=tile->next; } // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); return(FALSE); }
// insert a tile into the cache tilecacheelem *datacloud::inserttile(unsigned char *tileid,int col,int row,BOOLINT istexture,BOOLINT immediate,BOOLINT loprio) { int i; tilecacheelem *oldtile,*newtile; // check for already existing tile oldtile=checktile(tileid,col,row,istexture,immediate,loprio); // already existing tile if (oldtile!=NULL) { newtile=oldtile; newtile->refcount++; } // allocate and initialize new tile else { newtile=new tilecacheelem; newtile->tileid=(unsigned char *)strdup((char *)tileid); newtile->tile=new databuf; newtile->col=col; newtile->row=row; newtile->istexture=istexture; newtile->loprio=loprio; newtile->refcount=1; newtile->isavailable=FALSE; newtile->isloading=FALSE; newtile->background=0; } // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // load immediate data if (immediate && !newtile->isavailable) { // signal background thread to finish signalthread(); // check if actual tile is already being loaded in the background if (newtile->isloading) { // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // wait for background thread to finish loading stopthread(newtile->background); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); } // load actual tile directly if (!newtile->isavailable) { // signal direct loading newtile->isloading=TRUE; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // lock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) LOCKIO_CALLBACK(START_DATA); // load data REQUEST_CALLBACK(tileid,newtile->tile,istexture,0,REQUEST_DATA); // autocompress textures if (CONFIGURE_AUTOCOMPRESS!=0) newtile->tile->autocompress(); // unlock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) UNLOCKIO_CALLBACK(START_DATA); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // signal availability newtile->isavailable=TRUE; newtile->isloading=FALSE; // decrease pending tile count if (oldtile!=NULL) PENDINGTILES--; } } // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // set access time newtile->access=minitime(); // insert tile at cache tail if (oldtile==NULL) inserttile(TILECACHETAIL,newtile); return(newtile); }