From f1cf3ff1419fcca27652e169add07f1fe1bb776e Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Fri, 29 Jul 2022 20:31:13 +0200 Subject: [PATCH] UI: Fix Qt call on UI thread from graphics thread Calling `devicePixelRatioF` from any thread but the main UI thread triggers thread-safety warnings at runtime on macOS, because Qt uses NSView calls to determine the value. NSView calls are only allowed to be made from the main thread on macOS, so instead the value is stored as a property of the OBSQTDisplay at initialization, to be retrieved from the preview object later. Static functions that do not have access to the preview object have the pixel ratio passed in their call signature. --- UI/window-basic-main.cpp | 7 +++++++ UI/window-basic-main.hpp | 4 ++++ UI/window-basic-preview.cpp | 42 ++++++++++++++++++------------------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index be17dceda..7a7c6755c 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -319,7 +319,9 @@ OBSBasic::OBSBasic(QWidget *parent) ResizePreview(ovi.base_width, ovi.base_height); UpdateContextBarVisibility(); + dpi = devicePixelRatioF(); }; + dpi = devicePixelRatioF(); connect(windowHandle(), &QWindow::screenChanged, displayResize); connect(ui->preview, &OBSQTDisplay::DisplayResized, displayResize); @@ -10241,3 +10243,8 @@ void OBSBasic::UpdatePreviewSpacingHelpers() drawSpacingHelpers = config_get_bool( App()->GlobalConfig(), "BasicWindow", "SpacingHelpersEnabled"); } + +float OBSBasic::GetDevicePixelRatio() +{ + return dpi; +} diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 90374c3be..a5fb80636 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -636,6 +636,8 @@ private: void UpdatePreviewSpacingHelpers(); bool drawSpacingHelpers = true; + float GetDevicePixelRatio(); + public slots: void DeferSaveBegin(); void DeferSaveEnd(); @@ -844,6 +846,8 @@ private: OBSSource prevFTBSource = nullptr; + float dpi = 1.0; + public: OBSSource GetProgramSource(); OBSScene GetCurrentScene(); diff --git a/UI/window-basic-preview.cpp b/UI/window-basic-preview.cpp index 24461e0e0..234f7450a 100644 --- a/UI/window-basic-preview.cpp +++ b/UI/window-basic-preview.cpp @@ -40,7 +40,7 @@ OBSBasicPreview::~OBSBasicPreview() vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - float pixelRatio = main->devicePixelRatioF(); + float pixelRatio = main->GetDevicePixelRatio(); float scale = pixelRatio / main->previewScale; QPoint qtPos = event->pos(); vec2 pos; @@ -459,7 +459,7 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos, bool ignoreGroup) if (!scene) return; - float scale = main->previewScale / main->devicePixelRatioF(); + float scale = main->previewScale / main->GetDevicePixelRatio(); vec2 scaled_pos = pos; vec2_divf(&scaled_pos, &scaled_pos, scale); HandleFindData data(scaled_pos, scale); @@ -592,7 +592,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) } OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - float pixelRatio = main->devicePixelRatioF(); + float pixelRatio = main->GetDevicePixelRatio(); float x = pos.x() - main->previewX / pixelRatio; float y = pos.y() - main->previewY / pixelRatio; Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); @@ -1591,7 +1591,7 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) QPointF qtPos = event->localPos(); #endif - float pixelRatio = main->devicePixelRatioF(); + float pixelRatio = main->GetDevicePixelRatio(); if (scrollMode && event->buttons() == Qt::LeftButton) { scrollingOffset.x += pixelRatio * (qtPos.x() - scrollingFrom.x); @@ -1671,7 +1671,7 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) mousePos = pos; OBSBasic *main = reinterpret_cast( App()->GetMainWindow()); - float scale = main->devicePixelRatioF(); + float scale = main->GetDevicePixelRatio(); float x = qtPos.x() - main->previewX / scale; float y = qtPos.y() - main->previewY / scale; vec2_set(&startPos, x, y); @@ -1716,12 +1716,10 @@ static void DrawLine(float x1, float y1, float x2, float y2, float thickness, gs_vertexbuffer_destroy(line); } -static void DrawSquareAtPos(float x, float y) +static void DrawSquareAtPos(float x, float y, float pixelRatio) { OBSBasic *main = OBSBasic::Get(); - float pixelRatio = main->devicePixelRatioF(); - struct vec3 pos; vec3_set(&pos, x, y, 0.0f); @@ -1742,12 +1740,11 @@ static void DrawSquareAtPos(float x, float y) gs_matrix_pop(); } -static void DrawRotationHandle(gs_vertbuffer_t *circle, float rot) +static void DrawRotationHandle(gs_vertbuffer_t *circle, float rot, + float pixelRatio) { OBSBasic *main = OBSBasic::Get(); - float pixelRatio = main->devicePixelRatioF(); - struct vec3 pos; vec3_set(&pos, 0.5f, 0.0f, 0.0f); @@ -1985,7 +1982,7 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, OBSBasic *main = OBSBasic::Get(); - float pixelRatio = main->devicePixelRatioF(); + float pixelRatio = main->GetDevicePixelRatio(); bool hovered = false; { @@ -2100,14 +2097,14 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, gs_effect_set_vec4(colParam, &red); if (selected) { - DrawSquareAtPos(0.0f, 0.0f); - DrawSquareAtPos(0.0f, 1.0f); - DrawSquareAtPos(1.0f, 0.0f); - DrawSquareAtPos(1.0f, 1.0f); - DrawSquareAtPos(0.5f, 0.0f); - DrawSquareAtPos(0.0f, 0.5f); - DrawSquareAtPos(0.5f, 1.0f); - DrawSquareAtPos(1.0f, 0.5f); + DrawSquareAtPos(0.0f, 0.0f, pixelRatio); + DrawSquareAtPos(0.0f, 1.0f, pixelRatio); + DrawSquareAtPos(1.0f, 0.0f, pixelRatio); + DrawSquareAtPos(1.0f, 1.0f, pixelRatio); + DrawSquareAtPos(0.5f, 0.0f, pixelRatio); + DrawSquareAtPos(0.0f, 0.5f, pixelRatio); + DrawSquareAtPos(0.5f, 1.0f, pixelRatio); + DrawSquareAtPos(1.0f, 0.5f, pixelRatio); if (!prev->circleFill) { gs_render_start(true); @@ -2125,7 +2122,8 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, prev->circleFill = gs_render_save(); } - DrawRotationHandle(prev->circleFill, info.rot + prev->groupRot); + DrawRotationHandle(prev->circleFill, info.rot + prev->groupRot, + pixelRatio); } gs_matrix_pop(); @@ -2141,7 +2139,7 @@ bool OBSBasicPreview::DrawSelectionBox(float x1, float y1, float x2, float y2, { OBSBasic *main = OBSBasic::Get(); - float pixelRatio = main->devicePixelRatioF(); + float pixelRatio = main->GetDevicePixelRatio(); x1 = std::round(x1); x2 = std::round(x2);