1
0
forked from 0ad/0ad

bugfix when writing screenshot: was calculating rounded up size for VFS incorrectly.

also fix refcnt for tex_wrap temporarily until mem_assign/mem_get_ptr
do.

h_mgr: add disallow-reload support (required for wrapped ogl_tex since
they are not backed by a file)

This was SVN commit r2780.
This commit is contained in:
janwas 2005-09-27 15:35:17 +00:00
parent 609be94b8c
commit db27ff6c9b
4 changed files with 31 additions and 24 deletions

View File

@ -451,11 +451,6 @@ static void CALL_CONV emulate_glCompressedTexImage2D(
Tex t; Tex t;
const uint flags = dxt; const uint flags = dxt;
(void)tex_wrap((uint)w, (uint)h, s3tc_bpp, flags, (void*)data, &t); (void)tex_wrap((uint)w, (uint)h, s3tc_bpp, flags, (void*)data, &t);
// .. hack: prevent <data> from being freed when tex_transform
// replaces previous hm with the new transformed buffer.
// (important because mipmapped images share the same mem alloc and
// there's no way we know when to free that)
h_add_ref(t.hm);
(void)tex_transform(&t, TEX_DXT); (void)tex_transform(&t, TEX_DXT);
// uncompressed RGB[A] format info // uncompressed RGB[A] format info

View File

@ -516,6 +516,9 @@ int tex_wrap(uint w, uint h, uint bpp, uint flags, void* img, Tex* t)
void* reported_ptr = mem_get_ptr(t->hm); void* reported_ptr = mem_get_ptr(t->hm);
t->ofs = (u8*)img - (u8*)reported_ptr; t->ofs = (u8*)img - (u8*)reported_ptr;
// TODO: remove when mem_assign / mem_get_ptr add a reference correctly
h_add_ref(t->hm);
CHECK_TEX(t); CHECK_TEX(t);
return 0; return 0;
} }
@ -540,7 +543,6 @@ int tex_write(const char* fn, uint w, uint h, uint bpp, uint flags, void* in_img
const TexCodecVTbl* c; const TexCodecVTbl* c;
CHECK_ERR(tex_codec_for_filename(fn, &c)); CHECK_ERR(tex_codec_for_filename(fn, &c));
const size_t rounded_size = round_up(da.cur_size, FILE_BLOCK_SIZE);
// encode // encode
int err = c->encode(&t, &da); int err = c->encode(&t, &da);
if(err < 0) if(err < 0)
@ -549,12 +551,13 @@ int tex_write(const char* fn, uint w, uint h, uint bpp, uint flags, void* in_img
debug_warn("tex_writefailed"); debug_warn("tex_writefailed");
goto fail; goto fail;
} }
const size_t rounded_size = round_up(da.cur_size, FILE_BLOCK_SIZE);
CHECK_ERR(da_set_size(&da, rounded_size)); CHECK_ERR(da_set_size(&da, rounded_size));
WARN_ERR(vfs_store(fn, da.base, da.pos)); WARN_ERR(vfs_store(fn, da.base, da.pos));
err = 0; err = 0;
fail: fail:
WARN_ERR(da_free(&da)); (void)tex_free(&t);
WARN_ERR(mem_free_h(t.hm)); (void)da_free(&da);
return err; return err;
} }

View File

