From 8bbcfe4d6b619ca62e5086353e3f4928f0a3c4db Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 12 Aug 2024 18:19:18 +0100 Subject: [PATCH] Direct2D: Move DeviceContext helpers to shared DirectX header --- .../juce_Direct2DGraphicsContext_windows.cpp | 52 ++++++++++-------- .../juce_Direct2DHwndContext_windows.cpp | 10 ++-- .../native/juce_Direct2DImage_windows.cpp | 2 +- .../native/juce_Direct2DResources_windows.cpp | 53 +++---------------- .../native/juce_DirectX_windows.h | 28 ++++++++++ 5 files changed, 72 insertions(+), 73 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index f787c3bb29..8f715d0016 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -269,7 +269,7 @@ public: void pushLayer (const D2D1_LAYER_PARAMETERS1& layerParameters) { - layers.push (deviceResources.deviceContext.context, layerParameters); + layers.push (deviceResources.deviceContext, layerParameters); } void pushGeometryClipLayer (ComSmartPtr geometry) @@ -292,7 +292,7 @@ public: { JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, pushAliasedAxisAlignedLayerTime) - layers.push (deviceResources.deviceContext.context, r); + layers.push (deviceResources.deviceContext, r); } void pushTransparencyLayer (float opacity) @@ -303,12 +303,12 @@ public: void popLayers() { while (! layers.isEmpty()) - layers.popOne (deviceResources.deviceContext.context); + layers.popOne (deviceResources.deviceContext); } void popTopLayer() { - layers.popOne (deviceResources.deviceContext.context); + layers.popOne (deviceResources.deviceContext); } void setFont (const Font& newFont) @@ -351,17 +351,17 @@ public: JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime); - return Direct2DBitmap::toBitmap (fillType.image, deviceResources.deviceContext.context, Image::ARGB); + return Direct2DBitmap::toBitmap (fillType.image, deviceResources.deviceContext, Image::ARGB); }(); if (d2d1Bitmap != nullptr) { D2D1_BRUSH_PROPERTIES brushProps { fillType.getOpacity(), D2DUtilities::transformToMatrix (fillType.transform) }; auto bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP); - if (const auto hr = deviceResources.deviceContext.context->CreateBitmapBrush (d2d1Bitmap, - bmProps, - brushProps, - bitmapBrush.resetAndGetPointerAddress()); SUCCEEDED (hr)) + if (const auto hr = deviceResources.deviceContext->CreateBitmapBrush (d2d1Bitmap, + bmProps, + brushProps, + bitmapBrush.resetAndGetPointerAddress()); SUCCEEDED (hr)) { currentBrush = bitmapBrush; } @@ -371,12 +371,12 @@ public: { if (fillType.gradient->isRadial) { - radialGradient = deviceResources.radialGradientCache.get (*fillType.gradient, deviceResources.deviceContext.context, owner.metrics.get()); + radialGradient = deviceResources.radialGradientCache.get (*fillType.gradient, deviceResources.deviceContext, owner.metrics.get()); currentBrush = radialGradient; } else { - linearGradient = deviceResources.linearGradientCache.get (*fillType.gradient, deviceResources.deviceContext.context, owner.metrics.get()); + linearGradient = deviceResources.linearGradientCache.get (*fillType.gradient, deviceResources.deviceContext, owner.metrics.get()); currentBrush = linearGradient; } } @@ -626,14 +626,14 @@ public: JUCE_TRACE_EVENT_INT_RECT_LIST (etw::startD2DFrame, etw::direct2dKeyword, owner.getFrameId(), paintAreas); // Init device context transform - deviceResources.deviceContext.resetTransform(); + resetTransform (deviceResources.deviceContext); const auto effectiveDpi = USER_DEFAULT_SCREEN_DPI * dpiScale; - deviceResources.deviceContext.context->SetDpi (effectiveDpi, effectiveDpi); + deviceResources.deviceContext->SetDpi (effectiveDpi, effectiveDpi); // Start drawing - deviceResources.deviceContext.context->SetTarget (getDeviceContextTarget()); - deviceResources.deviceContext.context->BeginDraw(); + deviceResources.deviceContext->SetTarget (getDeviceContextTarget()); + deviceResources.deviceContext->BeginDraw(); // Init the save state stack and return the first saved state return pushFirstSavedState (paintBounds); @@ -651,8 +651,8 @@ public: JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, endDrawDuration) JUCE_SCOPED_TRACE_EVENT_FRAME (etw::endDraw, etw::direct2dKeyword, owner.getFrameId()); - hr = deviceResources.deviceContext.context->EndDraw(); - deviceResources.deviceContext.context->SetTarget (nullptr); + hr = deviceResources.deviceContext->EndDraw(); + deviceResources.deviceContext->SetTarget (nullptr); } jassert (SUCCEEDED (hr)); @@ -715,7 +715,7 @@ public: ComSmartPtr getDeviceContext() const noexcept { - return deviceResources.deviceContext.context; + return deviceResources.deviceContext; } const auto& getPaintAreas() const noexcept @@ -727,12 +727,12 @@ public: void setDeviceContextTransform (AffineTransform transform) { - deviceResources.deviceContext.setTransform (transform); + setTransform (deviceResources.deviceContext, transform); } void resetDeviceContextTransform() { - deviceResources.deviceContext.setTransform ({}); + resetTransform (deviceResources.deviceContext); } auto getDirect2DFactory() @@ -826,7 +826,7 @@ public: owner.applyPendingClipList(); - auto deviceContext = deviceResources.deviceContext.context; + auto deviceContext = deviceResources.deviceContext; if (deviceContext == nullptr) return; @@ -857,6 +857,16 @@ public: D2D1_COLOR_F backgroundColor{}; private: + static void resetTransform (ID2D1DeviceContext1* context) + { + context->SetTransform (D2D1::IdentityMatrix()); + } + + static void setTransform (ID2D1DeviceContext1* context, AffineTransform newTransform) + { + context->SetTransform (D2DUtilities::transformToMatrix (newTransform)); + } + void adapterCreated (DxgiAdapter::Ptr newAdapter) override { if (! adapter || adapter->uniqueIDMatches (newAdapter)) diff --git a/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp index f4b066abb5..c6094aafb2 100644 --- a/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp @@ -346,7 +346,7 @@ private: if (auto hr = swap.create (hwnd, frameSize, adapter); FAILED (hr)) return hr; - if (auto hr = swap.createBuffer (deviceResources.deviceContext.context); FAILED (hr)) + if (auto hr = swap.createBuffer (deviceResources.deviceContext); FAILED (hr)) return hr; } @@ -450,7 +450,7 @@ public: ComSmartPtr getDeviceContextTarget() const override { if (auto* p = presentation.getPresentation()) - return p->getPresentationBitmap (swap.getSize(), deviceResources.deviceContext.context); + return p->getPresentationBitmap (swap.getSize(), deviceResources.deviceContext); return {}; } @@ -478,7 +478,7 @@ public: // Resize/scale the swap chain prepare(); - if (auto deviceContext = deviceResources.deviceContext.context) + if (auto deviceContext = deviceResources.deviceContext) { ScopedMultithread scopedMultithread { directX->getD2DMultithread() }; @@ -632,7 +632,7 @@ public: Image createSnapshot() const { - if (frameSize.isEmpty() || deviceResources.deviceContext.context == nullptr || swap.buffer == nullptr) + if (frameSize.isEmpty() || deviceResources.deviceContext == nullptr || swap.buffer == nullptr) return {}; // Create the bitmap to receive the snapshot @@ -645,7 +645,7 @@ public: ComSmartPtr snapshot; - if (const auto hr = deviceResources.deviceContext.context->CreateBitmap (size, nullptr, 0, bitmapProperties, snapshot.resetAndGetPointerAddress()); FAILED (hr)) + if (const auto hr = deviceResources.deviceContext->CreateBitmap (size, nullptr, 0, bitmapProperties, snapshot.resetAndGetPointerAddress()); FAILED (hr)) return {}; const ScopedMultithread scope { directX->getD2DMultithread() }; diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp index faf833a1d6..862bab1c85 100644 --- a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp @@ -158,7 +158,7 @@ void Direct2DPixelData::createDeviceResources() adapter = directX->adapters.getDefaultAdapter(); if (context == nullptr) - context = Direct2DDeviceContext::createContext (adapter); + context = Direct2DDeviceContext::create (adapter); if (nativeBitmap == nullptr) { diff --git a/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp b/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp index 776bb8d19f..f06ba87fee 100644 --- a/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DResources_windows.cpp @@ -35,45 +35,6 @@ namespace juce { -struct Direct2DDeviceContext -{ - void resetTransform() - { - context->SetTransform (D2D1::IdentityMatrix()); - } - - void setTransform (AffineTransform newTransform) - { - context->SetTransform (D2DUtilities::transformToMatrix (newTransform)); - } - - void release() - { - context = nullptr; - } - - static ComSmartPtr createContext (DxgiAdapter::Ptr adapter) - { - ComSmartPtr result; - - if (const auto hr = adapter->direct2DDevice->CreateDeviceContext (D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, - result.resetAndGetPointerAddress()); - FAILED (hr)) - { - jassertfalse; - return {}; - } - - result->SetTextAntialiasMode (D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); - result->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - result->SetUnitMode (D2D1_UNIT_MODE_PIXELS); - - return result; - } - - ComSmartPtr context; -}; - static ComSmartPtr makeGradientStopCollection (const ColourGradient& gradient, ComSmartPtr deviceContext, [[maybe_unused]] Direct2DMetrics* metrics) noexcept @@ -300,13 +261,13 @@ public: { jassert (adapter); - if (deviceContext.context == nullptr) - deviceContext.context = Direct2DDeviceContext::createContext (adapter); + if (deviceContext == nullptr) + deviceContext = Direct2DDeviceContext::create (adapter); if (colourBrush == nullptr) { - if (const auto hr = deviceContext.context->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f), - colourBrush.resetAndGetPointerAddress()); + if (const auto hr = deviceContext->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f), + colourBrush.resetAndGetPointerAddress()); FAILED (hr)) { jassertfalse; @@ -326,15 +287,15 @@ public: linearGradientCache = {}; radialGradientCache = {}; colourBrush = nullptr; - deviceContext.release(); + deviceContext = nullptr; } bool canPaint (DxgiAdapter::Ptr adapter) const { - return adapter->direct2DDevice != nullptr && deviceContext.context != nullptr && colourBrush != nullptr; + return adapter->direct2DDevice != nullptr && deviceContext != nullptr && colourBrush != nullptr; } - Direct2DDeviceContext deviceContext; + ComSmartPtr deviceContext; ComSmartPtr colourBrush; LinearGradientCache linearGradientCache; RadialGradientCache radialGradientCache; diff --git a/modules/juce_graphics/native/juce_DirectX_windows.h b/modules/juce_graphics/native/juce_DirectX_windows.h index 3f1cfd2584..5e02859f3b 100644 --- a/modules/juce_graphics/native/juce_DirectX_windows.h +++ b/modules/juce_graphics/native/juce_DirectX_windows.h @@ -327,6 +327,34 @@ struct D2DUtilities } }; +//============================================================================== +struct Direct2DDeviceContext +{ + static ComSmartPtr create (DxgiAdapter::Ptr adapter) + { + if (adapter == nullptr) + return {}; + + ComSmartPtr result; + + if (const auto hr = adapter->direct2DDevice->CreateDeviceContext (D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, + result.resetAndGetPointerAddress()); + FAILED (hr)) + { + jassertfalse; + return {}; + } + + result->SetTextAntialiasMode (D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); + result->SetAntialiasMode (D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + result->SetUnitMode (D2D1_UNIT_MODE_PIXELS); + + return result; + } + + Direct2DDeviceContext() = delete; +}; + //============================================================================== struct Direct2DBitmap {