From 100d6e5fffd7700d12c79566847d74ef6f7cf2cc Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 May 2015 02:38:59 +0200 Subject: [PATCH] Render MyGUI in background thread, i.e. refactor to get rid of DYNAMIC DataVariance --- apps/openmw/mwrender/renderingmanager.cpp | 2 - .../myguiplatform/myguirendermanager.cpp | 37 +++++++++++++------ .../myguiplatform/myguirendermanager.hpp | 3 -- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 4d06d901a..853ba3834 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -144,8 +144,6 @@ namespace MWRender zNear = 5.f; zFar = mViewDistance; mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); - - mViewer.getCamera()->setCullMask(mViewer.getCamera()->getCullMask() & (~Mask_GUI)); } RenderingManager::~RenderingManager() diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index e1ebf781c..d1bf73904 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -7,10 +7,7 @@ #include #include -#include #include -#include -#include #include #include @@ -141,7 +138,9 @@ class Drawable : public osg::Drawable { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - for (std::vector::const_iterator it = mBatchVector.begin(); it != mBatchVector.end(); ++it) + mReadFrom = (mReadFrom+1)%2; + const std::vector& vec = mBatchVector[mReadFrom]; + for (std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) { const Batch& batch = *it; osg::VertexBufferObject *vbo = batch.mVertexBuffer; @@ -174,7 +173,10 @@ class Drawable : public osg::Drawable { } public: - Drawable(osgMyGUI::RenderManager *parent = nullptr) : mParent(parent) + Drawable(osgMyGUI::RenderManager *parent = nullptr) + : mParent(parent) + , mWriteTo(0) + , mReadFrom(0) { setSupportsDisplayList(false); @@ -182,7 +184,7 @@ public: collectDrawCalls->setRenderManager(mParent); setCullCallback(collectDrawCalls); - osg::ref_ptr frameUpdate = new Drawable::FrameUpdate; + osg::ref_ptr frameUpdate = new FrameUpdate; frameUpdate->setRenderManager(mParent); setUpdateCallback(frameUpdate); } @@ -199,30 +201,35 @@ public: osg::ref_ptr mTexture; osg::ref_ptr mVertexBuffer; + // need to hold on to this too as the mVertexBuffer does not hold a ref to its own array + osg::ref_ptr mArray; + size_t mVertexCount; }; void addBatch(const Batch& batch) { - mBatchVector.push_back(batch); + mBatchVector[mWriteTo].push_back(batch); } void clear() { - mBatchVector.clear(); + mWriteTo = (mWriteTo+1)%2; + mBatchVector[mWriteTo].clear(); } META_Object(osgMyGUI, Drawable) private: - std::vector mBatchVector; + std::vector mBatchVector[2]; + int mWriteTo; + mutable int mReadFrom; }; class OSGVertexBuffer : public MyGUI::IVertexBuffer { osg::ref_ptr mBuffer; osg::ref_ptr mVertexArray; - std::vector mLockedData; size_t mNeedVertexCount; @@ -241,6 +248,7 @@ public: void create(); osg::VertexBufferObject *getBuffer() const { return mBuffer.get(); } + osg::UByteArray *getArray() const { return mVertexArray.get(); } }; OSGVertexBuffer::OSGVertexBuffer() @@ -270,6 +278,12 @@ size_t OSGVertexBuffer::getVertexCount() MyGUI::Vertex *OSGVertexBuffer::lock() { + // Force recreating the buffer, to make sure we are not modifying a buffer currently + // queued for rendering in the last frame's draw thread. + // a more efficient solution might be double buffering + destroy(); + create(); + MYGUI_PLATFORM_ASSERT(mBuffer.valid(), "Vertex buffer is not created"); mVertexArray->resize(mNeedVertexCount * sizeof(MyGUI::Vertex)); @@ -297,6 +311,7 @@ void OSGVertexBuffer::create() mBuffer = new osg::VertexBufferObject; mBuffer->setDataVariance(osg::Object::DYNAMIC); mBuffer->setUsage(GL_DYNAMIC_DRAW); + // NB mBuffer does not own the array mBuffer->setArray(0, mVertexArray.get()); } @@ -338,7 +353,6 @@ void RenderManager::initialise() mUpdate = false; mDrawable = new Drawable(this); - mDrawable->setDataVariance(osg::Object::DYNAMIC); osg::ref_ptr geode = new osg::Geode; geode->addDrawable(mDrawable.get()); @@ -394,6 +408,7 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text Drawable::Batch batch; batch.mVertexCount = count; batch.mVertexBuffer = static_cast(buffer)->getBuffer(); + batch.mArray = static_cast(buffer)->getArray(); if (texture) batch.mTexture = static_cast(texture)->getTexture(); diff --git a/components/myguiplatform/myguirendermanager.hpp b/components/myguiplatform/myguirendermanager.hpp index 342050d90..afb07eaa6 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -46,9 +46,6 @@ class RenderManager : public MyGUI::RenderManager, public MyGUI::IRenderTarget osg::ref_ptr mGuiRoot; - // Only valid during drawFrame()! - osg::RenderInfo *mRenderInfo; - void destroyAllResources(); public: