From 339330f82f2aa4384e186abf2aa25b38fa39ea80 Mon Sep 17 00:00:00 2001 From: shun_iwasawa Date: Oct 11 2017 02:40:34 +0000 Subject: prevent windows outside the gui thread --- diff --git a/toonz/sources/include/stdfx/shaderinterface.h b/toonz/sources/include/stdfx/shaderinterface.h index abbc925..19e9f8d 100644 --- a/toonz/sources/include/stdfx/shaderinterface.h +++ b/toonz/sources/include/stdfx/shaderinterface.h @@ -173,8 +173,8 @@ public: // Sub-classes PERSIST_DECLARATION(ShaderData) public: - QString m_name; //!< A name associated to the shader action - TFilePath m_path; //!< The shader program's file path + QString m_name; //!< A name associated to the shader action + TFilePath m_path; //!< The shader program's file path QOpenGLShader::ShaderType m_type; //!< The shader type public: diff --git a/toonz/sources/include/stdfx/shadingcontext.h b/toonz/sources/include/stdfx/shadingcontext.h index 4fe77b8..078edf7 100644 --- a/toonz/sources/include/stdfx/shadingcontext.h +++ b/toonz/sources/include/stdfx/shadingcontext.h @@ -33,7 +33,7 @@ class QObject; class QOpenGLShaderProgram; class QDateTime; -class QOffScreenSurface; +class QOffscreenSurface; //========================================================= @@ -42,7 +42,7 @@ public: enum Support { OK, NO_PIXEL_BUFFER, NO_SHADERS }; public: - ShadingContext(); + ShadingContext(QOffscreenSurface *); ~ShadingContext(); //! Returns the status of OpenGL shading support. @@ -66,8 +66,10 @@ the context's output buffer is destroyed. //! Surrenders ownership of the supplied shader program to the shading //! context. - void addShaderProgram(const QString &shaderName, QOpenGLShaderProgram *program); - void addShaderProgram(const QString &shaderName, QOpenGLShaderProgram *program, + void addShaderProgram(const QString &shaderName, + QOpenGLShaderProgram *program); + void addShaderProgram(const QString &shaderName, + QOpenGLShaderProgram *program, const QDateTime &lastModified); bool removeShaderProgram(const QString &shaderName); @@ -103,8 +105,8 @@ private: class TQOpenGLWidget : public QOpenGLWidget { public: - TQOpenGLWidget(); - void initializeGL() override; + TQOpenGLWidget(); + void initializeGL() override; }; #endif // SHADINGCONTEXT_H diff --git a/toonz/sources/include/toonzqt/glwidget_for_highdpi.h b/toonz/sources/include/toonzqt/glwidget_for_highdpi.h index ce53df9..c64ba96 100644 --- a/toonz/sources/include/toonzqt/glwidget_for_highdpi.h +++ b/toonz/sources/include/toonzqt/glwidget_for_highdpi.h @@ -12,9 +12,9 @@ // TODO: replace with the "modern" OpenGL source and transfer to QOpenGLWidget class GLWidgetForHighDpi : public QOpenGLWidget { public: - GLWidgetForHighDpi(QWidget *parent = Q_NULLPTR, + GLWidgetForHighDpi(QWidget *parent = Q_NULLPTR, const QOpenGLWidget *shareWidget = Q_NULLPTR, - Qt::WindowFlags f = Qt::WindowFlags()) + Qt::WindowFlags f = Qt::WindowFlags()) : QOpenGLWidget(parent, f) {} // modify sizes for high DPI monitors diff --git a/toonz/sources/stdfx/shaderfx.cpp b/toonz/sources/stdfx/shaderfx.cpp index 3580ed5..79c84ef 100644 --- a/toonz/sources/stdfx/shaderfx.cpp +++ b/toonz/sources/stdfx/shaderfx.cpp @@ -24,6 +24,7 @@ #include #include #include +#include // Glew include #include @@ -191,10 +192,9 @@ public: void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override; private: - QOpenGLShaderProgram *touchShaderProgram(const ShaderInterface::ShaderData &sd, - ShadingContext &context, - int varyingsCount = 0, - const GLchar **varyings = 0); + QOpenGLShaderProgram *touchShaderProgram( + const ShaderInterface::ShaderData &sd, ShadingContext &context, + int varyingsCount = 0, const GLchar **varyings = 0); void bindParameters(QOpenGLShaderProgram *shaderProgram, double frame); @@ -230,8 +230,9 @@ public: class ShadingContextManager final : public QObject { mutable QMutex m_mutex; - ShadingContext m_shadingContext; + std::unique_ptr m_shadingContext; TAtomicVar m_activeRenderInstances; + std::unique_ptr m_surface; public: ShadingContextManager() { @@ -251,7 +252,10 @@ Suggestions are welcome as this is a tad beyond ridiculous... assert(thread() == mainScopeBoundObject ->thread()); // Parent object must be in the same thread, - //setParent(mainScopeBoundObject); // otherwise reparenting fails + // setParent(mainScopeBoundObject); // otherwise reparenting fails + m_surface.reset(new QOffscreenSurface()); + m_surface->create(); + m_shadingContext.reset(new ShadingContext(m_surface.get())); } static ShadingContextManager *instance() { @@ -261,8 +265,8 @@ Suggestions are welcome as this is a tad beyond ridiculous... QMutex *mutex() const { return &m_mutex; } - const ShadingContext &shadingContext() const { return m_shadingContext; } - ShadingContext &shadingContext() { return m_shadingContext; } + const ShadingContext &shadingContext() const { return *m_shadingContext; } + ShadingContext &shadingContext() { return *m_shadingContext; } void onRenderInstanceStart() { ++m_activeRenderInstances; } @@ -271,8 +275,8 @@ Suggestions are welcome as this is a tad beyond ridiculous... QMutexLocker mLocker(&m_mutex); // Release the shading context's output buffer - ::ContextLocker cLocker(m_shadingContext); - m_shadingContext.resize(0, 0); + ::ContextLocker cLocker(*m_shadingContext); + m_shadingContext->resize(0, 0); #ifdef DIAGNOSTICS DIAGNOSTICS_DUMP("ShaderLogs"); @@ -286,7 +290,7 @@ Suggestions are welcome as this is a tad beyond ridiculous... ShadingContextManager *m_this; ShadingContext::Support support() { QMutexLocker mLocker(&m_this->m_mutex); - ::ContextLocker cLocker(m_this->m_shadingContext); + ::ContextLocker cLocker(*m_this->m_shadingContext); return ShadingContext::support(); } @@ -315,6 +319,8 @@ Suggestions are welcome as this is a tad beyond ridiculous... return sup; } + + QOffscreenSurface *getSurface() { return m_surface.get(); } }; template class DV_EXPORT_API TFxDeclarationT; @@ -603,7 +609,8 @@ bool ShaderFx::doGetBBox(double frame, TRectD &bbox, QMutexLocker mLocker(manager->mutex()); // ShadingContext& context = manager->shadingContext(); - std::shared_ptr shadingContextPtr(new ShadingContext); + std::shared_ptr shadingContextPtr( + new ShadingContext(manager->getSurface())); ShadingContext &context = *shadingContextPtr.get(); ::ContextLocker cLocker(context); @@ -687,7 +694,8 @@ QOpenGLShaderProgram *ShaderFx::touchShaderProgram( int c, cCount = children.size(); for (c = 0; c != cCount; ++c) { - if (QOpenGLShader *shader = dynamic_cast(children[c])) { + if (QOpenGLShader *shader = + dynamic_cast(children[c])) { const QString &log = shader->log(); if (!log.isEmpty()) DVGui::info(log); } @@ -967,7 +975,7 @@ void ShaderFx::doCompute(TTile &tile, double frame, const TDimension &size, int bpp) { const QOpenGLFramebufferObjectFormat &fmt = makeFormat(bpp); - const TDimension ¤tSize = context.size(); + const TDimension ¤tSize = context.size(); const QOpenGLFramebufferObjectFormat ¤tFmt = context.format(); if (currentSize.lx < size.lx || currentSize.ly < size.ly || @@ -983,8 +991,8 @@ void ShaderFx::doCompute(TTile &tile, double frame, QMutexLocker mLocker( manager->mutex()); // As GPU access can be considered sequential anyway, // lock the full-scale mutex - - std::shared_ptr shadingContextPtr(new ShadingContext); + std::shared_ptr shadingContextPtr( + new ShadingContext(manager->getSurface())); ShadingContext &context = *shadingContextPtr.get(); // ShadingContext& context = manager->shadingContext(); @@ -1142,7 +1150,8 @@ void ShaderFx::doDryCompute(TRectD &rect, double frame, QMutexLocker mLocker(manager->mutex()); // ShadingContext& context = manager->shadingContext(); - std::shared_ptr shadingContextPtr(new ShadingContext); + std::shared_ptr shadingContextPtr( + new ShadingContext(manager->getSurface())); ShadingContext &context = *shadingContextPtr.get(); int pCount = getInputPortCount(); diff --git a/toonz/sources/stdfx/shadingcontext.cpp b/toonz/sources/stdfx/shadingcontext.cpp index ff8ae0d..0872dc0 100644 --- a/toonz/sources/stdfx/shadingcontext.cpp +++ b/toonz/sources/stdfx/shadingcontext.cpp @@ -11,7 +11,6 @@ #include #include - #include #include #include @@ -48,9 +47,9 @@ public: TQOpenGLWidget::TQOpenGLWidget() {} void TQOpenGLWidget::initializeGL() { - QOffscreenSurface *surface = new QOffscreenSurface(); - //context()->create(); - //context()->makeCurrent(surface); + QOffscreenSurface *surface = new QOffscreenSurface(); + // context()->create(); + // context()->makeCurrent(surface); } //***************************************************************** @@ -58,8 +57,8 @@ void TQOpenGLWidget::initializeGL() { //***************************************************************** struct ShadingContext::Imp { - QOpenGLContextP m_context; //!< OpenGL context. - QOpenGLFramebufferObjectP m_fbo; //!< Output buffer. + QOpenGLContextP m_context; //!< OpenGL context. + QOpenGLFramebufferObjectP m_fbo; //!< Output buffer. QOffscreenSurface *m_surface; std::mapm_surface = new QOffscreenSurface(); - m_imp->m_surface->create(); - QSurfaceFormat format; - m_imp->m_context->setFormat(format); - m_imp->m_context->create(); - m_imp->m_context->makeCurrent(m_imp->m_surface); - - //m_imp->m_pixelBuffer->context()->create(); - //m_imp->m_fbo(new QOpenGLFramebufferObject(1, 1)); +ShadingContext::ShadingContext(QOffscreenSurface *surface) : m_imp(new Imp) { + m_imp->m_surface = surface; + m_imp->m_surface->create(); + QSurfaceFormat format; + m_imp->m_context->setFormat(format); + m_imp->m_context->create(); + m_imp->m_context->makeCurrent(m_imp->m_surface); + + // m_imp->m_pixelBuffer->context()->create(); + // m_imp->m_fbo(new QOpenGLFramebufferObject(1, 1)); makeCurrent(); glewExperimental = GL_TRUE; glewInit(); @@ -141,10 +139,11 @@ ShadingContext::~ShadingContext() { //-------------------------------------------------------- ShadingContext::Support ShadingContext::support() { - //return !QGLPixelBuffer::hasOpenGLPbuffers() + // return !QGLPixelBuffer::hasOpenGLPbuffers() // ? NO_PIXEL_BUFFER - // : !QOpenGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : OK; - return OK; + // : !QOpenGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : + // OK; + return !QOpenGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : OK; } //-------------------------------------------------------- @@ -183,12 +182,12 @@ USE HARDWARE ACCELERATION //-------------------------------------------------------- void ShadingContext::makeCurrent() { - m_imp->m_context->moveToThread(QThread::currentThread()); + m_imp->m_context->moveToThread(QThread::currentThread()); m_imp->m_context.reset(new QOpenGLContext()); - QSurfaceFormat format; - m_imp->m_context->setFormat(format); - m_imp->m_context->create(); - m_imp->m_context->makeCurrent(m_imp->m_surface); + QSurfaceFormat format; + m_imp->m_context->setFormat(format); + m_imp->m_context->create(); + m_imp->m_context->makeCurrent(m_imp->m_surface); } //-------------------------------------------------------- @@ -209,12 +208,12 @@ void ShadingContext::resize(int lx, int ly, if (lx == 0 || ly == 0) { m_imp->m_fbo.reset(0); } else { - bool get = m_imp->m_fbo.get(); - QOpenGLContext *currContext = m_imp->m_context->currentContext(); - bool yes = false; - if (currContext) bool yes = true; - while (!currContext) currContext = m_imp->m_context->currentContext(); - m_imp->m_fbo.reset(new QOpenGLFramebufferObject(lx, ly, fmt)); + bool get = m_imp->m_fbo.get(); + QOpenGLContext *currContext = m_imp->m_context->currentContext(); + bool yes = false; + if (currContext) bool yes = true; + while (!currContext) currContext = m_imp->m_context->currentContext(); + m_imp->m_fbo.reset(new QOpenGLFramebufferObject(lx, ly, fmt)); assert(m_imp->m_fbo->isValid()); m_imp->m_fbo->bind(); diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index 568b1a4..acd9641 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -571,7 +571,7 @@ SceneViewer::~SceneViewer() { std::set::iterator ct, cEnd(l_contexts.end()); for (ct = l_contexts.begin(); ct != cEnd; ++ct) TGLDisplayListsManager::instance()->releaseContext(*ct); - //assert(!l_proxy); + // assert(!l_proxy); } makeCurrent(); @@ -635,8 +635,8 @@ void SceneViewer::onPreviewUpdate() { void SceneViewer::startForegroundDrawing() { makeCurrent(); - //setAutoBufferSwap(false); - update(); // needed? + // setAutoBufferSwap(false); + update(); // needed? glPushMatrix(); tglMultMatrix(getViewMatrix()); @@ -668,8 +668,8 @@ void SceneViewer::endForegroundDrawing() { assert(glGetError() == GL_NO_ERROR); } - //setAutoBufferSwap(true); - update(); // needed? + // setAutoBufferSwap(true); + update(); // needed? m_foregroundDrawing = false; } diff --git a/toonz/sources/toonz/viewerpane.cpp b/toonz/sources/toonz/viewerpane.cpp index 783aee6..da1bfa9 100644 --- a/toonz/sources/toonz/viewerpane.cpp +++ b/toonz/sources/toonz/viewerpane.cpp @@ -336,9 +336,9 @@ void SceneViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) { // buttons for show / hide toggle for the field guide and the safe area TPanelTitleBarButtonForSafeArea *safeAreaButton = - new TPanelTitleBarButtonForSafeArea(titleBar, ":Resources/pane_safe_off.svg", - ":Resources/pane_safe_over.svg", - ":Resources/pane_safe_on.svg"); + new TPanelTitleBarButtonForSafeArea( + titleBar, ":Resources/pane_safe_off.svg", + ":Resources/pane_safe_over.svg", ":Resources/pane_safe_on.svg"); safeAreaButton->setToolTip(tr("Safe Area (Right Click to Select)")); titleBar->add(QPoint(x, 0), safeAreaButton); ret = ret && connect(safeAreaButton, SIGNAL(toggled(bool)), @@ -407,8 +407,8 @@ void SceneViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) { // preview toggles m_previewButton = new TPanelTitleBarButton( - titleBar, ":Resources/pane_preview_off.svg", ":Resources/pane_preview_over.svg", - ":Resources/pane_preview_on.svg"); + titleBar, ":Resources/pane_preview_off.svg", + ":Resources/pane_preview_over.svg", ":Resources/pane_preview_on.svg"); x += 10 + iconWidth; titleBar->add(QPoint(x, 0), m_previewButton); m_previewButton->setToolTip(tr("Preview")); @@ -717,7 +717,7 @@ bool SceneViewerPanel::hasSoundtrack() { TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet(); TXsheet::SoundProperties *prop = new TXsheet::SoundProperties(); if (!m_sceneViewer->isPreviewEnabled()) prop->m_isPreview = true; - m_sound = xsheetHandle->getXsheet()->makeSound(prop); + m_sound = xsheetHandle->getXsheet()->makeSound(prop); if (m_sound == NULL) { m_hasSoundtrack = false; return false;