VideoBackends: Simplify initialization and deinitialization of resources

Approximately three or four times now, the issue of pointers being
in an inconsistent state been an issue in the video backend renderers
with regards to tripping up other developers.

Global (ugh) resources are put into a unique_ptr and will always have a
well-defined state of being - null or not null
This commit is contained in:
Lioncash 2015-12-20 21:49:49 -05:00
parent 1fbab188ad
commit f295182833
25 changed files with 104 additions and 86 deletions

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/GL/GLInterfaceBase.h"
#ifdef ANDROID
@ -20,19 +22,19 @@
#error Platform doesnt have a GLInterface
#endif
cInterfaceBase* HostGL_CreateGLInterface()
std::unique_ptr<cInterfaceBase> HostGL_CreateGLInterface()
{
#ifdef ANDROID
return new cInterfaceEGLAndroid;
return std::make_unique<cInterfaceEGLAndroid>();
#elif defined(__APPLE__)
return new cInterfaceAGL;
return std::make_unique<cInterfaceAGL>();
#elif defined(_WIN32)
return new cInterfaceWGL;
return std::make_unique<cInterfaceWGL>();
#elif defined(HAVE_X11) && HAVE_X11
#if defined(USE_EGL) && USE_EGL
return new cInterfaceEGLX11;
return std::make_unique<cInterfaceEGLX11>();
#else
return new cInterfaceGLX;
return std::make_unique<cInterfaceGLX>();
#endif
#else
return nullptr;

View File

@ -4,6 +4,7 @@
#pragma once
#include <memory>
#include <string>
#include "Common/CommonTypes.h"
@ -42,8 +43,8 @@ public:
virtual bool PeekMessages() { return false; }
};
extern cInterfaceBase *GLInterface;
extern std::unique_ptr<cInterfaceBase> GLInterface;
// This function has to be defined along the Host_ functions from Core/Host.h.
// Current canonical implementation: DolphinWX/GLInterface/GLInterface.cpp.
cInterfaceBase* HostGL_CreateGLInterface();
std::unique_ptr<cInterfaceBase> HostGL_CreateGLInterface();

View File

@ -2,12 +2,14 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/Assert.h"
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
#include "Common/Logging/Log.h"
cInterfaceBase *GLInterface;
std::unique_ptr<cInterfaceBase> GLInterface;
static GLuint attributelessVAO = 0;
static GLuint attributelessVBO = 0;

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h"
@ -21,7 +23,7 @@
namespace DX11
{
static TextureEncoder* g_encoder = nullptr;
static std::unique_ptr<TextureEncoder> g_encoder;
const size_t MAX_COPY_BUFFERS = 32;
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 };
@ -377,7 +379,7 @@ ID3D11PixelShader *GetConvertShader(const char* Type)
TextureCache::TextureCache()
{
// FIXME: Is it safe here?
g_encoder = new PSTextureEncoder;
g_encoder = std::make_unique<PSTextureEncoder>();
g_encoder->Init();
palette_buf = nullptr;
@ -407,8 +409,7 @@ TextureCache::~TextureCache()
SAFE_RELEASE(efbcopycbuf[k]);
g_encoder->Shutdown();
delete g_encoder;
g_encoder = nullptr;
g_encoder.reset();
SAFE_RELEASE(palette_buf);
SAFE_RELEASE(palette_buf_srv);

View File

@ -129,11 +129,11 @@ void VertexManager::Draw(u32 stride)
{
case PRIMITIVE_POINTS:
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
((DX11::Renderer*)g_renderer)->ApplyCullDisable();
static_cast<Renderer*>(g_renderer.get())->ApplyCullDisable();
break;
case PRIMITIVE_LINES:
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
((DX11::Renderer*)g_renderer)->ApplyCullDisable();
static_cast<Renderer*>(g_renderer.get())->ApplyCullDisable();
break;
case PRIMITIVE_TRIANGLES:
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@ -146,7 +146,7 @@ void VertexManager::Draw(u32 stride)
INCSTAT(stats.thisFrame.numDrawCalls);
if (current_primitive_type != PRIMITIVE_TRIANGLES)
((DX11::Renderer*)g_renderer)->RestoreCull();
static_cast<Renderer*>(g_renderer.get())->RestoreCull();
}
void VertexManager::vFlush(bool useDstAlpha)

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include <string>
#include "Common/FileUtil.h"
@ -176,10 +177,10 @@ bool VideoBackend::Initialize(void *window_handle)
void VideoBackend::Video_Prepare()
{
// internal interfaces
g_renderer = new Renderer(m_window_handle);
g_texture_cache = new TextureCache;
g_vertex_manager = new VertexManager;
g_perf_query = new PerfQuery;
g_renderer = std::make_unique<Renderer>(m_window_handle);
g_texture_cache = std::make_unique<TextureCache>();
g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = std::make_unique<PerfQuery>();
VertexShaderCache::Init();
PixelShaderCache::Init();
GeometryShaderCache::Init();
@ -225,14 +226,10 @@ void VideoBackend::Shutdown()
GeometryShaderCache::Shutdown();
BBox::Shutdown();
delete g_perf_query;
delete g_vertex_manager;
delete g_texture_cache;
delete g_renderer;
g_renderer = nullptr;
g_texture_cache = nullptr;
g_vertex_manager = nullptr;
g_perf_query = nullptr;
g_perf_query.reset();
g_vertex_manager.reset();
g_texture_cache.reset();
g_renderer.reset();
}
}

