From 6b3558e3c563427f1bdff7193151c57c59041ddb Mon Sep 17 00:00:00 2001 From: Thorsten Wagner Date: Sat, 6 Mar 2021 23:51:33 +0100 Subject: tdf#138122 Detect window scaling for multi display configurations on macOS (1) Activate window scaling when at least one retina display is connected (2) Remove environment variable VCL_MACOS_FORCE_WINDOW_SCALING (3) Disable related unit tests unless bitmap scaling has been implemented Backport of 0c36f364b14aacd0eeb53087ae2fce54402dc741 and 06d918dcc47ae3f1c511cbdccfeacc8adb123f28 for LibreOffice 7.1 Change-Id: I20b075bf4e2927d62a04cd935e4496721b4c695d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112106 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- vcl/inc/quartz/salgdi.h | 3 +- vcl/osx/salgdiutils.cxx | 50 ++++++++++++------------ vcl/osx/salmacos.cxx | 4 +- vcl/qa/cppunit/BackendTest.cxx | 9 +++++ vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx | 9 ++++- vcl/qa/cppunit/outdev.cxx | 4 ++ vcl/quartz/salgdi.cxx | 8 ---- 7 files changed, 48 insertions(+), 39 deletions(-) diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index f5ff134259a6..7282c50fef1c 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -175,7 +175,6 @@ class AquaSalGraphics : public SalGraphics #ifdef MACOSX /// is this a window graphics bool mbWindow; - bool mbWindowScaling; #else // IOS @@ -197,7 +196,7 @@ public: void copyResolution( AquaSalGraphics& ); void updateResolution(); - float GetWindowScaling(); + static float GetWindowScaling(); void SetWindowGraphics( AquaSalFrame* pFrame ); bool IsWindowGraphics() const { return mbWindow; } void SetPrinterGraphics(CGContextRef, sal_Int32 nRealDPIX, sal_Int32 nRealDPIY); diff --git a/vcl/osx/salgdiutils.cxx b/vcl/osx/salgdiutils.cxx index 892baed13ac9..a1012e704796 100644 --- a/vcl/osx/salgdiutils.cxx +++ b/vcl/osx/salgdiutils.cxx @@ -35,37 +35,35 @@ #include #include -float AquaSalGraphics::GetWindowScaling() -{ - float fScale = 1.0f; - -#ifdef MACOSX - - // Window scaling independent from main display may be forced by setting VCL_MACOS_FORCE_WINDOW_SCALING environment variable - // whose setting is stored in mbWindowScaling. After implementation of full support of scaled displays window scaling will be - // set to 2.0f for macOS as default. This will allow moving of windows between non retina and retina displays without blurry - // text and graphics. +// TODO: Scale will be set to 2.0f as default after implementation of full scaled display support . This will allow moving of +// windows between non retina and retina displays without blurry text and graphics. Static variables have to be removed thereafter. - // TODO: After implementation of full support of scaled displays code has to be modified to set a scaling of 2.0f as default. - - if (mbWindowScaling) - { - fScale = 2.0f; - return fScale; - } +// Currently scaled display support is not implemented for bitmaps. This will cause a slight performance degradation on displays +// with single precision. To preserve performance for now, window scaling is only activated if at least one display with double +// precision is present. Moving windows between displays is then possible without blurry text and graphics too. Adapting window +// scaling when displays are added while application is running is not supported. -#endif +static bool bWindowScaling = false; +static float fWindowScale = 1.0f; - AquaSalFrame *pSalFrame = mpFrame; - if (!pSalFrame) - pSalFrame = static_cast(GetSalData()->mpInstance->anyFrame()); - if (pSalFrame) +float AquaSalGraphics::GetWindowScaling() +{ + if (!bWindowScaling) { - NSWindow *pNSWindow = pSalFrame->getNSWindow(); - if (pNSWindow) - fScale = [pNSWindow backingScaleFactor]; + NSArray *aScreens = [NSScreen screens]; + if (aScreens != nullptr) + { + int nScreens = [aScreens count]; + for (int i = 0; i < nScreens; i++) + { + float fScale = [[aScreens objectAtIndex:i] backingScaleFactor]; + if (fScale > fWindowScale) + fWindowScale = fScale; + } + bWindowScaling = true; + } } - return fScale; + return fWindowScale; } void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame ) diff --git a/vcl/osx/salmacos.cxx b/vcl/osx/salmacos.cxx index 88f15e22d229..24a4b5b5a4d6 100644 --- a/vcl/osx/salmacos.cxx +++ b/vcl/osx/salmacos.cxx @@ -19,7 +19,7 @@ // This file contains the macOS-specific versions of the functions which were touched in the commit // to fix tdf#138122. The iOS-specific versions of these functions are kept (for now, when this -// comment is written) as they were before that commit in vcl/isx/salios.cxx. +// comment is written) as they were before that commit in vcl/ios/salios.cxx. #include #include @@ -345,7 +345,7 @@ bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY) mnWidth = nDX; mnHeight = nDY; - fScale = mpGraphics->GetWindowScaling(); + fScale = AquaSalGraphics::GetWindowScaling(); CGColorSpaceRef aColorSpace; uint32_t nFlags; if (mnBitmapDepth && (mnBitmapDepth < 16)) diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx index 94bf1e142960..29d7268445e1 100644 --- a/vcl/qa/cppunit/BackendTest.cxx +++ b/vcl/qa/cppunit/BackendTest.cxx @@ -674,6 +674,8 @@ public: // Test SalGraphics::blendBitmap() and blendAlphaBitmap() calls. void testDrawBlendExtended() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX // Create virtual device with alpha. ScopedVclPtr device = VclPtr::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); @@ -719,10 +721,13 @@ public: exportDevice("/tmp/blend_extended_04.png", device); CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(2, 2))); CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(6, 6))); +#endif } void testDrawAlphaBitmapMirrored() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX // Normal virtual device. ScopedVclPtr device = VclPtr::Create(DeviceFormat::DEFAULT); // Virtual device with alpha. @@ -777,10 +782,13 @@ public: CPPUNIT_ASSERT_EQUAL(COL_RED, alphaDevice->GetPixel(Point(2, 2))); CPPUNIT_ASSERT_EQUAL(COL_BLUE, alphaDevice->GetPixel(Point(3, 2))); alphaDevice->Erase(); +#endif } void testTdf124848() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX ScopedVclPtr device = VclPtr::Create(DeviceFormat::DEFAULT); device->SetOutputSizePixel(Size(100, 100)); device->SetBackground(Wallpaper(COL_WHITE)); @@ -809,6 +817,7 @@ public: CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(50, 20))); CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(49, 20))); CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(51, 20))); +#endif } void testTdf136171() diff --git a/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx b/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx index fb892395ecc1..8a60eebbc44c 100644 --- a/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx +++ b/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx @@ -45,6 +45,7 @@ public: CPPUNIT_TEST_SUITE(BitmapRenderTest); CPPUNIT_TEST(testTdf104141); CPPUNIT_TEST(testTdf113918); + CPPUNIT_TEST(testDrawAlphaBitmapEx); CPPUNIT_TEST(testAlphaVirtualDevice); CPPUNIT_TEST(testTdf116888); @@ -101,7 +102,7 @@ void BitmapRenderTest::testTdf113918() CPPUNIT_ASSERT(aColor.GetGreen() > 100); } -#if defined(_WIN32) || defined(MACOSX) || defined(IOS) +#if defined(_WIN32) || defined(IOS) namespace { @@ -119,6 +120,8 @@ int deltaColor(BitmapColor aColor1, BitmapColor aColor2) void BitmapRenderTest::testDrawAlphaBitmapEx() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX ScopedVclPtrInstance pVDev; pVDev->SetOutputSizePixel(Size(8, 8)); pVDev->SetBackground(Wallpaper(COL_WHITE)); @@ -163,10 +166,13 @@ void BitmapRenderTest::testDrawAlphaBitmapEx() #else CPPUNIT_ASSERT_EQUAL(Color(0x00, 0x7F, 0xFF, 0x7F), pVDev->GetPixel(Point(2, 2))); #endif +#endif } void BitmapRenderTest::testAlphaVirtualDevice() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX // Create an alpha virtual device ScopedVclPtr pAlphaVirtualDevice(VclPtr::Create( *Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::DEFAULT)); @@ -228,6 +234,7 @@ void BitmapRenderTest::testAlphaVirtualDevice() #else CPPUNIT_ASSERT_EQUAL(Color(0x4422FF55), aColor); #endif +#endif } void BitmapRenderTest::testTdf116888() diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx index 97ec62096ce9..5081082afc0b 100644 --- a/vcl/qa/cppunit/outdev.cxx +++ b/vcl/qa/cppunit/outdev.cxx @@ -41,6 +41,7 @@ public: void testRTLGuard(); CPPUNIT_TEST_SUITE(VclOutdevTest); + CPPUNIT_TEST(testVirtualDevice); CPPUNIT_TEST(testUseAfterDispose); CPPUNIT_TEST(testPrinterBackgroundColor); @@ -83,6 +84,8 @@ void VclOutdevTest::testWindowBackgroundColor() void VclOutdevTest::testVirtualDevice() { +// TODO: This unit test is not executed for macOS unless bitmap scaling is implemented +#ifndef MACOSX ScopedVclPtrInstance pVDev; pVDev->SetOutputSizePixel(Size(32, 32)); pVDev->SetBackground(Wallpaper(COL_WHITE)); @@ -131,6 +134,7 @@ void VclOutdevTest::testVirtualDevice() CPPUNIT_ASSERT( pWin ); OutputDevice *pOutDev = pWin.get(); #endif +#endif } void VclOutdevTest::testUseAfterDispose() diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 12281e85517d..704bba1fae9c 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -205,14 +205,6 @@ AquaSalGraphics::AquaSalGraphics() , mbVirDev( false ) #ifdef MACOSX , mbWindow( false ) - - // Window scaling independent from main display may be forced by setting VCL_MACOS_FORCE_WINDOW_SCALING environment variable. If - // unset window scaling from main display will be used. After implementation of full support of scaled displays window scaling - // will be set to 2.0f for macOS as default. - - // TODO: After implementation of full support of scaled displays VCL_FORCE_WINDOW_SCALING control has to be removed. - - , mbWindowScaling( getenv("VCL_MACOS_FORCE_WINDOW_SCALING") ) #else , mbForeignContext( false ) #endif -- cgit