Significant speed improvements to the BGFX renderer. [MooglyGuy]

This commit is contained in:
therealmogminer@gmail.com 2016-02-15 17:57:16 +01:00
parent a95323026c
commit b0a7bcd346
9 changed files with 1010 additions and 403 deletions

View File

@ -104,6 +104,7 @@ function osdmodulesbuild()
if USE_BGFX == 1 then
files {
MAME_DIR .. "src/osd/modules/render/drawbgfx.cpp",
MAME_DIR .. "src/osd/modules/render/binpacker.cpp",
}
defines {
"USE_BGFX"

View File

@ -442,8 +442,10 @@ void render_texture::hq_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const
// get_scaled - get a scaled bitmap (if we can)
//-------------------------------------------------
void render_texture::get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist)
void render_texture::get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist, bool packable)
{
texinfo.hash = 0;
// source width/height come from the source bounds
int swidth = m_sbounds.width();
int sheight = m_sbounds.height();
@ -520,6 +522,17 @@ void render_texture::get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &t
// palette will be set later
texinfo.seqid = scaled->seqid;
}
UINT32 hash = 0;
if (packable)
{
//printf("Packable, %d, %d\n", texinfo.width, texinfo.height);
}
if (packable && texinfo.width <= 128 && texinfo.height <= 128)
{
hash = reinterpret_cast<UINT64>(texinfo.base) & 0xffffffff;
}
texinfo.hash = hash;
}
@ -677,7 +690,7 @@ void render_container::add_char(float x0, float y0, float height, float aspect,
// add it like a quad
item &newitem = add_generic(CONTAINER_ITEM_QUAD, bounds.x0, bounds.y0, bounds.x1, bounds.y1, argb);
newitem.m_texture = texture;
newitem.m_flags = PRIMFLAG_TEXORIENT(ROT0) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
newitem.m_flags = PRIMFLAG_TEXORIENT(ROT0) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE;
newitem.m_internal = INTERNAL_FLAG_CHAR;
}
@ -1751,7 +1764,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
width = MIN(width, m_maxtexwidth);
height = MIN(height, m_maxtexheight);
curitem->texture()->get_scaled(width, height, prim->texture, list);
curitem->texture()->get_scaled(width, height, prim->texture, list, (curitem->flags() & PRIMFLAG_PACKABLE) ? true : false);
// set the palette
prim->texture.palette = curitem->texture()->get_adjusted_palette(container);
@ -1854,7 +1867,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob
// get the scaled texture and append it
texture->get_scaled(width, height, prim->texture, list);
texture->get_scaled(width, height, prim->texture, list, (prim->flags & PRIMFLAG_PACKABLE) ? true : false);
// compute the clip rect
render_bounds cliprect;

View File

@ -62,7 +62,9 @@ enum
BLENDMODE_NONE = 0, // no blending
BLENDMODE_ALPHA, // standard alpha blend
BLENDMODE_RGB_MULTIPLY, // apply source alpha to source pix, then multiply RGB values
BLENDMODE_ADD // apply source alpha to source pix, then add to destination
BLENDMODE_ADD, // apply source alpha to source pix, then add to destination
BLENDMODE_COUNT
};
@ -105,6 +107,9 @@ const UINT32 PRIMFLAG_TYPE_MASK = 3 << PRIMFLAG_TYPE_SHIFT;
const UINT32 PRIMFLAG_TYPE_LINE = 0 << PRIMFLAG_TYPE_SHIFT;
const UINT32 PRIMFLAG_TYPE_QUAD = 1 << PRIMFLAG_TYPE_SHIFT;
const int PRIMFLAG_PACKABLE_SHIFT = 1;
const UINT32 PRIMFLAG_PACKABLE = 1 << PRIMFLAG_PACKABLE_SHIFT;
//**************************************************************************
// MACROS
//**************************************************************************
@ -206,6 +211,7 @@ struct render_texinfo
UINT32 height; // height of the image
UINT32 seqid; // sequence ID
UINT64 osddata; // aux data to pass to osd
UINT32 hash; // hash (where applicable)
const rgb_t * palette; // palette for PALETTE16 textures, bcg lookup table for RGB32/YUY16
};
@ -430,7 +436,7 @@ public:
private:
// internal helpers
void get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist);
void get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist, bool packable = false);
const rgb_t *get_adjusted_palette(render_container &container);
static const int MAX_TEXTURE_SCALES = 16;