@ -131,14 +131,15 @@ struct HDATA
// smaller bitfields combined into 1 // smaller bitfields combined into 1
u32 refs : REF_BITS; u32 refs : REF_BITS;
u32 type_idx : TYPE_BITS; u32 type_idx : TYPE_BITS;
// .. if set, do not actually release the resource (i.e. call dtor)
// when the handle is h_free-d, regardless of the refcount.
// set by h_alloc; reset on exit and by housekeeping.
u32 keep_open : 1; u32 keep_open : 1;
// if set, do not actually release the resource (i.e. call dtor) // .. HACK: prevent adding to h_find lookup index if flags & RES_UNIQUE
// when the handle is h_free-d, regardless of the refcount. // (because those handles might have several instances open,
// set by h_alloc; reset on exit and by housekeeping. // which the index can't currently handle)
u32 unique : 1; u32 unique : 1;
// HACK: prevent adding to h_find lookup index if flags & RES_UNIQUE u32 disallow_reload : 1;
// (because those handles might have several instances open,
// which the index can't currently handle)
H_Type type; H_Type type;
@ -600,6 +601,8 @@ static Handle alloc_new_handle(H_Type type, const char* fn, uintptr_t key,
hd->refs = 1; hd->refs = 1;
if(!(flags & RES_NO_CACHE)) if(!(flags & RES_NO_CACHE))
hd->keep_open = 1; hd->keep_open = 1;
if(flags & RES_DISALLOW_RELOAD)
hd->disallow_reload = 1;
hd->unique = (flags & RES_UNIQUE) != 0; hd->unique = (flags & RES_UNIQUE) != 0;
hd->fn = 0; hd->fn = 0;
// .. filename is valid - store in hd // .. filename is valid - store in hd
@ -694,6 +697,7 @@ const char* h_filename(const Handle h)
} }
// TODO: what if iterating through all handles is too slow?
int h_reload(const char* fn) int h_reload(const char* fn)
{ {
if(!fn) if(!fn)
@ -704,26 +708,25 @@ int h_reload(const char* fn)
const u32 key = fnv_hash(fn); const u32 key = fnv_hash(fn);
i32 i;
// destroy (note: not free!) all handles backed by this file. // destroy (note: not free!) all handles backed by this file.
// do this before reloading any of them, because we don't specify reload // do this before reloading any of them, because we don't specify reload
// order (the parent resource may be reloaded first, and load the child, // order (the parent resource may be reloaded first, and load the child,
// whose original data would leak). // whose original data would leak).
for(i = 0; i <= last_in_use; i++) for(i32 i = 0; i <= last_in_use; i++)
{ {
HDATA* hd = h_data_from_idx(i); HDATA* hd = h_data_from_idx(i);
if(hd && hd->key == key) if(!hd || hd->key != key || hd->disallow_reload)
hd->type->dtor(hd->user); continue;
hd->type->dtor(hd->user);
} }
int ret = 0; int ret = 0;
// now reload all affected handles // now reload all affected handles
// TODO: what if iterating through all handles is too slow? for(i32 i = 0; i <= last_in_use; i++)
for(i = 0; i <= last_in_use; i++)
{ {
HDATA* hd = h_data_from_idx(i); HDATA* hd = h_data_from_idx(i);
if(!hd || hd->key != key) if(!hd || hd->key != key || hd->disallow_reload)
continue; continue;
Handle h = handle(i, hd->tag); Handle h = handle(i, hd->tag);

View File

@ -320,6 +320,7 @@ typedef H_VTbl* H_Type;
// resource scope // resource scope
// used together with flags (e.g. in mem), so no separate type // used together with flags (e.g. in mem), so no separate type
/*
enum enum
{ {
RES_TEMP = 1, RES_TEMP = 1,
@ -328,19 +329,24 @@ enum
}; };
#define RES_SCOPE_MASK 7 #define RES_SCOPE_MASK 7
*/
// h_alloc flags // h_alloc flags
enum enum
{ {
// alias for RES_TEMP scope. the handle will not be kept open. // alias for RES_TEMP scope. the handle will not be kept open.
RES_NO_CACHE = 1, RES_NO_CACHE = 0x01,
// not cached, and will never reuse a previous instance // not cached, and will never reuse a previous instance
RES_UNIQUE = RES_NO_CACHE|16, RES_UNIQUE = RES_NO_CACHE|0x10,
// the resource isn't backed by a file. the fn parameter is treated as the search key (uintptr_t) // the resource isn't backed by a file. the fn parameter is treated as the search key (uintptr_t)
// currently only used by mem manager // currently only used by mem manager
RES_KEY = 8 RES_KEY = 0x08,
// object is requesting it never be reloaded (e.g. because it's not
// backed by a file)
RES_DISALLOW_RELOAD = 0x20
}; };