View File

@ -55,7 +55,7 @@ GLVertexFormat::GLVertexFormat(const PortableVertexDeclaration& _vtx_decl)
if (vertex_stride & 3)
PanicAlert("Uneven vertex stride: %i", vertex_stride);
VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
VertexManager* const vm = static_cast<VertexManager*>(g_vertex_manager.get());
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
@ -10,15 +12,16 @@
namespace OGL
{
PerfQueryBase* GetPerfQuery()
std::unique_ptr<PerfQueryBase> GetPerfQuery()
{
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3 &&
GLExtensions::Supports("GL_NV_occlusion_query_samples"))
return new PerfQueryGLESNV();
else if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
return new PerfQueryGL(GL_ANY_SAMPLES_PASSED);
else
return new PerfQueryGL(GL_SAMPLES_PASSED);
return std::make_unique<PerfQueryGLESNV>();
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
return std::make_unique<PerfQueryGL>(GL_ANY_SAMPLES_PASSED);
return std::make_unique<PerfQueryGL>(GL_SAMPLES_PASSED);
}
PerfQuery::PerfQuery()

View File

@ -13,7 +13,7 @@
namespace OGL
{
PerfQueryBase* GetPerfQuery();
std::unique_ptr<PerfQueryBase> GetPerfQuery();
class PerfQuery : public PerfQueryBase
{

View File

@ -1599,7 +1599,7 @@ void Renderer::RestoreAPIState()
SetLogicOpMode();
SetViewport();
VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
const VertexManager* const vm = static_cast<VertexManager*>(g_vertex_manager.get());
glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
if (vm->m_last_vao)
glBindVertexArray(vm->m_last_vao);

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/GL/GLInterfaceBase.h"
#include "VideoBackends/OGL/SamplerCache.h"
#include "VideoCommon/DriverDetails.h"
@ -10,7 +12,7 @@
namespace OGL
{
SamplerCache *g_sampler_cache;
std::unique_ptr<SamplerCache> g_sampler_cache;
SamplerCache::SamplerCache()
: m_last_max_anisotropy()

View File

@ -5,6 +5,7 @@
#pragma once
#include <map>
#include <memory>
#include "Common/CommonTypes.h"
#include "Common/NonCopyable.h"
@ -80,6 +81,6 @@ private:
u32 m_sampler_id[2];
};
extern SamplerCache *g_sampler_cache;
extern std::unique_ptr<SamplerCache> g_sampler_cache;
}

View File

@ -19,6 +19,8 @@ class TextureCache : public TextureCacheBase
{
public:
TextureCache();
~TextureCache();
static void DisableStage(unsigned int stage);
static void SetStage();
@ -49,8 +51,6 @@ private:
bool Save(const std::string& filename, unsigned int level) override;
};
~TextureCache();
TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) override;
void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format) override;

