// 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; }
// 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); }
// unlock io operation void datacloud::unlockio() { if (LOCKIO_CALLBACK!=NULL) if (ISNOTREADY) UNLOCKIO_CALLBACK(START_DATA); }
// 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); }