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;
const uint flags = dxt;
(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);
// 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);
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);
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;
CHECK_ERR(tex_codec_for_filename(fn, &c));
const size_t rounded_size = round_up(da.cur_size, FILE_BLOCK_SIZE);
// encode
int err = c->encode(&t, &da);
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");
goto fail;
}
const size_t rounded_size = round_up(da.cur_size, FILE_BLOCK_SIZE);
CHECK_ERR(da_set_size(&da, rounded_size));
WARN_ERR(vfs_store(fn, da.base, da.pos));
err = 0;
fail:
WARN_ERR(da_free(&da));
WARN_ERR(mem_free_h(t.hm));
(void)tex_free(&t);
(void)da_free(&da);
return err;
}

View File

@ -131,14 +131,15 @@ struct HDATA
// smaller bitfields combined into 1
u32 refs : REF_BITS;
u32 type_idx : TYPE_BITS;
u32 keep_open : 1;
// if set, do not actually release the resource (i.e. call dtor)
// .. 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 unique : 1;
// HACK: prevent adding to h_find lookup index if flags & RES_UNIQUE
u32 keep_open : 1;
// .. HACK: prevent adding to h_find lookup index if flags & RES_UNIQUE
// (because those handles might have several instances open,
// which the index can't currently handle)
u32 unique : 1;
u32 disallow_reload : 1;
H_Type type;
@ -600,6 +601,8 @@ static Handle alloc_new_handle(H_Type type, const char* fn, uintptr_t key,
hd->refs = 1;
if(!(flags & RES_NO_CACHE))
hd->keep_open = 1;
if(flags & RES_DISALLOW_RELOAD)
hd->disallow_reload = 1;
hd->unique = (flags & RES_UNIQUE) != 0;
hd->fn = 0;
// .. 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)
{
if(!fn)
@ -704,26 +708,25 @@ int h_reload(const char* fn)
const u32 key = fnv_hash(fn);
i32 i;
// destroy (note: not free!) all handles backed by this file.
// 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,
// 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);
if(hd && hd->key == key)
if(!hd || hd->key != key || hd->disallow_reload)
continue;
hd->type->dtor(hd->user);
}
int ret = 0;
// now reload all affected handles
// TODO: what if iterating through all handles is too slow?
for(i = 0; i <= last_in_use; i++)
for(i32 i = 0; i <= last_in_use; i++)
{
HDATA* hd = h_data_from_idx(i);
if(!hd || hd->key != key)
if(!hd || hd->key != key || hd->disallow_reload)
continue;
Handle h = handle(i, hd->tag);

View File

@ -320,6 +320,7 @@ typedef H_VTbl* H_Type;
// resource scope
// used together with flags (e.g. in mem), so no separate type
/*
enum
{
RES_TEMP = 1,
@ -328,19 +329,24 @@ enum
};
#define RES_SCOPE_MASK 7
*/
// h_alloc flags
enum
{
// 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
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)
// 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
};