View File

@ -137,7 +137,7 @@ void VertexManager::Draw(u32 stride)
INCSTAT(stats.thisFrame.numDrawCalls);
if (current_primitive_type != PRIMITIVE_TRIANGLES)
((OGL::Renderer*)g_renderer)->SetGenerationMode();
static_cast<Renderer*>(g_renderer.get())->SetGenerationMode();
}
void VertexManager::vFlush(bool useDstAlpha)

View File

@ -38,6 +38,7 @@ Make AA apply instantly during gameplay if possible
#include <algorithm>
#include <cstdarg>
#include <memory>
#include "Common/Atomic.h"
#include "Common/CommonPaths.h"
@ -182,13 +183,13 @@ void VideoBackend::Video_Prepare()
{
GLInterface->MakeCurrent();
g_renderer = new Renderer;
g_renderer = std::make_unique<Renderer>();
CommandProcessor::Init();
PixelEngine::Init();
BPInit();
g_vertex_manager = new VertexManager;
g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = GetPerfQuery();
Fifo_Init(); // must be done before OpcodeDecoder_Init()
OpcodeDecoder_Init();
@ -197,8 +198,8 @@ void VideoBackend::Video_Prepare()
PixelShaderManager::Init();
GeometryShaderManager::Init();
ProgramShaderCache::Init();
g_texture_cache = new TextureCache();
g_sampler_cache = new SamplerCache();
g_texture_cache = std::make_unique<TextureCache>();
g_sampler_cache = std::make_unique<SamplerCache>();
Renderer::Init();
VertexLoaderManager::Init();
TextureConverter::Init();
@ -216,39 +217,35 @@ void VideoBackend::Shutdown()
OSD::DoCallbacks(OSD::OSD_SHUTDOWN);
GLInterface->Shutdown();
delete GLInterface;
GLInterface = nullptr;
GLInterface.reset();
}
void VideoBackend::Video_Cleanup()
{
if (g_renderer)
{
Fifo_Shutdown();
if (!g_renderer)
return;
// The following calls are NOT Thread Safe
// And need to be called from the video thread
Renderer::Shutdown();
BoundingBox::Shutdown();
TextureConverter::Shutdown();
VertexLoaderManager::Shutdown();
delete g_sampler_cache;
g_sampler_cache = nullptr;
delete g_texture_cache;
g_texture_cache = nullptr;
ProgramShaderCache::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown();
GeometryShaderManager::Shutdown();
delete g_perf_query;
g_perf_query = nullptr;
delete g_vertex_manager;
g_vertex_manager = nullptr;
OpcodeDecoder_Shutdown();
delete g_renderer;
g_renderer = nullptr;
GLInterface->ClearCurrent();
}
Fifo_Shutdown();
// The following calls are NOT Thread Safe
// And need to be called from the video thread
Renderer::Shutdown();
BoundingBox::Shutdown();
TextureConverter::Shutdown();
VertexLoaderManager::Shutdown();
g_sampler_cache.reset();
g_texture_cache.reset();
ProgramShaderCache::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown();
GeometryShaderManager::Shutdown();
g_perf_query.reset();
g_vertex_manager.reset();
OpcodeDecoder_Shutdown();
g_renderer.reset();
GLInterface->ClearCurrent();
}
}

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
#include "Common/Logging/Log.h"
@ -25,10 +27,9 @@ void SWOGLWindow::Init(void *window_handle)
void SWOGLWindow::Shutdown()
{
GLInterface->Shutdown();
delete GLInterface;
GLInterface = nullptr;
GLInterface.reset();
SWOGLWindow::s_instance.release();
s_instance.reset();
}
void SWOGLWindow::Prepare()

