From 670bb7badcf717f7c3c50345d79754c77fa443bf Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 27 Aug 2011 18:52:13 +0000 Subject: [PATCH] fix cachepic handling with respect to r_restart and Draw_NewPic Some forgotten memsets, and attempts to free the notexture, could wreak havoc git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11303 d7cf8633-e32d-0410-b094-e92efae38249 --- draw.h | 2 ++ gl_draw.c | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/draw.h b/draw.h index c7f1bc27..5cb62afa 100644 --- a/draw.h +++ b/draw.h @@ -45,6 +45,8 @@ typedef struct cachepic_s qboolean hasalpha; // name of pic char name[MAX_QPATH]; + // allow to override/free the texture + qboolean allow_free_tex; } cachepic_t; diff --git a/gl_draw.c b/gl_draw.c index aa6a0c38..86976c85 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -361,23 +361,31 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) return cachepics; // return the first one } pic = cachepics + (numcachepics++); + memset(pic, 0, sizeof(*pic)); strlcpy (pic->name, path, sizeof(pic->name)); // link into list pic->chain = cachepichash[hashkey]; cachepichash[hashkey] = pic; reload: + // TODO why does this crash? + if(pic->allow_free_tex && pic->tex) + R_PurgeTexture(pic->tex); + // check whether it is an dynamic texture (if so, we can directly use its texture handler) pic->flags = cachepicflags; pic->tex = CL_GetDynTexture( path ); // if so, set the width/height, too if( pic->tex ) { + pic->allow_free_tex = false; pic->width = R_TextureWidth(pic->tex); pic->height = R_TextureHeight(pic->tex); // we're done now (early-out) return pic; } + pic->allow_free_tex = true; + pic->hasalpha = true; // assume alpha unless we know it has none pic->texflags = texflags; pic->autoload = (cachepicflags & CACHEPICFLAG_NOTPERSISTENT); @@ -490,6 +498,7 @@ reload: pic->tex = draw_generatepic(pic->name, (cachepicflags & CACHEPICFLAG_QUIET) != 0); pic->width = R_TextureWidth(pic->tex); pic->height = R_TextureHeight(pic->tex); + pic->allow_free_tex = (pic->tex != r_texture_notexture); } return pic; @@ -573,26 +582,24 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u } else { - if (pic == NULL) + if (numcachepics == MAX_CACHED_PICS) { - if (numcachepics == MAX_CACHED_PICS) - { - Con_Printf ("Draw_NewPic: numcachepics == MAX_CACHED_PICS\n"); - // FIXME: support NULL in callers? - return cachepics; // return the first one - } - pic = cachepics + (numcachepics++); - strlcpy (pic->name, picname, sizeof(pic->name)); - // link into list - pic->chain = cachepichash[hashkey]; - cachepichash[hashkey] = pic; + Con_Printf ("Draw_NewPic: numcachepics == MAX_CACHED_PICS\n"); + // FIXME: support NULL in callers? + return cachepics; // return the first one } + pic = cachepics + (numcachepics++); + memset(pic, 0, sizeof(*pic)); + strlcpy (pic->name, picname, sizeof(pic->name)); + // link into list + pic->chain = cachepichash[hashkey]; + cachepichash[hashkey] = pic; } pic->flags = CACHEPICFLAG_NEWPIC; // disable texflags checks in Draw_CachePic pic->width = width; pic->height = height; - if (pic->tex) + if (pic->allow_free_tex && pic->tex) R_FreeTexture(pic->tex); pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels_bgra, TEXTYPE_BGRA, (alpha ? TEXF_ALPHA : 0), -1, NULL); return pic; -- 2.39.2