From 336dcfc08cd171255087b71e00e469915b1c0feb Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 9 Dec 2024 18:45:08 +0000 Subject: [PATCH] Direct2DImage: Update interface to accept a Device instead of a DeviceContext --- .../juce_Direct2DGraphicsContext_windows.cpp | 6 +- .../juce_Direct2DHwndContext_windows.cpp | 2 +- .../native/juce_Direct2DImage_windows.cpp | 75 ++++++++++--------- .../native/juce_Direct2DImage_windows.h | 12 +-- .../native/juce_DirectX_windows.h | 10 +++ .../native/juce_Windowing_windows.cpp | 2 +- 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index ec5dadb0a9..654996c40e 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -341,7 +341,7 @@ public: const auto d2d1Bitmap = [&] { if (auto direct2DPixelData = dynamic_cast (fillType.image.getPixelData().get())) - if (const auto page = direct2DPixelData->getFirstPageForContext (context)) + if (const auto page = direct2DPixelData->getFirstPageForDevice (D2DUtilities::getDeviceForContext (context))) if (page->GetPixelFormat().format == DXGI_FORMAT_B8G8R8A8_UNORM) return page; @@ -1171,7 +1171,7 @@ void Direct2DGraphicsContext::clipToImageAlpha (const Image& sourceImage, const ComSmartPtr d2d1Bitmap; if (auto direct2DPixelData = dynamic_cast (sourceImage.getPixelData().get())) - d2d1Bitmap = direct2DPixelData->getFirstPageForContext (deviceContext); + d2d1Bitmap = direct2DPixelData->getFirstPageForDevice (D2DUtilities::getDeviceForContext (deviceContext)); if (! d2d1Bitmap) { @@ -1481,7 +1481,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans auto drawTiles = [&] (const auto& pixelData, auto&& getRect) { - for (const auto& page : pixelData->getPagesForContext (deviceContext)) + for (const auto& page : pixelData->getPagesForDevice (D2DUtilities::getDeviceForContext (deviceContext))) { const auto pageBounds = page.getBounds(); const auto intersection = pageBounds.toFloat().getIntersection (imageClipArea.toFloat()); diff --git a/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp index bb99e00bcc..0e1c7b356d 100644 --- a/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DHwndContext_windows.cpp @@ -366,7 +366,7 @@ public: if (const auto hr = snapshot->CopyFromBitmap (&p, buffer, &sourceRect); FAILED (hr)) return {}; - const Image result { new Direct2DPixelData { deviceContext, snapshot } }; + const Image result { new Direct2DPixelData { D2DUtilities::getDeviceForContext (deviceContext), snapshot } }; swap.getChain()->Present (0, DXGI_PRESENT_DO_NOT_WAIT); diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp index 878862e4da..a0fcf12cc9 100644 --- a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp @@ -42,16 +42,6 @@ Rectangle Direct2DPixelDataPage::getBounds() const } //============================================================================== -static ComSmartPtr getDeviceForContext (ComSmartPtr context) -{ - if (context == nullptr) - return {}; - - ComSmartPtr device; - context->GetDevice (device.resetAndGetPointerAddress()); - return device.getInterface(); -} - static std::vector makePages (ComSmartPtr device, ImagePixelData::Ptr backingData, bool needsClear) @@ -236,11 +226,11 @@ Direct2DPixelDataPages::Direct2DPixelDataPages (ComSmartPtr bitmap jassert (image->createType()->getTypeID() == SoftwareImageType{}.getTypeID()); } -Direct2DPixelDataPages::Direct2DPixelDataPages (ComSmartPtr context, +Direct2DPixelDataPages::Direct2DPixelDataPages (ComSmartPtr device, ImagePixelData::Ptr image, State initialState) : backingData (image), - pages (makePages (getDeviceForContext (context), backingData, initialState == State::cleared)), + pages (makePages (device, backingData, initialState == State::cleared)), upToDate (initialState != State::unsuitableToRead) { // The backup image must be a software image @@ -284,12 +274,11 @@ Direct2DPixelData::Direct2DPixelData (ImagePixelData::Ptr ptr, State initialStat directX->adapters.addListener (*this); } -Direct2DPixelData::Direct2DPixelData (ComSmartPtr context, +Direct2DPixelData::Direct2DPixelData (ComSmartPtr device, ComSmartPtr page) - : Direct2DPixelData (readFromDirect2DBitmap (context, page), State::drawn) + : Direct2DPixelData (readFromDirect2DBitmap (Direct2DDeviceContext::create (device), page), State::drawn) { - if (const auto device1 = getDeviceForContext (context)) - pagesForDevice.emplace (device1, Direct2DPixelDataPages { page, backingData }); + pagesForDevice.emplace (device, Direct2DPixelDataPages { page, backingData }); } Direct2DPixelData::Direct2DPixelData (Image::PixelFormat formatToUse, int w, int h, bool clearIn) @@ -303,14 +292,12 @@ Direct2DPixelData::~Direct2DPixelData() directX->adapters.removeListener (*this); } -auto Direct2DPixelData::getIteratorForContext (ComSmartPtr context) +auto Direct2DPixelData::getIteratorForDevice (ComSmartPtr device) { - const auto device1 = getDeviceForContext (context); - - if (device1 == nullptr) + if (device == nullptr) return pagesForDevice.end(); - const auto iter = pagesForDevice.find (device1); + const auto iter = pagesForDevice.find (device); if (iter != pagesForDevice.end()) return iter; @@ -350,7 +337,7 @@ auto Direct2DPixelData::getIteratorForContext (ComSmartPtr return Pages::State::unsuitableToRead; }(); - const auto pair = pagesForDevice.emplace (device1, Pages { context, backingData, initialState }); + const auto pair = pagesForDevice.emplace (device, Pages { device, backingData, initialState }); return pair.first; } @@ -422,7 +409,12 @@ std::unique_ptr Direct2DPixelData::createLowLevelContex if (adapter == nullptr) return invalidateAllAndReturnSoftwareContext(); - const auto context = Direct2DDeviceContext::create (adapter); + const auto device = adapter->direct2DDevice; + + if (device == nullptr) + return invalidateAllAndReturnSoftwareContext(); + + const auto context = Direct2DDeviceContext::create (device); if (context == nullptr) return invalidateAllAndReturnSoftwareContext(); @@ -432,7 +424,7 @@ std::unique_ptr Direct2DPixelData::createLowLevelContex if (maxSize < width || maxSize < height) return invalidateAllAndReturnSoftwareContext(); - const auto iter = getIteratorForContext (context); + const auto iter = getIteratorForDevice (device); jassert (iter != pagesForDevice.end()); const auto pages = iter->second.getPages(); @@ -448,7 +440,7 @@ std::unique_ptr Direct2DPixelData::createLowLevelContex struct FlushingContext : public Direct2DImageContext { - FlushingContext (Direct2DPixelData::Ptr selfIn, + FlushingContext (Ptr selfIn, ComSmartPtr context, ComSmartPtr target) : Direct2DImageContext (context, target, D2DUtilities::rectFromSize (target->GetPixelSize())), @@ -473,7 +465,7 @@ std::unique_ptr Direct2DPixelData::createLowLevelContex ComSmartPtr storedContext; ComSmartPtr storedTarget; - Direct2DPixelData::Ptr self; + Ptr self; ImagePixelData::Ptr backup; }; @@ -534,7 +526,12 @@ void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result) return; } - const auto context = Direct2DDeviceContext::create (adapter); + const auto device = adapter->direct2DDevice; + + if (device == nullptr) + return; + + const auto context = Direct2DDeviceContext::create (device); const auto maxSize = (int) context->GetMaximumBitmapSize(); if (context == nullptr || maxSize < width || maxSize < height) @@ -551,7 +548,7 @@ void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result) return; } - effect->SetInput (0, getFirstPageForContext (context)); + effect->SetInput (0, getFirstPageForDevice (device)); effect->SetValue (D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, radius / 3.0f); const auto outputPixelData = Direct2DBitmap::createBitmap (context, @@ -565,7 +562,7 @@ void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result) context->DrawImage (effect); context->EndDraw(); - result = Image { new Direct2DPixelData { context, outputPixelData } }; + result = Image { new Direct2DPixelData { device, outputPixelData } }; } void Direct2DPixelData::applySingleChannelBoxBlurEffect (int radius, Image& result) @@ -581,7 +578,12 @@ void Direct2DPixelData::applySingleChannelBoxBlurEffect (int radius, Image& resu return; } - const auto context = Direct2DDeviceContext::create (adapter); + const auto device = adapter->direct2DDevice; + + if (device == nullptr) + return; + + const auto context = Direct2DDeviceContext::create (device); const auto maxSize = (int) context->GetMaximumBitmapSize(); if (context == nullptr || maxSize < width || maxSize < height) @@ -629,7 +631,7 @@ void Direct2DPixelData::applySingleChannelBoxBlurEffect (int radius, Image& resu return; } - begin->SetInput (0, getFirstPageForContext (context)); + begin->SetInput (0, getFirstPageForDevice (device)); const auto outputPixelData = Direct2DBitmap::createBitmap (context, Image::ARGB, @@ -642,12 +644,12 @@ void Direct2DPixelData::applySingleChannelBoxBlurEffect (int radius, Image& resu context->DrawImage (end); context->EndDraw(); - result = Image { new Direct2DPixelData { context, outputPixelData } }; + result = Image { new Direct2DPixelData { device, outputPixelData } }; } -auto Direct2DPixelData::getPagesForContext (ComSmartPtr context) -> Span +auto Direct2DPixelData::getPagesForDevice (ComSmartPtr device) -> Span { - return getIteratorForContext (context)->second.getPages(); + return getIteratorForDevice (device)->second.getPages(); } //============================================================================== @@ -753,7 +755,8 @@ public: beginTest ("Ensure data parity across mapped page boundaries"); { const auto adapterToUse = directX->adapters.getDefaultAdapter(); - const auto contextToUse = Direct2DDeviceContext::create (adapterToUse); + const auto deviceToUse = adapterToUse->direct2DDevice; + const auto contextToUse = Direct2DDeviceContext::create (deviceToUse); for (auto sourceFormat : formats) { @@ -779,7 +782,7 @@ public: const auto maxPageBounds = [&] { if (auto* data = dynamic_cast (d2dImage.getPixelData().get())) - if (auto pages = data->getPagesForContext (contextToUse); ! pages.empty()) + if (auto pages = data->getPagesForDevice (deviceToUse); ! pages.empty()) return pages.front().getBounds(); return Rectangle{}; diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.h b/modules/juce_graphics/native/juce_Direct2DImage_windows.h index fc303369d3..fa70036adb 100644 --- a/modules/juce_graphics/native/juce_Direct2DImage_windows.h +++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.h @@ -77,7 +77,7 @@ public: - mark the GPU images as up-to-date, or - clear the GPU images, then mark them as up-to-date */ - Direct2DPixelDataPages (ComSmartPtr, ImagePixelData::Ptr, State); + Direct2DPixelDataPages (ComSmartPtr, ImagePixelData::Ptr, State); /* Returns all pages included in this set. This will be called before reading from the pages (e.g. when drawing them). @@ -132,7 +132,7 @@ public: This will immediately copy the content of the image to the software backup, so that the image can still be drawn if original device goes away. */ - Direct2DPixelData (ComSmartPtr, ComSmartPtr); + Direct2DPixelData (ComSmartPtr, ComSmartPtr); /* Creates software image storage of the requested size. */ Direct2DPixelData (Image::PixelFormat, int, int, bool); @@ -178,14 +178,14 @@ public: through the Direct2D API will have unpredictable results. If you want to render into this image using D2D, call createLowLevelContext. */ - Span getPagesForContext (ComSmartPtr); + Span getPagesForDevice (ComSmartPtr); /* Utility function that just returns a pointer to the bitmap for the first page returned from getPagesForContext. */ - ComSmartPtr getFirstPageForContext (ComSmartPtr context) + ComSmartPtr getFirstPageForDevice (ComSmartPtr device) { - const auto pages = getPagesForContext (context); + const auto pages = getPagesForDevice (device); return ! pages.empty() ? pages.front().bitmap : nullptr; } @@ -199,7 +199,7 @@ private: }; Direct2DPixelData (ImagePixelData::Ptr, State); - auto getIteratorForContext (ComSmartPtr); + auto getIteratorForDevice (ComSmartPtr); void adapterCreated (DxgiAdapter::Ptr) override {} void adapterRemoved (DxgiAdapter::Ptr adapter) override diff --git a/modules/juce_graphics/native/juce_DirectX_windows.h b/modules/juce_graphics/native/juce_DirectX_windows.h index 516d20248e..e76eccffc0 100644 --- a/modules/juce_graphics/native/juce_DirectX_windows.h +++ b/modules/juce_graphics/native/juce_DirectX_windows.h @@ -333,6 +333,16 @@ struct D2DUtilities { return { (int) s.width, (int) s.height }; } + + static ComSmartPtr getDeviceForContext (ComSmartPtr context) + { + if (context == nullptr) + return {}; + + ComSmartPtr device; + context->GetDevice (device.resetAndGetPointerAddress()); + return device.getInterface(); + } }; //============================================================================== diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index a9f6ab7f86..2e2eec13ad 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -5277,7 +5277,7 @@ private: Image getImage() const { - return Image { new Direct2DPixelData { deviceContext, bitmap } }; + return Image { new Direct2DPixelData { adapter->direct2DDevice, bitmap } }; } ComSmartPtr getBitmap() const