View File

@ -1258,7 +1258,7 @@ void ui_menu::render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const
void ui_menu::highlight(render_container *container, float x0, float y0, float x1, float y1, rgb_t bgcolor)
{
container->add_quad(x0, y0, x1, y1, bgcolor, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
container->add_quad(x0, y0, x1, y1, bgcolor, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE) | PRIMFLAG_PACKABLE);
}
@ -1268,7 +1268,7 @@ void ui_menu::highlight(render_container *container, float x0, float y0, float x
void ui_menu::draw_arrow(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, UINT32 orientation)
{
container->add_quad(x0, y0, x1, y1, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation));
container->add_quad(x0, y0, x1, y1, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation) | PRIMFLAG_PACKABLE);
}
//-------------------------------------------------
@ -2116,7 +2116,7 @@ void ui_menu::draw_star(float x0, float y0)
{
float y1 = y0 + machine().ui().get_line_height();
float x1 = x0 + machine().ui().get_line_height() * container->manager().ui_aspect();
container->add_quad(x0, y0, x1, y1, ARGB_WHITE, star_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container->add_quad(x0, y0, x1, y1, ARGB_WHITE, star_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE);
}
//-------------------------------------------------
@ -2298,13 +2298,13 @@ void ui_menu::draw_common_arrow(float origx1, float origy1, float origx2, float
// apply arrow
if (current == dmin)
container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90));
container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
else if (current == dmax)
container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X));
container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
else
{
container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90));
container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X));
container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
}
}
@ -2409,7 +2409,7 @@ void ui_menu::draw_icon(int linenum, void *selectedref, float x0, float y0)
}
if (icons_bitmap[linenum]->valid())
container->add_quad(x0, y0, x1, y1, ARGB_WHITE, icons_texture[linenum], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container->add_quad(x0, y0, x1, y1, ARGB_WHITE, icons_texture[linenum], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE);
}
//-------------------------------------------------

View File

