1
0
mirror of https://github.com/thp/pyotherside.git synced 2025-01-28 23:52:55 +08:00

Clean up PyGLRenderers before replacing them.

This commit is contained in:
Dennis Tomas 2014-10-19 20:02:01 +02:00
parent 00abfc8570
commit 2662c423b4
4 changed files with 58 additions and 38 deletions

View File

@ -26,20 +26,40 @@ class PyFboRenderer : public QQuickFramebufferObject::Renderer
public:
PyFboRenderer()
: m_renderer(0)
, m_oldRenderer(0)
{
}
~PyFboRenderer()
{
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
if (m_oldRenderer) {
delete m_oldRenderer;
m_oldRenderer = 0;
}
}
void render() {
if (m_oldRenderer) {
m_oldRenderer->cleanup();
delete m_oldRenderer;
m_oldRenderer = 0;
}
if (!m_renderer) {
return;
}
m_renderer->init();
m_renderer->render();
update();
}
void setRenderer(PyGLRenderer *renderer) {
m_renderer = renderer;
void setRenderer(QVariant rendererRef) {
// Defer deleting the old renderer until render() is called,
// when we have an OpenGL context.
m_oldRenderer = m_renderer;
m_renderer = new PyGLRenderer(rendererRef, false);
update();
}
@ -50,39 +70,24 @@ public:
}
private:
PyGLRenderer *m_renderer;
PyGLRenderer *m_oldRenderer;
};
PyFbo::PyFbo()
: m_fboRenderer(0)
, m_renderer(0)
{
}
PyFbo::~PyFbo()
{
if (m_renderer) delete m_renderer;
// Do not delete m_fboRenderer, because we don't own it!
}
void PyFbo::setRenderer(QVariant rendererRef)
{
if (rendererRef == m_rendererRef)
return;
m_rendererRef = rendererRef;
// Delete the old python GL renderer.
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
// Create a renderer object from the reference.
m_renderer = new PyGLRenderer(m_rendererRef, false);
// If we already have a PyFboRenderer, set its python GL renderer.
// Otherwise it will be set when createRenderer() is called.
if (m_fboRenderer) {
static_cast<PyFboRenderer *>(m_fboRenderer)->setRenderer(m_renderer);
static_cast<PyFboRenderer *>(m_fboRenderer)->setRenderer(m_rendererRef);
}
}
@ -91,8 +96,8 @@ QQuickFramebufferObject::Renderer *PyFbo::createRenderer() const
m_fboRenderer = new PyFboRenderer();
// If we already have a python GL renderer, set it now.
if (m_renderer) {
static_cast<PyFboRenderer *>(m_fboRenderer)->setRenderer(m_renderer);
if (!m_rendererRef.isNull()) {
static_cast<PyFboRenderer *>(m_fboRenderer)->setRenderer(m_rendererRef);
}
return m_fboRenderer;
}

View File

@ -31,7 +31,6 @@ class PyFbo : public QQuickFramebufferObject
public:
PyFbo();
~PyFbo();
Renderer *createRenderer() const;
QVariant renderer() const { return m_rendererRef; };
@ -40,10 +39,9 @@ private:
QVariant m_rendererRef;
// We have to keep a pointer to the renderer created by createRenderer()
// around, for being able to swap out its PyGLRenderer when
// PyFboInSGRenderer::setRenderer() is called.
// around, for being able to swap out its PyGLRenderer
// when setRenderer() is called.
mutable Renderer *m_fboRenderer;
PyGLRenderer *m_renderer;
};
#endif

View File

@ -29,6 +29,8 @@
PyGLArea::PyGLArea()
: m_before(false)
, m_renderer(0)
, m_rendererChanged(false)
, m_beforeChanged(true)
{
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
}
@ -46,10 +48,10 @@ void PyGLArea::setRenderer(QVariant renderer)
if (renderer == m_pyRenderer)
return;
m_pyRenderer = renderer;
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
// Defer creating the PyGLRenderer until sync() is called,
// when we have an OpenGL context.
m_rendererChanged = true;
update();
}
@ -58,10 +60,8 @@ void PyGLArea::setBefore(bool before)
if (before == m_before)
return;
m_before = before;
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
m_beforeChanged = true;
update();
}
@ -80,10 +80,9 @@ void PyGLArea::update() {
void PyGLArea::sync()
{
if (!m_renderer && !m_pyRenderer.isNull()) {
if (m_beforeChanged) {
disconnect(window(), SIGNAL(beforeRendering()), this, SLOT(render()));
disconnect(window(), SIGNAL(afterRendering()), this, SLOT(render()));
m_renderer = new PyGLRenderer(m_pyRenderer);
if (m_before) {
// If we allow QML to do the clearing, they would clear what we paint
// and nothing would show.
@ -93,11 +92,28 @@ void PyGLArea::sync()
window()->setClearBeforeRendering(true);
connect(window(), SIGNAL(afterRendering()), this, SLOT(render()), Qt::DirectConnection);
}
m_beforeChanged = false;
}
if (m_rendererChanged) {
if (m_renderer) {
m_renderer->cleanup();
delete m_renderer;
m_renderer = 0;
}
if (!m_pyRenderer.isNull()) {
m_renderer = new PyGLRenderer(m_pyRenderer);
m_renderer->init();
window()->resetOpenGLState();
}
m_rendererChanged = false;
}
}
void PyGLArea::render()
{
if (!m_renderer)
return;
QPointF pos = mapToScene(QPointF(.0, .0));
m_renderer->setRect(
QRect(
@ -105,12 +121,11 @@ void PyGLArea::render()
(long)this->width(), (long)this->height()
)
);
m_renderer->init();
m_renderer->render();
window()->resetOpenGLState();
}
void PyGLArea::cleanup()
{
m_renderer->cleanup();
if (m_renderer) m_renderer->cleanup();
}

View File

@ -58,6 +58,8 @@ private:
QVariant m_pyRenderer;
bool m_before;
PyGLRenderer *m_renderer;
bool m_rendererChanged;
bool m_beforeChanged;
};
#endif /* PYOTHERSIDE_PYGLAREA_H */