Window resizing stability fixes

This commit is contained in:
Jack Andersen 2015-11-16 20:41:32 -10:00
parent 49da287791
commit 4d133edd2c
7 changed files with 83 additions and 21 deletions

View File

@ -53,6 +53,9 @@ public:
virtual IGraphicsCommandQueue* getCommandQueue()=0;
virtual IGraphicsDataFactory* getDataFactory()=0;
/* Creates a new context on current thread!! Call from main client thread */
virtual IGraphicsDataFactory* getMainContextDataFactory()=0;
/* Creates a new context on current thread!! Call from client loading thread */
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;

View File

@ -196,6 +196,9 @@ public:
virtual IGraphicsCommandQueue* getCommandQueue()=0;
virtual IGraphicsDataFactory* getDataFactory()=0;
/* Creates a new context on current thread!! Call from main client thread */
virtual IGraphicsDataFactory* getMainContextDataFactory()=0;
/* Creates a new context on current thread!! Call from client loading thread */
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;

View File

@ -25,6 +25,7 @@ struct IGraphicsCommandQueue
virtual void setViewport(const SWindowRect& rect)=0;
virtual void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)=0;
virtual void flushBufferUpdates()=0;
virtual void setClearColor(const float rgba[4])=0;
virtual void clearTarget(bool render=true, bool depth=true)=0;

View File

@ -552,7 +552,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
OpSetShaderDataBinding,
OpSetRenderTarget,
OpSetViewport,
OpResizeRenderTexture,
OpSetClearColor,
OpClearTarget,
OpSetDrawPrimitive,
@ -577,12 +576,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
size_t count;
size_t instCount;
};
struct
{
ITextureR* tex;
size_t width;
size_t height;
} resize;
};
Command(Op op) : m_op(op) {}
};
@ -599,7 +592,15 @@ struct GLCommandQueue : IGraphicsCommandQueue
std::unique_lock<std::mutex> m_initlk;
std::thread m_thr;
struct RenderTextureResize
{
GLTextureR* tex;
size_t width;
size_t height;
};
/* These members are locked for multithreaded access */
std::vector<RenderTextureResize> m_pendingResizes;
std::vector<GLVertexFormat*> m_pendingFmtAdds;
std::vector<GLuint> m_pendingFmtDels;
std::vector<GLTextureR*> m_pendingFboAdds;
@ -673,26 +674,41 @@ struct GLCommandQueue : IGraphicsCommandQueue
break;
self->m_drawBuf = self->m_completeBuf;
if (self->m_pendingResizes.size())
{
for (const RenderTextureResize& resize : self->m_pendingResizes)
resize.tex->resize(resize.width, resize.height);
self->m_pendingResizes.clear();
}
if (self->m_pendingFmtAdds.size())
{
for (GLVertexFormat* fmt : self->m_pendingFmtAdds)
ConfigureVertexFormat(fmt);
self->m_pendingFmtAdds.clear();
}
if (self->m_pendingFmtDels.size())
{
for (GLuint fmt : self->m_pendingFmtDels)
glDeleteVertexArrays(1, &fmt);
self->m_pendingFmtDels.clear();
}
if (self->m_pendingFboAdds.size())
{
for (GLTextureR* tex : self->m_pendingFboAdds)
ConfigureFBO(tex);
self->m_pendingFboAdds.clear();
}
if (self->m_pendingFboDels.size())
{
for (GLuint fbo : self->m_pendingFboDels)
glDeleteFramebuffers(1, &fbo);
self->m_pendingFboDels.clear();
}
}
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
GLenum prim = GL_TRIANGLES;
for (const Command& cmd : cmds)
@ -715,11 +731,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
glViewport(cmd.rect.location[0], cmd.rect.location[1],
cmd.rect.size[0], cmd.rect.size[1]);
break;
case Command::OpResizeRenderTexture:
{
GLTextureR* tex = static_cast<GLTextureR*>(cmd.resize.tex);
tex->resize(cmd.resize.width, cmd.resize.height);
}
case Command::OpSetClearColor:
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
break;
@ -800,11 +811,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpResizeRenderTexture);
cmds.back().resize.tex = tex;
cmds.back().resize.width = width;
cmds.back().resize.height = height;
std::unique_lock<std::mutex> lk(m_mt);
GLTextureR* texgl = static_cast<GLTextureR*>(tex);
m_pendingResizes.push_back({texgl, width, height});
}
void flushBufferUpdates()
{
glFlush();
}
void setClearColor(const float rgba[4])
@ -1022,6 +1036,7 @@ GLDataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
{
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
GLTextureR* retval = new GLTextureR(q, width, height, samples);
q->resizeRenderTexture(retval, width, height);
static_cast<GLData*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}

View File

@ -17,6 +17,8 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#include <sys/param.h>
#include <thread>
#include <mutex>
#include <condition_variable>
namespace boo
{
@ -239,11 +241,18 @@ public:
/* Spawn client thread */
int clientReturn = INT_MIN;
std::mutex initmt;
std::condition_variable initcv;
std::unique_lock<std::mutex> outerLk(initmt);
std::thread clientThread([&]()
{
std::unique_lock<std::mutex> innerLk(initmt);
innerLk.unlock();
initcv.notify_one();
clientReturn = m_callback.appMain(this);
pthread_kill(mainThread, SIGTERM);
});
initcv.wait(outerLk);
/* Begin application event loop */
while (clientReturn == INT_MIN)

View File

@ -72,6 +72,11 @@ public:
return nullptr;
}
IGraphicsDataFactory* getMainContextDataFactory()
{
return nullptr;
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return nullptr;
@ -196,6 +201,11 @@ struct WindowWayland : IWindow
return m_gfxCtx.getDataFactory();
}
IGraphicsDataFactory* getMainContextDataFactory()
{
return m_gfxCtx.getMainContextDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_gfxCtx.getLoadContextDataFactory();

View File

@ -185,6 +185,7 @@ struct GraphicsContextGLX : IGraphicsContext
IGraphicsCommandQueue* m_commandQueue = nullptr;
IGraphicsDataFactory* m_dataFactory = nullptr;
GLXContext m_mainCtx = 0;
GLXContext m_loadCtx = 0;
std::thread m_vsyncThread;
@ -396,6 +397,21 @@ public:
return m_dataFactory;
}
IGraphicsDataFactory* getMainContextDataFactory()
{
XLockDisplay(m_xDisp);
if (!m_mainCtx)
{
m_mainCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribs);
if (!m_mainCtx)
Log.report(LogVisor::FatalError, "unable to make main GLX context");
}
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_mainCtx))
Log.report(LogVisor::FatalError, "unable to make main GLX context current");
XUnlockDisplay(m_xDisp);
return getDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
XLockDisplay(m_xDisp);
@ -1180,6 +1196,11 @@ public:
return m_gfxCtx.getDataFactory();
}
IGraphicsDataFactory* getMainContextDataFactory()
{
return m_gfxCtx.getMainContextDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_gfxCtx.getLoadContextDataFactory();