@ -0,0 +1,195 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
// binpacker.cpp - Simple texture packer for dynamic atlasing
//
//============================================================
#include "binpacker.h"
#include <algorithm>
bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size)
{
clear();
m_pack_size = pack_size;
// Add rects to member array, and check to make sure none is too big
for (size_t rect = 0; rect < rects.size(); rect++)
{
m_rects.push_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
}
// Sort from greatest to least area
std::sort(m_rects.rbegin(), m_rects.rend());
// Pack
while (m_num_packed < (int)m_rects.size())
{
int i = m_packs.size();
m_packs.push_back(rectangle(m_pack_size));
m_roots.push_back(i);
if (!fill(i))
{
return false;
}
}
// Write out
packs.resize(m_roots.size());
for (size_t i = 0; i < m_roots.size(); ++i)
{
packs[i].clear();
add_pack_to_array(m_roots[i], packs[i]);
}
return true;
}
void rectangle_packer::clear()
{
m_pack_size = 0;
m_num_packed = 0;
m_rects.clear();
m_packs.clear();
m_roots.clear();
}
bool rectangle_packer::fill(int pack)
{
// For each rect
for (size_t rect = 0; rect < m_rects.size(); ++rect)
{
// If it's not already packed
if (!m_rects[rect].packed)
{
// If it fits in the current working area
if (fits(m_rects[rect], m_packs[pack]))
{
// Store in lower-left of working area, split, and recurse
m_num_packed++;
split(pack, rect);
fill(m_packs[pack].children[0]);
fill(m_packs[pack].children[1]);
return true;
}
}
}
return false;
}
void rectangle_packer::split(int pack, int rect)
{
// Split the working area either horizontally or vertically with respect
// to the rect we're storing, such that we get the largest possible child
// area.
rectangle left = m_packs[pack];
rectangle right = m_packs[pack];
rectangle bottom = m_packs[pack];
rectangle top = m_packs[pack];
left.y += m_rects[rect].h;
left.w = m_rects[rect].w;
left.h -= m_rects[rect].h;
right.x += m_rects[rect].w;
right.w -= m_rects[rect].w;
bottom.x += m_rects[rect].w;
bottom.h = m_rects[rect].h;
bottom.w -= m_rects[rect].w;
top.y += m_rects[rect].h;
top.h -= m_rects[rect].h;
int max_lr_area = left.get_area();
if (right.get_area() > max_lr_area)
{
max_lr_area = right.get_area();
}
int max_bt_area = bottom.get_area();
if (top.get_area() > max_bt_area)
{
max_bt_area = top.get_area();
}
if (max_lr_area > max_bt_area)
{
if (left.get_area() > right.get_area())
{
m_packs.push_back(left);
m_packs.push_back(right);
}
else
{
m_packs.push_back(right);
m_packs.push_back(left);
}
}
else
{
if (bottom.get_area() > top.get_area())
{
m_packs.push_back(bottom);
m_packs.push_back(top);
}
else
{
m_packs.push_back(top);
m_packs.push_back(bottom);
}
}
// This pack area now represents the rect we've just stored, so save the
// relevant info to it, and assign children.
m_packs[pack].w = m_rects[rect].w;
m_packs[pack].h = m_rects[rect].h;
m_packs[pack].hash = m_rects[rect].hash;
m_packs[pack].format = m_rects[rect].format;
m_packs[pack].rowpixels = m_rects[rect].rowpixels;
m_packs[pack].palette = m_rects[rect].palette;
m_packs[pack].base = m_rects[rect].base;
m_packs[pack].children[0] = m_packs.size() - 2;
m_packs[pack].children[1] = m_packs.size() - 1;
// Done with the rect
m_rects[rect].packed = true;
}
bool rectangle_packer::fits(rectangle& rect1, const rectangle& rect2)
{
// Check to see if rect1 fits in rect2
if (rect1.w <= rect2.w && rect1.h <= rect2.h)
{
return true;
}
else
{
return false;
}
}
void rectangle_packer::add_pack_to_array(int pack, std::vector<packed_rectangle>& array) const
{
if (m_packs[pack].hash != 0)
{
array.push_back(packed_rectangle(m_packs[pack].hash, m_packs[pack].format,
m_packs[pack].w, m_packs[pack].h, m_packs[pack].x, m_packs[pack].y,
m_packs[pack].rowpixels, m_packs[pack].palette, m_packs[pack].base));
if (m_packs[pack].children[0] != -1)
{
add_pack_to_array(m_packs[pack].children[0], array);
}
if (m_packs[pack].children[1] != -1)
{
add_pack_to_array(m_packs[pack].children[1], array);
}
}
}

View File