View File

@ -2,10 +2,11 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "VideoCommon/PerfQueryBase.h"
#include "VideoCommon/VideoConfig.h"
PerfQueryBase* g_perf_query = nullptr;
std::unique_ptr<PerfQueryBase> g_perf_query;
bool PerfQueryBase::ShouldEmulate()
{

View File

@ -4,6 +4,7 @@
#pragma once
#include <memory>
#include "Common/CommonTypes.h"
enum PerfQueryType
@ -65,4 +66,4 @@ protected:
volatile u32 m_results[PQG_NUM_MEMBERS];
};
extern PerfQueryBase* g_perf_query;
extern std::unique_ptr<PerfQueryBase> g_perf_query;

View File

@ -14,6 +14,7 @@
#include <cinttypes>
#include <cmath>
#include <memory>
#include <string>
#include "Common/Atomic.h"
@ -51,7 +52,7 @@ int frameCount;
int OSDChoice;
static int OSDTime;
Renderer *g_renderer = nullptr;
std::unique_ptr<Renderer> g_renderer;
std::mutex Renderer::s_criticalScreenshot;
std::string Renderer::s_sScreenshotName;

View File

@ -14,6 +14,7 @@
#pragma once
#include <memory>
#include <mutex>
#include <string>
@ -182,5 +183,5 @@ private:
static unsigned int efb_scale_denominatorY;
};
extern Renderer *g_renderer;
extern std::unique_ptr<Renderer> g_renderer;

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
#include <memory>
#include <string>
#include "Common/FileUtil.h"
@ -28,7 +29,7 @@ static const int TEXTURE_KILL_THRESHOLD = 64; // Sonic the Fighters (inside Soni
static const int TEXTURE_POOL_KILL_THRESHOLD = 3;
static const int FRAMECOUNT_INVALID = 0;
TextureCacheBase* g_texture_cache;
std::unique_ptr<TextureCacheBase> g_texture_cache;
alignas(16) u8* TextureCacheBase::temp = nullptr;
size_t TextureCacheBase::temp_size;

View File

@ -6,6 +6,7 @@
#include <functional>
#include <map>
#include <memory>
#include <unordered_map>
#include "Common/CommonTypes.h"
@ -179,4 +180,4 @@ private:
} backup_config;
};
extern TextureCacheBase* g_texture_cache;
extern std::unique_ptr<TextureCacheBase> g_texture_cache;

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/CommonTypes.h"
#include "VideoCommon/BPStructs.h"
@ -22,7 +24,7 @@
#include "VideoCommon/VideoConfig.h"
#include "VideoCommon/XFMemory.h"
VertexManagerBase* g_vertex_manager;
std::unique_ptr<VertexManagerBase> g_vertex_manager;
u8* VertexManagerBase::s_pCurBufferPointer;
u8* VertexManagerBase::s_pBaseBufferPointer;

View File

@ -4,7 +4,9 @@
#pragma once
#include <memory>
#include <vector>
#include "Common/CommonFuncs.h"
#include "Common/CommonTypes.h"
#include "VideoCommon/DataReader.h"
@ -82,4 +84,4 @@ private:
virtual void DestroyDeviceObjects() {}
};
extern VertexManagerBase* g_vertex_manager;
extern std::unique_ptr<VertexManagerBase> g_vertex_manager;

View File

@ -5,6 +5,7 @@
// Stub implementation of the Host_* callbacks for tests. These implementations
// do nothing except return default values when required.
#include <memory>
#include <string>
#include "Common/GL/GLInterfaceBase.h"
@ -26,4 +27,4 @@ bool Host_RendererIsFullscreen() { return false; }
void Host_ConnectWiimote(int, bool) {}
void Host_SetWiiMoteConnectionState(int) {}
void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {}
cInterfaceBase* HostGL_CreateGLInterface() { return nullptr; }
std::unique_ptr<cInterfaceBase> HostGL_CreateGLInterface() { return nullptr; }