From 18b508343dcac6498609298d31e20914b66c2d3b Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 9 Apr 2025 13:23:09 +0100 Subject: [PATCH] Direct2D: Move Direct2DResources to juce_DirectX_windows.h --- .../Builds/Android/app/CMakeLists.txt | 2 - .../VisualStudio2019/DemoRunner_App.vcxproj | 3 - .../DemoRunner_App.vcxproj.filters | 3 - .../VisualStudio2022/DemoRunner_App.vcxproj | 3 - .../DemoRunner_App.vcxproj.filters | 3 - .../Builds/Android/app/CMakeLists.txt | 2 - .../AudioPerformanceTest_App.vcxproj | 3 - .../AudioPerformanceTest_App.vcxproj.filters | 3 - .../Builds/Android/app/CMakeLists.txt | 2 - .../AudioPluginHost_App.vcxproj | 3 - .../AudioPluginHost_App.vcxproj.filters | 3 - .../AudioPluginHost_App.vcxproj | 3 - .../AudioPluginHost_App.vcxproj.filters | 3 - .../Builds/Android/app/CMakeLists.txt | 2 - .../NetworkGraphicsDemo_App.vcxproj | 3 - .../NetworkGraphicsDemo_App.vcxproj.filters | 3 - .../VisualStudio2019/Projucer_App.vcxproj | 3 - .../Projucer_App.vcxproj.filters | 3 - .../VisualStudio2022/Projucer_App.vcxproj | 3 - .../Projucer_App.vcxproj.filters | 3 - .../UnitTestRunner_ConsoleApp.vcxproj | 3 - .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 - .../UnitTestRunner_ConsoleApp.vcxproj | 3 - .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 - .../WindowsDLL_DynamicLibrary.vcxproj | 3 - .../WindowsDLL_DynamicLibrary.vcxproj.filters | 3 - modules/juce_graphics/juce_graphics.cpp | 1 - .../native/juce_Direct2DResources_windows.cpp | 600 ------------------ .../native/juce_DirectX_windows.h | 562 ++++++++++++++++ modules/juce_gui_basics/juce_gui_basics.cpp | 1 + 30 files changed, 563 insertions(+), 675 deletions(-) delete mode 100644 modules/juce_graphics/native/juce_Direct2DResources_windows.cpp diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 72b6547b68..0a88f13551 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -1990,7 +1990,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" @@ -4643,7 +4642,6 @@ set_source_files_properties( "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index ff6d1306c2..90c63aed28 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -2418,9 +2418,6 @@ true - - true - true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 6932001272..407c1812c3 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -3196,9 +3196,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 08e1fb346e..c8de13cd52 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -2418,9 +2418,6 @@ true - - true - true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index 78181d2f39..306f410f93 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -3196,9 +3196,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 74fb7850f5..3379993892 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -1752,7 +1752,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" @@ -4019,7 +4018,6 @@ set_source_files_properties( "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 26faa98a92..d6ef99bb44 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -2109,9 +2109,6 @@ true - - true - true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index ae73bf9263..6ec05a8ce6 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -2704,9 +2704,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 38a6fdaeca..20b3245a97 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -1882,7 +1882,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" @@ -4302,7 +4301,6 @@ set_source_files_properties( "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 819d9e6515..078896cc5e 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -2243,9 +2243,6 @@ true - - true - true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index a2b6d40386..abd33a38fa 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -2911,9 +2911,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index 9ad8708791..2c3212530a 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -2243,9 +2243,6 @@ true - - true - true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index 638ee8e089..5dab64aca9 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -2911,9 +2911,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 2790ed2335..1dcfe277c3 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -1771,7 +1771,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" @@ -4118,7 +4117,6 @@ set_source_files_properties( "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.cpp" "../../../../../modules/juce_graphics/native/juce_Direct2DMetrics_windows.h" "../../../../../modules/juce_graphics/native/juce_Direct2DPixelDataPage_windows.h" - "../../../../../modules/juce_graphics/native/juce_Direct2DResources_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp" "../../../../../modules/juce_graphics/native/juce_DirectX_windows.h" "../../../../../modules/juce_graphics/native/juce_EventTracing.h" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index a7b2bbfedd..f262f0ac2e 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -2130,9 +2130,6 @@ true - - true - true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 6f0578ebf9..01b685d236 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -2758,9 +2758,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index 87dc2749b0..4acf2f40fb 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -1272,9 +1272,6 @@ true - - true - true diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index 38c21b37e2..e8c1a479e2 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -1597,9 +1597,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj index c8414367c6..5429c32d50 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj @@ -1272,9 +1272,6 @@ true - - true - true diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters index bad3e2c0ab..51f71a607b 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters @@ -1597,9 +1597,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 4865e4f55a..75d794d9c9 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -2251,9 +2251,6 @@ true - - true - true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index d8104cbaca..70b7fa0b40 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -2959,9 +2959,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index 99e600adb3..9599888aa2 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -2251,9 +2251,6 @@ true - - true - true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index cfa2f6cc46..fa0be06296 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -2959,9 +2959,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj index bbfce27bd3..83f5d676bc 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj @@ -2129,9 +2129,6 @@ true - - true - true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters index 01163314a8..1e1bd7677a 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters @@ -2755,9 +2755,6 @@ JUCE Modules\juce_graphics\native - - JUCE Modules\juce_graphics\native - JUCE Modules\juce_graphics\native diff --git a/modules/juce_graphics/juce_graphics.cpp b/modules/juce_graphics/juce_graphics.cpp index 4222121cb0..cb552afd01 100644 --- a/modules/juce_graphics/juce_graphics.cpp +++ b/modules/juce_graphics/juce_graphics.cpp @@ -229,7 +229,6 @@ extern "C" #include "native/juce_DirectWriteTypeface_windows.cpp" #include "native/juce_IconHelpers_windows.cpp" - #include "native/juce_Direct2DResources_windows.cpp" #include "native/juce_Direct2DGraphicsContext_windows.cpp" #include "native/juce_Direct2DHwndContext_windows.cpp" #include "native/juce_Direct2DImageContext_windows.cpp" diff --git a/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp b/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp deleted file mode 100644 index 0cf9ff0ec6..0000000000 --- a/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE framework. - Copyright (c) Raw Material Software Limited - - JUCE is an open source framework subject to commercial or open source - licensing. - - By downloading, installing, or using the JUCE framework, or combining the - JUCE framework with any other source code, object code, content or any other - copyrightable work, you agree to the terms of the JUCE End User Licence - Agreement, and all incorporated terms including the JUCE Privacy Policy and - the JUCE Website Terms of Service, as applicable, which will bind you. If you - do not agree to the terms of these agreements, we will not license the JUCE - framework to you, and you must discontinue the installation or download - process and cease use of the JUCE framework. - - JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ - JUCE Privacy Policy: https://juce.com/juce-privacy-policy - JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ - - Or: - - You may also use this code under the terms of the AGPLv3: - https://www.gnu.org/licenses/agpl-3.0.en.html - - THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL - WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. - - ============================================================================== -*/ - -namespace juce -{ - -static ComSmartPtr makeGradientStopCollection (const ColourGradient& gradient, - ComSmartPtr deviceContext, - [[maybe_unused]] Direct2DMetrics* metrics) noexcept -{ - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createGradientTime); - - const int numColors = gradient.getNumColours(); - - std::vector stops ((size_t) numColors); - - for (auto [index, stop] : enumerate (stops, int{})) - { - stop.color = D2DUtilities::toCOLOR_F (gradient.getColour (index)); - stop.position = (FLOAT) gradient.getColourPosition (index); - } - - ComSmartPtr result; - deviceContext->CreateGradientStopCollection (stops.data(), (UINT32) stops.size(), result.resetAndGetPointerAddress()); - return result; -} - -class LinearGradientCache -{ -public: - ComSmartPtr get (const ColourGradient& gradient, - ComSmartPtr deviceContext, - Direct2DMetrics* metrics) - { - jassert (! gradient.isRadial); - - return cache.get (gradient, [&deviceContext, &metrics] (const auto& key) - { - const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics); - const auto p1 = key.point1; - const auto p2 = key.point2; - const auto linearGradientBrushProperties = D2D1::LinearGradientBrushProperties ({ p1.x, p1.y }, { p2.x, p2.y }); - const D2D1_BRUSH_PROPERTIES brushProps { 1.0f, D2D1::IdentityMatrix() }; - - ComSmartPtr result; - deviceContext->CreateLinearGradientBrush (linearGradientBrushProperties, - brushProps, - gradientStops, - result.resetAndGetPointerAddress()); - return result; - }); - } - -private: - LruCache> cache; -}; - -class RadialGradientCache -{ -public: - ComSmartPtr get (const ColourGradient& gradient, - ComSmartPtr deviceContext, - Direct2DMetrics* metrics) - { - jassert (gradient.isRadial); - - return cache.get (gradient, [&deviceContext, &metrics] (const auto& key) - { - const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics); - - const auto p1 = key.point1; - const auto p2 = key.point2; - const auto r = p1.getDistanceFrom (p2); - const auto radialGradientBrushProperties = D2D1::RadialGradientBrushProperties ({ p1.x, p1.y }, {}, r, r); - const D2D1_BRUSH_PROPERTIES brushProps { 1.0F, D2D1::IdentityMatrix() }; - - ComSmartPtr result; - deviceContext->CreateRadialGradientBrush (radialGradientBrushProperties, - brushProps, - gradientStops, - result.resetAndGetPointerAddress()); - return result; - }); - } - -private: - LruCache> cache; -}; - -class RectangleListSpriteBatch -{ -public: - RectangleListSpriteBatch() = default; - - ~RectangleListSpriteBatch() - { - release(); - } - - void release() - { - whiteRectangle = nullptr; - spriteBatches = {}; - destinations.free(); - destinationsCapacity = 0; - } - - template - void fillRectangles (ComSmartPtr deviceContext, - const RectangleList& rectangles, - const Colour colour, - TransformRectangle&& transformRectangle, - [[maybe_unused]] Direct2DMetrics* metrics) - { - if (rectangles.isEmpty()) - return; - - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchTime) - - auto numRectanglesPainted = 0; - while (numRectanglesPainted < rectangles.getNumRectangles()) - { - auto numRectanglesRemaining = rectangles.getNumRectangles() - numRectanglesPainted; - auto spriteBatchSize = isPowerOfTwo (numRectanglesRemaining) ? numRectanglesRemaining : (nextPowerOfTwo (numRectanglesRemaining) >> 1); - - { - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchSetupTime); - - if (destinationsCapacity < (size_t) spriteBatchSize) - { - destinations.calloc (spriteBatchSize); - destinationsCapacity = (size_t) spriteBatchSize; - } - - auto destination = destinations.getData(); - - for (int i = numRectanglesPainted; i < numRectanglesPainted + spriteBatchSize; ++i) - { - auto r = rectangles.getRectangle (i); - r = transformRectangle (r); - *destination = D2DUtilities::toRECT_F (r); - ++destination; - } - } - - if (! whiteRectangle) - { - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createSpriteSourceTime); - - auto hr = deviceContext->CreateCompatibleRenderTarget (D2D1_SIZE_F { (float) rectangleSize, (float) rectangleSize }, - D2D1_SIZE_U { rectangleSize, rectangleSize }, - D2D1_PIXEL_FORMAT { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED }, - whiteRectangle.resetAndGetPointerAddress()); - if (FAILED (hr)) - return; - - whiteRectangle->BeginDraw(); - whiteRectangle->Clear (D2D1_COLOR_F { 1.0f, 1.0f, 1.0f, 1.0f }); - whiteRectangle->EndDraw(); - } - - ComSmartPtr bitmap; - if (auto hr = whiteRectangle->GetBitmap (bitmap.resetAndGetPointerAddress()); SUCCEEDED (hr)) - { - ComSmartPtr deviceContext3; - if (hr = deviceContext->QueryInterface (deviceContext3.resetAndGetPointerAddress()); SUCCEEDED (hr)) - { - auto d2dColour = D2DUtilities::toCOLOR_F (colour); - auto spriteBatch = getSpriteBatch (*deviceContext3, (uint32) spriteBatchSize); - - if (spriteBatch == nullptr) - return; - - auto setCount = jmin ((uint32) spriteBatchSize, spriteBatch->GetSpriteCount()); - auto addCount = (uint32) spriteBatchSize > setCount ? (uint32) spriteBatchSize - setCount : 0; - - if (setCount != 0) - { - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, setSpritesTime); - - spriteBatch->SetSprites (0, setCount, destinations.getData(), nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0); - } - - if (addCount != 0) - { - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, addSpritesTime); - - spriteBatch->AddSprites (addCount, destinations.getData() + setCount, nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0); - } - - JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, drawSpritesTime); - - deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_ALIASED); - deviceContext3->DrawSpriteBatch (spriteBatch, bitmap); - deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - } - } - - numRectanglesPainted += spriteBatchSize; - } - } - -private: - ComSmartPtr getSpriteBatch (ID2D1DeviceContext3& dc, uint32 key) - { - return spriteBatches.get ((uint32) key, [&dc] (auto) -> ComSmartPtr - { - ComSmartPtr result; - if (const auto hr = dc.CreateSpriteBatch (result.resetAndGetPointerAddress()); SUCCEEDED (hr)) - return result; - - return nullptr; - }); - } - - static constexpr uint32 rectangleSize = 32; - ComSmartPtr whiteRectangle; - HeapBlock destinations; - size_t destinationsCapacity = 0; - LruCache, 8> spriteBatches; -}; - -class Direct2DDeviceResources -{ -public: - static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& adapters, ID2D1Bitmap1* bitmap) - { - if (bitmap == nullptr) - return {}; - - ComSmartPtr surface; - bitmap->GetSurface (surface.resetAndGetPointerAddress()); - - if (surface == nullptr) - return {}; - - ComSmartPtr device; - JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") - surface->GetDevice (__uuidof (device), (void**) device.resetAndGetPointerAddress()); - JUCE_END_IGNORE_WARNINGS_GCC_LIKE - - return findAdapter (adapters, device); - } - - static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& dxgiAdapters, IDXGIDevice* dxgiDevice) - { - if (dxgiDevice == nullptr) - return {}; - - ComSmartPtr adapter; - dxgiDevice->GetAdapter (adapter.resetAndGetPointerAddress()); - - if (adapter == nullptr) - return {}; - - ComSmartPtr adapter1; - adapter.QueryInterface (adapter1); - - if (adapter1 == nullptr) - return {}; - - const auto adapterLuid = getLUID (adapter1); - - const auto& adapters = dxgiAdapters.getAdapterArray(); - - const auto it = std::find_if (adapters.begin(), adapters.end(), [&] (DxgiAdapter::Ptr ptr) - { - const auto tie = [] (const LUID& x) { return std::tie (x.LowPart, x.HighPart); }; - - const auto thisLuid = getLUID (ptr->dxgiAdapter); - return tie (thisLuid) == tie (adapterLuid); - }); - - if (it == adapters.end()) - return {}; - - return *it; - } - - static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& dxgiAdapters, ID2D1DeviceContext1* context) - { - if (context == nullptr) - return {}; - - ComSmartPtr device; - context->GetDevice (device.resetAndGetPointerAddress()); - - if (device == nullptr) - return {}; - - ComSmartPtr dxgiDevice; - device.QueryInterface (dxgiDevice); - - return findAdapter (dxgiAdapters, dxgiDevice); - } - - static LUID getLUID (ComSmartPtr adapter) - { - DXGI_ADAPTER_DESC1 desc{}; - adapter->GetDesc1 (&desc); - return desc.AdapterLuid; - } - - static std::optional create (ComSmartPtr context) - { - if (context == nullptr) - return {}; - - Direct2DDeviceResources result; - - if (const auto hr = context->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f), - result.colourBrush.resetAndGetPointerAddress()); - FAILED (hr)) - { - jassertfalse; - return {}; - } - - result.rectangleListSpriteBatch = std::make_unique(); - - return result; - } - - ComSmartPtr colourBrush; - LinearGradientCache linearGradientCache; - RadialGradientCache radialGradientCache; - std::unique_ptr rectangleListSpriteBatch; - -private: - Direct2DDeviceResources() = default; -}; - -class SwapChain -{ -public: - SwapChain() = default; - - HRESULT create (HWND hwnd, Rectangle size, DxgiAdapter::Ptr adapter) - { - if (chain != nullptr || hwnd == nullptr) - return S_OK; - - auto dxgiFactory = directX->adapters.getFactory(); - - if (dxgiFactory == nullptr || adapter->direct3DDevice == nullptr) - return E_FAIL; - - buffer = nullptr; - chain = nullptr; - - // Make the waitable swap chain - // Create the swap chain with premultiplied alpha support for transparent windows - DXGI_SWAP_CHAIN_DESC1 swapChainDescription = {}; - swapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - swapChainDescription.Width = (UINT) size.getWidth(); - swapChainDescription.Height = (UINT) size.getHeight(); - swapChainDescription.SampleDesc.Count = 1; - swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDescription.BufferCount = 2; - swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - swapChainDescription.Flags = swapChainFlags; - - swapChainDescription.Scaling = DXGI_SCALING_STRETCH; - swapChainDescription.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED; - - if (const auto hr = dxgiFactory->CreateSwapChainForComposition (adapter->direct3DDevice, - &swapChainDescription, - nullptr, - chain.resetAndGetPointerAddress()); - FAILED (hr)) - { - return hr; - } - - // Get the waitable swap chain presentation event and set the maximum frame latency - ComSmartPtr chain2; - if (const auto hr = chain.QueryInterface (chain2); FAILED (hr)) - return hr; - - if (chain2 == nullptr) - return E_FAIL; - - swapChainEvent.emplace (chain2->GetFrameLatencyWaitableObject()); - if (swapChainEvent->getHandle() == INVALID_HANDLE_VALUE) - return E_NOINTERFACE; - - chain2->SetMaximumFrameLatency (1); - - createBuffer (adapter); - return buffer != nullptr ? S_OK : E_FAIL; - } - - bool canPaint() const - { - return chain != nullptr && buffer != nullptr; - } - - HRESULT resize (Rectangle newSize) - { - if (chain == nullptr) - return E_FAIL; - - constexpr auto minFrameSize = 1; - constexpr auto maxFrameSize = 16384; - - auto scaledSize = newSize.getUnion ({ minFrameSize, minFrameSize }) - .getIntersection ({ maxFrameSize, maxFrameSize }); - - buffer = nullptr; - - if (const auto hr = chain->ResizeBuffers (0, (UINT) scaledSize.getWidth(), (UINT) scaledSize.getHeight(), DXGI_FORMAT_B8G8R8A8_UNORM, swapChainFlags); FAILED (hr)) - return hr; - - ComSmartPtr device; - JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") - chain->GetDevice (__uuidof (device), (void**) device.resetAndGetPointerAddress()); - JUCE_END_IGNORE_WARNINGS_GCC_LIKE - - createBuffer (Direct2DDeviceResources::findAdapter (directX->adapters, device)); - - return buffer != nullptr ? S_OK : E_FAIL; - } - - Rectangle getSize() const - { - const auto surface = getSurface(); - - if (surface == nullptr) - return {}; - - DXGI_SURFACE_DESC desc{}; - if (FAILED (surface->GetDesc (&desc))) - return {}; - - return { (int) desc.Width, (int) desc.Height }; - } - - WindowsScopedEvent* getEvent() - { - if (swapChainEvent.has_value()) - return &*swapChainEvent; - - return nullptr; - } - - auto getChain() const - { - return chain; - } - - ComSmartPtr getBuffer() const - { - return buffer; - } - - static constexpr uint32 swapChainFlags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - static constexpr uint32 presentSyncInterval = 1; - static constexpr uint32 presentFlags = 0; - -private: - ComSmartPtr getSurface() const - { - if (chain == nullptr) - return nullptr; - - ComSmartPtr surface; - JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") - if (const auto hr = chain->GetBuffer (0, __uuidof (surface), reinterpret_cast (surface.resetAndGetPointerAddress())); FAILED (hr)) - return nullptr; - JUCE_END_IGNORE_WARNINGS_GCC_LIKE - - return surface; - } - - void createBuffer (DxgiAdapter::Ptr adapter) - { - buffer = nullptr; - - const auto deviceContext = Direct2DDeviceContext::create (adapter); - - if (deviceContext == nullptr) - return; - - const auto surface = getSurface(); - - if (surface == nullptr) - return; - - D2D1_BITMAP_PROPERTIES1 bitmapProperties{}; - bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; - bitmapProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; - bitmapProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - - deviceContext->CreateBitmapFromDxgiSurface (surface, bitmapProperties, buffer.resetAndGetPointerAddress()); - } - - class AssignableDirectX - { - public: - AssignableDirectX() = default; - AssignableDirectX (const AssignableDirectX&) {} - AssignableDirectX (AssignableDirectX&&) noexcept {} - AssignableDirectX& operator= (const AssignableDirectX&) { return *this; } - AssignableDirectX& operator= (AssignableDirectX&&) noexcept { return *this; } - ~AssignableDirectX() = default; - - DirectX* operator->() const { return directX.operator->(); } - - private: - SharedResourcePointer directX; - }; - - AssignableDirectX directX; - ComSmartPtr chain; - ComSmartPtr buffer; - std::optional swapChainEvent; -}; - -//============================================================================== -/* DirectComposition - Using DirectComposition enables transparent windows and smoother window - resizing - - This class builds a simple DirectComposition tree that ultimately contains - the swap chain -*/ -class CompositionTree -{ -public: - static std::optional create (IDXGIDevice* dxgiDevice, HWND hwnd, IDXGISwapChain1* swapChain) - { - if (dxgiDevice == nullptr) - return {}; - - CompositionTree result; - - JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") - if (const auto hr = DCompositionCreateDevice (dxgiDevice, - __uuidof (IDCompositionDevice), - reinterpret_cast (result.compositionDevice.resetAndGetPointerAddress())); - FAILED (hr)) - { - return {}; - } - JUCE_END_IGNORE_WARNINGS_GCC_LIKE - - if (const auto hr = result.compositionDevice->CreateTargetForHwnd (hwnd, FALSE, result.compositionTarget.resetAndGetPointerAddress()); FAILED (hr)) - return {}; - if (const auto hr = result.compositionDevice->CreateVisual (result.compositionVisual.resetAndGetPointerAddress()); FAILED (hr)) - return {}; - if (const auto hr = result.compositionTarget->SetRoot (result.compositionVisual); FAILED (hr)) - return {}; - if (const auto hr = result.compositionVisual->SetContent (swapChain); FAILED (hr)) - return {}; - if (const auto hr = result.compositionDevice->Commit(); FAILED (hr)) - return {}; - - return result; - } - -private: - CompositionTree() = default; - - ComSmartPtr compositionDevice; - ComSmartPtr compositionTarget; - ComSmartPtr compositionVisual; -}; - -} // namespace juce diff --git a/modules/juce_graphics/native/juce_DirectX_windows.h b/modules/juce_graphics/native/juce_DirectX_windows.h index 2160a19b46..c36acb8486 100644 --- a/modules/juce_graphics/native/juce_DirectX_windows.h +++ b/modules/juce_graphics/native/juce_DirectX_windows.h @@ -861,4 +861,566 @@ private: uint32 numRect = 0; }; +static ComSmartPtr makeGradientStopCollection (const ColourGradient& gradient, + ComSmartPtr deviceContext, + [[maybe_unused]] Direct2DMetrics* metrics) noexcept +{ + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createGradientTime); + + const int numColors = gradient.getNumColours(); + + std::vector stops ((size_t) numColors); + + for (auto [index, stop] : enumerate (stops, int{})) + { + stop.color = D2DUtilities::toCOLOR_F (gradient.getColour (index)); + stop.position = (FLOAT) gradient.getColourPosition (index); + } + + ComSmartPtr result; + deviceContext->CreateGradientStopCollection (stops.data(), (UINT32) stops.size(), result.resetAndGetPointerAddress()); + return result; +} + +class LinearGradientCache +{ +public: + ComSmartPtr get (const ColourGradient& gradient, + ComSmartPtr deviceContext, + Direct2DMetrics* metrics) + { + jassert (! gradient.isRadial); + + return cache.get (gradient, [&deviceContext, &metrics] (const auto& key) + { + const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics); + const auto p1 = key.point1; + const auto p2 = key.point2; + const auto linearGradientBrushProperties = D2D1::LinearGradientBrushProperties ({ p1.x, p1.y }, { p2.x, p2.y }); + const D2D1_BRUSH_PROPERTIES brushProps { 1.0f, D2D1::IdentityMatrix() }; + + ComSmartPtr result; + deviceContext->CreateLinearGradientBrush (linearGradientBrushProperties, + brushProps, + gradientStops, + result.resetAndGetPointerAddress()); + return result; + }); + } + +private: + LruCache> cache; +}; + +class RadialGradientCache +{ +public: + ComSmartPtr get (const ColourGradient& gradient, + ComSmartPtr deviceContext, + Direct2DMetrics* metrics) + { + jassert (gradient.isRadial); + + return cache.get (gradient, [&deviceContext, &metrics] (const auto& key) + { + const auto gradientStops = makeGradientStopCollection (key, deviceContext, metrics); + + const auto p1 = key.point1; + const auto p2 = key.point2; + const auto r = p1.getDistanceFrom (p2); + const auto radialGradientBrushProperties = D2D1::RadialGradientBrushProperties ({ p1.x, p1.y }, {}, r, r); + const D2D1_BRUSH_PROPERTIES brushProps { 1.0F, D2D1::IdentityMatrix() }; + + ComSmartPtr result; + deviceContext->CreateRadialGradientBrush (radialGradientBrushProperties, + brushProps, + gradientStops, + result.resetAndGetPointerAddress()); + return result; + }); + } + +private: + LruCache> cache; +}; + +class RectangleListSpriteBatch +{ +public: + RectangleListSpriteBatch() = default; + + ~RectangleListSpriteBatch() + { + release(); + } + + void release() + { + whiteRectangle = nullptr; + spriteBatches = {}; + destinations.free(); + destinationsCapacity = 0; + } + + template + void fillRectangles (ComSmartPtr deviceContext, + const RectangleList& rectangles, + const Colour colour, + TransformRectangle&& transformRectangle, + [[maybe_unused]] Direct2DMetrics* metrics) + { + if (rectangles.isEmpty()) + return; + + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchTime) + + auto numRectanglesPainted = 0; + while (numRectanglesPainted < rectangles.getNumRectangles()) + { + auto numRectanglesRemaining = rectangles.getNumRectangles() - numRectanglesPainted; + auto spriteBatchSize = isPowerOfTwo (numRectanglesRemaining) ? numRectanglesRemaining : (nextPowerOfTwo (numRectanglesRemaining) >> 1); + + { + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, spriteBatchSetupTime); + + if (destinationsCapacity < (size_t) spriteBatchSize) + { + destinations.calloc (spriteBatchSize); + destinationsCapacity = (size_t) spriteBatchSize; + } + + auto destination = destinations.getData(); + + for (int i = numRectanglesPainted; i < numRectanglesPainted + spriteBatchSize; ++i) + { + auto r = rectangles.getRectangle (i); + r = transformRectangle (r); + *destination = D2DUtilities::toRECT_F (r); + ++destination; + } + } + + if (! whiteRectangle) + { + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, createSpriteSourceTime); + + auto hr = deviceContext->CreateCompatibleRenderTarget (D2D1_SIZE_F { (float) rectangleSize, (float) rectangleSize }, + D2D1_SIZE_U { rectangleSize, rectangleSize }, + D2D1_PIXEL_FORMAT { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED }, + whiteRectangle.resetAndGetPointerAddress()); + if (FAILED (hr)) + return; + + whiteRectangle->BeginDraw(); + whiteRectangle->Clear (D2D1_COLOR_F { 1.0f, 1.0f, 1.0f, 1.0f }); + whiteRectangle->EndDraw(); + } + + ComSmartPtr bitmap; + if (auto hr = whiteRectangle->GetBitmap (bitmap.resetAndGetPointerAddress()); SUCCEEDED (hr)) + { + ComSmartPtr deviceContext3; + if (hr = deviceContext->QueryInterface (deviceContext3.resetAndGetPointerAddress()); SUCCEEDED (hr)) + { + auto d2dColour = D2DUtilities::toCOLOR_F (colour); + auto spriteBatch = getSpriteBatch (*deviceContext3, (uint32) spriteBatchSize); + + if (spriteBatch == nullptr) + return; + + auto setCount = jmin ((uint32) spriteBatchSize, spriteBatch->GetSpriteCount()); + auto addCount = (uint32) spriteBatchSize > setCount ? (uint32) spriteBatchSize - setCount : 0; + + if (setCount != 0) + { + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, setSpritesTime); + + spriteBatch->SetSprites (0, setCount, destinations.getData(), nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0); + } + + if (addCount != 0) + { + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, addSpritesTime); + + spriteBatch->AddSprites (addCount, destinations.getData() + setCount, nullptr, &d2dColour, nullptr, sizeof (D2D1_RECT_F), 0, 0, 0); + } + + JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (metrics, drawSpritesTime); + + deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_ALIASED); + deviceContext3->DrawSpriteBatch (spriteBatch, bitmap); + deviceContext3->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + } + } + + numRectanglesPainted += spriteBatchSize; + } + } + +private: + ComSmartPtr getSpriteBatch (ID2D1DeviceContext3& dc, uint32 key) + { + return spriteBatches.get ((uint32) key, [&dc] (auto) -> ComSmartPtr + { + ComSmartPtr result; + if (const auto hr = dc.CreateSpriteBatch (result.resetAndGetPointerAddress()); SUCCEEDED (hr)) + return result; + + return nullptr; + }); + } + + static constexpr uint32 rectangleSize = 32; + ComSmartPtr whiteRectangle; + HeapBlock destinations; + size_t destinationsCapacity = 0; + LruCache, 8> spriteBatches; +}; + +class Direct2DDeviceResources +{ +public: + static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& adapters, ID2D1Bitmap1* bitmap) + { + if (bitmap == nullptr) + return {}; + + ComSmartPtr surface; + bitmap->GetSurface (surface.resetAndGetPointerAddress()); + + if (surface == nullptr) + return {}; + + ComSmartPtr device; + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") + surface->GetDevice (__uuidof (device), (void**) device.resetAndGetPointerAddress()); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + + return findAdapter (adapters, device); + } + + static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& dxgiAdapters, IDXGIDevice* dxgiDevice) + { + if (dxgiDevice == nullptr) + return {}; + + ComSmartPtr adapter; + dxgiDevice->GetAdapter (adapter.resetAndGetPointerAddress()); + + if (adapter == nullptr) + return {}; + + ComSmartPtr adapter1; + adapter.QueryInterface (adapter1); + + if (adapter1 == nullptr) + return {}; + + const auto adapterLuid = getLUID (adapter1); + + const auto& adapters = dxgiAdapters.getAdapterArray(); + + const auto it = std::find_if (adapters.begin(), adapters.end(), [&] (DxgiAdapter::Ptr ptr) + { + const auto tie = [] (const LUID& x) { return std::tie (x.LowPart, x.HighPart); }; + + const auto thisLuid = getLUID (ptr->dxgiAdapter); + return tie (thisLuid) == tie (adapterLuid); + }); + + if (it == adapters.end()) + return {}; + + return *it; + } + + static DxgiAdapter::Ptr findAdapter (const DxgiAdapters& dxgiAdapters, ID2D1DeviceContext1* context) + { + if (context == nullptr) + return {}; + + ComSmartPtr device; + context->GetDevice (device.resetAndGetPointerAddress()); + + if (device == nullptr) + return {}; + + ComSmartPtr dxgiDevice; + device.QueryInterface (dxgiDevice); + + return findAdapter (dxgiAdapters, dxgiDevice); + } + + static LUID getLUID (ComSmartPtr adapter) + { + DXGI_ADAPTER_DESC1 desc{}; + adapter->GetDesc1 (&desc); + return desc.AdapterLuid; + } + + static std::optional create (ComSmartPtr context) + { + if (context == nullptr) + return {}; + + Direct2DDeviceResources result; + + if (const auto hr = context->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f), + result.colourBrush.resetAndGetPointerAddress()); + FAILED (hr)) + { + jassertfalse; + return {}; + } + + result.rectangleListSpriteBatch = std::make_unique(); + + return result; + } + + ComSmartPtr colourBrush; + LinearGradientCache linearGradientCache; + RadialGradientCache radialGradientCache; + std::unique_ptr rectangleListSpriteBatch; + +private: + Direct2DDeviceResources() = default; +}; + +class SwapChain +{ +public: + SwapChain() = default; + + HRESULT create (HWND hwnd, Rectangle size, DxgiAdapter::Ptr adapter) + { + if (chain != nullptr || hwnd == nullptr) + return S_OK; + + auto dxgiFactory = directX->adapters.getFactory(); + + if (dxgiFactory == nullptr || adapter->direct3DDevice == nullptr) + return E_FAIL; + + buffer = nullptr; + chain = nullptr; + + // Make the waitable swap chain + // Create the swap chain with premultiplied alpha support for transparent windows + DXGI_SWAP_CHAIN_DESC1 swapChainDescription = {}; + swapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapChainDescription.Width = (UINT) size.getWidth(); + swapChainDescription.Height = (UINT) size.getHeight(); + swapChainDescription.SampleDesc.Count = 1; + swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDescription.BufferCount = 2; + swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDescription.Flags = swapChainFlags; + + swapChainDescription.Scaling = DXGI_SCALING_STRETCH; + swapChainDescription.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED; + + if (const auto hr = dxgiFactory->CreateSwapChainForComposition (adapter->direct3DDevice, + &swapChainDescription, + nullptr, + chain.resetAndGetPointerAddress()); + FAILED (hr)) + { + return hr; + } + + // Get the waitable swap chain presentation event and set the maximum frame latency + ComSmartPtr chain2; + if (const auto hr = chain.QueryInterface (chain2); FAILED (hr)) + return hr; + + if (chain2 == nullptr) + return E_FAIL; + + swapChainEvent.emplace (chain2->GetFrameLatencyWaitableObject()); + if (swapChainEvent->getHandle() == INVALID_HANDLE_VALUE) + return E_NOINTERFACE; + + chain2->SetMaximumFrameLatency (1); + + createBuffer (adapter); + return buffer != nullptr ? S_OK : E_FAIL; + } + + bool canPaint() const + { + return chain != nullptr && buffer != nullptr; + } + + HRESULT resize (Rectangle newSize) + { + if (chain == nullptr) + return E_FAIL; + + constexpr auto minFrameSize = 1; + constexpr auto maxFrameSize = 16384; + + auto scaledSize = newSize.getUnion ({ minFrameSize, minFrameSize }) + .getIntersection ({ maxFrameSize, maxFrameSize }); + + buffer = nullptr; + + if (const auto hr = chain->ResizeBuffers (0, (UINT) scaledSize.getWidth(), (UINT) scaledSize.getHeight(), DXGI_FORMAT_B8G8R8A8_UNORM, swapChainFlags); FAILED (hr)) + return hr; + + ComSmartPtr device; + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") + chain->GetDevice (__uuidof (device), (void**) device.resetAndGetPointerAddress()); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + + createBuffer (Direct2DDeviceResources::findAdapter (directX->adapters, device)); + + return buffer != nullptr ? S_OK : E_FAIL; + } + + Rectangle getSize() const + { + const auto surface = getSurface(); + + if (surface == nullptr) + return {}; + + DXGI_SURFACE_DESC desc{}; + if (FAILED (surface->GetDesc (&desc))) + return {}; + + return { (int) desc.Width, (int) desc.Height }; + } + + WindowsScopedEvent* getEvent() + { + if (swapChainEvent.has_value()) + return &*swapChainEvent; + + return nullptr; + } + + auto getChain() const + { + return chain; + } + + ComSmartPtr getBuffer() const + { + return buffer; + } + + static constexpr uint32 swapChainFlags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + static constexpr uint32 presentSyncInterval = 1; + static constexpr uint32 presentFlags = 0; + +private: + ComSmartPtr getSurface() const + { + if (chain == nullptr) + return nullptr; + + ComSmartPtr surface; + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") + if (const auto hr = chain->GetBuffer (0, __uuidof (surface), reinterpret_cast (surface.resetAndGetPointerAddress())); FAILED (hr)) + return nullptr; + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + + return surface; + } + + void createBuffer (DxgiAdapter::Ptr adapter) + { + buffer = nullptr; + + const auto deviceContext = Direct2DDeviceContext::create (adapter); + + if (deviceContext == nullptr) + return; + + const auto surface = getSurface(); + + if (surface == nullptr) + return; + + D2D1_BITMAP_PROPERTIES1 bitmapProperties{}; + bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + bitmapProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + bitmapProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + + deviceContext->CreateBitmapFromDxgiSurface (surface, bitmapProperties, buffer.resetAndGetPointerAddress()); + } + + class AssignableDirectX + { + public: + AssignableDirectX() = default; + AssignableDirectX (const AssignableDirectX&) {} + AssignableDirectX (AssignableDirectX&&) noexcept {} + AssignableDirectX& operator= (const AssignableDirectX&) { return *this; } + AssignableDirectX& operator= (AssignableDirectX&&) noexcept { return *this; } + ~AssignableDirectX() = default; + + DirectX* operator->() const { return directX.operator->(); } + + private: + SharedResourcePointer directX; + }; + + AssignableDirectX directX; + ComSmartPtr chain; + ComSmartPtr buffer; + std::optional swapChainEvent; +}; + +//============================================================================== +/* DirectComposition + Using DirectComposition enables transparent windows and smoother window + resizing + + This class builds a simple DirectComposition tree that ultimately contains + the swap chain +*/ +class CompositionTree +{ +public: + static std::optional create (IDXGIDevice* dxgiDevice, HWND hwnd, IDXGISwapChain1* swapChain) + { + if (dxgiDevice == nullptr) + return {}; + + CompositionTree result; + + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") + if (const auto hr = DCompositionCreateDevice (dxgiDevice, + __uuidof (IDCompositionDevice), + reinterpret_cast (result.compositionDevice.resetAndGetPointerAddress())); + FAILED (hr)) + { + return {}; + } + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + + if (const auto hr = result.compositionDevice->CreateTargetForHwnd (hwnd, FALSE, result.compositionTarget.resetAndGetPointerAddress()); FAILED (hr)) + return {}; + if (const auto hr = result.compositionDevice->CreateVisual (result.compositionVisual.resetAndGetPointerAddress()); FAILED (hr)) + return {}; + if (const auto hr = result.compositionTarget->SetRoot (result.compositionVisual); FAILED (hr)) + return {}; + if (const auto hr = result.compositionVisual->SetContent (swapChain); FAILED (hr)) + return {}; + if (const auto hr = result.compositionDevice->Commit(); FAILED (hr)) + return {}; + + return result; + } + +private: + CompositionTree() = default; + + ComSmartPtr compositionDevice; + ComSmartPtr compositionTarget; + ComSmartPtr compositionVisual; +}; + } // namespace juce diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 21dc145cb6..77c18509d4 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -92,6 +92,7 @@ #include #include #include + #include #if JUCE_ETW_TRACELOGGING #include