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