diff --git a/toonz/sources/toonz/main.cpp b/toonz/sources/toonz/main.cpp index 7e6d03c..6b87580 100644 --- a/toonz/sources/toonz/main.cpp +++ b/toonz/sources/toonz/main.cpp @@ -629,7 +629,6 @@ int main(int argc, char *argv[]) { QString currentStyle = Preferences::instance()->getCurrentStyleSheetPath(); a.setStyleSheet(currentStyle); - TApp::instance()->setMainWindow(&w); w.setWindowTitle(applicationFullName); if (TEnv::getIsPortable()) { splash.showMessage(offsetStr + "Starting OpenToonz Portable ...", diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 9388982..26e4b63 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -377,6 +377,9 @@ MainWindow::MainWindow(const QString &argumentLayoutFileName, QWidget *parent, , m_saveSettingsOnQuit(true) , m_oldRoomIndex(0) , m_layoutName("") { + // store a main window pointer in advance of making its contents + TApp::instance()->setMainWindow(this); + m_toolsActionGroup = new QActionGroup(this); m_toolsActionGroup->setExclusive(true); m_currentRoomsChoice = Preferences::instance()->getCurrentRoomChoice(); @@ -2416,9 +2419,9 @@ RecentFiles::~RecentFiles() {} void RecentFiles::addFilePath(QString path, FileType fileType) { QList files = - (fileType == Scene) ? m_recentScenes : (fileType == Level) - ? m_recentLevels - : m_recentFlipbookImages; + (fileType == Scene) + ? m_recentScenes + : (fileType == Level) ? m_recentLevels : m_recentFlipbookImages; int i; for (i = 0; i < files.size(); i++) if (files.at(i) == path) files.removeAt(i); @@ -2543,9 +2546,9 @@ void RecentFiles::saveRecentFiles() { QList RecentFiles::getFilesNameList(FileType fileType) { QList files = - (fileType == Scene) ? m_recentScenes : (fileType == Level) - ? m_recentLevels - : m_recentFlipbookImages; + (fileType == Scene) + ? m_recentScenes + : (fileType == Level) ? m_recentLevels : m_recentFlipbookImages; QList names; int i; for (i = 0; i < files.size(); i++) { @@ -2572,9 +2575,9 @@ void RecentFiles::refreshRecentFilesMenu(FileType fileType) { menu->setEnabled(false); else { CommandId clearActionId = - (fileType == Scene) ? MI_ClearRecentScene : (fileType == Level) - ? MI_ClearRecentLevel - : MI_ClearRecentImage; + (fileType == Scene) + ? MI_ClearRecentScene + : (fileType == Level) ? MI_ClearRecentLevel : MI_ClearRecentImage; menu->setActions(names); menu->addSeparator(); QAction *clearAction = CommandManager::instance()->getAction(clearActionId); diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index 0495f07..1f50118 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -83,6 +83,7 @@ #endif #include #include +#include #include "sceneviewer.h" @@ -92,6 +93,19 @@ void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d, //------------------------------------------------------------------------------- namespace { +int l_mainDisplayListsSpaceId = + -1; //!< Display lists space id associated with SceneViewers +std::set + l_contexts; //!< Stores every SceneViewer context (see ~SceneViewer) + +//------------------------------------------------------------------------------- + +struct DummyProxy : public TGLDisplayListsProxy { + ~DummyProxy() {} + void makeCurrent() {} + void doneCurrent() {} +}; + //------------------------------------------------------------------------------- double getActualFrameRate() { @@ -532,6 +546,12 @@ void SceneViewer::setVisual(const ImagePainter::VisualSettings &settings) { SceneViewer::~SceneViewer() { if (m_fbo) delete m_fbo; + + // release all the registered context (once when exit the software) + std::set::iterator ct, cEnd(l_contexts.end()); + for (ct = l_contexts.begin(); ct != cEnd; ++ct) + TGLDisplayListsManager::instance()->releaseContext(*ct); + l_contexts.clear(); } //------------------------------------------------------------------------------- @@ -825,6 +845,8 @@ double SceneViewer::getHGuide(int index) { return m_hRuler->getGuide(index); } void SceneViewer::initializeGL() { initializeOpenGLFunctions(); + registerContext(); + // to be computed once through the software if (m_lutCalibrator) { m_lutCalibrator->initialize(); @@ -2580,3 +2602,45 @@ void SceneViewer::onContextAboutToBeDestroyed() { m_lutCalibrator->cleanup(); doneCurrent(); } + +//----------------------------------------------------------------------------- +// called from SceneViewer::initializeGL() + +void SceneViewer::registerContext() { + // release the old context, if any + // this will be happen when dock / float the viewer panel. + bool hasOldContext; +#ifdef _WIN32 + hasOldContext = + (m_currentContext.first != nullptr && m_currentContext.second != nullptr); +#else + hasOldContext = m_currentContext != nullptr; +#endif + if (hasOldContext) { + int ret = l_contexts.erase(m_currentContext); + if (ret) + TGLDisplayListsManager::instance()->releaseContext(m_currentContext); + } + + // then, register context and the space Id correspondent to it. + int displayListId; + if (TApp::instance()->getMainWindow() && + TApp::instance()->getMainWindow()->isAncestorOf(this) && + QThread::currentThread() == qGuiApp->thread()) { + // obtain displaySpaceId for main thread + if (l_mainDisplayListsSpaceId == -1) + l_mainDisplayListsSpaceId = + TGLDisplayListsManager::instance()->storeProxy(new DummyProxy); + + displayListId = l_mainDisplayListsSpaceId; + } + // for the other cases (such as for floating viewer), it can't share the + // context so + // obtain different id + else + displayListId = + TGLDisplayListsManager::instance()->storeProxy(new DummyProxy); + TGlContext tglContext(tglGetCurrentContext()); + TGLDisplayListsManager::instance()->attachContext(displayListId, tglContext); + l_contexts.insert(tglContext); +} diff --git a/toonz/sources/toonz/sceneviewer.h b/toonz/sources/toonz/sceneviewer.h index 97a3066..cfd4906 100644 --- a/toonz/sources/toonz/sceneviewer.h +++ b/toonz/sources/toonz/sceneviewer.h @@ -168,9 +168,12 @@ class SceneViewer final : public GLWidgetForHighDpi, QMatrix4x4 m_projectionMatrix; + // Used for texture management. + // Changing dock / float state of the panel will alter the context. + // So discarding the resources in old context in initializeGL. + TGlContext m_currentContext; + public: - // iwsw commented out temporarily - // Ghibli3DLutUtil* get3DLutUtil(){ return m_ghibli3DLutUtil; } enum ReferenceMode { NORMAL_REFERENCE = 1, CAMERA3D_REFERENCE = 2, @@ -381,6 +384,8 @@ protected: void setFocus() override { QWidget::setFocus(); }; + void registerContext(); + public slots: void resetSceneViewer();