mirror of https://github.com/AxioDL/boo.git
Window resizing stability fixes
This commit is contained in:
parent
49da287791
commit
4d133edd2c
|
@ -53,6 +53,9 @@ public:
|
||||||
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
||||||
virtual IGraphicsDataFactory* getDataFactory()=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 */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
|
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,9 @@ public:
|
||||||
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
||||||
virtual IGraphicsDataFactory* getDataFactory()=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 */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
|
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct IGraphicsCommandQueue
|
||||||
virtual void setViewport(const SWindowRect& rect)=0;
|
virtual void setViewport(const SWindowRect& rect)=0;
|
||||||
|
|
||||||
virtual void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)=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 setClearColor(const float rgba[4])=0;
|
||||||
virtual void clearTarget(bool render=true, bool depth=true)=0;
|
virtual void clearTarget(bool render=true, bool depth=true)=0;
|
||||||
|
|
|
@ -552,7 +552,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
OpSetShaderDataBinding,
|
OpSetShaderDataBinding,
|
||||||
OpSetRenderTarget,
|
OpSetRenderTarget,
|
||||||
OpSetViewport,
|
OpSetViewport,
|
||||||
OpResizeRenderTexture,
|
|
||||||
OpSetClearColor,
|
OpSetClearColor,
|
||||||
OpClearTarget,
|
OpClearTarget,
|
||||||
OpSetDrawPrimitive,
|
OpSetDrawPrimitive,
|
||||||
|
@ -577,12 +576,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
size_t count;
|
size_t count;
|
||||||
size_t instCount;
|
size_t instCount;
|
||||||
};
|
};
|
||||||
struct
|
|
||||||
{
|
|
||||||
ITextureR* tex;
|
|
||||||
size_t width;
|
|
||||||
size_t height;
|
|
||||||
} resize;
|
|
||||||
};
|
};
|
||||||
Command(Op op) : m_op(op) {}
|
Command(Op op) : m_op(op) {}
|
||||||
};
|
};
|
||||||
|
@ -599,7 +592,15 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
std::unique_lock<std::mutex> m_initlk;
|
std::unique_lock<std::mutex> m_initlk;
|
||||||
std::thread m_thr;
|
std::thread m_thr;
|
||||||
|
|
||||||
|
struct RenderTextureResize
|
||||||
|
{
|
||||||
|
GLTextureR* tex;
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
|
};
|
||||||
|
|
||||||
/* These members are locked for multithreaded access */
|
/* These members are locked for multithreaded access */
|
||||||
|
std::vector<RenderTextureResize> m_pendingResizes;
|
||||||
std::vector<GLVertexFormat*> m_pendingFmtAdds;
|
std::vector<GLVertexFormat*> m_pendingFmtAdds;
|
||||||
std::vector<GLuint> m_pendingFmtDels;
|
std::vector<GLuint> m_pendingFmtDels;
|
||||||
std::vector<GLTextureR*> m_pendingFboAdds;
|
std::vector<GLTextureR*> m_pendingFboAdds;
|
||||||
|
@ -673,25 +674,40 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
break;
|
break;
|
||||||
self->m_drawBuf = self->m_completeBuf;
|
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())
|
if (self->m_pendingFmtAdds.size())
|
||||||
|
{
|
||||||
for (GLVertexFormat* fmt : self->m_pendingFmtAdds)
|
for (GLVertexFormat* fmt : self->m_pendingFmtAdds)
|
||||||
ConfigureVertexFormat(fmt);
|
ConfigureVertexFormat(fmt);
|
||||||
self->m_pendingFmtAdds.clear();
|
self->m_pendingFmtAdds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (self->m_pendingFmtDels.size())
|
if (self->m_pendingFmtDels.size())
|
||||||
|
{
|
||||||
for (GLuint fmt : self->m_pendingFmtDels)
|
for (GLuint fmt : self->m_pendingFmtDels)
|
||||||
glDeleteVertexArrays(1, &fmt);
|
glDeleteVertexArrays(1, &fmt);
|
||||||
self->m_pendingFmtDels.clear();
|
self->m_pendingFmtDels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (self->m_pendingFboAdds.size())
|
if (self->m_pendingFboAdds.size())
|
||||||
|
{
|
||||||
for (GLTextureR* tex : self->m_pendingFboAdds)
|
for (GLTextureR* tex : self->m_pendingFboAdds)
|
||||||
ConfigureFBO(tex);
|
ConfigureFBO(tex);
|
||||||
self->m_pendingFboAdds.clear();
|
self->m_pendingFboAdds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (self->m_pendingFboDels.size())
|
if (self->m_pendingFboDels.size())
|
||||||
|
{
|
||||||
for (GLuint fbo : self->m_pendingFboDels)
|
for (GLuint fbo : self->m_pendingFboDels)
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
self->m_pendingFboDels.clear();
|
self->m_pendingFboDels.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
||||||
GLenum prim = GL_TRIANGLES;
|
GLenum prim = GL_TRIANGLES;
|
||||||
|
@ -715,11 +731,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
glViewport(cmd.rect.location[0], cmd.rect.location[1],
|
glViewport(cmd.rect.location[0], cmd.rect.location[1],
|
||||||
cmd.rect.size[0], cmd.rect.size[1]);
|
cmd.rect.size[0], cmd.rect.size[1]);
|
||||||
break;
|
break;
|
||||||
case Command::OpResizeRenderTexture:
|
|
||||||
{
|
|
||||||
GLTextureR* tex = static_cast<GLTextureR*>(cmd.resize.tex);
|
|
||||||
tex->resize(cmd.resize.width, cmd.resize.height);
|
|
||||||
}
|
|
||||||
case Command::OpSetClearColor:
|
case Command::OpSetClearColor:
|
||||||
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
|
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
|
||||||
break;
|
break;
|
||||||
|
@ -800,11 +811,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
cmds.emplace_back(Command::OpResizeRenderTexture);
|
GLTextureR* texgl = static_cast<GLTextureR*>(tex);
|
||||||
cmds.back().resize.tex = tex;
|
m_pendingResizes.push_back({texgl, width, height});
|
||||||
cmds.back().resize.width = width;
|
}
|
||||||
cmds.back().resize.height = height;
|
|
||||||
|
void flushBufferUpdates()
|
||||||
|
{
|
||||||
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClearColor(const float rgba[4])
|
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());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
||||||
GLTextureR* retval = new GLTextureR(q, width, height, samples);
|
GLTextureR* retval = new GLTextureR(q, width, height, samples);
|
||||||
|
q->resizeRenderTexture(retval, width, height);
|
||||||
static_cast<GLData*>(m_deferredData)->m_RTexs.emplace_back(retval);
|
static_cast<GLData*>(m_deferredData)->m_RTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -239,11 +241,18 @@ public:
|
||||||
|
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
int clientReturn = INT_MIN;
|
int clientReturn = INT_MIN;
|
||||||
|
std::mutex initmt;
|
||||||
|
std::condition_variable initcv;
|
||||||
|
std::unique_lock<std::mutex> outerLk(initmt);
|
||||||
std::thread clientThread([&]()
|
std::thread clientThread([&]()
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> innerLk(initmt);
|
||||||
|
innerLk.unlock();
|
||||||
|
initcv.notify_one();
|
||||||
clientReturn = m_callback.appMain(this);
|
clientReturn = m_callback.appMain(this);
|
||||||
pthread_kill(mainThread, SIGTERM);
|
pthread_kill(mainThread, SIGTERM);
|
||||||
});
|
});
|
||||||
|
initcv.wait(outerLk);
|
||||||
|
|
||||||
/* Begin application event loop */
|
/* Begin application event loop */
|
||||||
while (clientReturn == INT_MIN)
|
while (clientReturn == INT_MIN)
|
||||||
|
|
|
@ -72,6 +72,11 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getMainContextDataFactory()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -196,6 +201,11 @@ struct WindowWayland : IWindow
|
||||||
return m_gfxCtx.getDataFactory();
|
return m_gfxCtx.getDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getMainContextDataFactory()
|
||||||
|
{
|
||||||
|
return m_gfxCtx.getMainContextDataFactory();
|
||||||
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
{
|
{
|
||||||
return m_gfxCtx.getLoadContextDataFactory();
|
return m_gfxCtx.getLoadContextDataFactory();
|
||||||
|
|
|
@ -185,6 +185,7 @@ struct GraphicsContextGLX : IGraphicsContext
|
||||||
|
|
||||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||||
|
GLXContext m_mainCtx = 0;
|
||||||
GLXContext m_loadCtx = 0;
|
GLXContext m_loadCtx = 0;
|
||||||
|
|
||||||
std::thread m_vsyncThread;
|
std::thread m_vsyncThread;
|
||||||
|
@ -396,6 +397,21 @@ public:
|
||||||
return m_dataFactory;
|
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()
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
{
|
{
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
@ -1180,6 +1196,11 @@ public:
|
||||||
return m_gfxCtx.getDataFactory();
|
return m_gfxCtx.getDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getMainContextDataFactory()
|
||||||
|
{
|
||||||
|
return m_gfxCtx.getMainContextDataFactory();
|
||||||
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
{
|
{
|
||||||
return m_gfxCtx.getLoadContextDataFactory();
|
return m_gfxCtx.getLoadContextDataFactory();
|
||||||
|
|
Loading…
Reference in New Issue