1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Direct2D: Move SwapChain into Direct2DHwndContext.cpp

This commit is contained in:
reuk 2025-04-17 14:09:58 +01:00 committed by Oli
parent 43c9f28d59
commit f56c7faf40
3 changed files with 187 additions and 200 deletions

View file

@ -598,151 +598,6 @@ std::optional<Direct2DDeviceResources> Direct2DDeviceResources::create (ComSmart
return result;
}
//==============================================================================
HRESULT SwapChain::create (HWND hwnd, Rectangle<int> 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<IDXGISwapChain2> 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 SwapChain::canPaint() const
{
return chain != nullptr && buffer != nullptr;
}
HRESULT SwapChain::resize (Rectangle<int> 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<IDXGIDevice> 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<int> SwapChain::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* SwapChain::getEvent()
{
if (swapChainEvent.has_value())
return &*swapChainEvent;
return nullptr;
}
ComSmartPtr<IDXGISurface> SwapChain::getSurface() const
{
if (chain == nullptr)
return nullptr;
ComSmartPtr<IDXGISurface> surface;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
if (const auto hr = chain->GetBuffer (0, __uuidof (surface), reinterpret_cast<void**> (surface.resetAndGetPointerAddress())); FAILED (hr))
return nullptr;
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
return surface;
}
void SwapChain::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());
}
//==============================================================================
std::optional<CompositionTree> CompositionTree::create (IDXGIDevice* dxgiDevice,
HWND hwnd,

View file

@ -434,61 +434,6 @@ private:
Direct2DDeviceResources() = default;
};
class SwapChain
{
public:
SwapChain() = default;
HRESULT create (HWND hwnd, Rectangle<int> size, DxgiAdapter::Ptr adapter);
bool canPaint() const;
HRESULT resize (Rectangle<int> newSize);
Rectangle<int> getSize() const;
WindowsScopedEvent* getEvent();
auto getChain() const
{
return chain;
}
ComSmartPtr<ID2D1Bitmap1> 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<IDXGISurface> getSurface() const;
void createBuffer (DxgiAdapter::Ptr adapter);
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> directX;
};
AssignableDirectX directX;
ComSmartPtr<IDXGISwapChain1> chain;
ComSmartPtr<ID2D1Bitmap1> buffer;
std::optional<WindowsScopedEvent> swapChainEvent;
};
//==============================================================================
/* DirectComposition
Using DirectComposition enables transparent windows and smoother window