mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
Store drawing engine and painter inside Context so that it is disposed before Context.
This commit is contained in:
@@ -35,12 +35,14 @@
|
||||
#include "core/Path.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "core/Util.hpp"
|
||||
#include "drawing/IDrawingEngine.h"
|
||||
#include "FileClassifier.h"
|
||||
#include "HandleParkLoad.h"
|
||||
#include "network/network.h"
|
||||
#include "object/ObjectManager.h"
|
||||
#include "object/ObjectRepository.h"
|
||||
#include "OpenRCT2.h"
|
||||
#include "paint/Painter.h"
|
||||
#include "ParkImporter.h"
|
||||
#include "platform/Crash.h"
|
||||
#include "PlatformEnvironment.h"
|
||||
@@ -74,7 +76,9 @@
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Audio;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Localisation;
|
||||
using namespace OpenRCT2::Paint;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
namespace OpenRCT2
|
||||
@@ -101,6 +105,10 @@ namespace OpenRCT2
|
||||
// Game states
|
||||
std::unique_ptr<TitleScreen> _titleScreen;
|
||||
|
||||
sint32 _drawingEngineType = DRAWING_ENGINE_SOFTWARE;
|
||||
std::unique_ptr<IDrawingEngine> _drawingEngine;
|
||||
std::unique_ptr<Painter> _painter;
|
||||
|
||||
bool _initialised = false;
|
||||
bool _isWindowMinimised = false;
|
||||
uint32 _lastTick = 0;
|
||||
@@ -123,9 +131,9 @@ namespace OpenRCT2
|
||||
const std::shared_ptr<IAudioContext>& audioContext,
|
||||
const std::shared_ptr<IUiContext>& uiContext)
|
||||
: _env(env),
|
||||
_audioContext(audioContext),
|
||||
_uiContext(uiContext),
|
||||
_localisationService(std::make_shared<LocalisationService>(env))
|
||||
_audioContext(audioContext),
|
||||
_uiContext(uiContext),
|
||||
_localisationService(std::make_shared<LocalisationService>(env))
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
@@ -186,6 +194,16 @@ namespace OpenRCT2
|
||||
return _scenarioRepository.get();
|
||||
}
|
||||
|
||||
sint32 GetDrawingEngineType() override
|
||||
{
|
||||
return _drawingEngineType;
|
||||
}
|
||||
|
||||
IDrawingEngine * GetDrawingEngine() override
|
||||
{
|
||||
return _drawingEngine.get();
|
||||
}
|
||||
|
||||
sint32 RunOpenRCT2(int argc, const char * * argv) override
|
||||
{
|
||||
if (Initialise())
|
||||
@@ -429,6 +447,73 @@ namespace OpenRCT2
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitialiseDrawingEngine() final override
|
||||
{
|
||||
assert(_drawingEngine == nullptr);
|
||||
assert(_painter == nullptr);
|
||||
|
||||
_drawingEngineType = gConfigGeneral.drawing_engine;
|
||||
|
||||
auto drawingEngineFactory = _uiContext->GetDrawingEngineFactory();
|
||||
auto drawingEngine = drawingEngineFactory->Create((DRAWING_ENGINE_TYPE)_drawingEngineType, _uiContext);
|
||||
|
||||
if (drawingEngine == nullptr)
|
||||
{
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
{
|
||||
_drawingEngineType = DRAWING_ENGINE_NONE;
|
||||
log_fatal("Unable to create a drawing engine.");
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Unable to create drawing engine. Falling back to software.");
|
||||
|
||||
// Fallback to software
|
||||
gConfigGeneral.drawing_engine = DRAWING_ENGINE_SOFTWARE;
|
||||
config_save_default();
|
||||
drawing_engine_init();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter = std::make_unique<Painter>(_uiContext);
|
||||
try
|
||||
{
|
||||
drawingEngine->Initialise();
|
||||
drawingEngine->SetVSync(gConfigGeneral.use_vsync);
|
||||
_drawingEngine = std::unique_ptr<IDrawingEngine>(std::move(drawingEngine));
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
_painter = nullptr;
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
{
|
||||
_drawingEngineType = DRAWING_ENGINE_NONE;
|
||||
log_error(ex.what());
|
||||
log_fatal("Unable to initialise a drawing engine.");
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error(ex.what());
|
||||
log_error("Unable to initialise drawing engine. Falling back to software.");
|
||||
|
||||
// Fallback to software
|
||||
gConfigGeneral.drawing_engine = DRAWING_ENGINE_SOFTWARE;
|
||||
config_save_default();
|
||||
drawing_engine_init();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisposeDrawingEngine() final override
|
||||
{
|
||||
_drawingEngine = nullptr;
|
||||
_painter = nullptr;
|
||||
}
|
||||
|
||||
bool LoadParkFromFile(const std::string &path, bool loadTitleScreenOnFail) final override
|
||||
{
|
||||
try
|
||||
@@ -767,7 +852,9 @@ namespace OpenRCT2
|
||||
Update();
|
||||
if (!_isWindowMinimised && !gOpenRCT2Headless)
|
||||
{
|
||||
drawing_engine_draw();
|
||||
_drawingEngine->BeginDraw();
|
||||
_painter->Paint(*_drawingEngine);
|
||||
_drawingEngine->EndDraw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -810,7 +897,9 @@ namespace OpenRCT2
|
||||
const float alpha = (float)_accumulator / GAME_UPDATE_TIME_MS;
|
||||
sprite_position_tween_all(alpha);
|
||||
|
||||
drawing_engine_draw();
|
||||
_drawingEngine->BeginDraw();
|
||||
_painter->Paint(*_drawingEngine);
|
||||
_drawingEngine->EndDraw();
|
||||
|
||||
sprite_position_tween_restore();
|
||||
}
|
||||
|
||||
@@ -77,6 +77,11 @@ namespace OpenRCT2
|
||||
interface IAudioContext;
|
||||
}
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
interface IDrawingEngine;
|
||||
}
|
||||
|
||||
namespace Localisation
|
||||
{
|
||||
class LocalisationService;
|
||||
@@ -102,10 +107,14 @@ namespace OpenRCT2
|
||||
virtual std::shared_ptr<IObjectRepository> GetObjectRepository() abstract;
|
||||
virtual ITrackDesignRepository * GetTrackDesignRepository() abstract;
|
||||
virtual IScenarioRepository * GetScenarioRepository() abstract;
|
||||
virtual sint32 GetDrawingEngineType() abstract;
|
||||
virtual Drawing::IDrawingEngine * GetDrawingEngine() abstract;
|
||||
|
||||
virtual sint32 RunOpenRCT2(int argc, const char * * argv) abstract;
|
||||
|
||||
virtual bool Initialise() abstract;
|
||||
virtual void InitialiseDrawingEngine() abstract;
|
||||
virtual void DisposeDrawingEngine() abstract;
|
||||
virtual bool LoadParkFromFile(const std::string &path, bool loadTitleScreenOnFail = false) abstract;
|
||||
virtual bool LoadParkFromStream(IStream * stream, const std::string &path, bool loadTitleScreenFirstOnFail = false) abstract;
|
||||
virtual void WriteLine(const std::string &s) abstract;
|
||||
|
||||
@@ -31,11 +31,6 @@ using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Paint;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
static sint32 _drawingEngineType = DRAWING_ENGINE_SOFTWARE;
|
||||
static std::shared_ptr<IDrawingEngine> _drawingEngine;
|
||||
// TODO move this to Context
|
||||
static Painter * _painter = nullptr;
|
||||
|
||||
rct_string_id DrawingEngineStringIds[] =
|
||||
{
|
||||
STR_DRAWING_ENGINE_SOFTWARE,
|
||||
@@ -45,7 +40,19 @@ rct_string_id DrawingEngineStringIds[] =
|
||||
|
||||
sint32 drawing_engine_get_type()
|
||||
{
|
||||
return _drawingEngineType;
|
||||
auto context = GetContext();
|
||||
return context->GetDrawingEngineType();
|
||||
}
|
||||
|
||||
static IDrawingEngine * GetDrawingEngine()
|
||||
{
|
||||
IDrawingEngine * result = nullptr;
|
||||
auto context = GetContext();
|
||||
if (context != nullptr)
|
||||
{
|
||||
result = context->GetDrawingEngine();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool drawing_engine_requires_new_window(sint32 srcEngine, sint32 dstEngine)
|
||||
@@ -64,147 +71,104 @@ bool drawing_engine_requires_new_window(sint32 srcEngine, sint32 dstEngine)
|
||||
|
||||
void drawing_engine_init()
|
||||
{
|
||||
assert(_drawingEngine == nullptr);
|
||||
assert(_painter == nullptr);
|
||||
|
||||
_drawingEngineType = gConfigGeneral.drawing_engine;
|
||||
|
||||
auto context = GetContext();
|
||||
auto uiContext = context->GetUiContext();
|
||||
auto drawingEngineFactory = uiContext->GetDrawingEngineFactory();
|
||||
auto drawingEngine = drawingEngineFactory->Create((DRAWING_ENGINE_TYPE)_drawingEngineType, uiContext);
|
||||
|
||||
if (drawingEngine == nullptr)
|
||||
if (context != nullptr)
|
||||
{
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
{
|
||||
_drawingEngineType = DRAWING_ENGINE_NONE;
|
||||
log_fatal("Unable to create a drawing engine.");
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Unable to create drawing engine. Falling back to software.");
|
||||
|
||||
// Fallback to software
|
||||
gConfigGeneral.drawing_engine = DRAWING_ENGINE_SOFTWARE;
|
||||
config_save_default();
|
||||
drawing_engine_init();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter = new Painter(uiContext);
|
||||
try
|
||||
{
|
||||
drawingEngine->Initialise();
|
||||
drawingEngine->SetVSync(gConfigGeneral.use_vsync);
|
||||
_drawingEngine = std::shared_ptr<IDrawingEngine>(std::move(drawingEngine));
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
delete _painter;
|
||||
_painter = nullptr;
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
{
|
||||
_drawingEngineType = DRAWING_ENGINE_NONE;
|
||||
log_error(ex.what());
|
||||
log_fatal("Unable to initialise a drawing engine.");
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error(ex.what());
|
||||
log_error("Unable to initialise drawing engine. Falling back to software.");
|
||||
|
||||
// Fallback to software
|
||||
gConfigGeneral.drawing_engine = DRAWING_ENGINE_SOFTWARE;
|
||||
config_save_default();
|
||||
drawing_engine_init();
|
||||
}
|
||||
}
|
||||
context->InitialiseDrawingEngine();
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_resize()
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto context = GetContext();
|
||||
if (context != nullptr)
|
||||
{
|
||||
auto uiContext = GetContext()->GetUiContext();
|
||||
_drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
||||
auto drawingEngine = context->GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
auto uiContext = context->GetUiContext();
|
||||
drawingEngine->Resize(uiContext->GetWidth(), uiContext->GetHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_set_palette(const rct_palette_entry * colours)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto context = GetContext();
|
||||
if (context != nullptr)
|
||||
{
|
||||
_drawingEngine->SetPalette(colours);
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_draw()
|
||||
{
|
||||
if (_drawingEngine != nullptr && _painter != nullptr)
|
||||
{
|
||||
_drawingEngine->BeginDraw();
|
||||
_painter->Paint(*_drawingEngine);
|
||||
_drawingEngine->EndDraw();
|
||||
auto drawingEngine = context->GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
drawingEngine->SetPalette(colours);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_copy_rect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto context = GetContext();
|
||||
if (context != nullptr)
|
||||
{
|
||||
_drawingEngine->CopyRect(x, y, width, height, dx, dy);
|
||||
auto drawingEngine = context->GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
drawingEngine->CopyRect(x, y, width, height, dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_dispose()
|
||||
{
|
||||
delete _painter;
|
||||
_drawingEngine = nullptr;
|
||||
_painter = nullptr;
|
||||
auto context = GetContext();
|
||||
if (context != nullptr)
|
||||
{
|
||||
context->DisposeDrawingEngine();
|
||||
}
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * drawing_engine_get_dpi()
|
||||
{
|
||||
assert(_drawingEngine != nullptr);
|
||||
return _drawingEngine->GetDrawingPixelInfo();
|
||||
auto context = GetContext();
|
||||
auto drawingEngine = context->GetDrawingEngine();
|
||||
return drawingEngine->GetDrawingPixelInfo();
|
||||
}
|
||||
|
||||
bool drawing_engine_has_dirty_optimisations()
|
||||
{
|
||||
bool result = false;
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
result = (_drawingEngine->GetFlags() & DEF_DIRTY_OPTIMISATIONS);
|
||||
result = (drawingEngine->GetFlags() & DEF_DIRTY_OPTIMISATIONS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void drawing_engine_invalidate_image(uint32 image)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
_drawingEngine->InvalidateImage(image);
|
||||
drawingEngine->InvalidateImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
void drawing_engine_set_vsync(bool vsync)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
_drawingEngine->SetVSync(vsync);
|
||||
drawingEngine->SetVSync(vsync);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_set_dirty_blocks(sint16 left, sint16 top, sint16 right, sint16 bottom)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
_drawingEngine->Invalidate(left, top, right, bottom);
|
||||
drawingEngine->Invalidate(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,81 +178,90 @@ void gfx_draw_all_dirty_blocks()
|
||||
|
||||
void gfx_clear(rct_drawpixelinfo * dpi, uint8 paletteIndex)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->Clear(paletteIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_fill_rect(rct_drawpixelinfo * dpi, sint32 left, sint32 top, sint32 right, sint32 bottom, sint32 colour)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->FillRect(colour, left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_filter_rect(rct_drawpixelinfo * dpi, sint32 left, sint32 top, sint32 right, sint32 bottom, FILTER_PALETTE_ID palette)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->FilterRect(palette, left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_draw_line(rct_drawpixelinfo *dpi, sint32 x1, sint32 y1, sint32 x2, sint32 y2, sint32 colour)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawLine(colour, x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo * dpi, sint32 image, sint32 x, sint32 y, uint32 tertiary_colour)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawSprite(image, x, y, tertiary_colour);
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo * dpi, sint32 image, sint32 x, sint32 y, uint8 * palette)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawGlyph(image, x, y, palette);
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo * dpi, sint32 x, sint32 y, sint32 maskImage, sint32 colourImage)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawSpriteRawMasked(x, y, maskImage, colourImage);
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, sint32 image, sint32 x, sint32 y, uint8 colour)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi);
|
||||
dc->DrawSpriteSolid(image, x, y, colour);
|
||||
}
|
||||
}
|
||||
|
||||
sint32 screenshot_dump()
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
auto drawingEngine = GetDrawingEngine();
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
return _drawingEngine->Screenshot();
|
||||
return drawingEngine->Screenshot();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ bool drawing_engine_requires_new_window(sint32 srcEngine, sint32 dstEngine);
|
||||
void drawing_engine_init();
|
||||
void drawing_engine_resize();
|
||||
void drawing_engine_set_palette(const rct_palette_entry * colours);
|
||||
void drawing_engine_draw();
|
||||
void drawing_engine_copy_rect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy);
|
||||
void drawing_engine_dispose();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user