@ -0,0 +1,183 @@
#pragma once
#ifndef __RECTPACKER_H__
#define __RECTPACKER_H__
#include "emu.h"
#include <vector>
class rectangle_packer
{
public:
// The input and output are in terms of vectors of ints to avoid
// dependencies (although I suppose a public member struct could have been
// used). The parameters are:
// packs : After packing, the outer array contains the packs (therefore
// the number of packs is packs.size()). Each inner array contains a
// sequence of sets of 3 ints. Each set represents a rectangle in the
// pack. The elements in the set are 1) the rect ID, 2) the x position
// of the rect with respect to the pack, and 3) the y position of the rect
// with respect to the pack. The widths and heights of the rects are not
// included, as it's assumed they are stored on the caller's side (they
// were after all the input to the function).
class packable_rectangle
{
public:
packable_rectangle() : m_hash(0), m_width(-1), m_height(-1) { }
packable_rectangle(UINT32 hash, UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
: m_hash(hash)
, m_format(format)
, m_width(width)
, m_height(height)
, m_rowpixels(rowpixels)
, m_palette(palette)
, m_base(base)
{
}
UINT32 hash() const { return m_hash; }
UINT32 format() const { return m_format; }
int width() const { return m_width; }
int height() const { return m_height; }
int rowpixels() const { return m_rowpixels; }
const rgb_t* palette() const { return m_palette; }
void* base() const { return m_base; }
private:
UINT32 m_hash;
UINT32 m_format;
int m_width;
int m_height;
int m_rowpixels;
const rgb_t* m_palette;
void* m_base;
};
class packed_rectangle
{
public:
packed_rectangle() : m_hash(0), m_format(0), m_width(-1), m_height(-1), m_x(-1), m_y(-1), m_rowpixels(0), m_palette(nullptr), m_base(nullptr) { }
packed_rectangle(const packed_rectangle& rect)
: m_hash(rect.m_hash)
, m_format(rect.m_format)
, m_width(rect.m_width)
, m_height(rect.m_height)
, m_x(rect.m_x)
, m_y(rect.m_y)
, m_rowpixels(rect.m_rowpixels)
, m_palette(rect.m_palette)
, m_base(rect.m_base)
{
}
packed_rectangle(UINT32 hash, UINT32 format, int width, int height, int x, int y, int rowpixels, const rgb_t *palette, void *base)
: m_hash(hash)
, m_format(format)
, m_width(width)
, m_height(height)
, m_x(x)
, m_y(y)
, m_rowpixels(rowpixels)
, m_palette(palette)
, m_base(base)
{
}
UINT32 hash() const { return m_hash; }
UINT32 format() const { return m_format; }
int width() const { return m_width; }
int height() const { return m_height; }
int x() const { return m_x; }
int y() const { return m_y; }
int rowpixels() const { return m_rowpixels; }
const rgb_t* palette() const { return m_palette; }
void* base() const { return m_base; }
private:
UINT32 m_hash;
UINT32 m_format;
int m_width;
int m_height;
int m_x;
int m_y;
int m_rowpixels;
const rgb_t* m_palette;
void* m_base;
};
bool pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size);
private:
struct rectangle
{
rectangle(int size)
: x(0)
, y(0)
, w(size)
, h(size)
, hash(-1)
, format(0)
, rowpixels(0)
, palette(nullptr)
, base(nullptr)
, packed(false)
{
children[0] = -1;
children[1] = -1;
}
rectangle(int x, int y, int w, int h, int hash, UINT32 format, int rowpixels, const rgb_t *palette, void *base)
: x(x)
, y(y)
, w(w)
, h(h)
, hash(hash)
, format(format)
, rowpixels(rowpixels)
, palette(palette)
, base(base)
, packed(false)
{
children[0] = -1;
children[1] = -1;
}
int get_area() const
{
return w * h;
}
bool operator<(const rectangle& rect) const
{
return get_area() < rect.get_area();
}
int x;
int y;
int w;
int h;
int hash;
UINT32 format;
int rowpixels;
const rgb_t* palette;
void* base;
int children[2];
bool packed;
};
void clear();
bool fill(int pack);
void split(int pack, int rect);
bool fits(rectangle& rect1, const rectangle& rect2);
void add_pack_to_array(int pack, std::vector<packed_rectangle>& array) const;
int m_pack_size;
int m_num_packed;
std::vector<rectangle> m_rects;
std::vector<rectangle> m_packs;
std::vector<int> m_roots;
};
#endif // __RECTPACKER_H__

View File

