Annotation of quake1/d_surf.c, revision 1.1.1.1

1.1       root        1: // d_surf.c: rasterization driver surface heap manager
                      2: 
                      3: #include "quakedef.h"
                      4: #include "d_local.h"
                      5: #include "r_local.h"
                      6: 
                      7: float           surfscale;
                      8: qboolean        r_cache_thrash;         // set if surface cache is thrashing
                      9: 
                     10: int                                     sc_size;
                     11: surfcache_t                     *sc_rover, *sc_base;
                     12: 
                     13: #define GUARDSIZE       4
                     14: 
                     15: 
                     16: int     D_SurfaceCacheForRes (int width, int height)
                     17: {
                     18:        int             size, pix;
                     19: 
                     20:        if (COM_CheckParm ("-surfcachesize"))
                     21:        {
                     22:                size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024;
                     23:                return size;
                     24:        }
                     25:        
                     26:        size = SURFCACHE_SIZE_AT_320X200;
                     27: 
                     28:        pix = width*height;
                     29:        if (pix > 64000)
                     30:                size += (pix-64000)*3;
                     31:                
                     32: 
                     33:        return size;
                     34: }
                     35: 
                     36: void D_CheckCacheGuard (void)
                     37: {
                     38:        byte    *s;
                     39:        int             i;
                     40: 
                     41:        s = (byte *)sc_base + sc_size;
                     42:        for (i=0 ; i<GUARDSIZE ; i++)
                     43:                if (s[i] != (byte)i)
                     44:                        Sys_Error ("D_CheckCacheGuard: failed");
                     45: }
                     46: 
                     47: void D_ClearCacheGuard (void)
                     48: {
                     49:        byte    *s;
                     50:        int             i;
                     51:        
                     52:        s = (byte *)sc_base + sc_size;
                     53:        for (i=0 ; i<GUARDSIZE ; i++)
                     54:                s[i] = (byte)i;
                     55: }
                     56: 
                     57: 
                     58: /*
                     59: ================
                     60: D_InitCaches
                     61: 
                     62: ================
                     63: */
                     64: void D_InitCaches (void *buffer, int size)
                     65: {
                     66:        Con_Printf ("%ik surface cache\n", size/1024);
                     67: 
                     68:        sc_size = size - GUARDSIZE;
                     69:        sc_base = (surfcache_t *)buffer;
                     70:        sc_rover = sc_base;
                     71:        
                     72:        sc_base->next = NULL;
                     73:        sc_base->owner = NULL;
                     74:        sc_base->size = sc_size;
                     75:        
                     76:        D_ClearCacheGuard ();
                     77: }
                     78: 
                     79: 
                     80: /*
                     81: ==================
                     82: D_FlushCaches
                     83: ==================
                     84: */
                     85: void D_FlushCaches (void)
                     86: {
                     87:        surfcache_t     *c;
                     88:        
                     89:        if (!sc_base)
                     90:                return;
                     91: 
                     92:        for (c = sc_base ; c ; c = c->next)
                     93:        {
                     94:                if (c->owner)
                     95:                        *c->owner = NULL;
                     96:        }
                     97:        
                     98:        sc_rover = sc_base;
                     99:        sc_base->next = NULL;
                    100:        sc_base->owner = NULL;
                    101:        sc_base->size = sc_size;
                    102: }
                    103: 
                    104: /*
                    105: =================
                    106: D_SCAlloc
                    107: =================
                    108: */
                    109: surfcache_t     *D_SCAlloc (int width, int size)
                    110: {
                    111:        surfcache_t             *new;
                    112:        qboolean                wrapped_this_time;
                    113: 
                    114:        if ((width < 0) || (width > 256))
                    115:                Sys_Error ("D_SCAlloc: bad cache width %d\n", width);
                    116: 
                    117:        if ((size <= 0) || (size > 0x10000))
                    118:                Sys_Error ("D_SCAlloc: bad cache size %d\n", size);
                    119:        
                    120:        size = (int)&((surfcache_t *)0)->data[size];
                    121:        size = (size + 3) & ~3;
                    122:        if (size > sc_size)
                    123:                Sys_Error ("D_SCAlloc: %i > cache size",size);
                    124: 
                    125: // if there is not size bytes after the rover, reset to the start
                    126:        wrapped_this_time = false;
                    127: 
                    128:        if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
                    129:        {
                    130:                if (sc_rover)
                    131:                {
                    132:                        wrapped_this_time = true;
                    133:                }
                    134:                sc_rover = sc_base;
                    135:        }
                    136:                
                    137: // colect and free surfcache_t blocks until the rover block is large enough
                    138:        new = sc_rover;
                    139:        if (sc_rover->owner)
                    140:                *sc_rover->owner = NULL;
                    141:        
                    142:        while (new->size < size)
                    143:        {
                    144:        // free another
                    145:                sc_rover = sc_rover->next;
                    146:                if (!sc_rover)
                    147:                        Sys_Error ("D_SCAlloc: hit the end of memory");
                    148:                if (sc_rover->owner)
                    149:                        *sc_rover->owner = NULL;
                    150:                        
                    151:                new->size += sc_rover->size;
                    152:                new->next = sc_rover->next;
                    153:        }
                    154: 
                    155: // create a fragment out of any leftovers
                    156:        if (new->size - size > 256)
                    157:        {
                    158:                sc_rover = (surfcache_t *)( (byte *)new + size);
                    159:                sc_rover->size = new->size - size;
                    160:                sc_rover->next = new->next;
                    161:                sc_rover->width = 0;
                    162:                sc_rover->owner = NULL;
                    163:                new->next = sc_rover;
                    164:                new->size = size;
                    165:        }
                    166:        else
                    167:                sc_rover = new->next;
                    168:        
                    169:        new->width = width;
                    170: // DEBUG
                    171:        if (width > 0)
                    172:                new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
                    173: 
                    174:        new->owner = NULL;              // should be set properly after return
                    175: 
                    176:        if (d_roverwrapped)
                    177:        {
                    178:                if (wrapped_this_time || (sc_rover >= d_initial_rover))
                    179:                        r_cache_thrash = true;
                    180:        }
                    181:        else if (wrapped_this_time)
                    182:        {       
                    183:                d_roverwrapped = true;
                    184:        }
                    185: 
                    186: D_CheckCacheGuard ();   // DEBUG
                    187:        return new;
                    188: }
                    189: 
                    190: 
                    191: /*
                    192: =================
                    193: D_SCDump
                    194: =================
                    195: */
                    196: void D_SCDump (void)
                    197: {
                    198:        surfcache_t             *test;
                    199: 
                    200:        for (test = sc_base ; test ; test = test->next)
                    201:        {
                    202:                if (test == sc_rover)
                    203:                        Sys_Printf ("ROVER:\n");
                    204:                printf ("%p : %i bytes     %i width\n",test, test->size, test->width);
                    205:        }
                    206: }
                    207: 
                    208: //=============================================================================
                    209: 
                    210: // if the num is not a power of 2, assume it will not repeat
                    211: 
                    212: int     MaskForNum (int num)
                    213: {
                    214:        if (num==128)
                    215:                return 127;
                    216:        if (num==64)
                    217:                return 63;
                    218:        if (num==32)
                    219:                return 31;
                    220:        if (num==16)
                    221:                return 15;
                    222:        return 255;
                    223: }
                    224: 
                    225: int D_log2 (int num)
                    226: {
                    227:        int     c;
                    228:        
                    229:        c = 0;
                    230:        
                    231:        while (num>>=1)
                    232:                c++;
                    233:        return c;
                    234: }
                    235: 
                    236: //=============================================================================
                    237: 
                    238: /*
                    239: ================
                    240: D_CacheSurface
                    241: ================
                    242: */
                    243: surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
                    244: {
                    245:        surfcache_t     *cache;
                    246: 
                    247: //
                    248: // if the surface is animating or flashing, flush the cache
                    249: //
                    250:        r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture);
                    251:        r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
                    252:        r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
                    253:        r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
                    254:        r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
                    255:        
                    256: //
                    257: // see if the cache holds apropriate data
                    258: //
                    259:        cache = surface->cachespots[miplevel];
                    260: 
                    261:        if (cache && !cache->dlight && surface->dlightframe != r_framecount
                    262:                        && cache->texture == r_drawsurf.texture
                    263:                        && cache->lightadj[0] == r_drawsurf.lightadj[0]
                    264:                        && cache->lightadj[1] == r_drawsurf.lightadj[1]
                    265:                        && cache->lightadj[2] == r_drawsurf.lightadj[2]
                    266:                        && cache->lightadj[3] == r_drawsurf.lightadj[3] )
                    267:                return cache;
                    268: 
                    269: //
                    270: // determine shape of surface
                    271: //
                    272:        surfscale = 1.0 / (1<<miplevel);
                    273:        r_drawsurf.surfmip = miplevel;
                    274:        r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
                    275:        r_drawsurf.rowbytes = r_drawsurf.surfwidth;
                    276:        r_drawsurf.surfheight = surface->extents[1] >> miplevel;
                    277:        
                    278: //
                    279: // allocate memory if needed
                    280: //
                    281:        if (!cache)     // if a texture just animated, don't reallocate it
                    282:        {
                    283:                cache = D_SCAlloc (r_drawsurf.surfwidth,
                    284:                                                   r_drawsurf.surfwidth * r_drawsurf.surfheight);
                    285:                surface->cachespots[miplevel] = cache;
                    286:                cache->owner = &surface->cachespots[miplevel];
                    287:                cache->mipscale = surfscale;
                    288:        }
                    289:        
                    290:        if (surface->dlightframe == r_framecount)
                    291:                cache->dlight = 1;
                    292:        else
                    293:                cache->dlight = 0;
                    294: 
                    295:        r_drawsurf.surfdat = (pixel_t *)cache->data;
                    296:        
                    297:        cache->texture = r_drawsurf.texture;
                    298:        cache->lightadj[0] = r_drawsurf.lightadj[0];
                    299:        cache->lightadj[1] = r_drawsurf.lightadj[1];
                    300:        cache->lightadj[2] = r_drawsurf.lightadj[2];
                    301:        cache->lightadj[3] = r_drawsurf.lightadj[3];
                    302: 
                    303: //
                    304: // draw and light the surface texture
                    305: //
                    306:        r_drawsurf.surf = surface;
                    307: 
                    308:        c_surf++;
                    309:        R_DrawSurface ();
                    310: 
                    311:        return surface->cachespots[miplevel];
                    312: }
                    313: 
                    314: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.