Skip to content

Test merge qt6 to main#1

Open
bernie-laberge wants to merge 45 commits into
mainfrom
test_merge_qt6_to_main
Open

Test merge qt6 to main#1
bernie-laberge wants to merge 45 commits into
mainfrom
test_merge_qt6_to_main

Conversation

@bernie-laberge
Copy link
Copy Markdown
Owner

Linked issues

Summarize your change.

Describe the reason for the change.

Describe what you have tested and on which operating system.

Add a list of changes, and note any that might need special attention during the review.

If possible, provide screenshots.

cedrik-fuoco-adsk and others added 30 commits October 25, 2024 09:33
### Feature - Qt 6 port # 1

### Linked issues
AcademySoftwareFoundation#367 

### Summarize your change.
This is the first phase of the Qt 6 port. It was mostly tested on Rocky
Linux 8.

There are a lot of generated files under `src/lib/mu/MuQt6`, and some
modifications but you don't need to go over that folder.

There are known issues that will be addressed in future PR:

**All platforms:**
- Refactor _QtAudioRenderer_ class. Currently, The _pulse_ audio output
device is not enabled, and they are loud white noise issues on MacOS.
- Remove the usage of _Core5compat_ and refactor what is deprecated. I
don't think there is a lot to do here, but it is mostly about refactor
the usage of _QTextCodec_.

**MacOS:**
- The _Open File dialog_ does not open anymore.
- Loud white noise audio (Should be related to _QtAudioRenderer_)
- The Central widget is rendered in the bottom left corner, but as soon
as you resize the windows, it goes back to normal.

**Windows:**
- Issue with the compilation of Shiboken6

### Describe what you have tested and on which operating system.

- [ ] Rocky LInux 8
- [ ] MacOS

### Add a list of changes, and note any that might need special
attention during the review.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Rebasing Qt6 feature branch to main 

Rebasing the feature branch to main to keep it updated.

