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
4
#
include
"qwindowsd3d11texturebridge_p.h"
5
6
#
include
<
QtCore
/
qloggingcategory
.
h
>
7
#
include
<
QtCore
/
private
/
qsystemerror_p
.
h
>
8
9
#
include
<
dxgi1_2
.
h
>
10
11
QT_BEGIN_NAMESPACE
12
13
namespace
QtMultimediaPrivate
{
14
15
namespace
{
16
Q_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.
21
static
constexpr
DWORD
kMutexTimeoutMs
= 5000;
22
23
bool
QWindowsD3D11TextureBridge
::
copyToSharedTex
(
ID3D11Device
*
dev
,
ID3D11DeviceContext
*
ctx
,
24
const
ComPtr
<
ID3D11Texture2D
> &
tex
,
25
const
QSize
&
frameSize
,
UINT
index
)
26
{
27
Q_ASSERT
(
dev
);
28
Q_ASSERT
(
ctx
);
29
Q_ASSERT
(
tex
);
30
31
if
(!
ensureSrcTex
(
dev
,
tex
,
frameSize
))
32
return
false
;
33
34
// Flush to ensure that texture is fully updated before we share it.
35
ctx
->
Flush
();
36
37
if
(
const
HRESULT
hr
=
m_srcMutex
->
AcquireSync
(
kSrcKey
,
kMutexTimeoutMs
);
hr
!=
S_OK
) {
38
qCWarning
(
lcD3D11TextureBridge
)
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
51
m_srcMutex
->
ReleaseSync
(
kDestKey
);
52
return
true
;
53
}
54
55
bool
QWindowsD3D11TextureBridge
::
copyToSharedTex
(
const
ComPtr
<
ID3D11Device
> &
device
,
56
const
ComPtr
<
ID3D11DeviceContext
> &
deviceContext
,
57
const
ComPtr
<
ID3D11Texture2D
> &
texture
,
58
const
QSize
&
frameSize
,
UINT
index
)
59
{
60
return
copyToSharedTex
(
device
.
Get
(),
deviceContext
.
Get
(),
texture
,
frameSize
,
index
);
61
}
62
63
ComPtr
<
ID3D11Texture2D
>
64
QWindowsD3D11TextureBridge
::
copyFromSharedTex
(
const
ComPtr
<
ID3D11Device1
> &
dev
,
65
const
ComPtr
<
ID3D11DeviceContext
> &
ctx
)
66
{
67
if
(!
ensureDestTex
(
dev
))
68
return
{};
69
70
if
(!
copyFromSharedTex
(
dev
,
ctx
,
m_outputTex
))
71
return
{};
72
73
return
m_outputTex
;
74
}
75
76
bool
QWindowsD3D11TextureBridge
::
copyFromSharedTex
(
const
ComPtr
<
ID3D11Device1
> &
dev
,
77
const
ComPtr
<
ID3D11DeviceContext
> &
ctx
,
78
const
ComPtr
<
ID3D11Texture2D
> &
destination
)
79
{
80
Q_ASSERT
(
destination
);
81
82
if
(!
ensureDestTex
(
dev
))
83
return
false
;
84
85
if
(
const
HRESULT
hr
=
m_destMutex
->
AcquireSync
(
kDestKey
,
kMutexTimeoutMs
);
hr
!=
S_OK
) {
86
qCWarning
(
lcD3D11TextureBridge
)
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
93
m_destMutex
->
ReleaseSync
(
kSrcKey
);
94
95
return
true
;
96
}
97
98
bool
QWindowsD3D11TextureBridge
::
ensureDestTex
(
const
ComPtr
<
ID3D11Device1
> &
dev
)
99
{
100
if
(
m_destDevice
!=
dev
) {
101
// Destination device changed. Recreate texture.
102
m_destTex
=
nullptr
;
103
m_destDevice
=
dev
;
104
}
105
106
if
(
m_destTex
)
107
return
true
;
108
109
if
(
const
HRESULT
hr
=
110
m_destDevice
->
OpenSharedResource1
(
m_sharedHandle
.
get
(),
IID_PPV_ARGS
(&
m_destTex
));
111
hr
!=
S_OK
) {
112
qCWarning
(
lcD3D11TextureBridge
)
113
<<
"OpenSharedResource1 failed:"
<<
QSystemError
::
windowsComString
(
hr
);
114
return
false
;
115
}
116
117
CD3D11_TEXTURE2D_DESC
desc
{};
118
m_destTex
->
GetDesc
(&
desc
);
119
120
desc
.
MiscFlags
= 0;
121
desc
.
BindFlags
=
D3D11_BIND_SHADER_RESOURCE
;
122
123
if
(
const
HRESULT
hr
=
124
m_destDevice
->
CreateTexture2D
(&
desc
,
nullptr
,
m_outputTex
.
ReleaseAndGetAddressOf
());
125
hr
!=
S_OK
) {
126
qCWarning
(
lcD3D11TextureBridge
)
127
<<
"CreateTexture2D failed:"
<<
QSystemError
::
windowsComString
(
hr
);
128
return
false
;
129
}
130
131
if
(
const
HRESULT
hr
=
m_destTex
.
As
(&
m_destMutex
);
hr
!=
S_OK
) {
132
qCWarning
(
lcD3D11TextureBridge
)
133
<<
"QueryInterface(IDXGIKeyedMutex) failed:"
<<
QSystemError
::
windowsComString
(
hr
);
134
return
false
;
135
}
136
137
return
true
;
138
}
139
140
bool
QWindowsD3D11TextureBridge
::
ensureSrcTex
(
ID3D11Device
*
dev
,
const
ComPtr
<
ID3D11Texture2D
> &
tex
,
141
const
QSize
&
frameSize
)
142
{
143
if
(!
isSrcInitialized
(
dev
,
tex
,
frameSize
))
144
return
recreateSrc
(
dev
,
tex
,
frameSize
);
145
146
return
true
;
147
}
148
149
bool
QWindowsD3D11TextureBridge
::
isSrcInitialized
(
const
ID3D11Device
*
dev
,
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
157
ComPtr
<
ID3D11Device
>
texDevice
;
158
m_srcTex
->
GetDevice
(
texDevice
.
GetAddressOf
());
159
if
(
dev
!=
texDevice
.
Get
())
160
return
false
;
161
162
// Check if shared texture has correct size and format
163
CD3D11_TEXTURE2D_DESC
inputDesc
{};
164
tex
->
GetDesc
(&
inputDesc
);
165
166
CD3D11_TEXTURE2D_DESC
currentDesc
{};
167
m_srcTex
->
GetDesc
(&
currentDesc
);
168
169
if
(
inputDesc
.
Format
!=
currentDesc
.
Format
)
170
return
false
;
171
172
const
UINT
width
=
static_cast
<
UINT
>(
frameSize
.
width
());
173
const
UINT
height
=
static_cast
<
UINT
>(
frameSize
.
height
());
174
175
if
(
currentDesc
.
Width
!=
width
||
currentDesc
.
Height
!=
height
)
176
return
false
;
177
178
return
true
;
179
}
180
181
bool
QWindowsD3D11TextureBridge
::
recreateSrc
(
ID3D11Device
*
dev
,
const
ComPtr
<
ID3D11Texture2D
> &
tex
,
182
const
QSize
&
frameSize
)
183
{
184
m_sharedHandle
.
close
();
185
186
CD3D11_TEXTURE2D_DESC
desc
{};
187
tex
->
GetDesc
(&
desc
);
188
189
const
UINT
width
=
static_cast
<
UINT
>(
frameSize
.
width
());
190
const
UINT
height
=
static_cast
<
UINT
>(
frameSize
.
height
());
191
192
CD3D11_TEXTURE2D_DESC
texDesc
{
desc
.
Format
,
width
,
height
};
193
texDesc
.
MipLevels
= 1;
194
texDesc
.
MiscFlags
=
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
|
D3D11_RESOURCE_MISC_SHARED_NTHANDLE
;
195
196
if
(
const
HRESULT
hr
=
197
dev
->
CreateTexture2D
(&
texDesc
,
nullptr
,
m_srcTex
.
ReleaseAndGetAddressOf
());
198
hr
!=
S_OK
) {
199
qCWarning
(
lcD3D11TextureBridge
)
200
<<
"CreateTexture2D failed:"
<<
QSystemError
::
windowsComString
(
hr
);
201
return
false
;
202
}
203
204
ComPtr
<
IDXGIResource1
>
res
;
205
if
(
const
HRESULT
hr
=
m_srcTex
.
As
(&
res
);
hr
!=
S_OK
) {
206
qCWarning
(
lcD3D11TextureBridge
)
207
<<
"QueryInterface(IDXGIResource1) failed:"
<<
QSystemError
::
windowsComString
(
hr
);
208
return
false
;
209
}
210
211
const
HRESULT
hr
=
212
res
->
CreateSharedHandle
(
nullptr
,
DXGI_SHARED_RESOURCE_READ
,
nullptr
, &
m_sharedHandle
);
213
214
if
(
hr
!=
S_OK
|| !
m_sharedHandle
) {
215
qCWarning
(
lcD3D11TextureBridge
)
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:"
222
<<
QSystemError
::
windowsComString
(
mutexHr
);
223
return
false
;
224
}
225
226
m_destTex
=
nullptr
;
227
m_destMutex
=
nullptr
;
228
return
true
;
229
}
230
231
}
// namespace QtMultimediaPrivate
232
233
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtMultimediaPrivate::impl
Definition
qaudiosystem_p.h:257
QtMultimediaPrivate::kMutexTimeoutMs
static constexpr DWORD kMutexTimeoutMs
Definition
qwindowsd3d11texturebridge.cpp:21
qtmultimedia
src
multimedia
windows
qwindowsd3d11texturebridge.cpp
Generated on
for Qt by
1.16.1