Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsd3d11texturebridge.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qloggingcategory.h>
7#include <QtCore/private/qsystemerror_p.h>
8
9#include <dxgi1_2.h>
10
12
13namespace QtMultimediaPrivate {
14
15namespace {
16Q_LOGGING_CATEGORY(lcD3D11TextureBridge, "qt.multimedia.windows.d3d11texturebridge");
17}
18
19// Timeout for keyed mutex acquisition. Using a finite timeout prevents
20// deadlocks when the D3D device is lost between AcquireSync and ReleaseSync.
21static constexpr DWORD kMutexTimeoutMs = 5000;
22
25 const QSize &frameSize, UINT index)
26{
30
32 return false;
33
34 // Flush to ensure that texture is fully updated before we share it.
35 ctx->Flush();
36
39 << "AcquireSync failed:" << QSystemError::windowsComString(hr);
40 return false;
41 }
42
43 const UINT width = static_cast<UINT>(frameSize.width());
44 const UINT height = static_cast<UINT>(frameSize.height());
45
46 // A crop box is needed because the source texture may be bigger than the
47 // frame size, e.g. to account for a decoder's surface alignment requirements.
48 const D3D11_BOX crop{ 0, 0, 0, width, height, 1 };
49 ctx->CopySubresourceRegion(m_srcTex.Get(), 0, 0, 0, 0, tex.Get(), index, &crop);
50
52 return true;
53}
54
62
66{
67 if (!ensureDestTex(dev))
68 return {};
69
71 return {};
72
73 return m_outputTex;
74}
75
79{
81
82 if (!ensureDestTex(dev))
83 return false;
84
87 << "AcquireSync failed:" << QSystemError::windowsComString(hr);
88 return false;
89 }
90
91 ctx->CopySubresourceRegion(destination.Get(), 0, 0, 0, 0, m_destTex.Get(), 0, nullptr);
92
94
95 return true;
96}
97
99{
100 if (m_destDevice != dev) {
101 // Destination device changed. Recreate texture.
102 m_destTex = nullptr;
104 }
105
106 if (m_destTex)
107 return true;
108
109 if (const HRESULT hr =
111 hr != S_OK) {
113 << "OpenSharedResource1 failed:" << QSystemError::windowsComString(hr);
114 return false;
115 }
116
119
120 desc.MiscFlags = 0;
122
123 if (const HRESULT hr =
125 hr != S_OK) {
127 << "CreateTexture2D failed:" << QSystemError::windowsComString(hr);
128 return false;
129 }
130
131 if (const HRESULT hr = m_destTex.As(&m_destMutex); hr != S_OK) {
133 << "QueryInterface(IDXGIKeyedMutex) failed:" << QSystemError::windowsComString(hr);
134 return false;
135 }
136
137 return true;
138}
139
141 const QSize &frameSize)
142{
144 return recreateSrc(dev, tex, frameSize);
145
146 return true;
147}
148
150 const ComPtr<ID3D11Texture2D> &tex,
151 const QSize &frameSize) const
152{
153 if (!m_srcTex)
154 return false;
155
156 // Check if device has changed
159 if (dev != texDevice.Get())
160 return false;
161
162 // Check if shared texture has correct size and format
165
168
170 return false;
171
172 const UINT width = static_cast<UINT>(frameSize.width());
173 const UINT height = static_cast<UINT>(frameSize.height());
174
176 return false;
177
178 return true;
179}
180
182 const QSize &frameSize)
183{
185
187 tex->GetDesc(&desc);
188
189 const UINT width = static_cast<UINT>(frameSize.width());
190 const UINT height = static_cast<UINT>(frameSize.height());
191
193 texDesc.MipLevels = 1;
195
196 if (const HRESULT hr =
198 hr != S_OK) {
200 << "CreateTexture2D failed:" << QSystemError::windowsComString(hr);
201 return false;
202 }
203
205 if (const HRESULT hr = m_srcTex.As(&res); hr != S_OK) {
207 << "QueryInterface(IDXGIResource1) failed:" << QSystemError::windowsComString(hr);
208 return false;
209 }
210
211 const HRESULT hr =
213
214 if (hr != S_OK || !m_sharedHandle) {
216 << "CreateSharedHandle failed:" << QSystemError::windowsComString(hr);
217 return false;
218 }
219
220 if (const HRESULT mutexHr = m_srcTex.As(&m_srcMutex); mutexHr != S_OK || !m_srcMutex) {
221 qCWarning(lcD3D11TextureBridge) << "QueryInterface(IDXGIKeyedMutex) failed:"
223 return false;
224 }
225
226 m_destTex = nullptr;
227 m_destMutex = nullptr;
228 return true;
229}
230
231} // namespace QtMultimediaPrivate
232
233QT_END_NAMESPACE
Combined button and popup list for selecting options.
static constexpr DWORD kMutexTimeoutMs