From 04960035c1a58989d0990555dd9beecc0c32ed5a Mon Sep 17 00:00:00 2001 From: krzys-h Date: Mon, 3 Aug 2015 21:40:30 +0200 Subject: [PATCH] Save screenshot image in a separate background thread (#546) --- src/graphics/engine/engine.cpp | 35 ++++++++++++++++++++++++++-------- src/graphics/engine/engine.h | 2 ++ src/object/robotmain.cpp | 17 ++++++----------- src/object/robotmain.h | 2 +- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index af3c2fb8..6ecb135b 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -52,6 +52,7 @@ #include "ui/interface.h" #include +#include template<> Gfx::CEngine* CSingleton::m_instance = nullptr; @@ -483,24 +484,42 @@ void CEngine::FrameUpdate() } } +struct WriteScreenShotData +{ + std::unique_ptr img; + std::string fileName; +}; + bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height) { - void *pixels = m_device->GetFrameBufferPixels(); - CImage img({width, height}); + WriteScreenShotData* data = new WriteScreenShotData(); + data->img = MakeUnique(Math::IntPoint(width, height)); - img.SetDataPixels(pixels); - img.FlipVertically(); + data->img->SetDataPixels(m_device->GetFrameBufferPixels()); + data->img->FlipVertically(); - if ( img.SavePNG(fileName.c_str()) ) + data->fileName = fileName; + SDL_CreateThread(CEngine::WriteScreenShotThread, data); + return true; +} + +int CEngine::WriteScreenShotThread(void* data_ptr) +{ + WriteScreenShotData* data = static_cast(data_ptr); + + if ( data->img->SavePNG(data->fileName.c_str()) ) { GetLogger()->Debug("Save screenshot saved successfully\n"); - return true; } else { - GetLogger()->Error("%s!\n", img.GetError().c_str()); - return false; + GetLogger()->Error("%s!\n", data->img->GetError().c_str()); } + + delete data; + + CRobotMain::GetInstancePointer()->IOWriteSceneFinished(); + return 0; } bool CEngine::GetPause() diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 7fd409e7..aa560cd4 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1348,6 +1348,8 @@ protected: int GetEngineState(const ModelTriangle& triangle); + static int WriteScreenShotThread(void* data_ptr); + protected: CApplication* m_app; CSoundInterface* m_sound; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 425f6ece..18954e0d 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -179,7 +179,6 @@ CRobotMain::CRobotMain(CController* controller) m_satcomRepeat = true; m_editorTrack = ""; m_editorRepeat = true; - m_delayWriteMessage = 0; m_selectObject = 0; m_infoUsed = 0; @@ -2754,15 +2753,6 @@ bool CRobotMain::EventFrame(const Event &event) } } - if (m_delayWriteMessage > 0) - { - m_delayWriteMessage --; - if (m_delayWriteMessage == 0) - { - m_displayText->DisplayError(INFO_WRITEOK, Math::Vector(0.0f,0.0f,0.0f)); - } - } - if (GetMissionType() == MISSION_CODE_BATTLE) { if (!m_codeBattleInit) @@ -5128,10 +5118,15 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * CBotClass::SaveStaticState(file); fClose(file); - m_delayWriteMessage = 4; // displays message in 3 frames return true; } +//! Notifies the user that scene write is finished +void CRobotMain::IOWriteSceneFinished() +{ + m_displayText->DisplayError(INFO_WRITEOK, Math::Vector(0.0f,0.0f,0.0f)); +} + //! Resumes the game CObject* CRobotMain::IOReadObject(CLevelParserLine *line, const char* filename, int objRank) { diff --git a/src/object/robotmain.h b/src/object/robotmain.h index 8134a8f7..9d8a0962 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -299,6 +299,7 @@ public: bool IsBusy(); bool IOWriteScene(const char *filename, const char *filecbot, char *info); + void IOWriteSceneFinished(); CObject* IOReadScene(const char *filename, const char *filecbot); void IOWriteObject(CLevelParserLine *line, CObject* obj); CObject* IOReadObject(CLevelParserLine *line, const char* filename, int objRank); @@ -479,7 +480,6 @@ protected: bool m_satcomRepeat; std::string m_editorTrack; bool m_editorRepeat; - int m_delayWriteMessage; int m_movieInfoIndex; CObject* m_controller;