mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Direct2D: Correctly recreate ID2D1DeviceContext when moving transparent windows between devices
This commit is contained in:
parent
14d52769dc
commit
25e2fa44ff
4 changed files with 73 additions and 67 deletions
|
|
@ -255,9 +255,11 @@ public:
|
||||||
// Constructor for first stack entry
|
// Constructor for first stack entry
|
||||||
SavedState (Direct2DGraphicsContext& ownerIn,
|
SavedState (Direct2DGraphicsContext& ownerIn,
|
||||||
Rectangle<int> frameSizeIn,
|
Rectangle<int> frameSizeIn,
|
||||||
|
ComSmartPtr<ID2D1DeviceContext1> deviceContext,
|
||||||
ComSmartPtr<ID2D1SolidColorBrush>& colourBrushIn,
|
ComSmartPtr<ID2D1SolidColorBrush>& colourBrushIn,
|
||||||
Direct2DDeviceResources& deviceResourcesIn)
|
Direct2DDeviceResources& deviceResourcesIn)
|
||||||
: owner (ownerIn),
|
: owner (ownerIn),
|
||||||
|
context (deviceContext),
|
||||||
currentBrush (colourBrushIn),
|
currentBrush (colourBrushIn),
|
||||||
colourBrush (colourBrushIn),
|
colourBrush (colourBrushIn),
|
||||||
deviceResources (deviceResourcesIn),
|
deviceResources (deviceResourcesIn),
|
||||||
|
|
@ -267,7 +269,7 @@ public:
|
||||||
|
|
||||||
void pushLayer (const D2D1_LAYER_PARAMETERS1& layerParameters)
|
void pushLayer (const D2D1_LAYER_PARAMETERS1& layerParameters)
|
||||||
{
|
{
|
||||||
layers.push (deviceResources.deviceContext, layerParameters);
|
layers.push (context, layerParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushGeometryClipLayer (ComSmartPtr<ID2D1Geometry> geometry)
|
void pushGeometryClipLayer (ComSmartPtr<ID2D1Geometry> geometry)
|
||||||
|
|
@ -290,7 +292,7 @@ public:
|
||||||
{
|
{
|
||||||
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, pushAliasedAxisAlignedLayerTime)
|
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, pushAliasedAxisAlignedLayerTime)
|
||||||
|
|
||||||
layers.push (deviceResources.deviceContext, r);
|
layers.push (context, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushTransparencyLayer (float opacity)
|
void pushTransparencyLayer (float opacity)
|
||||||
|
|
@ -301,12 +303,12 @@ public:
|
||||||
void popLayers()
|
void popLayers()
|
||||||
{
|
{
|
||||||
while (! layers.isEmpty())
|
while (! layers.isEmpty())
|
||||||
layers.popOne (deviceResources.deviceContext);
|
layers.popOne (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void popTopLayer()
|
void popTopLayer()
|
||||||
{
|
{
|
||||||
layers.popOne (deviceResources.deviceContext);
|
layers.popOne (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFont (const Font& newFont)
|
void setFont (const Font& newFont)
|
||||||
|
|
@ -349,17 +351,17 @@ public:
|
||||||
|
|
||||||
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime);
|
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (Direct2DMetricsHub::getInstance()->imageContextMetrics, createBitmapTime);
|
||||||
|
|
||||||
return Direct2DBitmap::toBitmap (fillType.image, deviceResources.deviceContext, Image::ARGB);
|
return Direct2DBitmap::toBitmap (fillType.image, context, Image::ARGB);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (d2d1Bitmap != nullptr)
|
if (d2d1Bitmap != nullptr)
|
||||||
{
|
{
|
||||||
D2D1_BRUSH_PROPERTIES brushProps { fillType.getOpacity(), D2DUtilities::transformToMatrix (fillType.transform) };
|
D2D1_BRUSH_PROPERTIES brushProps { fillType.getOpacity(), D2DUtilities::transformToMatrix (fillType.transform) };
|
||||||
auto bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
|
auto bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
|
||||||
if (const auto hr = deviceResources.deviceContext->CreateBitmapBrush (d2d1Bitmap,
|
if (const auto hr = context->CreateBitmapBrush (d2d1Bitmap,
|
||||||
bmProps,
|
bmProps,
|
||||||
brushProps,
|
brushProps,
|
||||||
bitmapBrush.resetAndGetPointerAddress()); SUCCEEDED (hr))
|
bitmapBrush.resetAndGetPointerAddress()); SUCCEEDED (hr))
|
||||||
{
|
{
|
||||||
currentBrush = bitmapBrush;
|
currentBrush = bitmapBrush;
|
||||||
}
|
}
|
||||||
|
|
@ -369,12 +371,12 @@ public:
|
||||||
{
|
{
|
||||||
if (fillType.gradient->isRadial)
|
if (fillType.gradient->isRadial)
|
||||||
{
|
{
|
||||||
radialGradient = deviceResources.radialGradientCache.get (*fillType.gradient, deviceResources.deviceContext, owner.metrics.get());
|
radialGradient = deviceResources.radialGradientCache.get (*fillType.gradient, context, owner.metrics.get());
|
||||||
currentBrush = radialGradient;
|
currentBrush = radialGradient;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linearGradient = deviceResources.linearGradientCache.get (*fillType.gradient, deviceResources.deviceContext, owner.metrics.get());
|
linearGradient = deviceResources.linearGradientCache.get (*fillType.gradient, context, owner.metrics.get());
|
||||||
currentBrush = linearGradient;
|
currentBrush = linearGradient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -509,7 +511,8 @@ public:
|
||||||
|
|
||||||
Direct2DGraphicsContext& owner;
|
Direct2DGraphicsContext& owner;
|
||||||
|
|
||||||
ComSmartPtr<ID2D1Brush> currentBrush = nullptr;
|
ComSmartPtr<ID2D1DeviceContext1> context;
|
||||||
|
ComSmartPtr<ID2D1Brush> currentBrush;
|
||||||
ComSmartPtr<ID2D1SolidColorBrush>& colourBrush; // reference to shared colour brush
|
ComSmartPtr<ID2D1SolidColorBrush>& colourBrush; // reference to shared colour brush
|
||||||
ComSmartPtr<ID2D1BitmapBrush> bitmapBrush;
|
ComSmartPtr<ID2D1BitmapBrush> bitmapBrush;
|
||||||
ComSmartPtr<ID2D1LinearGradientBrush> linearGradient;
|
ComSmartPtr<ID2D1LinearGradientBrush> linearGradient;
|
||||||
|
|
@ -520,7 +523,7 @@ public:
|
||||||
Direct2DDeviceResources& deviceResources;
|
Direct2DDeviceResources& deviceResources;
|
||||||
RectangleList<float> deviceSpaceClipList;
|
RectangleList<float> deviceSpaceClipList;
|
||||||
|
|
||||||
Font font { FontOptions {} };
|
Font font { FontOptions{} };
|
||||||
|
|
||||||
FillType fillType;
|
FillType fillType;
|
||||||
|
|
||||||
|
|
@ -552,12 +555,12 @@ protected:
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Direct2DGraphicsContext::SavedState>> savedClientStates;
|
std::vector<std::unique_ptr<Direct2DGraphicsContext::SavedState>> savedClientStates;
|
||||||
|
|
||||||
virtual HRESULT prepare()
|
virtual bool prepare()
|
||||||
{
|
{
|
||||||
if (! deviceResources.has_value())
|
if (! deviceResources.has_value())
|
||||||
deviceResources = Direct2DDeviceResources::create (directX->adapters.getDefaultAdapter());
|
deviceResources = Direct2DDeviceResources::create (getDeviceContext());
|
||||||
|
|
||||||
return deviceResources.has_value() ? S_OK : E_FAIL;
|
return deviceResources.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void teardown()
|
virtual void teardown()
|
||||||
|
|
@ -565,8 +568,6 @@ protected:
|
||||||
deviceResources.reset();
|
deviceResources.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ComSmartPtr<ID2D1Image> getDeviceContextTarget() const = 0;
|
|
||||||
|
|
||||||
virtual bool checkPaintReady()
|
virtual bool checkPaintReady()
|
||||||
{
|
{
|
||||||
return deviceResources.has_value();
|
return deviceResources.has_value();
|
||||||
|
|
@ -607,15 +608,17 @@ public:
|
||||||
|
|
||||||
JUCE_TRACE_EVENT_INT_RECT_LIST (etw::startD2DFrame, etw::direct2dKeyword, owner.getFrameId(), paintAreas);
|
JUCE_TRACE_EVENT_INT_RECT_LIST (etw::startD2DFrame, etw::direct2dKeyword, owner.getFrameId(), paintAreas);
|
||||||
|
|
||||||
|
const auto deviceContext = getDeviceContext();
|
||||||
|
|
||||||
// Init device context transform
|
// Init device context transform
|
||||||
resetTransform (deviceResources->deviceContext);
|
resetTransform (deviceContext);
|
||||||
|
|
||||||
const auto effectiveDpi = USER_DEFAULT_SCREEN_DPI * dpiScale;
|
const auto effectiveDpi = USER_DEFAULT_SCREEN_DPI * dpiScale;
|
||||||
deviceResources->deviceContext->SetDpi (effectiveDpi, effectiveDpi);
|
deviceContext->SetDpi (effectiveDpi, effectiveDpi);
|
||||||
|
|
||||||
// Start drawing
|
// Start drawing
|
||||||
deviceResources->deviceContext->SetTarget (getDeviceContextTarget());
|
deviceContext->SetTarget (getDeviceContextTarget());
|
||||||
deviceResources->deviceContext->BeginDraw();
|
deviceContext->BeginDraw();
|
||||||
|
|
||||||
// Init the save state stack and return the first saved state
|
// Init the save state stack and return the first saved state
|
||||||
return pushFirstSavedState (paintBounds);
|
return pushFirstSavedState (paintBounds);
|
||||||
|
|
@ -633,8 +636,9 @@ public:
|
||||||
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, endDrawDuration)
|
JUCE_D2DMETRICS_SCOPED_ELAPSED_TIME (owner.metrics, endDrawDuration)
|
||||||
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::endDraw, etw::direct2dKeyword, owner.getFrameId());
|
JUCE_SCOPED_TRACE_EVENT_FRAME (etw::endDraw, etw::direct2dKeyword, owner.getFrameId());
|
||||||
|
|
||||||
hr = deviceResources->deviceContext->EndDraw();
|
const auto deviceContext = getDeviceContext();
|
||||||
deviceResources->deviceContext->SetTarget (nullptr);
|
hr = deviceContext->EndDraw();
|
||||||
|
deviceContext->SetTarget (nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
jassert (SUCCEEDED (hr));
|
jassert (SUCCEEDED (hr));
|
||||||
|
|
@ -660,6 +664,7 @@ public:
|
||||||
|
|
||||||
savedClientStates.push_back (std::make_unique<SavedState> (owner,
|
savedClientStates.push_back (std::make_unique<SavedState> (owner,
|
||||||
initialClipRegion,
|
initialClipRegion,
|
||||||
|
getDeviceContext(),
|
||||||
deviceResources->colourBrush,
|
deviceResources->colourBrush,
|
||||||
*deviceResources));
|
*deviceResources));
|
||||||
|
|
||||||
|
|
@ -689,22 +694,19 @@ public:
|
||||||
popSavedState();
|
popSavedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
ComSmartPtr<ID2D1DeviceContext1> getDeviceContext() const noexcept
|
|
||||||
{
|
|
||||||
return deviceResources->deviceContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual RectangleList<int> getPaintAreas() const = 0;
|
virtual RectangleList<int> getPaintAreas() const = 0;
|
||||||
virtual Rectangle<int> getFrameSize() const = 0;
|
virtual Rectangle<int> getFrameSize() const = 0;
|
||||||
|
virtual ComSmartPtr<ID2D1DeviceContext1> getDeviceContext() const = 0;
|
||||||
|
virtual ComSmartPtr<ID2D1Image> getDeviceContextTarget() const = 0;
|
||||||
|
|
||||||
void setDeviceContextTransform (AffineTransform transform)
|
void setDeviceContextTransform (AffineTransform transform)
|
||||||
{
|
{
|
||||||
setTransform (deviceResources->deviceContext, transform);
|
setTransform (getDeviceContext(), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetDeviceContextTransform()
|
void resetDeviceContextTransform()
|
||||||
{
|
{
|
||||||
resetTransform (deviceResources->deviceContext);
|
resetTransform (getDeviceContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getDirect2DFactory()
|
auto getDirect2DFactory()
|
||||||
|
|
@ -737,7 +739,7 @@ public:
|
||||||
if (rectangleListSpriteBatch == nullptr)
|
if (rectangleListSpriteBatch == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto deviceContext = getDeviceContext();
|
const auto deviceContext = getDeviceContext();
|
||||||
|
|
||||||
if (deviceContext == nullptr)
|
if (deviceContext == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -798,7 +800,7 @@ public:
|
||||||
|
|
||||||
owner.applyPendingClipList();
|
owner.applyPendingClipList();
|
||||||
|
|
||||||
auto deviceContext = deviceResources->deviceContext;
|
auto deviceContext = getDeviceContext();
|
||||||
|
|
||||||
if (deviceContext == nullptr)
|
if (deviceContext == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
@ -838,10 +840,7 @@ private:
|
||||||
|
|
||||||
DxgiAdapter::Ptr findAdapter() const
|
DxgiAdapter::Ptr findAdapter() const
|
||||||
{
|
{
|
||||||
if (! deviceResources.has_value())
|
return Direct2DDeviceResources::findAdapter (directX->adapters, getDeviceContext());
|
||||||
return {};
|
|
||||||
|
|
||||||
return deviceResources->findAdapter (directX->adapters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adapterCreated (DxgiAdapter::Ptr newAdapter) override
|
void adapterCreated (DxgiAdapter::Ptr newAdapter) override
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
SwapChain swap;
|
SwapChain swap;
|
||||||
|
ComSmartPtr<ID2D1DeviceContext1> deviceContext;
|
||||||
std::unique_ptr<SwapChainThread> swapChainThread;
|
std::unique_ptr<SwapChainThread> swapChainThread;
|
||||||
BackBufferLock presentation;
|
BackBufferLock presentation;
|
||||||
std::optional<CompositionTree> compositionTree;
|
std::optional<CompositionTree> compositionTree;
|
||||||
|
|
@ -324,29 +325,35 @@ private:
|
||||||
|
|
||||||
HWND hwnd = nullptr;
|
HWND hwnd = nullptr;
|
||||||
|
|
||||||
HRESULT prepare() override
|
bool prepare() override
|
||||||
{
|
{
|
||||||
const auto adapter = directX->adapters.getAdapterForHwnd (hwnd);
|
const auto adapter = directX->adapters.getAdapterForHwnd (hwnd);
|
||||||
|
|
||||||
if (adapter == nullptr)
|
if (adapter == nullptr)
|
||||||
return E_FAIL;
|
return false;
|
||||||
|
|
||||||
|
if (deviceContext == nullptr)
|
||||||
|
deviceContext = Direct2DDeviceContext::create (adapter);
|
||||||
|
|
||||||
|
if (deviceContext == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (! deviceResources.has_value())
|
if (! deviceResources.has_value())
|
||||||
deviceResources = Direct2DDeviceResources::create (adapter);
|
deviceResources = Direct2DDeviceResources::create (deviceContext);
|
||||||
|
|
||||||
if (! deviceResources.has_value())
|
if (! deviceResources.has_value())
|
||||||
return E_FAIL;
|
return false;
|
||||||
|
|
||||||
if (! hwnd || frameSize.isEmpty())
|
if (! hwnd || frameSize.isEmpty())
|
||||||
return E_FAIL;
|
return false;
|
||||||
|
|
||||||
if (! swap.canPaint())
|
if (! swap.canPaint())
|
||||||
{
|
{
|
||||||
if (auto hr = swap.create (hwnd, frameSize, adapter); FAILED (hr))
|
if (auto hr = swap.create (hwnd, frameSize, adapter); FAILED (hr))
|
||||||
return hr;
|
return false;
|
||||||
|
|
||||||
if (auto hr = swap.createBuffer (deviceResources->deviceContext); FAILED (hr))
|
if (auto hr = swap.createBuffer (getDeviceContext()); FAILED (hr))
|
||||||
return hr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! swapChainThread && swap.swapChainEvent.has_value())
|
if (! swapChainThread && swap.swapChainEvent.has_value())
|
||||||
|
|
@ -356,9 +363,9 @@ private:
|
||||||
compositionTree = CompositionTree::create (adapter->dxgiDevice, hwnd, swap.chain);
|
compositionTree = CompositionTree::create (adapter->dxgiDevice, hwnd, swap.chain);
|
||||||
|
|
||||||
if (! compositionTree.has_value())
|
if (! compositionTree.has_value())
|
||||||
return E_FAIL;
|
return false;
|
||||||
|
|
||||||
return S_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void teardown() override
|
void teardown() override
|
||||||
|
|
@ -435,10 +442,15 @@ public:
|
||||||
return getClientRect();
|
return getClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComSmartPtr<ID2D1DeviceContext1> getDeviceContext() const override
|
||||||
|
{
|
||||||
|
return deviceContext;
|
||||||
|
}
|
||||||
|
|
||||||
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
|
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
|
||||||
{
|
{
|
||||||
if (auto* p = presentation.getPresentation())
|
if (auto* p = presentation.getPresentation())
|
||||||
return p->getPresentationBitmap (swap.getSize(), deviceResources->deviceContext);
|
return p->getPresentationBitmap (swap.getSize(), getDeviceContext());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
@ -466,11 +478,11 @@ public:
|
||||||
// Resize/scale the swap chain
|
// Resize/scale the swap chain
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
if (auto deviceContext = deviceResources->deviceContext)
|
if (auto dc = getDeviceContext())
|
||||||
{
|
{
|
||||||
ScopedMultithread scopedMultithread { directX->getD2DMultithread() };
|
ScopedMultithread scopedMultithread { directX->getD2DMultithread() };
|
||||||
|
|
||||||
auto hr = swap.resize (size, deviceContext);
|
auto hr = swap.resize (size, dc);
|
||||||
jassert (SUCCEEDED (hr));
|
jassert (SUCCEEDED (hr));
|
||||||
if (FAILED (hr))
|
if (FAILED (hr))
|
||||||
teardown();
|
teardown();
|
||||||
|
|
@ -609,7 +621,9 @@ public:
|
||||||
// This won't capture child windows. Perhaps a better approach would be to use
|
// This won't capture child windows. Perhaps a better approach would be to use
|
||||||
// IGraphicsCaptureItemInterop, although this is only supported on Windows 10 v1903+
|
// IGraphicsCaptureItemInterop, although this is only supported on Windows 10 v1903+
|
||||||
|
|
||||||
if (frameSize.isEmpty() || deviceResources->deviceContext == nullptr || swap.buffer == nullptr)
|
const auto context = getDeviceContext();
|
||||||
|
|
||||||
|
if (frameSize.isEmpty() || context == nullptr || swap.buffer == nullptr)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
// Create the bitmap to receive the snapshot
|
// Create the bitmap to receive the snapshot
|
||||||
|
|
@ -621,7 +635,7 @@ public:
|
||||||
|
|
||||||
ComSmartPtr<ID2D1Bitmap1> snapshot;
|
ComSmartPtr<ID2D1Bitmap1> snapshot;
|
||||||
|
|
||||||
if (const auto hr = deviceResources->deviceContext->CreateBitmap (size, nullptr, 0, bitmapProperties, snapshot.resetAndGetPointerAddress()); FAILED (hr))
|
if (const auto hr = context->CreateBitmap (size, nullptr, 0, bitmapProperties, snapshot.resetAndGetPointerAddress()); FAILED (hr))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const ScopedMultithread scope { directX->getD2DMultithread() };
|
const ScopedMultithread scope { directX->getD2DMultithread() };
|
||||||
|
|
@ -636,7 +650,7 @@ public:
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const Image result { Direct2DPixelData::fromDirect2DBitmap (directX->adapters.getAdapterForHwnd (hwnd),
|
const Image result { Direct2DPixelData::fromDirect2DBitmap (directX->adapters.getAdapterForHwnd (hwnd),
|
||||||
deviceResources->deviceContext,
|
context,
|
||||||
snapshot) };
|
snapshot) };
|
||||||
|
|
||||||
swap.chain->Present (0, DXGI_PRESENT_DO_NOT_WAIT);
|
swap.chain->Present (0, DXGI_PRESENT_DO_NOT_WAIT);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,11 @@ public:
|
||||||
return { (int) size.width, (int) size.height };
|
return { (int) size.width, (int) size.height };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComSmartPtr<ID2D1DeviceContext1> getDeviceContext() const override
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
|
ComSmartPtr<ID2D1Image> getDeviceContextTarget() const override
|
||||||
{
|
{
|
||||||
return bitmap;
|
return bitmap;
|
||||||
|
|
|
||||||
|
|
@ -332,21 +332,15 @@ public:
|
||||||
return desc.AdapterLuid;
|
return desc.AdapterLuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<Direct2DDeviceResources> create (DxgiAdapter::Ptr adapter)
|
|
||||||
{
|
|
||||||
return create (Direct2DDeviceContext::create (adapter));
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::optional<Direct2DDeviceResources> create (ComSmartPtr<ID2D1DeviceContext1> context)
|
static std::optional<Direct2DDeviceResources> create (ComSmartPtr<ID2D1DeviceContext1> context)
|
||||||
{
|
{
|
||||||
if (context == nullptr)
|
if (context == nullptr)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Direct2DDeviceResources result;
|
Direct2DDeviceResources result;
|
||||||
result.deviceContext = context;
|
|
||||||
|
|
||||||
if (const auto hr = result.deviceContext->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f),
|
if (const auto hr = context->CreateSolidColorBrush (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f),
|
||||||
result.colourBrush.resetAndGetPointerAddress());
|
result.colourBrush.resetAndGetPointerAddress());
|
||||||
FAILED (hr))
|
FAILED (hr))
|
||||||
{
|
{
|
||||||
jassertfalse;
|
jassertfalse;
|
||||||
|
|
@ -358,12 +352,6 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DxgiAdapter::Ptr findAdapter (const DxgiAdapters& adapters) const
|
|
||||||
{
|
|
||||||
return findAdapter (adapters, deviceContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
ComSmartPtr<ID2D1DeviceContext1> deviceContext;
|
|
||||||
ComSmartPtr<ID2D1SolidColorBrush> colourBrush;
|
ComSmartPtr<ID2D1SolidColorBrush> colourBrush;
|
||||||
LinearGradientCache linearGradientCache;
|
LinearGradientCache linearGradientCache;
|
||||||
RadialGradientCache radialGradientCache;
|
RadialGradientCache radialGradientCache;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue