Merge pull request #9435 from norihiro/qtdisplay-destroy-at-surface-event-3

Fix crash at render_display while shutdown on macOS
This commit is contained in:
Lain authored and GitHub committed 2023-08-15 15:49:54 -07:00
commit fee4f2dc48
3 files changed
+24 -45

No files matched your search

+7 -39
View File
@@ -13,15 +13,11 @@
#include <Windows.h>
#endif
#ifdef ENABLE_WAYLAND
#include <obs-nix-platform.h>
class SurfaceEventFilter : public QObject {
OBSQTDisplay *display;
int mTimerId;
public:
SurfaceEventFilter(OBSQTDisplay *src) : display(src), mTimerId(0) {}
SurfaceEventFilter(OBSQTDisplay *src) : display(src) {}
protected:
bool eventFilter(QObject *obj, QEvent *event) override
@@ -35,22 +31,12 @@ protected:
static_cast<QPlatformSurfaceEvent *>(event);
switch (surfaceEvent->surfaceEventType()) {
case QPlatformSurfaceEvent::SurfaceCreated:
if (display->windowHandle()->isExposed())
createOBSDisplay();
else
mTimerId = startTimer(67); // Arbitrary
break;
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
display->DestroyDisplay();
break;
default:
break;
}
break;
case QEvent::Expose:
createOBSDisplay();
break;
default:
break;
@@ -58,25 +44,8 @@ protected:
return result;
}
void timerEvent(QTimerEvent *) override
{
createOBSDisplay(display->isVisible());
}
private:
void createOBSDisplay(bool force = false)
{
display->CreateDisplay(force);
if (mTimerId > 0) {
killTimer(mTimerId);
mTimerId = 0;
}
}
};
#endif
static inline long long color_to_int(const QColor &color)
{
auto shift = [&](unsigned val, int shift) {
@@ -130,11 +99,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
connect(windowHandle(), &QWindow::visibleChanged, windowVisible);
connect(windowHandle(), &QWindow::screenChanged, screenChanged);
#ifdef ENABLE_WAYLAND
if (obs_get_nix_platform() == OBS_NIX_PLATFORM_WAYLAND)
windowHandle()->installEventFilter(
new SurfaceEventFilter(this));
#endif
windowHandle()->installEventFilter(new SurfaceEventFilter(this));
}
QColor OBSQTDisplay::GetDisplayBackgroundColor() const
@@ -157,12 +122,15 @@ void OBSQTDisplay::UpdateDisplayBackgroundColor()
obs_display_set_background_color(display, backgroundColor);
}
void OBSQTDisplay::CreateDisplay(bool force)
void OBSQTDisplay::CreateDisplay()
{
if (display)
return;
if (!windowHandle()->isExposed() && !force)
if (destroying)
return;
if (!windowHandle()->isExposed())
return;
QSize size = GetPixelSize(this);
+7 -2
View File
@@ -12,6 +12,7 @@ class OBSQTDisplay : public QWidget {
SetDisplayBackgroundColor)
OBSDisplay display;
bool destroying = false;
virtual void paintEvent(QPaintEvent *event) override;
virtual void moveEvent(QMoveEvent *event) override;
@@ -37,8 +38,12 @@ public:
QColor GetDisplayBackgroundColor() const;
void SetDisplayBackgroundColor(const QColor &color);
void UpdateDisplayBackgroundColor();
void CreateDisplay(bool force = false);
void DestroyDisplay() { display = nullptr; };
void CreateDisplay();
void DestroyDisplay()
{
display = nullptr;
destroying = true;
};
void OnMove();
void OnDisplayChange();
+10 -4
View File
@@ -5128,6 +5128,16 @@ void OBSBasic::closeEvent(QCloseEvent *event)
closing = true;
/* While closing, a resize event to OBSQTDisplay could be triggered.
* The graphics thread on macOS dispatches a lambda function to be
* executed asynchronously in the main thread. However, the display is
* sometimes deleted before the lambda function is actually executed.
* To avoid such a case, destroy displays earlier than others such as
* deleting browser docks. */
ui->preview->DestroyDisplay();
if (program)
program->DestroyDisplay();
if (outputHandler->VirtualCamActive())
outputHandler->StopVirtualCam();
@@ -5154,10 +5164,6 @@ void OBSBasic::closeEvent(QCloseEvent *event)
delete extraBrowsers;
ui->preview->DestroyDisplay();
if (program)
program->DestroyDisplay();
config_set_string(App()->GlobalConfig(), "BasicWindow", "DockState",
saveState().toBase64().constData());