Write screenshots to file asynchronously

dont-compose-content
elsid 4 years ago
parent 33aa4d0822
commit f8e02000ec
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -17,6 +17,7 @@
Bug #6129: Player avatar not displayed correctly for large window sizes when GUI scaling active
Bug #6131: Item selection in the avatar window not working correctly for large window sizes
Bug #6133: Cannot reliably sneak or steal in the sight of the NPCs siding with player
Bug #6143: Capturing a screenshot makes engine to be a temporary unresponsive
Feature #2780: A way to see current OpenMW version in the console
Feature #5489: MCP: Telekinesis fix for activators
Feature #6017: Separate persistent and temporary cell references when saving

@ -670,6 +670,18 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
throw std::runtime_error("Invalid setting: 'preload num threads' must be >0");
mWorkQueue = new SceneUtil::WorkQueue(numThreads);
mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation(
mWorkQueue,
new SceneUtil::WriteScreenshotToFileOperation(
mCfgMgr.getScreenshotPath().string(),
Settings::Manager::getString("screenshot format", "General")
)
);
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation);
mViewer->addEventHandler(mScreenCaptureHandler);
// Create input and UI first to set up a bootstrapping environment for
// showing a loading screen and keeping the window responsive while doing so
@ -814,14 +826,6 @@ void OMW::Engine::go()
mViewer->setUseConfigureAffinity(false);
#endif
mScreenCaptureOperation = new SceneUtil::WriteScreenshotToFileOperation(
mCfgMgr.getScreenshotPath().string(),
Settings::Manager::getString("screenshot format", "General"));
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation);
mViewer->addEventHandler(mScreenCaptureHandler);
mEnvironment.setFrameRateLimit(Settings::Manager::getFloat("framerate limit", "Video"));
prepareEngine (settings);

@ -3,6 +3,7 @@
#include <components/debug/debuglog.hpp>
#include <components/sceneutil/workqueue.hpp>
#include <osg/ref_ptr>
#include <osg/Image>
#include <osgDB/ReaderWriter>
#include <osgDB/Registry>
@ -10,9 +11,43 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/operations.hpp>
#include <string>
#include <sstream>
#include <cassert>
#include <iomanip>
#include <sstream>
#include <string>
namespace
{
class ScreenCaptureWorkItem : public SceneUtil::WorkItem
{
public:
ScreenCaptureWorkItem(const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation>& impl,
const osg::Image& image, unsigned int contextId)
: mImpl(impl),
mImage(new osg::Image(image)),
mContextId(contextId)
{
assert(mImpl != nullptr);
}
void doWork() override
{
try
{
(*mImpl)(*mImage, mContextId);
}
catch (const std::exception& e)
{
Log(Debug::Error) << "ScreenCaptureWorkItem exception: " << e.what();
}
}
private:
const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> mImpl;
const osg::ref_ptr<const osg::Image> mImage;
const unsigned int mContextId;
};
}
namespace SceneUtil
{
@ -70,4 +105,18 @@ namespace SceneUtil
<< "\", format=\"" << mScreenshotFormat << "\": " << e.what();
}
}
AsyncScreenCaptureOperation::AsyncScreenCaptureOperation(osg::ref_ptr<WorkQueue> queue,
osg::ref_ptr<CaptureOperation> impl)
: mQueue(std::move(queue)),
mImpl(std::move(impl))
{
assert(mQueue != nullptr);
assert(mImpl != nullptr);
}
void AsyncScreenCaptureOperation::operator()(const osg::Image& image, const unsigned int context_id)
{
mQueue->addWorkItem(new ScreenCaptureWorkItem(mImpl, image, context_id));
}
}

@ -1,6 +1,7 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H
#define OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H
#include <osg/ref_ptr>
#include <osgViewer/ViewerEventHandlers>
#include <string>
@ -12,6 +13,8 @@ namespace osg
namespace SceneUtil
{
class WorkQueue;
void writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat,
const osg::Image& image);
@ -20,12 +23,25 @@ namespace SceneUtil
public:
WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat);
void operator()(const osg::Image& image, const unsigned int /*context_id*/) override;
void operator()(const osg::Image& image, const unsigned int context_id) override;
private:
const std::string mScreenshotPath;
const std::string mScreenshotFormat;
};
class AsyncScreenCaptureOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation
{
public:
AsyncScreenCaptureOperation(osg::ref_ptr<SceneUtil::WorkQueue> queue,
osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> impl);
void operator()(const osg::Image& image, const unsigned int context_id) override;
private:
const osg::ref_ptr<SceneUtil::WorkQueue> mQueue;
const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> mImpl;
};
}
#endif

Loading…
Cancel
Save