---------

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Will Wira <4399853+williamwira@users.noreply.github.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: williamwira <4399853+williamwira@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
It seems like it was missing some commit on the last rebase. They should
be there now.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Will Wira <4399853+williamwira@users.noreply.github.com>
Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Co-authored-by: williamwira <4399853+williamwira@users.noreply.github.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
…xcept Windows) (AcademySoftwareFoundation#618)

### Qt6 feature branch - Various fix for all platforms and VFX 2024 CI
(Except Windows)

### Linked issues
AcademySoftwareFoundation#366 

### Summarize your change.

Here's are the changes:

- Added VFX 2024 CI (except for Windows) without ci-openrv from
aswf-docker for now (Linux only, not tested yet)
- Code changes to fix issues on Windows
- Code changes to fix issues on MacOS
- Added OpenSSL 3 for VFX2024
- Added some logic to all `.wrapper` to detect which VFX platform is
active (using Python version) and then use the right OpenSSL version.
- FIx issue with Python not finding Tkinter on MacOS. The issue was with
VFX2024, but the fix make sense for VFX2023 too.

**There are a lot of reformatting because of the pre-commit hook.
Windows is not included in the VFX 2024 CI because of issues with
PySide6 in the CI.**




### Describe what you have tested and on which operating system.
- [x] Rocky linux 8/9
- [x] MacOS
- [ ] Windows (partial, can compile with my windows, but not in CI
because of pyside6 issue)

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Qt6 Feature branch - Rebase to main

### Linked issues
n/a

### Summarize your change.
I rebased by cherry-picking the commits since the last rebase.

### Describe the reason for the change.
Rebase to main to minimize efforts

---------

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
…ndation#641)

### Qt6 Feature branch - Fix issue with menu on MacOS

### Linked issues
n/a

### Summarize your change.
The QMenuBar and QMenu has changed in Qt6. Some behaviours seems to have
changed in Qt6, and the code around a memory leak (based on the
comments) is not longer working.

I made some changes that works on MacOS and Rocky Linux 8. There no
information about how to reproduce that memory leak.
**We'll need to test around that to make sure that it is not the case
with Qt6 anymore.**

### Describe the reason for the change.
Multiple menu were appearing on the menu bar on MacOS.

### Describe what you have tested and on which operating system.

- [x] MacOS
- [x] Rocky Linux 8

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…Windows (AcademySoftwareFoundation#651)

### Qt6 Feature - Fix issues with Python

### Linked issues
AcademySoftwareFoundation#367 

### Describe the reason for the change.

I created two functions to do the install step of Python. One for Python
3.10 (VFX2023) and one for Python 3.11 (VFX2024). I think it will be
easier to maintain and remove later on. The difference was only for
Windows, but both functions contains the code for all platforms.

Since Python 3.11, the `PLATLIBDIR` directory was renamed to `DLLs`
instead of `lib`. You can changed it by modifying the Visual studio
project file, but I found some place in the Python source code that was
hardcoded to `DLLs`. I opted to keep `DLLs` and copy that over to the
OpenRV's stage directory. It does not change anything functionally
because the Python executable is looking for the DLLs library
automatically.

**The changes above also fixes the issue with PySide6 compilation on
Windows.**

### Describe what you have tested and on which operating system.
Windows

### If possible, provide screenshots.
stage directory:

![image](https://github.com/user-attachments/assets/dadbad51-b8a5-4cfe-abd8-55e3ab4dd2fd)

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Feature/Qt6 - Fixing the audio settings

### Linked issues
n/a

### Describe the reason for the change.

The code that was handling the audio sample rate changes was refactored
in this PR because of the Qt Audio module refactor in Qt 6. In Qt 5, you
could get a list of valid sample rate from the audio device, but in Qt
6, you only get a minimum and maximum value.

With Qt6 OpenRV, the widget to change the sample rate is a SpinBox
instead of a ComboBox.

**_What is left to do for Audio:_**

- [ ] There are still some memory issues (crash) when changing audio
sample rate on MacOS (tested on ARM64). **This PR does not fix that.**
- [ ] Other refactor to support audio format (e.g. int8) that are not
available by default in Qt 6 anymore.

### Describe what you have tested and on which operating system.
Windows, MacOS and Rocky.

### If possible, provide screenshots.

With Qt 6, a QSpinBox is used for the sample rate setting.


![image](https://github.com/user-attachments/assets/eff2580e-a060-4d87-bbd9-7aa6cdbda3c5)

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…#664)

### Feature/Qt6 - Rebase to main (Jan 21 2025)

### Linked issues
n/a

### Describe the reason for the change.
Rebase to main

---------

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: mcoms <mastercoms@tuta.io>
Signed-off-by: Mirco Tornow <mirco.tornow@outlook.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
Co-authored-by: mcoms <mastercoms@tuta.io>
Co-authored-by: Mirco Tornow <mirco.tornow@outlook.com>
Co-authored-by: Bernard Laberge <bernard.laberge@autodesk.com>
### Feature/Qt6 - Format and rebase

### Linked issues
n/a

### Summarize your change.
Reformatted and rebased branch to main.

### Describe the reason for the change.
Reformatted the code base manually in the branch to prevent a lot of
conflicts when this branch will be merged in main.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
…cademySoftwareFoundation#679)

### Feature/Qt6 - Fix issues with bindings and adding missing handrolled

### Linked issues
n/a

### Summarize your change.
Here's the list of changes:

- Some formatting
- Fixed some issue with Mu bindingds
- Added missing methods in the Mu bindings by adding them in the
handrolled section (they will be generated the next time)
- Added new classes that were needed

### Describe the reason for the change.
Prevent issues with Mu plugins and prevent future issues in the next Mu
bindings generation.

### Describe what you have tested and on which operating system.
all

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…s for clang-format (AcademySoftwareFoundation#684)

### Feature/Qt6 - Add QTimezone to the MuQt5 bindings and ignore
templates for clang-format

### Linked issues
n/a

### Summarize your change.
This PR adds QTimezone to the MuQt5 bindings and added
.clang-format-ignore to ignore the MuQt templates.

### Describe the reason for the change.
This is needed to fix some Mu plugins.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…AcademySoftwareFoundation#685)

### Feature/Qt6 - Fix issue with QItemSelectionModel::select method in
Mu

### Linked issues
n/a

### Summarize your change.
Added a special case to deal with calls to
`QItemSelectionModel::select`.

### Describe the reason for the change.
The new implementation of `QMetaMethod:invoke` in Qt 6 is using variadic
templates and C++ type deduction (instead of `QGenericArgument`).
Therefore, it does not convert the `QItemSelectionModel::SelectionFlags`
enum to `int` and an error message appears.

### Describe what you have tested and on which operating system.
Rocky 8 and MacOS

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Feature/Qt6 - Fix issue when cloning RV

### Linked issues
n/a

### Summarize your change.

- Fixed issue with `Clone RV` and `Clone Synced RV` operation and 
- Fixed issue with a few Mu script in the Qt5 build.
- Fixed a warning about an unknown signal named `error`. The `error`
signal was renamed to `errorOccurred` in Qt 5.15 and Qt 6+.

### Describe the reason for the change.
The Clone RV application was not launching due to the incorrect usage of
`startDetached` method.

### Describe what you have tested and on which operating system.
Rocky

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…#690)

### Feature/Qt6 - Rebase main into feature/qt6

### Linked issues
n/a

### Summarize your change.
Rebase main into feature/qt6

---------

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Christopher Lee <christophercarlos.lee@gmail.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Chris <34953610+chrisc-lee@users.noreply.github.com>
…cademySoftwareFoundation#691)

### Feature/Qt6 - Fix issue where Mu Command API Browser is not opening

### Linked issues
n/a

### Summarize your change.
There were some changes in the Qt 6 QVariant type and it seems like we
need to explicitly define a QVariant constructor for QIcon in Qt 6.

### Describe the reason for the change.
Mu Command API Browser is not opening in the build using Qt 6.

### Describe what you have tested and on which operating system.
Rocky 8

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…sing Qt6Test.dll) (AcademySoftwareFoundation#692)

### Feature/Qt6 - Fix issue that prevent OpenRV to launch on Windows
(Missing Qt6Test.dll)

### Linked issues
n/a

### Summarize your change.
Fix issue that prevent OpenRV to launch on Windows (Missing Qt6Test.dll)

### Describe the reason for the change.
OpenRV is not launching on Windows.

### Describe what you have tested and on which operating system.
Windows

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…ndation#693)

### Feature/Qt6 - Reverting old changes in RvDocument

### Linked issues
n/a

### Summarize your change.
Reverting changes from a couple weeks ago

### Describe the reason for the change.
A couple weeks ago, there was an issue with duplicated menu on MacOS
(multiple time the same menu), but the fix broke something in the menu
system for all platforms. Therefore, I am reverting the changes and I'll
go back to the drawing board for the MacOS issue.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…emySoftwareFoundation#695)

### Feature/qt6 - Fix issue with all menu being duplicated on MacOS

### Linked issues
n/a

### Summarize your change.
I removed old code that was dealing with a potential memory leaks
related to QAction and specific behavior for MacOS that causes issues
now.

### Describe the reason for the change.
This changes was done to fix an issue where all the menus are duplicated
multiple times in the QToolBar.

### Describe what you have tested and on which operating system.
Rocky 8 and MacOS

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…emySoftwareFoundation#703)

### Summarize your change.

When exporting (or, for that matter, calling an external process) was
finished, the "finish" callback faied and caused RV to crash.

The fix was simply to add a missing parameter at the end of the
signature of the callback method called by connect() when
QProcess.finish is called, to match what is expected in Qt6 (and Qt5,
actually)

This crash appeared whenever launching an external process, not just
rvio. So other issues we found regarding a crash when launching an
external process should also be fixed with this change.

### Describe the reason for the change.

Fixes crash at end of export process


### Describe what you have tested and on which operating system.
Tested on Linux64 Rocky 9.5.

It's not clear why this worked on the Qt5 branch and crashed on Qt6.
Indeed, the "finish" signal always took 2 parameters, while the Mu
signal only took one.

see below : similar signature of QProcess.finish()
https://doc.qt.io/qt-5/qprocess.html
https://doc.qt.io/qt-6/qprocess.html

**Please retest this with a Qt5 build of the qt6 branch.**

### Add a list of changes, and note any that might need special
attention during the review.
n/a

### If possible, provide screenshots.
n/a

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
AcademySoftwareFoundation#702)

### Summarize your change.

This fix is to prevent QCoreApplication::initLocale() method to complain
that an invalid locale is currently set. Before this bugfix, RV's init
code explicitly set the current locale to "C". At the same time, this
locale is now explicitly unsupported by Qt6, and instead will instead
switch to "C.UTF-8" under Linux, or "UTF-8" under Darwin (macOS)

For more information about how Qt initializes the locale, look at
initLocale() in the file:

QT_HOME/Qt6.x.x/Src/qtbase/src/corelib/kernel/qcoreapplication.cpp

### Describe the reason for the change.

See above.

### Describe what you have tested and on which operating system.
Tested on Rocky 9.5, waiting on Cedrik to test on Darwin.

### Add a list of changes, and note any that might need special
attention during the review.
n/a

### If possible, provide screenshots.
n/a

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
)

### Feature/Qt6 - Rebase with the main branch

### Linked issues
n/a

### Summarize your change.

### Describe the reason for the change.
Rebasing the feature branch with the main branch

### Describe what you have tested and on which operating system.
See commits list

---------

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
…s exporting quicktime video (#35176) (AcademySoftwareFoundation#704)

### Describe the reason for the change.

When we clicked or dragged the widget during a quicktime export (or any
instance of the ProcessInfo widget for that matter), we (almost)
inevitably always crashed. Happened in Qt5 and Qt6 branch, and as far
back as RV 2023, apparently.

### Summarize your change.

When we clicked on the ProcessInfo widget, the code tries to access the
_buttons[] array to see if we are clicking in the (X) button, but simply
reading this array crashed RV.

It turns out that for the ProcessInfo widget, the render() method
recreated the _buttons[] array, which contained the coordinates and
process info for the (X) cancel button. This was in a different thread
than the event-handling thread. So, while the render method was
executing and the _buttons[] array was being recreated, the
event-handling thread was trying to read the same array to see if w were
clicking in the (X) button. Since the memory had been disposed and
replaced in the meantime, this caused a crash .

The fix was simply to initialize the array when the ProcessInfo widget
is created, and in the render() method we update the x/y/w/h/pid. This
does not cause a change in memory space, and the crash no longer
happens. Ideally, we'd need a mutex to sync the read/write tof the
x/y/w/h/pid values, but, we're really just reading/writing coordinates
here, and the pid always remains constant, so even if there was
concurrent read/write access it should be completely harmless.

Either way, the crash no longer occurs.


### Describe what you have tested and on which operating system
.
This was 100% reproducible on Linux, and I think also macOS, the problem
was no platform-specific but Mu-specifc.


### Add a list of changes, and note any that might need special
attention during the review.

There is only 1 file to review, so, no big deal.

### If possible, provide screenshots.
n/a

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
…g the main window (AcademySoftwareFoundation#709)

### Summarize your change.

Added a singleshot timer to force a resize event to the main window, in
order to fix an image scale issue when first starting RV.

### Describe the reason for the change.

On macOS (and, presumably, any platform that supports HDPI) the initial
display of the main view's image will not be scaled properly. After much
investigation, this appears to be a Qt bug but were being unable to
truly identify the root cause (coordinates are ok, pixel scale is ok,
pixel ratio is ok, gl surface is ok, gl viewport is ok, etc etc.

Oddly enough, the issue disappeared when resizing the view, even 1
pixel, but this has to be done after the view is first shown.

As a result, we dimply decided to force two resize events to occur (+1
pixel, and then -1 pixel). This has no visible effect on startup (or,
you'd really need eagle eyes) to go: "A-HA!"

### Describe what you have tested and on which operating system.

This was reported on macOS, so I tested it on macOS, but it's possible
it may occur on other platofrms as well. Unfortunately I did not have
HDPI displays where the OS does pixel-doubling by itself like on macOS.

### Add a list of changes, and note any that might need special
attention during the review.

This is a simple change in RvDocument, where we initially set up the
main view.

### If possible, provide screenshots.

No need, simply confirm that RV now starts correctly on macOS

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
… (eg: NDI) (AcademySoftwareFoundation#707)

Fixes #38133

### Describe the reason for the change.

Could not open presentation device after setting Presenation device to
NDIDevice, and then doing CTRL-P to enable it. The error message was due
to a ";" at the end of an if-statement, but then it caused opengl errors
down the line due to the gl context being invalid after calling
swapBuffers.

Turns out all the swapBuffer management is no longer needed with
QOpenGLWidget, explanation in the summary below.

### Summarize your change.

Note for Qt6 . QOpenGLWidget implementation:

With the new QOpenGLWidget (Qt6 branch), all of the rendering of each
widget is done in its own FBOs (aka: off-screen buffers), as opposed to
the old Qt5/QGLWidget branch where the rendering was done in each
GGLWidget's backbuffer (aka: GL_BACK, an on-screen framebuffer surface).

With QOpenGLWidget, it is now the WainWindow's responsibility (more
technically, the MainWindow's rendering backend, which happens to be
Qt's OpenGL rendering backend when QOpenGLWidget are present in the
children tree) to gather and composite all of the off-screen buffers
(regardless of which image type they are, eg: cpu-memory images,
gpu/opengl images, etc) and finally to call swapBuffers to show the
final contents of the mainWindow.

As a result, I'm not sure there's a point -- at all -- in calling
swapBuffers on the GLView anywhere amnymore. From old comments in the
previous version of this tile, it appears that calling swapBuffers was
done to force a quicker visual update, or to minimize visual tearing of
some sort. This would have worked with the old QGLWidget (becayuse each
QGLWidget had its own context, and its rendering target was directly the
GL_BACK
framebuffer, but, again, with QOpenGLWidget, the rendering target is no
longer GL_BACK, it is an FBO that is meant to be used at the end of the
application's drawing / visual update pipeline.

I am not sure how this would affect (if at all?) the display of the
rendered buffer on external video devices. This needs to be tested
extensively.



### Describe what you have tested and on which operating system.

I have tested on Linux64 and have seen no adverse effects.

**Note for QA**: Please test this extensively on all 3 platforms, and
with all VideoDevices (NDI, SDI, AJA, BlackMagic), to make sure this
causes no problem.


### Add a list of changes, and note any that might need special
attention during the review.


### If possible, provide screenshots.
n/a

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
Co-authored-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
…reFoundation#700)

### Summarize your change.

The dropperSampler tool in RV was not working correctly anymore in the
qt6 branch. It had a strange offset (horizontally and vertically)
because the OpenGL function glReadPixels was reading from the wrong
context and the wrong framebuffer object.

in annotate_mode.mu, the method dropperSampler() called an OpenGL method
(glReadPixels) while not in a rendering pass. This somehow worked in the
old Qt5/GLWidget implementation, because the current OpenGL context and
FBO always remained set to the main view widget. But since switching to
Qt6/QOpenGLWidget, this no longer holds true - the Qt6/QOpenGLWidget
backend has a OpenGL compositor that works differently, and the OpenGL
context/fbo of the main view was no longer current after the application
was done refreshing.

Since we want to query the final rendered view using glReadPixels, we
implemented a mu method called framebufferPixelValue(x, y) which
internally eventually sets the OpenGL context/fbo to the correct one
before calling glReadPixels. (after PR 707, there is no need to restore
the previous one)


### Describe the reason for the change.

See first paragraph of the "Summarize your change" section

### Describe what you have tested and on which operating system.

I have tested the dropperSampler tool, with different layouts and docked
windows, but on Linux64 only. Please test in Darwin and Windows.

### Add a list of changes, and note any that might need special
attention during the review.

Please test and review on all other platforms please; although I am
confident this will work just fine. During investigating this bug, the
easiest way to see this problem was to dock the annotation bar on the
left portion of the application window, thus pushing the main image
window a bit to the right. Then, you'd easily notice that the color was
wrong when you picked a color, which was horizontally offset by the
width of the docked panel.

The easiest way to test and repro this, and to notice the fix works, is
to start TV with the "smptebars.movieproc" argument, where you can
clearly see the differences in color.

### If possible, provide screenshots.
n/a

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
…ndation#710)

### Feature/qt6 - Remove usage of Core5Compat library

### Linked issues
n/a

### Summarize your change.

I have eliminated all instances of QTextCodec, as this class is no
longer supported in Qt 6. Previously, the code relied on the Core5Compat
library, which incorporates deprecated and obsolete Qt 5 classes.

### Describe what you have tested and on which operating system.

I created a python plugin to execute the httpGet method from the
RvWebManager class.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…ndation#719)

### Feature/qt6 - Fix issue with Windows CI (release)

### Linked issues
n/a

### Summarize your change.
I added the architecture and vfx platform to the key for the
dependencies cache on Windows. It is already present for MacOS.

### Describe the reason for the change.
Sometimes, the release Windows build was failing because it was using
the cache from a VFX2023 build.

### Describe what you have tested and on which operating system.
CI

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
)

### Feature/Qt6 - Fix nuke and rv integration

### Linked issues
n/a

### Summarize your change.
This PR update the rvNetwork,py to Python 3 (copied from
src/plugins/python/network/network/rvNetwork.py) and fix some issues in
the Mu binding for the QTextStream class.

I will also update the rvNetwork.py file in the main branch in another
PR.

### Describe the reason for the change.
Nuke and RV integration was broken. An image or video could not be
played in RV.

### Describe what you have tested and on which operating system.
Rocky Linux 8

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…Foundation#718)

### Feature/qt6 - Support both Qt 5 and Qt 6 in rvcmd.sh

### Linked issues
n/a

### Summarize your change.
I added checks to detect existing installations of Qt 5 or Qt 6. The
search prioritise Qt 6 over Qt 5.
Once Qt is found, the script set the right variables for the aliases. 

If QT_HOME is already set, I added a check to detect if it is Qt 5 or Qt
6.

Note that the logic only look for `Qt*` and either `5.15*` or `6.5*` in
the path. The script is not looking at the actual libraries files.

### Describe the reason for the change.
rvcmd.sh had to be reworked to support both Qt 5 and Qt 6.

### Describe what you have tested and on which operating system.
Rocky Linux 8

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
pbergeron-adsk and others added 15 commits March 19, 2025 08:58
…ion#714)

This fixes SG-36654 SG-36655 SG-36656 

### Summarize your change.

Added a method to filter out some Qt messages that are known/harmless
warnings.

One such warning had Qt reporting a warning about a scroll event
occuring from a HID device whenever it was connected/disconnected/kvm'd.
This appears to be fixed with Qt 6.6.3 but we are at 6.5.3, so we shut
it up.

Another such warning was about a Qt handler for a type conversion
already registered (but when initializing PyQt it was tried to be
initialized again), etc.

### Describe the reason for the change.

Pollutes the console window needlessly with harmless warnings which are
Qt bugs that were later fixed.

### Describe what you have tested and on which operating system.

macOS and Linux.

### Add a list of changes, and note any that might need special
attention during the review.

### If possible, provide screenshots.

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
Co-authored-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
…BO (AcademySoftwareFoundation#721)

### Summarize your change.

This is an initial code fix while debugging and fixing SG-25296 (can't
use 2nd monitor desktop window as presentation device on macOS M
computers). This change does NOT Fix the issue (we still get a black
screen) but during the port to Qt6, we introduced a change that deleted
the current FBO in the current OpenGL context (a GLFBO class destroyed a
FBO object that was owned by Qt, not by GLFBO) and made the GLView class
unstable. This fix only addresses the incorrect OpenGL FBO destruction
that occurs after exiting presentation mode.

More concretely: GLFBO has 2 constructors: one where a FBO object is
created using glGenFramebuffersEXT (in which case the GLFBO instance
owns the FBO) and another one where the FBO handle is passed as an
argument to the constructor (in which case the GLFBO instance does not
own the FBO). Upon calling the destructor, any non-zero handle was
destroyed, but since the non-owned FBOs actually belonged to Qt, we
ended up corrupting the current OpenGL context because it no longer had
a rendering surface to render onto. To fix this, I have just added a
bool member to GLFBO to guide what happens in the GLFBO destructor.

Also, while investigating this issue, I noticed that several places
missed a call to the de debug macro TWK_GLDEBUG, so I have added them.

Finally, I updated the formatting of the error log for gl errors, which
was overly verbose.

### Describe the reason for the change.

After exiting 2nd-monitor-desktop presentation mode, the OpenGL context
got scrapped because an FBO object was mistakenly destroyed, which
caused RV to stop displaying content until the view got resize/recreated
with new FBOs.

### Describe what you have tested and on which operating system.

macOS. Should work just the same on other platforms.

### Add a list of changes, and note any that might need special
attention during the review.
n/a

### If possible, provide screenshots.
n/a

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
…Foundation#724)

### Feature/qt6 - Clean up code in QTAudioRenderer class

### Linked issues
n/a

### Summarize your change.
Removed #ifdef related to RV_VFX_CY2023 since they are not needed in
QTAudioRenderer class (QT5AudioRenderer is used for CY2023).

### Describe the reason for the change.
Clean up code to make it more readable.

### Describe what you have tested and on which operating system.
Rocky Linux 8

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Feature/Qt6 - Rebase to main

### Linked issues
n/a

### Summarize your change.
I cherry-picked the missing commits from main.

1. [Fix the failing readthedocs
build](AcademySoftwareFoundation@5c54a9c)

2. [Fix network issue with rvnuke
plugin](AcademySoftwareFoundation@eeae944)
(No changes because the fix was already in the feature/qt6 branch)

3. [712: Adapt build to latest MSYS2
release](AcademySoftwareFoundation@ead6e53)

4. [Fix MMR support in OTIO
reader](AcademySoftwareFoundation@1da73a9)

### Describe the reason for the change.
Get the latest changes from the main branch.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
### Feature/qt6 - rebase to main

### Linked issues
n/a

### Summarize your change.
The rebase only include the PNG changes, but I want to get it right away
in the feature/qt6 branch since it is affecting performance.

### Describe the reason for the change.
Rebase

### Describe what you have tested and on which operating system.

### Add a list of changes, and note any that might need special
attention during the review.

### If possible, provide screenshots.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Feature/qt6 - Rebase

### Linked issues
n/a

### Summarize your change.
Rebase the branch to main

### Describe the reason for the change.
Rebase the branch to main and this is needed to fix a build issue with
PR AcademySoftwareFoundation#741

---------

Signed-off-by: Ken McGaugh <ken@mcgaugh.co.uk>
Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: kenmcgaugh <ken@mcgaugh.co.uk>
Co-authored-by: kenmcgaugh <ken@mcgaugh.co.uk>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
…twareFoundation#741)

### Feature/qt6 - Fix issue with multiple_source_media_rep.py

### Linked issues
n/a

### Summarize your change.
Call QAction() from QtGui.

### Describe the reason for the change.
QAction() was moved to QtGui

### Describe what you have tested and on which operating system.
Rocky linux 8

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…reFoundation#745)

### Feature/qt6 - Fix issue with icons in file open dialog

### Linked issues
n/a

### Summarize your change.
For Qt 6. I added more heuristics to find the right icon using the MIME
type.

### Describe the reason for the change.
All files were using the text-generic icon in the file open dialog.

### Describe what you have tested and on which operating system.

### Add a list of changes, and note any that might need special
attention during the review.

### If possible, provide screenshots.

**Before:**

![before_icon](https://github.com/user-attachments/assets/d0e99618-aa9a-49c0-8a67-8eae57bebe97)

**After:**

![after_icon](https://github.com/user-attachments/assets/fef831e9-2cdc-4df6-ba65-947bc6a3bff0)

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
### Feature/Qt6 - Rebase to main

### Linked issues
n/a

### Summarize your change.
Rebase to main

b3aa898
81b918f
b13dc6d

### Describe the reason for the change.
Rebase to main

---------

Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Ken McGaugh <ken@mcgaugh.co.uk>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
Co-authored-by: kenmcgaugh <ken@mcgaugh.co.uk>
…on#752)

### Feature/Qt6 - Small tweak of the audio logic

### Linked issues
n/a

### Summarize your change.
I removed the conditions to check the state of the QAudioSink object
because it does not make sense in Qt 6. In Qt 6, when we call the `start
`method on the QAudioSink object, The code starts transferring audio
data from the device to the system's audio output right away and changes
the device state afterwards (while in Qt 5, the state was changed first,
and then the audio data was read). Therefore, it does not make sense to
check the state in the `readData` callback because even if the state is
STOPPED, we want to start reading the audio data.

The audio cache/processing seems to behave just like the main branch
with those changes. I tested it on Windows and MacOS.


### Describe the reason for the change.
Fix audio on Windows and the new logic makes more sense based on how Qt
6 works now.

### Describe what you have tested and on which operating system.
Windows and MacOS

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…demySoftwareFoundation#754)

### Finalize port of QTabletEvent to Qt6 and fix tablet eraser issue

### Linked issues

NA

### Describe the reason for the change.

@cedrik-fuoco-adsk had already did the bulk of the work to port the
QTTranslator from Qt5 to Qt6 but the QTabletEvent needed some attention
because of the Qt6 refactoring with respect to its events handling.

### Summarize your change.

**TabletDevice and TabletKind were removed**

Rationale:
In RV, when handling a table event, we used to record the TabletDevice
(ie stylus) and the TabletKind (ie pen or eraser) in the RV's TableEvent
class.
In Qt6, QTabletEvent::FourDMouse and QTabletEvent::RotationStylus have
been removed and replaced with QInputDevice::DeviceType::Puck and
QInputDevice::DeviceType::Stylus respectively.
So technically we would have had to create Qt version specific enums of
TabletDevice and TabletKind.
However, they were NOT used anywhere. Note that the important part is
the name of the event like for example "stylus-pen--drag". This is what
packages such as annotation_mode.mu use to act on tablet events.
By getting rid of TabletDevice and TabletKind altogether in the RV
codebase, we were able to minimize the differences between Qt5 and Qt6
with respect to Tablet Events.

**Added all the Qt6 supported in options for tablet device type and
tablet pointer type**

Also in this commit:

**Fixed a legacy issue when using a tablet's stylus eraser and going
pack to the pen:**
When using the eraser, the code was correctly switching to the eraser
mode but when the user was selecting the pen again, it was not
automatically switching to the pen mode, it was still erasing.

### Describe what you have tested and on which operating system.

Successfully tested on macOS with a Wacom Intuos tablet

### Add a list of changes, and note any that might need special
attention during the review.

### If possible, provide screenshots.

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
### Rebase to main

### Linked issues
n/a

### Summarize your change.
Rebase to main: 
410dae8

---------

Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
### Summarize your change.

Note: This is a test PR for internal Autodesk review that needs to
undergo testing.

This PR aims to dramatically improve the loading time of playlists,
especially online playlists, which was quite painful for customers,
sometimes having to wait several minutes. For example, on my
workstation, loading a playlist of 250 clips went from 3-4 minutes to
about 10 seconds, which is pretty nice improvement.

Some years ago, RV introduced "progressive source loading" which aimed
to achieve a similar result, but caused lots of unintended support
issues, like scrips not working well and some random crashes sometimes,
and other side effects. This PR is *not* an attempt to improve
progressive loading, which had fundamental flaws, instead we use a
different technique altogether.

Several changes were made in order to achieve this, but first, it's
worthwhile to describe the cause of the issue to understand the fix.

The reason for the slowness is because after we receive the playlist
(the list or URLs) we must create the RV graph, for which we create one
FileSourceIPNode per movie, sequentially, in the main thread. For each
FileSourceIPNode created sequentially, we must open the movie header (to
get the number of frames, framerate, duration, etc) by calling
FileSourceIPNode::openMovie(), eventually calling upon libav (ffmpeg),
which initiates an http request (with cookies and headers), sends the
request, downloads the response and the data, and then can open the
movie's header. Unfortunately, doing this over the network, one file at
a time, causes RV to block on I/O while the shotgrid server is serving
only a single request. To give a rough idea, for a single clip, that
network lag is about 0.5-to-1.0 seconds as I measured it, so multiply
that by 250 and you've got "several minutes".

Obviously, the shotgrid server can handle multiple concurrent requests
at once, so we simply decided to create a preloader which loads all 250+
file headers in the background, using up to 32 concurrent threads to
issue those http requests. In other words, the idea is to parallelize
the I/O waiting time, hopefully by a factor of "up to" 32.

So while the preloader is doing all of this work (well, waiting, mostly)
in the background, the RV graph gets created in the main thread, just as
before. But, by the time FileSourceIPNode::openMovie gets called --
lo-and-behold! -- the movie's header has already been opened (or so
we're hoping) so the call completes almost immediately without having to
pay that 0.5-to-1.0 second lag time.

Unfortunately, there's some post-fixup stuff going on after we load a
clip, which causes RV to still need to spend about 0.05 second per node,
but still, it's a much better outcome than before.

Another performance bug was fixed in this PR: we're no longer paying a
O(n^2) (maybe O(n^3)?) loop on trying to determine if the UI name of a
clip already exists, by searching for an existing name in the RV graph
(which is NOT free), and instead we have an O(1) algorithm to figure out
the next UI name for a node in case there's a duplicate.

Other little fixes were done here and there, but the crux of the problem
is solved using the above approach, with other details provided herein
below.


### Describe the reason for the change.

Loading long playlists was unusably slow; it was time to improve this
for customers especially for the purpose of collaborative review.

### Describe what you have tested and on which operating system.

I tested this on my Mac. When logged in shotgrid, I select a playlist of
250 clips, right-click, and then "play in RV".

Also, using the Live Review workflow on shotgrid, we join a session in
RV, and the clips load way faster than before, although this has made us
uncover other issues we need to debug/fix separately.


### Add a list of changes, and note any that might need special
attention during the review.

**NOTE: For QA testing, please check that this continues to work as
before even for static files or image sequences, even though we may not
benefit much from preloading speed in some cases.**


A few things to mention here.

**(1) New methods to MovieReader's public API**

The class MovieReader's base public interface was modified to add two
new methods, and all MovieReader-derived classes must implement two new
functions:

- preloadOpen() -- which gets executed in the background to open the
movie file.
- postPreloadOpen() -- which gets executed in the main thread to perform
work done in the FileSourceIPNode's current loading context at node
creation.

Implementing the above two functions is actually quite easy -- you
basically just need to break in two what was previously done in the
open() methods. All of this is documented at length in MovieReader.h so
if you're interested you may read the comments there.

When we did this for MovieFFMpegReader, it turns out that there's a
thread-unsafe method that we would have liked to put in preloadOpen().
Indeed, findStreamInfo() calls libav's avformat_find_stream_info() which
_should_ be thread safe but isn't, and causes crashes when called
concurrently. I haven't debugged this (yet?) but it's a long-time bug
that was first reported like 15 years ago, but apparently remains, and I
provided a link to one of the places I found online that mentions the
issue (as a side note, it might have been a cause for random crashes
with progressive loading years ago). In any case, the crashes went away
when I moved findStreamInfo() to postPreloadOpen() (which is serialized
and executed in the main thread) just like before.

**(2) You may not like the way the background thread scheduler works.**

It's perhaps possible that the background thread management and reader
scheduler is a bit overly complex, although it's still a relatively
simple thing overall. Nevertheless, it might be a worthwhile exercise to
use a thread pool with each thread in the pool having a queue, instead
of a thread scheduler that dispatches one new thread whenever we have
pending files to read. While a thread pool has the benefit of reusing
threads, all threads remain in existence (but paused) after everything
is done loading, consuming some memory and resources. On the other hand,
my current approach launches/ends one thread per movie, and the thread
ends when the movie's done reading, thus releasing the thread memory
after the movie's header is read. We also maybe could have used a thread
pool library, like the one provided by boost, but, at this time this
custom code works well enough as it is, and it's tweakable to try new
things, so why not.

**(3) Finding the next UI Name is done is a super simple helper class
called UINameCache**

It is found in Session.h, and simply maintains a counter to a root name,
and every time "nextUIName" is called, the counter increments. While
this is a super simple solution to an O(N^2-or-3) problem, it does have
slightly different behavior than before, which is also documented in the
header file. These differences in behavior were discussed at length with
Bernie, and we're ok with the changes.

**(4) There's a function called lookupFilenameInMediaLibrary which has
moved.**

This is a function that not just gets the filename in the media library,
but also fetches the cookies and headers used to create the http request
(otherwise, fetching the file via http will fail due to not having
session cookies).

The method used to be in FileSourceIPNode, but it's been moved to a
namespace that is accessible by the preloader. It used no special member
of FIleSourceIPNode, and mostly static functions at that, so it was easy
to move elsewhere; it was mostly copy/pasted from one spot to another.

**(5) You may be wondering why some "if()" statements are now like "if
(( ))"**
This is because of an assignment within the if statement. By adding a ()
around the assignment, the compiler doesn't complain about the if
statement and doesn't issue a warning. I got tired of looking at the
same verbose warnings constantly.

### If possible, provide screenshots.

No screenshot to provide, but, you may imagine in your head a picture of
a coffee mug with more coffee in it than before, by the time the
playlist is done loading.

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
)

### Feature/qt6 - Merge main into feature/qt6

### Linked issues
n/a

### Summarize your change.
Executed a `git merge main` and I fixed some issues in the MuQt6
templates discovered during the merge due to the clang formatting.

---------

Signed-off-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Ben Chamberland <becha9260@gmail.com>
Signed-off-by: paulbarton90 <28630076+paulbarton90@users.noreply.github.com>
Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Signed-off-by: Will Wira <4399853+williamwira@users.noreply.github.com>
Signed-off-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: mcoms <mastercoms@tuta.io>
Signed-off-by: Mirco Tornow <mirco.tornow@outlook.com>
Signed-off-by: Christopher Lee <christophercarlos.lee@gmail.com>
Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
Signed-off-by: Ken McGaugh <ken@mcgaugh.co.uk>
Signed-off-by: kenmcgaugh <ken@mcgaugh.co.uk>
Co-authored-by: Éloïse Brosseau <54746458+eloisebrosseau@users.noreply.github.com>
Co-authored-by: Ben Chamberland <85132405+chxmberland@users.noreply.github.com>
Co-authored-by: Paul Barton <28630076+paulbarton90@users.noreply.github.com>
Co-authored-by: Éloïse Brosseau <eloise.brosseau@autodesk.com>
Co-authored-by: Bernard Laberge <117092886+bernie-laberge@users.noreply.github.com>
Co-authored-by: williamwira <4399853+williamwira@users.noreply.github.com>
Co-authored-by: mcoms <mastercoms@tuta.io>
Co-authored-by: Mirco Tornow <mirco.tornow@outlook.com>
Co-authored-by: Bernard Laberge <bernard.laberge@autodesk.com>
Co-authored-by: Chris <34953610+chrisc-lee@users.noreply.github.com>
Co-authored-by: pbergeron-adsk <patrick.bergeron@autodesk.com>
Co-authored-by: kenmcgaugh <ken@mcgaugh.co.uk>
…AcademySoftwareFoundation#736)

### Describe the reason for the change.

With the port to Qt6/QOpenGLWidget, the DesktopVideoDevice
implementation was broken for all platforms (macOS, Linux, Windows).
This is a long-time desired fix, since on Apple-Silicon macOS Arm64,
DesktopPresentationDevice was broken for over 3 years.

This PR aims to restore desktop presentation device functionality, by
using the common Qt path to open a full-screen desktop window on the
target screen. This was the path taken for Windows and Linux, but for
macOS, there was a special CGDesktopVideoDevice, which used Apple's
CoreGraphics API to achieve this.



### Summarize your change.

This PR contains a surprisingly large amount of code changes to restore
this functionality using QOpenGLWidget. The main difference is that
where QGLWidget used the default BackBuffer to render to screen (GL FBO
id 0), this is no longer allowed using QOpenGLWidget, which exclusively
uses off-screen FBOs to render the view. Previous RV code made many,
many assumptions about when it was safe to use FBO 0, and this was the
root cause of the problem. The other major cause was that during RV's
rendering of the session, the temporary FBOs created for the presenation
device were created in the wrong OpenGL context. Somehow, this used to
"work" in the old implementation (presumably because we were rendering
to FBO 0 so it didn't matter) but when we started using actual
off-screen FBOs, the FBO for the external desktop view never had any
content rendered to it.

Thus, the approach taken for this fix are as follows:

0) In RV main for macOS, Added setAttribute to allow accessing GL from
different threads. This was enabled for Windows and Linux for the QT
path, so we also need it.

1) Since we decided to use the Qt path for the core technology to render
to another full-screen display, I merged the relevant (specialized) code
from class QTDesktopPresentationDevice back into class
DesktopPresentationDevice.

2) The QTDesktopVideoDevice (or was it DesktopVideoDevice?)'s bind() and
bind2() methods were removed, which was causing the FBOs to be created
in the wrong opengl context. This legacy code caused a very mysterious
issue where the FBO to blit to the external screen was always empty.
This is because the FBO for the screen was created in the wrong context.
Fwiw, no other external video device overrode bind() and bind2()
either... not sure why this was ever done in the first place.

3) In DesktopVideoModule, we checked the 3 platforms and added
platform-specific code to enumerate and instantiate the proper
DesktopVideoDevices. This enumeration/instantiation code was moved the
various implementations of the VideoDevice classes (DesktopVideoDevice,
CGDesktopVideoDevice - no longer used for now, CGDesktopVideoDeviceArm -
no longer used for now, but soon)

4) On macOS, showng the rendered framebuffer on the screen was done
using some kind of janky multi-threaded swapbuffer kludge. That kludge
was completely removed, and besides, we don't use swapBuffer anymore --
it's not allowed with QOpenGLWidget - we simply force the QOpenGLWidget
to repaint itself in the main thread after the transfer function is
called. (See SyncBufferThreadData stuff that was removed in GLView)

5) An important, but subtle new implementation note, has to do with
changes to GLFBO, which has 2 constructors: The first one, where an FBO
is explicitly created at resolution width/height, and with its own pixel
buffer (aka render buffer), and the Second, where an GLFBO is created to
attach to a video device, which was originally thought to output to a
"default" framebuffer (aka: FBO 0, the GL backbuffer directly, which is
not allowed anymore). In an early version of the FeatureQt6, the id of
the FBO was take from the OpenGL Current context, but, this was
incorrect. The real solution is that the id of the GLFBO, when created
with constructor 2, is in fact the ID of the FBO owned by the
QOpenGLWidget attached to the VideoDevice. It is NOT the id of the
current context (which happened to work when there was no
DesktopVideoDevice). Therefore, I updated "GLFBO::fboId()", to not
return m_id, but to return the id of the QOpenGLWidget's fbo id. It's
important to always query the view, because the QOpenGLWidget's fbo id
might actually be recycled/changed if the view is changed/resized/etc.
Querying the ID of the widget's fbo follows the same patter as asking
for the width/height of the fbo when using the constructor 2.

6) At the moment, the DesktopVideoModule initialization method is still
a bit janky. You'll see this with some code that checks which platform
we're running on, even though we now we always instantiate the
DesktopVideoDevice class (the same Qt class). I've left this
platform-checking code because It will be required anyway to fix 25296
properly, and I'll clean that a bit better for that PR, see the note
below.

7) As part of this work, I had to implement debugging tools to see what
was going on with the state of the current openGL context, and the state
of the currently bound FBO. In GL.cpp, I've implemented an OpenGL
Context Tracker, which is updated every time the TWK_GLDEBUG; macro is
invoked. This tracker will query the opengl state and currently bound
context, and will report any changes to the currently bound opengl
state. I could have destroyed this code, but I thought it would be
helpful in the future, so I've left it in GL.cpp but deactivated it
through a #define.

PLEASE NOTE: 

This PR is mainly a fix for 38492-Broken-on-all-platforms and thus
successfully restores functionality on macOS (25296).

However we do lose a bit of functionality on macOS versus the old RV --
in particular the ability to select the target screen's resolution and
change the screen's resolution when activating presentation mode
(because we use the Qt path instead of the CoreGraphics path). A lot of
code in this PR is necessary to fully implement 25296, and since I was
working on both at the same time, some of the code serving as groundwork
to fully fix 25296 is included in this PR, but I've decided to break it
into 2 PRs.

(That groundwork code is found in CGDesktopVideoDevice.cpp and
CGDesktopVideoDeviceArm.cpp)

### Describe what you have tested and on which operating system.

**I have tested this on macOS, but testing on Windows and Linux is
needed.**

I also suspect that the Stereo or Quad mode remains broken. But since I
have no way to test this. I will create another Jira ticket to address
this.


### Add a list of changes, and note any that might need special
attention during the review.

As per above, we need to test this functionality EXTENSIVELY, on all
platforms.

For MacOS, support for DisplayLink was removed, however DisplayLink may
already be transparently taken care of using the Qt implementation of
the DesktopVideoDevice. (I have no way to test this). Even if this does
not work, Bernard approved its sacrifice.


### If possible, provide screenshots.

---------

Signed-off-by: Patrick Bergeron <patrick.bergeron@autodesk.com>
bernie-laberge pushed a commit that referenced this pull request May 5, 2025
This is the first phase of the Qt 6 port. It was mostly tested on Rocky
Linux 8.

There are a lot of generated files under `src/lib/mu/MuQt6`, and some
modifications but you don't need to go over that folder.

There are known issues that will be addressed in future PR:

**All platforms:**
- Refactor _QtAudioRenderer_ class. Currently, The _pulse_ audio output
device is not enabled, and they are loud white noise issues on MacOS.
- Remove the usage of _Core5compat_ and refactor what is deprecated. I
don't think there is a lot to do here, but it is mostly about refactor
the usage of _QTextCodec_.

**MacOS:**
- The _Open File dialog_ does not open anymore.
- Loud white noise audio (Should be related to _QtAudioRenderer_)
- The Central widget is rendered in the bottom left corner, but as soon
as you resize the windows, it goes back to normal.

**Windows:**
- Issue with the compilation of Shiboken6

- [ ] Rocky LInux 8
- [ ] MacOS

attention during the review.

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
bernie-laberge pushed a commit that referenced this pull request Feb 23, 2026
…ftwareFoundation#1122)

### Fix crash calling sourcesAtFrame at session clear.

### Summarize your change.

If sourcesAtFrame is called in an event from which the graph is cleared
(`graph-node-inputs-changed` in my case, but it could be anything that
clears the graph), RV will crash with a stack resembling the below:
```
* thread #1, name = 'RV Main', queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x793bcc0f30f4744a)
  * frame #0: 0x00000001003e8688 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a96080780, c=0x000000016fdf6290, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31
    frame #1: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a96080a00, context=0x000000016fdf6290, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame #2: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a96074000, context=0x000000016fdf6290, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame #3: 0x00000001007d5eb0 RV`IPCore::RetimeIPNode::metaEvaluate(this=0x0000000a96074000, context=0x000000016fdf6378, visitor=0x000000016fdf6c40) at RetimeIPNode.cpp:661:17
    frame AcademySoftwareFoundation#4: 0x00000001007e1790 RV`IPCore::StackIPNode::metaEvaluate(this=0x0000000a94a2f100, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at StackIPNode.cpp:791:25
    frame AcademySoftwareFoundation#5: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a9320d500, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame AcademySoftwareFoundation#6: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf2080, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25
    frame AcademySoftwareFoundation#7: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94774a00, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31
    frame AcademySoftwareFoundation#8: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94cf8c80, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31
    frame AcademySoftwareFoundation#9: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0500, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25
    frame AcademySoftwareFoundation#10: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a8cd01500, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame AcademySoftwareFoundation#11: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a95bf0280, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame AcademySoftwareFoundation#12: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0a00, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25
    frame AcademySoftwareFoundation#13: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94cf8780, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31
    frame AcademySoftwareFoundation#14: 0x00000001003f4a40 RV`IPCore::DisplayStereoIPNode::metaEvaluate(this=0x0000000a95437480, context=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at DisplayStereoIPNode.cpp:393:20
    frame AcademySoftwareFoundation#15: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a947bd180, c=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31
    frame AcademySoftwareFoundation#16: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a95b96800, context=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame AcademySoftwareFoundation#17: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0f00, c=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25
    frame AcademySoftwareFoundation#18: 0x00000001003ee27c RV`IPCore::DisplayGroupIPNode::metaEvaluate(this=0x0000000a93e41500, context=0x000000016fdf6bb8, visitor=0x000000016fdf6c40) at DisplayGroupIPNode.cpp:425:21
    frame AcademySoftwareFoundation#19: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a94774780, context=0x000000016fdf6bb8, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23
    frame AcademySoftwareFoundation#20: 0x00000001006ce2b4 RV`IPMu::sourcesAtFrame(node_=0x000000013a849440, thread_=0x0000000117748e00) at CommandsModule.cpp:1937:28
    frame AcademySoftwareFoundation#21: 0x0000000100e7a890 RV`Mu::DynamicArrayType::nodeEval(this=0x00000001176fcdc0, n=0x000000013a849440, thread=0x0000000117748e00) const at DynamicArrayType.cpp:78:90
    frame AcademySoftwareFoundation#22: 0x0000000100076e80 RV`Mu::Node::eval(this=0x000000013a849440, t=0x0000000117748e00) const at Node.cpp:142:62
    frame AcademySoftwareFoundation#23: 0x00000001000a92ac RV`Mu::Thread::call(this=0x0000000117748e00, f=0x0000000117e86d20, args=size=1, returnArguments=false) at Thread.cpp:422:23
    frame AcademySoftwareFoundation#24: 0x00000001001d2e2c RV`TwkApp::MuSymbol_call(_self=0x000000011b52a7f0, args=0x000000030a0d8bb0, kwds=0x0000000000000000) at PyMuSymbolType.cpp:389:48
    frame AcademySoftwareFoundation#25: 0x0000000108d17350 libpython3.11.dylib`_PyObject_MakeTpCall(tstate=0x00000001090a3c30, callable=0x000000011b52a7f0, args=<unavailable>, nargs=<unavailable>, keywords=0x0000000000000000) at call.c:214:18 [opt]
    frame AcademySoftwareFoundation#26: 0x0000000108d17850 libpython3.11.dylib`PyObject_Vectorcall [inlined] _PyObject_VectorcallTstate(tstate=<unavailable>, callable=<unavailable>, args=<unavailable>, nargsf=<unavailable>, kwnames=<unavailable>) at pycore_call.h:90:16 [opt] [artificial]
    frame AcademySoftwareFoundation#27: 0x0000000108df4dc0 libpython3.11.dylib`_PyEval_EvalFrameDefault(tstate=<unavailable>, frame=0x000000010a6f01d8, throwflag=<unavailable>) at ceval.c:0 [opt]
    frame AcademySoftwareFoundation#28: 0x0000000108df05fc libpython3.11.dylib`_PyEval_Vector [inlined] _PyEval_EvalFrame(tstate=0x00000001090a3c30, frame=0x000000010a6f01d8, throwflag=0) at pycore_ceval.h:73:16 [opt]
    frame AcademySoftwareFoundation#29: 0x0000000108df05ec libpython3.11.dylib`_PyEval_Vector(tstate=0x00000001090a3c30, func=<unavailable>, locals=<unavailable>, args=<unavailable>, argcount=<unavailable>, kwnames=<unavailable>) at ceval.c:6434:24 [opt]
    frame AcademySoftwareFoundation#30: 0x0000000108d19f24 libpython3.11.dylib`method_vectorcall [inlined] _PyObject_VectorcallTstate(tstate=0x00000001090a3c30, callable=0x000000013792e7a0, args=0x000000016fdf7ab0, nargsf=<unavailable>, kwnames=0x0000000000000000) at pycore_call.h:92:11 [opt]
    frame AcademySoftwareFoundation#31: 0x0000000108d19efc libpython3.11.dylib`method_vectorcall(method=<unavailable>, args=0x000000030a0d8268, nargsf=<unavailable>, kwnames=0x0000000000000000) at classobject.c:89:18 [opt]
    frame AcademySoftwareFoundation#32: 0x00000001001cf9d4 RV`TwkApp::PyFunctionAction::execute(this=0x0000000a8fade490, d=0x0000000a912c6000, event=0x000000016fdf7f28) const at PyFunctionAction.cpp:58:17
    frame AcademySoftwareFoundation#33: 0x00000001006612a8 RV`TwkApp::Document::executeAction(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Document.cpp:486:20
    frame AcademySoftwareFoundation#34: 0x0000000100661b7c RV`TwkApp::Document::receiveEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Document.cpp:613:9
    frame AcademySoftwareFoundation#35: 0x000000010066fc38 RV`TwkApp::EventNode::propagateEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at EventNode.cpp:71:13
    frame AcademySoftwareFoundation#36: 0x00000001001ecd94 RV`IPCore::Session::propagateEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Session.cpp:4644:43
    frame AcademySoftwareFoundation#37: 0x000000010066fca8 RV`TwkApp::EventNode::propagateEvent(this=0x0000000a909c9800, event=0x000000016fdf7f28) at EventNode.cpp:82:24
    frame AcademySoftwareFoundation#38: 0x000000010066fc00 RV`TwkApp::EventNode::sendEvent(this=0x0000000a909c9800, event=0x000000016fdf7f28) at EventNode.cpp:60:16
    frame AcademySoftwareFoundation#39: 0x000000010038b604 RV`IPCore::IPGraph::inputsChanged(this=0x0000000a909c9800, n=0x0000000a8d8b2800) at IPGraph.cpp:3449:13
    frame AcademySoftwareFoundation#40: 0x000000010027af8c RV`IPCore::IPNode::setInputs(this=0x0000000a8d8b2800, nodes=size=0) at IPNode.cpp:303:26
    frame AcademySoftwareFoundation#41: 0x0000000100279c4c RV`IPCore::IPNode::removeInput(this=0x0000000a8d8b2800, n=0x0000000a94a30500) at IPNode.cpp:166:13
    frame AcademySoftwareFoundation#42: 0x000000010027984c RV`IPCore::IPNode::~IPNode(this=0x0000000a94a30500) at IPNode.cpp:57:32
    frame AcademySoftwareFoundation#43: 0x000000010040c900 RV`IPCore::GroupIPNode::~GroupIPNode(this=0x0000000a94a30500) at GroupIPNode.cpp:48:5
    frame AcademySoftwareFoundation#44: 0x0000000100807490 RV`IPCore::SwitchGroupIPNode::~SwitchGroupIPNode(this=0x0000000a94a30500) at SwitchGroupIPNode.cpp:42:5
```
Notice the destructors are triggering a sourcesAtFrame call, which then
tries to access those same objects being destroyed resulting in a
use-after-free crash.

To fix this, we'll set a guard when the graph is being cleared, and if
sourcesAtFrame is called when the guard is set, we'll return an empty
array. This is the as what would happen if you called sourcesAtFrame
when there were no sources (ie after the graph was cleared). So we'll
just return the eventual result early, which is likely what the users
want anyway, and this will protect python events from crashing RV.

### Describe the reason for the change.

Prevent crashes

### Describe what you have tested and on which operating system.

Mac OS 26.2

---------

Signed-off-by: Roger Nelson <roger.nelson@autodesk.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants