Use overcommit for palettes, bitmaps, dbitmaps and tilemaps
This makes the large size of these objects visible to Lua, hopefully allowing Lua GC to make better decisions.
This commit is contained in:
parent
e0827ce54f
commit
7ba7fc24f6
5 changed files with 109 additions and 49 deletions
|
@ -204,6 +204,17 @@ private:
|
|||
bool registered;
|
||||
};
|
||||
|
||||
static const size_t overcommit_std_align = 32;
|
||||
|
||||
/**
|
||||
* Align a overcommit pointer.
|
||||
*/
|
||||
template<typename T, typename U> U* align_overcommit(T* th)
|
||||
{
|
||||
size_t ptr = reinterpret_cast<size_t>(th) + sizeof(T);
|
||||
return reinterpret_cast<U*>(ptr + (overcommit_std_align - ptr % overcommit_std_align) % overcommit_std_align);
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of Lua classes.
|
||||
*/
|
||||
|
|
|
@ -14,9 +14,15 @@
|
|||
|
||||
struct lua_palette
|
||||
{
|
||||
std::vector<framebuffer::color> colors;
|
||||
std::vector<framebuffer::color> lcolors;
|
||||
framebuffer::color* colors;
|
||||
framebuffer::color* scolors;
|
||||
lua_palette(lua::state& L);
|
||||
static size_t overcommit() { return 0; }
|
||||
size_t color_count;
|
||||
const static size_t reserved_colors = 32;
|
||||
static size_t overcommit() {
|
||||
return lua::overcommit_std_align + reserved_colors * sizeof(framebuffer::color);
|
||||
}
|
||||
~lua_palette();
|
||||
threads::lock palette_mutex;
|
||||
std::string print();
|
||||
|
@ -27,16 +33,20 @@ struct lua_palette
|
|||
int hash(lua::state& L, lua::parameters& P);
|
||||
int debug(lua::state& L, lua::parameters& P);
|
||||
int adjust_transparency(lua::state& L, lua::parameters& P);
|
||||
void adjust_palette_size(size_t newsize);
|
||||
void push_back(const framebuffer::color& c);
|
||||
};
|
||||
|
||||
struct lua_bitmap
|
||||
{
|
||||
lua_bitmap(lua::state& L, uint32_t w, uint32_t h);
|
||||
static size_t overcommit(uint32_t w, uint32_t h) { return 0; }
|
||||
static size_t overcommit(uint32_t w, uint32_t h) {
|
||||
return lua::overcommit_std_align + sizeof(uint16_t) * w * h;
|
||||
}
|
||||
~lua_bitmap();
|
||||
size_t width;
|
||||
size_t height;
|
||||
std::vector<uint16_t> pixels;
|
||||
uint16_t* pixels;
|
||||
std::vector<char> save_png(const lua_palette& pal) const;
|
||||
std::string print();
|
||||
static int create(lua::state& L, lua::parameters& P);
|
||||
|
@ -54,11 +64,13 @@ struct lua_bitmap
|
|||
struct lua_dbitmap
|
||||
{
|
||||
lua_dbitmap(lua::state& L, uint32_t w, uint32_t h);
|
||||
static size_t overcommit(uint32_t w, uint32_t h) { return 0; }
|
||||
static size_t overcommit(uint32_t w, uint32_t h) {
|
||||
return lua::overcommit_std_align + sizeof(framebuffer::color) * w * h;
|
||||
}
|
||||
~lua_dbitmap();
|
||||
size_t width;
|
||||
size_t height;
|
||||
std::vector<framebuffer::color> pixels;
|
||||
framebuffer::color* pixels;
|
||||
std::vector<char> save_png() const;
|
||||
std::string print();
|
||||
static int create(lua::state& L, lua::parameters& P);
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace
|
|||
|
||||
if(!create) {
|
||||
P(p);
|
||||
size_t ccount = p->colors.size();
|
||||
size_t ccount = p->color_count;
|
||||
if(ccount != 16 && ccount != 256)
|
||||
throw std::runtime_error("Palette to read must be 16 or 256 colors");
|
||||
full = (ccount == 256);
|
||||
|
@ -127,7 +127,7 @@ namespace
|
|||
size_t ps = full ? 256 : 16;
|
||||
if(create) {
|
||||
p = lua::_class<lua_palette>::create(L);
|
||||
p->colors.resize(ps);
|
||||
p->adjust_palette_size(ps);
|
||||
}
|
||||
uint8_t* mem = reinterpret_cast<uint8_t*>(lsnes_memory.get_physical_mapping(addr, 2 * ps));
|
||||
if(mem) {
|
||||
|
|
|
@ -41,11 +41,11 @@ std::vector<char> lua_bitmap::save_png(const lua_palette& pal) const
|
|||
img.has_palette = true;
|
||||
img.has_alpha = false;
|
||||
img.data.resize(width * height);
|
||||
img.palette.resize(pal.colors.size());
|
||||
img.palette.resize(pal.color_count);
|
||||
for(size_t i = 0; i < width * height; i++) {
|
||||
img.data[i] = pixels[i];
|
||||
}
|
||||
for(size_t i = 0; i < pal.colors.size(); i++) {
|
||||
for(size_t i = 0; i < pal.color_count; i++) {
|
||||
const framebuffer::color& c = pal.colors[i];
|
||||
if(c.origa != 256)
|
||||
img.has_alpha = true;
|
||||
|
@ -100,8 +100,8 @@ namespace
|
|||
size_t w, h;
|
||||
framebuffer::color* palette;
|
||||
if(b) {
|
||||
palette = &p->colors[0];
|
||||
pallim = p->colors.size();
|
||||
palette = p->colors;
|
||||
pallim = p->color_count;
|
||||
w = b->width;
|
||||
h = b->height;
|
||||
} else {
|
||||
|
@ -150,7 +150,7 @@ namespace
|
|||
operand_dbitmap(lua_dbitmap& _bitmap)
|
||||
: bitmap(_bitmap), _transparent(-1)
|
||||
{
|
||||
pixels = &bitmap.pixels[0];
|
||||
pixels = bitmap.pixels;
|
||||
}
|
||||
size_t get_width() { return bitmap.width; }
|
||||
size_t get_height() { return bitmap.height; }
|
||||
|
@ -172,7 +172,7 @@ namespace
|
|||
operand_bitmap(lua_bitmap& _bitmap)
|
||||
: bitmap(_bitmap)
|
||||
{
|
||||
pixels = &bitmap.pixels[0];
|
||||
pixels = bitmap.pixels;
|
||||
}
|
||||
size_t get_width() { return bitmap.width; }
|
||||
size_t get_height() { return bitmap.height; }
|
||||
|
@ -193,9 +193,9 @@ namespace
|
|||
operand_bitmap_pal(lua_bitmap& _bitmap, lua_palette& _palette)
|
||||
: bitmap(_bitmap), palette(_palette), _transparent(-1)
|
||||
{
|
||||
pixels = &bitmap.pixels[0];
|
||||
limit = palette.colors.size();
|
||||
pal = &palette.colors[0];
|
||||
pixels = bitmap.pixels;
|
||||
limit = palette.color_count;
|
||||
pal = palette.colors;
|
||||
}
|
||||
size_t get_width() { return bitmap.width; }
|
||||
size_t get_height() { return bitmap.height; }
|
||||
|
@ -271,8 +271,8 @@ namespace
|
|||
{
|
||||
srcdest_priority(lua_bitmap& dest, lua_bitmap& src)
|
||||
{
|
||||
darray = &dest.pixels[0];
|
||||
sarray = &src.pixels[0];
|
||||
darray = dest.pixels;
|
||||
sarray = src.pixels;
|
||||
swidth = src.width;
|
||||
sheight = src.height;
|
||||
dwidth = dest.width;
|
||||
|
@ -525,7 +525,7 @@ namespace
|
|||
lua_palette* p = lua::_class<lua_palette>::create(L);
|
||||
for(size_t i = 0; i < bitmap.w * bitmap.h; i++)
|
||||
b->pixels[i] = bitmap.bitmap[i];
|
||||
p->colors.resize(bitmap.palette.size());
|
||||
p->adjust_palette_size(bitmap.palette.size());
|
||||
for(size_t i = 0; i < bitmap.palette.size(); i++)
|
||||
p->colors[i] = framebuffer::color(bitmap.palette[i]);
|
||||
return 2;
|
||||
|
@ -638,7 +638,7 @@ namespace
|
|||
lua_palette* p = lua::_class<lua_palette>::create(L);
|
||||
for(size_t i = 0; i < img.width * img.height; i++)
|
||||
b->pixels[i] = img.data[i];
|
||||
p->colors.resize(img.palette.size());
|
||||
p->adjust_palette_size(img.palette.size());
|
||||
for(size_t i = 0; i < img.palette.size(); i++)
|
||||
p->colors[i] = framebuffer::color(mangle_color(img.palette[i]));
|
||||
return 2;
|
||||
|
@ -667,18 +667,18 @@ namespace
|
|||
cb = parse_value<uint8_t>(r[3]);
|
||||
ca = 256 - parse_value<uint16_t>(r[4]);
|
||||
if(ca == 256)
|
||||
p->colors.push_back(framebuffer::color(-1));
|
||||
p->push_back(framebuffer::color(-1));
|
||||
else
|
||||
p->colors.push_back(framebuffer::color((ca << 24) | (cr << 16)
|
||||
p->push_back(framebuffer::color((ca << 24) | (cr << 16)
|
||||
| (cg << 8) | cb));
|
||||
} else if(r = regex("[ \t]*([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]*", line)) {
|
||||
int64_t cr, cg, cb;
|
||||
cr = parse_value<uint8_t>(r[1]);
|
||||
cg = parse_value<uint8_t>(r[2]);
|
||||
cb = parse_value<uint8_t>(r[3]);
|
||||
p->colors.push_back(framebuffer::color((cr << 16) | (cg << 8) | cb));
|
||||
p->push_back(framebuffer::color((cr << 16) | (cg << 8) | cb));
|
||||
} else if(r = regex("[ \t]*([^ \t]|[^ \t].*[^ \t])[ \t]*", line)) {
|
||||
p->colors.push_back(framebuffer::color(r[1]));
|
||||
p->push_back(framebuffer::color(r[1]));
|
||||
} else
|
||||
throw std::runtime_error("Invalid line format (" + line + ")");
|
||||
}
|
||||
|
@ -753,6 +753,10 @@ namespace
|
|||
/** Palette **/
|
||||
lua_palette::lua_palette(lua::state& L)
|
||||
{
|
||||
color_count = 0;
|
||||
scolors = colors = lua::align_overcommit<lua_palette, framebuffer::color>(this);
|
||||
for(unsigned i = 0; i < reserved_colors; i++)
|
||||
scolors[i] = framebuffer::color(-1);
|
||||
}
|
||||
|
||||
lua_palette::~lua_palette()
|
||||
|
@ -761,7 +765,7 @@ lua_palette::~lua_palette()
|
|||
|
||||
std::string lua_palette::print()
|
||||
{
|
||||
size_t s = colors.size();
|
||||
size_t s = color_count;
|
||||
return (stringfmt() << s << " " << ((s != 1) ? "colors" : "color")).str();
|
||||
}
|
||||
|
||||
|
@ -805,11 +809,8 @@ int lua_palette::set(lua::state& L, lua::parameters& P)
|
|||
|
||||
P(P.skipped(), c, nc);
|
||||
|
||||
//The lock protects only the internals of colors array.
|
||||
if(this->colors.size() <= c) {
|
||||
this->palette_mutex.lock();
|
||||
this->colors.resize(static_cast<uint32_t>(c) + 1);
|
||||
this->palette_mutex.unlock();
|
||||
if(this->color_count <= c) {
|
||||
this->adjust_palette_size(static_cast<uint32_t>(c) + 1);
|
||||
}
|
||||
this->colors[c] = nc;
|
||||
return 0;
|
||||
|
@ -822,7 +823,7 @@ int lua_palette::hash(lua::state& L, lua::parameters& P)
|
|||
int bufferuse = 0;
|
||||
char buf[buffersize];
|
||||
unsigned realsize = 0;
|
||||
for(unsigned i = 0; i < this->colors.size(); i++)
|
||||
for(unsigned i = 0; i < this->color_count; i++)
|
||||
if(this->colors[i].origa) realsize = i + 1;
|
||||
for(unsigned i = 0; i < realsize; i++) {
|
||||
if(bufferuse + 6 > buffersize) {
|
||||
|
@ -840,9 +841,8 @@ int lua_palette::hash(lua::state& L, lua::parameters& P)
|
|||
|
||||
int lua_palette::debug(lua::state& L, lua::parameters& P)
|
||||
{
|
||||
size_t i = 0;
|
||||
for(auto c : this->colors)
|
||||
messages << "Color #" << (i++) << ": " << c.orig << ":" << c.origa << std::endl;
|
||||
for(size_t i = 0; i < color_count; i++)
|
||||
messages << "Color #" << i << ": " << colors[i].orig << ":" << colors[i].origa << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -852,18 +852,45 @@ int lua_palette::adjust_transparency(lua::state& L, lua::parameters& P)
|
|||
|
||||
P(P.skipped(), tadj);
|
||||
|
||||
for(auto& c : this->colors)
|
||||
c = tadjust(c, tadj);
|
||||
for(size_t i = 0; i < color_count; i++)
|
||||
colors[i] = tadjust(colors[i], tadj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lua_palette::adjust_palette_size(size_t newsize)
|
||||
{
|
||||
threads::alock h(palette_mutex);
|
||||
if(newsize > reserved_colors) {
|
||||
lcolors.resize(newsize);
|
||||
if(color_count <= reserved_colors) {
|
||||
for(unsigned i = 0; i < color_count; i++)
|
||||
lcolors[i] = colors[i];
|
||||
}
|
||||
colors = &lcolors[0];
|
||||
} else {
|
||||
if(color_count > reserved_colors) {
|
||||
for(unsigned i = 0; i < color_count; i++)
|
||||
scolors[i] = lcolors[i];
|
||||
}
|
||||
colors = scolors;
|
||||
}
|
||||
color_count = newsize;
|
||||
}
|
||||
|
||||
void lua_palette::push_back(const framebuffer::color& cx)
|
||||
{
|
||||
size_t c = color_count;
|
||||
adjust_palette_size(c + 1);
|
||||
colors[c] = cx;
|
||||
}
|
||||
|
||||
/** BITMAP **/
|
||||
lua_bitmap::lua_bitmap(lua::state& L, uint32_t w, uint32_t h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
pixels.resize(width * height);
|
||||
memset(&pixels[0], 0, width * height);
|
||||
pixels = lua::align_overcommit<lua_bitmap, uint16_t>(this);
|
||||
memset(pixels, 0, 2 * width * height);
|
||||
}
|
||||
|
||||
lua_bitmap::~lua_bitmap()
|
||||
|
@ -1026,7 +1053,11 @@ lua_dbitmap::lua_dbitmap(lua::state& L, uint32_t w, uint32_t h)
|
|||
{
|
||||
width = w;
|
||||
height = h;
|
||||
pixels.resize(width * height);
|
||||
pixels = lua::align_overcommit<lua_dbitmap, framebuffer::color>(this);
|
||||
//Initialize the bitmap data.
|
||||
framebuffer::color transparent(-1);
|
||||
for(size_t i = 0; i < width * height; i++)
|
||||
new(pixels + i) framebuffer::color(transparent);
|
||||
}
|
||||
|
||||
lua_dbitmap::~lua_dbitmap()
|
||||
|
@ -1206,8 +1237,8 @@ int lua_dbitmap::adjust_transparency(lua::state& L, lua::parameters& P)
|
|||
|
||||
P(P.skipped(), tadj);
|
||||
|
||||
for(auto& c : this->pixels)
|
||||
c = tadjust(c, tadj);
|
||||
for(size_t i = 0; i < width * height; i++)
|
||||
pixels[i] = tadjust(pixels[i], tadj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ namespace
|
|||
struct tilemap
|
||||
{
|
||||
tilemap(lua::state& L, size_t _width, size_t _height, size_t _cwidth, size_t _cheight);
|
||||
static size_t overcommit(size_t _width, size_t _height, size_t _cwidth, size_t _cheight) { return 0; }
|
||||
static size_t overcommit(size_t _width, size_t _height, size_t _cwidth, size_t _cheight) {
|
||||
return lua::overcommit_std_align + 2 * sizeof(tilemap_entry) * _width * _height;
|
||||
}
|
||||
~tilemap()
|
||||
{
|
||||
threads::alock h(lock);
|
||||
|
@ -131,8 +133,7 @@ namespace
|
|||
y0 + h < y0)
|
||||
throw std::runtime_error("Scroll window out of range");
|
||||
if(!ox && !oy) return 0;
|
||||
std::vector<tilemap_entry> tmp;
|
||||
tmp.resize(w * h);
|
||||
tilemap_entry* tmp = tmpmap;
|
||||
for(size_t _y = 0; _y < h; _y++) {
|
||||
size_t y = _y + y0;
|
||||
size_t sy = calcshift(y, oy, h, y0, circy);
|
||||
|
@ -161,7 +162,8 @@ namespace
|
|||
size_t height;
|
||||
size_t cwidth;
|
||||
size_t cheight;
|
||||
std::vector<tilemap_entry> map;
|
||||
tilemap_entry* map;
|
||||
tilemap_entry* tmpmap;
|
||||
threads::lock lock;
|
||||
};
|
||||
|
||||
|
@ -208,8 +210,8 @@ namespace
|
|||
{
|
||||
if(xmin >= xmax || ymin >= ymax) return;
|
||||
p.palette_mutex.lock();
|
||||
framebuffer::color* palette = &p.colors[0];
|
||||
size_t pallim = p.colors.size();
|
||||
framebuffer::color* palette = p.colors;
|
||||
size_t pallim = p.color_count;
|
||||
|
||||
for(int32_t r = ymin; r < ymax; r++) {
|
||||
typename framebuffer::fb<T>::element_t* rptr = scr.rowptr(yp + r);
|
||||
|
@ -317,6 +319,10 @@ namespace
|
|||
{
|
||||
if(width * height / height != width)
|
||||
throw std::bad_alloc();
|
||||
map.resize(width * height);
|
||||
map = lua::align_overcommit<tilemap, tilemap_entry>(this);
|
||||
tmpmap = &map[width * height];
|
||||
//Initialize the map!
|
||||
for(size_t i = 0; i < 2 * width * height; i++)
|
||||
new(map + i) tilemap_entry();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue