From 47aa6fd60d6b1aca920f4c49175752d8124ed689 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 2 Feb 2023 00:43:13 +1100 Subject: render/bgfx: Fixed texture object lifecycle issues. --- src/osd/modules/render/bgfx/chainmanager.cpp | 104 ++++++++--------- src/osd/modules/render/bgfx/chainmanager.h | 2 +- src/osd/modules/render/bgfx/chainreader.cpp | 10 +- src/osd/modules/render/bgfx/chainreader.h | 3 +- src/osd/modules/render/bgfx/targetmanager.cpp | 106 ++++++++--------- src/osd/modules/render/bgfx/targetmanager.h | 28 +++-- src/osd/modules/render/bgfx/targetreader.cpp | 2 +- .../modules/render/bgfx/texturehandleprovider.h | 10 +- src/osd/modules/render/bgfx/texturemanager.cpp | 125 ++++++++++++--------- src/osd/modules/render/bgfx/texturemanager.h | 33 +++--- src/osd/modules/render/drawbgfx.cpp | 1 - 11 files changed, 229 insertions(+), 195 deletions(-) diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 156b46464dd..5fb764cd4e6 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -34,6 +34,7 @@ #include "sliderdirtynotifier.h" +#include "util/path.h" #include "util/xmlfile.h" #include "osdcore.h" @@ -141,7 +142,7 @@ void chain_manager::destroy_unloaded_chains() // O(shaders*available_chains), but we don't care because asset reloading happens rarely for (int i = 0; i < m_chain_names.size(); i++) { - std::string name = m_chain_names[i]; + const std::string &name = m_chain_names[i]; if (name.length() > 0) { for (chain_desc desc : m_available_chains) @@ -200,14 +201,13 @@ void chain_manager::find_available_chains(std::string root, std::string path) } } -bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index) +std::unique_ptr chain_manager::load_chain(std::string name, uint32_t screen_index) { if (name.length() < 5 || (name.compare(name.length() - 5, 5, ".json") != 0)) { - name = name + ".json"; + name += ".json"; } - std::string path = util::string_format("%s" PATH_SEPARATOR "chains" PATH_SEPARATOR, m_options.bgfx_path()); - path += name; + const std::string path = util::path_concat(m_options.bgfx_path(), "chains", name); bx::FileReader reader; if (!bx::open(&reader, path.c_str())) @@ -216,30 +216,35 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index) return nullptr; } - int32_t size(bx::getSize(&reader)); + const int32_t size(bx::getSize(&reader)); bx::ErrorAssert err; - char* data = new char[size + 1]; - bx::read(&reader, reinterpret_cast(data), size, &err); + std::unique_ptr data(new (std::nothrow) char [size + 1]); + if (!data) + { + osd_printf_error("Out of memory reading chain file %s\n", path); + bx::close(&reader); + return nullptr; + } + + bx::read(&reader, reinterpret_cast(data.get()), size, &err); bx::close(&reader); data[size] = 0; Document document; - document.Parse(data); - - delete [] data; + document.Parse(data.get()); + data.reset(); if (document.HasParseError()) { std::string error(GetParseError_En(document.GetParseError())); - osd_printf_warning("Unable to parse chain %s. Errors returned:\n", path); - osd_printf_warning("%s\n", error); + osd_printf_warning("Unable to parse chain %s. Errors returned:\n%s\n", path, error); return nullptr; } - bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", *this, screen_index, m_user_prescale, m_max_prescale_size); + std::unique_ptr chain = chain_reader::read_from_value(document, name + ": ", *this, screen_index, m_user_prescale, m_max_prescale_size); - if (chain == nullptr) + if (!chain) { osd_printf_warning("Unable to load chain %s, falling back to no post processing\n", path); return nullptr; @@ -320,7 +325,7 @@ void chain_manager::load_chains() { chain_desc& desc = m_available_chains[m_current_chain[chain]]; m_chain_names[chain] = desc.m_name; - m_screen_chains[chain] = load_chain(desc.m_path + "/" + desc.m_name, uint32_t(chain)); + m_screen_chains[chain] = load_chain(util::path_concat(desc.m_path, desc.m_name), uint32_t(chain)).release(); } } } @@ -421,9 +426,9 @@ void chain_manager::update_screen_count(uint32_t screen_count) m_screen_chains.push_back(nullptr); int32_t chain_index = CHAIN_NONE; - std::string chain_name = ""; + std::string chain_name; get_default_chain_info(chain_name, chain_index); - m_chain_names.push_back(chain_name); + m_chain_names.emplace_back(std::move(chain_name)); m_current_chain.push_back(chain_index); } @@ -508,23 +513,17 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive * const uint32_t src_format = (prim.m_flags & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT; const bool needs_conversion = m_converters[src_format] != nullptr; const bool needs_adjust = prim.m_prim->texture.palette != nullptr && src_format != TEXFORMAT_PALETTE16; - std::string screen_index = std::to_string(screen); - std::string source_name = "source" + screen_index; - std::string screen_name = "screen" + screen_index; - std::string palette_name = "palette" + screen_index; - std::string full_name = (needs_conversion || needs_adjust) ? source_name : screen_name; + const std::string screen_index = std::to_string(screen); + const std::string source_name = "source" + screen_index; + const std::string screen_name = "screen" + screen_index; + const std::string palette_name = "palette" + screen_index; + const std::string &full_name = (needs_conversion || needs_adjust) ? source_name : screen_name; if (texture && (texture->width() != tex_width || texture->height() != tex_height)) { - m_textures.add_provider(full_name, nullptr); - delete texture; + m_textures.remove_provider(full_name); + m_textures.remove_provider(palette_name); texture = nullptr; - - if (palette) - { - m_textures.add_provider(palette_name, nullptr); - delete palette; - palette = nullptr; - } + palette = nullptr; } bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8; @@ -534,13 +533,14 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive * const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, prim.m_flags & PRIMFLAG_TEXFORMAT_MASK, prim.m_rowpixels, prim.m_prim->texture.width_margin, tex_height, prim.m_prim->texture.palette, prim.m_prim->texture.base, pitch, width_div_factor, width_mul_factor); - if (texture == nullptr) + if (!texture) { uint32_t flags = BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT; if (!PRIMFLAG_GET_TEXWRAP(prim.m_flags)) flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP; - bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, prim.m_prim->texture.width_margin, tex_height, mem, flags, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor); - m_textures.add_provider(full_name, texture); + auto newtex = std::make_unique(full_name, dst_format, tex_width, prim.m_prim->texture.width_margin, tex_height, mem, flags, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor); + texture = newtex.get(); + m_textures.add_provider(full_name, std::move(newtex)); if (prim.m_prim->texture.palette) { @@ -549,19 +549,20 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive * m_palette_temp.resize(palette_width * palette_height * 4); memcpy(&m_palette_temp[0], prim.m_prim->texture.palette, prim.m_palette_length * 4); const bgfx::Memory *palmem = bgfx::copy(&m_palette_temp[0], palette_width * palette_height * 4); - palette = new bgfx_texture(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4); - m_textures.add_provider(palette_name, palette); + auto newpal = std::make_unique(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4); + palette = newpal.get(); + m_textures.add_provider(palette_name, std::move(newpal)); } while (screen >= m_screen_textures.size()) { - m_screen_textures.push_back(nullptr); + m_screen_textures.emplace_back(nullptr); } m_screen_textures[screen] = texture; while (screen >= m_screen_palettes.size()) { - m_screen_palettes.push_back(nullptr); + m_screen_palettes.emplace_back(nullptr); } if (palette) { @@ -587,11 +588,12 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive * } else { - palette = new bgfx_texture(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4); - m_textures.add_provider(palette_name, palette); + auto newpal = std::make_unique(palette_name, bgfx::TextureFormat::BGRA8, palette_width, 0, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width * 4); + palette = newpal.get(); + m_textures.add_provider(palette_name, std::move(newpal)); while (screen >= m_screen_palettes.size()) { - m_screen_palettes.push_back(nullptr); + m_screen_palettes.emplace_back(nullptr); } m_screen_palettes[screen] = palette; } @@ -661,12 +663,12 @@ uint32_t chain_manager::process_screen_chains(uint32_t view, osd_window& window) bool chain_manager::has_applicable_chain(uint32_t screen) { - return screen < m_screen_count && m_current_chain[screen] != CHAIN_NONE && m_screen_chains[screen] != nullptr; + return (screen < m_screen_count) && (m_current_chain[screen] != CHAIN_NONE) && m_screen_chains[screen]; } bool chain_manager::needs_sliders() { - return m_screen_count > 0 && m_available_chains.size() > 1; + return (m_screen_count > 0) && (m_available_chains.size() > 1); } void chain_manager::restore_slider_settings(int32_t id, std::vector>& settings) @@ -689,7 +691,7 @@ void chain_manager::restore_slider_settings(int32_t id, std::vector chain_sliders = chain->sliders(); + const std::vector &chain_sliders = chain->sliders(); for (size_t slider = 0; slider < chain_sliders.size(); slider++) { chain_sliders[slider]->import(settings[index][slider]); @@ -851,7 +853,7 @@ std::vector> chain_manager::slider_settings() continue; } - std::vector chain_sliders = chain->sliders(); + const std::vector &chain_sliders = chain->sliders(); for (bgfx_slider* slider : chain_sliders) { curr[index].push_back(slider->value()); @@ -880,24 +882,24 @@ std::vector chain_manager::get_slider_list() continue; } - std::vector chain_entries = chain->entries(); + const std::vector &chain_entries = chain->entries(); for (bgfx_chain_entry* entry : chain_entries) { - std::vector entry_inputs = entry->inputs(); + const std::vector &entry_inputs = entry->inputs(); for (bgfx_input_pair* input : entry_inputs) { std::vector input_sliders = input->get_slider_list(); - for (ui::menu_item slider : input_sliders) + for (ui::menu_item &slider : input_sliders) { sliders.emplace_back(slider); } } } - std::vector chain_sliders = chain->sliders(); + const std::vector &chain_sliders = chain->sliders(); for (bgfx_slider* slider : chain_sliders) { - slider_state* core_slider = slider->core_slider(); + slider_state *const core_slider = slider->core_slider(); ui::menu_item item(ui::menu_item_type::SLIDER, core_slider); item.set_text(core_slider->description); diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h index eb30e6cc835..0e8b938e6d2 100644 --- a/src/osd/modules/render/bgfx/chainmanager.h +++ b/src/osd/modules/render/bgfx/chainmanager.h @@ -87,7 +87,7 @@ public: uint32_t window_index() const { return m_window_index; } uint32_t screen_count() const { return m_screen_count; } bgfx_chain* screen_chain(uint32_t screen); - bgfx_chain* load_chain(std::string name, uint32_t screen_index); + std::unique_ptr load_chain(std::string name, uint32_t screen_index); bool has_applicable_chain(uint32_t screen); std::vector get_slider_list(); std::vector> slider_settings(); diff --git a/src/osd/modules/render/bgfx/chainreader.cpp b/src/osd/modules/render/bgfx/chainreader.cpp index 7e890682a60..362baa42c82 100644 --- a/src/osd/modules/render/bgfx/chainreader.cpp +++ b/src/osd/modules/render/bgfx/chainreader.cpp @@ -21,7 +21,13 @@ #include #include -bgfx_chain* chain_reader::read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index, uint16_t user_prescale, uint16_t max_prescale_size) +std::unique_ptr chain_reader::read_from_value( + const Value& value, + const std::string &prefix, + chain_manager& chains, + uint32_t screen_index, + uint16_t user_prescale, + uint16_t max_prescale_size) { if (!validate_parameters(value, prefix)) { @@ -120,7 +126,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, const std::string } } - return new bgfx_chain( + return std::make_unique( std::move(name), std::move(author), transform, diff --git a/src/osd/modules/render/bgfx/chainreader.h b/src/osd/modules/render/bgfx/chainreader.h index 97df49c5970..6bbd2058501 100644 --- a/src/osd/modules/render/bgfx/chainreader.h +++ b/src/osd/modules/render/bgfx/chainreader.h @@ -13,6 +13,7 @@ #include "statereader.h" +#include #include class bgfx_chain; @@ -21,7 +22,7 @@ class chain_manager; class chain_reader : public state_reader { public: - static bgfx_chain* read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index, uint16_t user_prescale, uint16_t max_prescale_size); + static std::unique_ptr read_from_value(const Value& value, const std::string &prefix, chain_manager& chains, uint32_t screen_index, uint16_t user_prescale, uint16_t max_prescale_size); private: static bool validate_parameters(const Value& value, const std::string &prefix); diff --git a/src/osd/modules/render/bgfx/targetmanager.cpp b/src/osd/modules/render/bgfx/targetmanager.cpp index 38ef04b61f9..eae09c48008 100644 --- a/src/osd/modules/render/bgfx/targetmanager.cpp +++ b/src/osd/modules/render/bgfx/targetmanager.cpp @@ -9,15 +9,15 @@ // //============================================================ -#include - -#include "modules/lib/osdobj_common.h" +#include "targetmanager.h" #include "bgfxutil.h" -#include "targetmanager.h" #include "target.h" -#include +#include "modules/lib/osdobj_common.h" + +#include + const int32_t target_manager::MAX_SCREENS = 100; @@ -29,76 +29,85 @@ target_manager::target_manager(texture_manager& textures) target_manager::~target_manager() { - std::vector to_delete; - for (std::pair target : m_targets) - { - if (target.second != nullptr) - { - to_delete.push_back(target.second); - } - } - m_targets.clear(); - - for (uint32_t i = 0; i < to_delete.size(); i++) - { - delete to_delete[i]; - } + for (auto iter = m_targets.begin(); iter != m_targets.end(); iter = m_targets.erase(iter)) + m_textures.remove_provider(iter->first); } -bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale, - uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen) +bgfx_target* target_manager::create_target( + std::string &&name, + bgfx::TextureFormat::Enum format, + uint16_t width, + uint16_t height, + uint16_t xprescale, + uint16_t yprescale, + uint32_t style, + bool double_buffer, + bool filter, + uint16_t scale, + uint32_t screen) { - std::string full_name = name + std::to_string(screen); + const std::string full_name = name + std::to_string(screen); auto iter = m_targets.find(full_name); if (iter != m_targets.end()) - destroy_target(name, screen); + { + iter->second.reset(); + m_textures.remove_provider(full_name); + } - bgfx_target *target = new bgfx_target(name, format, width, height, xprescale, yprescale, style, double_buffer, filter, scale, screen); - m_targets[full_name] = target; - m_textures.add_provider(full_name, target); + auto target = std::make_unique(std::move(name), format, width, height, xprescale, yprescale, style, double_buffer, filter, scale, screen); + if (iter != m_targets.end()) + iter->second = std::move(target); + else + iter = m_targets.emplace(full_name, std::move(target)).first; + m_textures.add_provider(full_name, *iter->second); - return target; + return iter->second.get(); } -void target_manager::destroy_target(std::string name, uint32_t screen) +void target_manager::destroy_target(const std::string &name, uint32_t screen) { - std::string full_name = (screen < 0) ? name : (name + std::to_string(screen)); - if (m_targets.find(full_name) != m_targets.end()) + const std::string full_name = (screen < 0) ? name : (name + std::to_string(screen)); + const auto found = m_targets.find(full_name); + if (found != m_targets.end()) { - delete m_targets[full_name]; - m_targets.erase(full_name); + m_targets.erase(found); m_textures.remove_provider(full_name); } } bgfx_target* target_manager::create_backbuffer(void *handle, uint16_t width, uint16_t height) { - auto* target = new bgfx_target(handle, width, height); - m_targets["backbuffer"] = target; - return target; + auto target = std::make_unique(handle, width, height); + return (m_targets["backbuffer"] = std::move(target)).get(); } -bgfx_target* target_manager::target(uint32_t screen, std::string name) +bgfx_target* target_manager::target(uint32_t screen, const std::string &name) { - std::string full_name = name + std::to_string(screen); - if (m_targets.find(full_name) == m_targets.end()) + const std::string full_name = name + std::to_string(screen); + const auto found = m_targets.find(full_name); + if (found != m_targets.end()) + { + return found->second.get(); + } + else { osd_printf_verbose("Warning: Attempting to retrieve a nonexistent target '%s' for screen %d\n", name, screen); + return nullptr; } - return m_targets[full_name]; } bool target_manager::update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size) { - if (style == TARGET_STYLE_CUSTOM) return false; + if (style == TARGET_STYLE_CUSTOM) + return false; - std::vector& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims; + std::vector &sizes = (style == TARGET_STYLE_GUEST) ? m_guest_dims : m_native_dims; // Ensure that there's an entry to fill while (sizes.size() <= screen) { - sizes.emplace_back(osd_dim(0, 0)); + sizes.emplace_back(0, 0); } if (width != sizes[screen].width() || height != sizes[screen].height()) @@ -116,14 +125,10 @@ void target_manager::rebuild_targets(uint32_t screen, uint32_t style, uint16_t u if (style == TARGET_STYLE_CUSTOM) return; std::vector to_resize; - for (std::pair target_pair : m_targets) + for (const auto &[name, target] : m_targets) { - bgfx_target* target = target_pair.second; - if (target == nullptr || target->style() != style || target->screen_index() != screen) - { - continue; - } - to_resize.push_back(target); + if (target && (target->style() == style) && (target->screen_index() == screen)) + to_resize.push_back(target.get()); } std::vector& sizes = style == TARGET_STYLE_GUEST ? m_guest_dims : m_native_dims; @@ -140,8 +145,7 @@ void target_manager::rebuild_targets(uint32_t screen, uint32_t style, uint16_t u uint16_t yprescale = user_prescale; bgfx_util::find_prescale_factor(width, height, max_prescale_size, xprescale, yprescale); - destroy_target(name, screen); - create_target(name, format, width, height, xprescale, yprescale, style, double_buffered, filter, scale, screen); + create_target(std::move(name), format, width, height, xprescale, yprescale, style, double_buffered, filter, scale, screen); } } diff --git a/src/osd/modules/render/bgfx/targetmanager.h b/src/osd/modules/render/bgfx/targetmanager.h index e3406722eda..38bba4c5db5 100644 --- a/src/osd/modules/render/bgfx/targetmanager.h +++ b/src/osd/modules/render/bgfx/targetmanager.h @@ -9,37 +9,41 @@ // //============================================================ +#ifndef MAME_RENDER_BGFX_TARGETMANAGER_H +#define MAME_RENDER_BGFX_TARGETMANAGER_H + #pragma once -#ifndef __DRAWBGFX_TARGET_MANAGER__ -#define __DRAWBGFX_TARGET_MANAGER__ +#include "texturemanager.h" -#include -#include +#include "modules/osdhelper.h" #include -#include "modules/osdhelper.h" +#include +#include +#include +#include -#include "texturemanager.h" class bgfx_target; -class target_manager { +class target_manager +{ public: target_manager(texture_manager& textures); ~target_manager(); - bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale, + bgfx_target* create_target(std::string &&name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint16_t xprescale, uint16_t yprescale, uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen); - void destroy_target(std::string name, uint32_t screen = -1); + void destroy_target(const std::string &name, uint32_t screen = -1); bgfx_target* create_backbuffer(void *handle, uint16_t width, uint16_t height); bool update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size); void update_screen_count(uint32_t count, uint16_t user_prescale, uint16_t max_prescale_size); // Getters - bgfx_target* target(uint32_t screen, std::string name); + bgfx_target* target(uint32_t screen, const std::string &name); uint16_t width(uint32_t style, uint32_t screen); uint16_t height(uint32_t style, uint32_t screen); @@ -47,7 +51,7 @@ private: void rebuild_targets(uint32_t screen, uint32_t style, uint16_t user_prescale, uint16_t max_prescale_size); void create_output_if_nonexistent(uint32_t screen, uint16_t user_prescale, uint16_t max_prescale_size); - std::map m_targets; + std::map > m_targets; texture_manager& m_textures; std::vector m_guest_dims; @@ -57,4 +61,4 @@ private: static const int32_t MAX_SCREENS; }; -#endif // __DRAWBGFX_TARGET_MANAGER__ +#endif // MAME_RENDER_BGFX_TARGETMANAGER_H diff --git a/src/osd/modules/render/bgfx/targetreader.cpp b/src/osd/modules/render/bgfx/targetreader.cpp index ce02ac95db0..12386428822 100644 --- a/src/osd/modules/render/bgfx/targetreader.cpp +++ b/src/osd/modules/render/bgfx/targetreader.cpp @@ -87,7 +87,7 @@ bgfx_target* target_reader::read_from_value( break; } - return chains.targets().create_target(target_name, bgfx::TextureFormat::BGRA8, width, height, xprescale, yprescale, mode, double_buffer, bilinear, scale, screen_index); + return chains.targets().create_target(std::move(target_name), bgfx::TextureFormat::BGRA8, width, height, xprescale, yprescale, mode, double_buffer, bilinear, scale, screen_index); } bool target_reader::validate_parameters(const Value& value, const std::string &prefix) diff --git a/src/osd/modules/render/bgfx/texturehandleprovider.h b/src/osd/modules/render/bgfx/texturehandleprovider.h index aa6a41157e2..35e4e12dc43 100644 --- a/src/osd/modules/render/bgfx/texturehandleprovider.h +++ b/src/osd/modules/render/bgfx/texturehandleprovider.h @@ -7,17 +7,17 @@ // //============================================================ -#pragma once +#ifndef MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H +#define MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H -#ifndef __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__ -#define __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__ +#pragma once #include class bgfx_texture_handle_provider { public: - virtual ~bgfx_texture_handle_provider() { } + virtual ~bgfx_texture_handle_provider() = default; // Getters virtual bgfx::TextureHandle texture() const = 0; @@ -30,4 +30,4 @@ public: virtual int width_mul_factor() const = 0; }; -#endif // __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__ +#endif // MAME_RENDER_BGFX_TEXTUREHANDLEPROVIDER_H diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp index 623ca6365db..b9acd5748e8 100644 --- a/src/osd/modules/render/bgfx/texturemanager.cpp +++ b/src/osd/modules/render/bgfx/texturemanager.cpp @@ -11,23 +11,24 @@ #include "texturemanager.h" -#include "texture.h" #include "bgfxutil.h" +#include "texture.h" + +#include "modules/render/copyutil.h" +#include "osdcore.h" + #include "emucore.h" #include "fileio.h" #include "rendutil.h" -#include "osdcore.h" -#include "modules/render/copyutil.h" + + +texture_manager::texture_manager() +{ + // out-of-line so header works with forward declarations +} texture_manager::~texture_manager() { - for (std::pair texture : m_textures) - { - if (texture.second != nullptr && !(texture.second)->is_target()) - { - delete texture.second; - } - } m_textures.clear(); for (std::pair mame_texture : m_mame_textures) @@ -37,27 +38,45 @@ texture_manager::~texture_manager() m_mame_textures.clear(); } -void texture_manager::add_provider(std::string name, bgfx_texture_handle_provider* provider) +void texture_manager::add_provider(const std::string &name, std::unique_ptr &&provider) { - auto iter = m_textures.find(name); + const auto iter = m_textures.find(name); if (iter != m_textures.end()) - { - iter->second = provider; - } + iter->second = std::make_pair(provider.get(), std::move(provider)); else - { - m_textures[name] = provider; - } + m_textures.emplace(name, std::make_pair(provider.get(), std::move(provider))); } -bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t width_margin, uint32_t height, void* data, uint32_t flags) +void texture_manager::add_provider(const std::string &name, bgfx_texture_handle_provider &provider) { - auto* texture = new bgfx_texture(name, format, width, width_margin, height, flags, data); - m_textures[name] = texture; - return texture; + const auto iter = m_textures.find(name); + if (iter != m_textures.end()) + iter->second = std::make_pair(&provider, nullptr); + else + m_textures.emplace(name, std::make_pair(&provider, nullptr)); +} + +bgfx_texture* texture_manager::create_texture( + const std::string &name, + bgfx::TextureFormat::Enum format, + uint32_t width, + uint32_t width_margin, + uint32_t height, + void* data, + uint32_t flags) +{ + auto texture = std::make_unique(name, format, width, width_margin, height, flags, data); + bgfx_texture &result = *texture; + m_textures[name] = std::make_pair(texture.get(), std::move(texture)); + return &result; } -bgfx_texture* texture_manager::create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags, uint32_t screen) +bgfx_texture* texture_manager::create_png_texture( + const std::string &path, + const std::string &file_name, + std::string texture_name, + uint32_t flags, + uint32_t screen) { bitmap_argb32 bitmap; emu_file file(path, OPEN_FLAG_READ); @@ -73,36 +92,41 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string return nullptr; } - auto *data = new uint8_t[bitmap.width() * bitmap.height() * 4]; - auto *data32 = reinterpret_cast(data); - const uint32_t width = bitmap.width(); const uint32_t height = bitmap.height(); + auto data32 = std::make_unique(width * height); + const uint32_t rowpixels = bitmap.rowpixels(); auto* base = reinterpret_cast(bitmap.raw_pixptr(0)); for (int y = 0; y < height; y++) { - copy_util::copyline_argb32_to_bgra(data32 + y * width, base + y * rowpixels, width, nullptr); + copy_util::copyline_argb32_to_bgra(&data32[y * width], base + y * rowpixels, width, nullptr); } if (screen >= 0) { texture_name += std::to_string(screen); } - bgfx_texture* texture = create_texture(texture_name, bgfx::TextureFormat::BGRA8, width, 0, height, data, flags); - - delete [] data; - - return texture; + return create_texture(texture_name, bgfx::TextureFormat::BGRA8, width, 0, height, data32.get(), flags); } -bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t format, int width, int width_margin, int height - , int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key) +bgfx::TextureHandle texture_manager::create_or_update_mame_texture( + uint32_t format, + int width, + int width_margin, + int height, + int rowpixels, + const rgb_t *palette, + void *base, + uint32_t seqid, + uint32_t flags, + uint64_t key, + uint64_t old_key) { bgfx::TextureHandle handle = BGFX_INVALID_HANDLE; if (old_key != ~0ULL) { - auto iter = m_mame_textures.find(old_key); + const auto iter = m_mame_textures.find(old_key); if (iter != m_mame_textures.end()) { handle = iter->second.handle; @@ -178,38 +202,27 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form return handle; } -bgfx::TextureHandle texture_manager::handle(std::string name) +bgfx::TextureHandle texture_manager::handle(const std::string &name) { bgfx::TextureHandle handle = BGFX_INVALID_HANDLE; - auto iter = m_textures.find(name); + const auto iter = m_textures.find(name); if (iter != m_textures.end()) - { - handle = (iter->second)->texture(); - } + handle = iter->second.first->texture(); assert(handle.idx != bgfx::kInvalidHandle); return handle; } -bgfx_texture_handle_provider* texture_manager::provider(std::string name) +bgfx_texture_handle_provider* texture_manager::provider(const std::string &name) { - auto iter = m_textures.find(name); + const auto iter = m_textures.find(name); if (iter != m_textures.end()) - { - return iter->second; - } - - return nullptr; + return iter->second.first; + else + return nullptr; } -void texture_manager::remove_provider(std::string name, bool delete_provider) +void texture_manager::remove_provider(const std::string &name) { - if (provider(name) != nullptr) - { - if (delete_provider) - { - delete m_textures[name]; - } - m_textures.erase(name); - } + m_textures.erase(name); } diff --git a/src/osd/modules/render/bgfx/texturemanager.h b/src/osd/modules/render/bgfx/texturemanager.h index 904837e917b..8ed5d410f75 100644 --- a/src/osd/modules/render/bgfx/texturemanager.h +++ b/src/osd/modules/render/bgfx/texturemanager.h @@ -9,40 +9,45 @@ // //============================================================ -#pragma once +#ifndef MAME_RENDER_BGFX_TEXTUREMANAGER_H +#define MAME_RENDER_BGFX_TEXTUREMANAGER_H -#ifndef DRAWBGFX_TEXTURE_MANAGER -#define DRAWBGFX_TEXTURE_MANAGER +#pragma once #include "bitmap.h" #include #include +#include #include +#include #include + class bgfx_texture_handle_provider; class bgfx_texture; -class texture_manager { +class texture_manager +{ public: - texture_manager() { } + texture_manager(); ~texture_manager(); - bgfx_texture* create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t width_margin, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP); - bgfx_texture* create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint32_t screen = -1); - void add_provider(std::string name, bgfx_texture_handle_provider* texture); - void remove_provider(std::string name, bool delete_provider = false); + bgfx_texture* create_texture(const std::string &name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t width_margin, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP); + bgfx_texture* create_png_texture(const std::string &path, const std::string &file_name, std::string texture_name, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint32_t screen = -1); + void add_provider(const std::string &name, std::unique_ptr &&texture); + void add_provider(const std::string &name, bgfx_texture_handle_provider &texture); + void remove_provider(const std::string &name); bgfx::TextureHandle create_or_update_mame_texture(uint32_t format, int width, int width_margin, int height, int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key); // Getters - bgfx::TextureHandle handle(std::string name); - bgfx_texture_handle_provider* provider(std::string name); + bgfx::TextureHandle handle(const std::string &name); + bgfx_texture_handle_provider* provider(const std::string &name); private: - bgfx_texture* create_texture(std::string name); + bgfx_texture* create_texture(const std::string &name); struct sequenced_handle { @@ -52,8 +57,8 @@ private: int height; }; - std::map m_textures; + std::map > > m_textures; std::map m_mame_textures; }; -#endif // DRAWBGFX_TEXTURE_MANAGER +#endif // MAME_RENDER_BGFX_TEXTUREMANAGER_H diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index aa4cf95f7be..3edc3cfd465 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -1199,7 +1199,6 @@ bool renderer_bgfx::update_dimensions() if (window().index() != 0) { - delete m_framebuffer; #ifdef OSD_WINDOWS m_framebuffer = m_targets->create_backbuffer(dynamic_cast(window()).platform_window(), width, height); #elif defined(OSD_MAC) -- cgit v1.2.3