@ -1416,14 +1416,9 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
float screen_scale[2] = { xscale, yscale };
float screen_offset[2] = { xoffset, yoffset };
rgb_t back_color_rgb = !machine->first_screen()->has_palette()
? rgb_t(0, 0, 0)
: machine->first_screen()->palette().palette()->entry_color(0);
rgb_t back_color_rgb = !machine->first_screen()->has_palette() ? rgb_t(0, 0, 0) : machine->first_screen()->palette().palette()->entry_color(0);
back_color_rgb = apply_color_convolution(back_color_rgb);
float back_color[3] = {
static_cast<float>(back_color_rgb.r()) / 255.0f,
static_cast<float>(back_color_rgb.g()) / 255.0f,
static_cast<float>(back_color_rgb.b()) / 255.0f };
float back_color[3] = { static_cast<float>(back_color_rgb.r()) / 255.0f, static_cast<float>(back_color_rgb.g()) / 255.0f, static_cast<float>(back_color_rgb.b()) / 255.0f };
curr_effect = post_effect;
curr_effect->update_uniforms();
@ -1463,9 +1458,9 @@ int shaders::downsample_pass(render_target *rt, int source_index, poly_info *pol
curr_effect->set_bool("PrepareVector", prepare_vector);
int bloom_index = 0;
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
float bloom_width = prepare_vector ? rt->target_width : rt->target_width / hlsl_prescale_x;
float bloom_height = prepare_vector ? rt->target_height : rt->target_height / hlsl_prescale_y;
float bloom_size = (bloom_width < bloom_height) ? bloom_width : bloom_height;
for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
{
bloom_dims[bloom_index][0] = (float)(int)bloom_width;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
#pragma once
#ifndef __RENDER_BGFX__
#define __RENDER_BGFX__
#include <map>
#include <vector>
#include "binpacker.h"
/* sdl_info is the information about SDL for the current screen */
class renderer_bgfx : public osd_renderer
{
public:
renderer_bgfx(osd_window *w)
: osd_renderer(w, FLAG_NONE)
, m_dimensions(0, 0)
{
}
virtual int create() override;
virtual int draw(const int update) override;
#ifdef OSD_SDL
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
#else
virtual void save() override { }
virtual void record() override { }
virtual void toggle_fsfx() override { }
#endif
virtual void destroy() override;
virtual render_primitive_list *get_primitives() override
{
osd_dim wdim = window().get_size();
window().target()->set_bounds(wdim.width(), wdim.height(), window().aspect());
return &window().target()->get_primitives();
}
private:
struct PosColorTexCoord0Vertex
{
float m_x;
float m_y;
float m_z;
UINT32 m_rgba;
float m_u;
float m_v;
static void init()
{
ms_decl.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.end();
}
static bgfx::VertexDecl ms_decl;
};
struct PosColorVertex
{
float m_x;
float m_y;
float m_z;
UINT32 m_rgba;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.end();
}
static bgfx::VertexDecl ms_decl;
};
void allocate_buffers(bgfx::TransientVertexBuffer *flat_buffer, bgfx::TransientVertexBuffer *textured_buffer);
void render_textured_quad(int view, render_primitive* prim);
void render_flat_quad(int view, render_primitive *prim);
void put_packed_quad(render_primitive *prim, UINT32 hash, PosColorTexCoord0Vertex* vertex);
void put_polygon(const float* coords, UINT32 num_coords, float r, UINT32 rgba, PosColorVertex* vertex);
void put_line(float x0, float y0, float x1, float y1, float r, UINT32 rgba, PosColorVertex* vertex, float fth = 1.0f);
void set_bgfx_state(UINT32 blend);
uint32_t u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a);
bool check_for_dirty_atlas();
bool update_atlas();
const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
bgfx::ProgramHandle loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName);
bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName);
bgfx::ProgramHandle m_progQuad;
bgfx::ProgramHandle m_progQuadTexture;
bgfx::UniformHandle m_s_texColor;
bgfx::FrameBufferHandle fbh;
bgfx::TextureHandle m_texture_cache;
// Original display_mode
osd_dim m_dimensions;
std::map<UINT32, rectangle_packer::packed_rectangle> m_hash_to_entry;
std::vector<rectangle_packer::packable_rectangle> m_texinfo;
rectangle_packer m_packer;
static const uint16_t CACHE_SIZE = 1024;
};
#endif