2 * Copyright 2014 Michael Müller for Pipelight
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "physicalmonitorenumerationapi.h"
27 #include "lowlevelmonitorconfigurationapi.h"
28 #include "highlevelmonitorconfigurationapi.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dxva2
);
37 enum device_handle_flags
39 HANDLE_FLAG_OPEN
= 0x1,
40 HANDLE_FLAG_INVALID
= 0x2,
46 IDirect3DStateBlock9
*state_block
;
51 IDirect3DDeviceManager9 IDirect3DDeviceManager9_iface
;
52 IDirectXVideoProcessorService IDirectXVideoProcessorService_iface
;
53 IDirectXVideoDecoderService IDirectXVideoDecoderService_iface
;
56 IDirect3DDevice9
*device
;
59 struct device_handle
*handles
;
63 HANDLE locking_handle
;
66 CONDITION_VARIABLE lock
;
69 struct video_processor
71 IDirectXVideoProcessor IDirectXVideoProcessor_iface
;
74 IDirectXVideoProcessorService
*service
;
76 DXVA2_VideoDesc video_desc
;
78 unsigned int max_substreams
;
81 static BOOL
dxva_array_reserve(void **elements
, size_t *capacity
, size_t count
, size_t size
)
83 size_t new_capacity
, max_capacity
;
86 if (count
<= *capacity
)
89 max_capacity
= ~(SIZE_T
)0 / size
;
90 if (count
> max_capacity
)
93 new_capacity
= max(4, *capacity
);
94 while (new_capacity
< count
&& new_capacity
<= max_capacity
/ 2)
96 if (new_capacity
< count
)
97 new_capacity
= max_capacity
;
99 if (!(new_elements
= heap_realloc(*elements
, new_capacity
* size
)))
102 *elements
= new_elements
;
103 *capacity
= new_capacity
;
108 static struct device_manager
*impl_from_IDirect3DDeviceManager9(IDirect3DDeviceManager9
*iface
)
110 return CONTAINING_RECORD(iface
, struct device_manager
, IDirect3DDeviceManager9_iface
);
113 static struct device_manager
*impl_from_IDirectXVideoProcessorService(IDirectXVideoProcessorService
*iface
)
115 return CONTAINING_RECORD(iface
, struct device_manager
, IDirectXVideoProcessorService_iface
);
118 static struct device_manager
*impl_from_IDirectXVideoDecoderService(IDirectXVideoDecoderService
*iface
)
120 return CONTAINING_RECORD(iface
, struct device_manager
, IDirectXVideoDecoderService_iface
);
123 static struct video_processor
*impl_from_IDirectXVideoProcessor(IDirectXVideoProcessor
*iface
)
125 return CONTAINING_RECORD(iface
, struct video_processor
, IDirectXVideoProcessor_iface
);
128 static HRESULT WINAPI
video_processor_QueryInterface(IDirectXVideoProcessor
*iface
, REFIID riid
, void **obj
)
130 if (IsEqualIID(riid
, &IID_IDirectXVideoProcessor
) ||
131 IsEqualIID(riid
, &IID_IUnknown
))
134 IDirectXVideoProcessor_AddRef(iface
);
138 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
140 return E_NOINTERFACE
;
143 static ULONG WINAPI
video_processor_AddRef(IDirectXVideoProcessor
*iface
)
145 struct video_processor
*processor
= impl_from_IDirectXVideoProcessor(iface
);
146 ULONG refcount
= InterlockedIncrement(&processor
->refcount
);
148 TRACE("%p, refcount %u.\n", iface
, refcount
);
153 static ULONG WINAPI
video_processor_Release(IDirectXVideoProcessor
*iface
)
155 struct video_processor
*processor
= impl_from_IDirectXVideoProcessor(iface
);
156 ULONG refcount
= InterlockedDecrement(&processor
->refcount
);
158 TRACE("%p, refcount %u.\n", iface
, refcount
);
162 IDirectXVideoProcessorService_Release(processor
->service
);
163 heap_free(processor
);
169 static HRESULT WINAPI
video_processor_GetVideoProcessorService(IDirectXVideoProcessor
*iface
,
170 IDirectXVideoProcessorService
**service
)
172 struct video_processor
*processor
= impl_from_IDirectXVideoProcessor(iface
);
174 TRACE("%p, %p.\n", iface
, service
);
176 *service
= processor
->service
;
177 IDirectXVideoProcessorService_AddRef(*service
);
182 static HRESULT WINAPI
video_processor_GetCreationParameters(IDirectXVideoProcessor
*iface
,
183 GUID
*device
, DXVA2_VideoDesc
*video_desc
, D3DFORMAT
*rt_format
, UINT
*max_substreams
)
185 struct video_processor
*processor
= impl_from_IDirectXVideoProcessor(iface
);
187 TRACE("%p, %p, %p, %p, %p.\n", iface
, device
, video_desc
, rt_format
, max_substreams
);
189 if (!device
&& !video_desc
&& !rt_format
&& !max_substreams
)
193 *device
= processor
->device
;
195 *video_desc
= processor
->video_desc
;
197 *rt_format
= processor
->rt_format
;
199 *max_substreams
= processor
->max_substreams
;
204 static HRESULT WINAPI
video_processor_GetVideoProcessorCaps(IDirectXVideoProcessor
*iface
,
205 DXVA2_VideoProcessorCaps
*caps
)
207 FIXME("%p, %p.\n", iface
, caps
);
212 static HRESULT WINAPI
video_processor_GetProcAmpRange(IDirectXVideoProcessor
*iface
, UINT cap
, DXVA2_ValueRange
*range
)
214 FIXME("%p, %u, %p.\n", iface
, cap
, range
);
219 static HRESULT WINAPI
video_processor_GetFilterPropertyRange(IDirectXVideoProcessor
*iface
, UINT setting
,
220 DXVA2_ValueRange
*range
)
222 FIXME("%p, %u, %p.\n", iface
, setting
, range
);
227 static BOOL
intersect_rect(RECT
*dest
, const RECT
*src1
, const RECT
*src2
)
229 if (IsRectEmpty(src1
) || IsRectEmpty(src2
) ||
230 (src1
->left
>= src2
->right
) || (src2
->left
>= src1
->right
) ||
231 (src1
->top
>= src2
->bottom
) || (src2
->top
>= src1
->bottom
))
236 dest
->left
= max(src1
->left
, src2
->left
);
237 dest
->right
= min(src1
->right
, src2
->right
);
238 dest
->top
= max(src1
->top
, src2
->top
);
239 dest
->bottom
= min(src1
->bottom
, src2
->bottom
);
244 static HRESULT WINAPI
video_processor_VideoProcessBlt(IDirectXVideoProcessor
*iface
, IDirect3DSurface9
*rt
,
245 const DXVA2_VideoProcessBltParams
*params
, const DXVA2_VideoSample
*samples
, UINT sample_count
,
246 HANDLE
*complete_handle
)
248 IDirect3DDevice9
*device
;
253 TRACE("%p, %p, %p, %p, %u, %p.\n", iface
, rt
, params
, samples
, sample_count
, complete_handle
);
255 if (FAILED(hr
= IDirect3DSurface9_GetDevice(rt
, &device
)))
257 WARN("Failed to get surface device, hr %#x.\n", hr
);
261 /* FIXME: use specified color */
262 IDirect3DDevice9_ColorFill(device
, rt
, NULL
, 0);
264 for (i
= 0; i
< sample_count
; ++i
)
266 dst_rect
= params
->TargetRect
;
268 if (!intersect_rect(&dst_rect
, &dst_rect
, &samples
[i
].DstRect
))
271 if (FAILED(hr
= IDirect3DDevice9_StretchRect(device
, samples
[i
].SrcSurface
, &samples
[i
].SrcRect
,
272 rt
, &dst_rect
, D3DTEXF_POINT
)))
274 WARN("Failed to copy sample %u, hr %#x.\n", i
, hr
);
278 IDirect3DDevice9_Release(device
);
283 static const IDirectXVideoProcessorVtbl video_processor_vtbl
=
285 video_processor_QueryInterface
,
286 video_processor_AddRef
,
287 video_processor_Release
,
288 video_processor_GetVideoProcessorService
,
289 video_processor_GetCreationParameters
,
290 video_processor_GetVideoProcessorCaps
,
291 video_processor_GetProcAmpRange
,
292 video_processor_GetFilterPropertyRange
,
293 video_processor_VideoProcessBlt
,
296 static HRESULT WINAPI
device_manager_processor_service_QueryInterface(IDirectXVideoProcessorService
*iface
,
297 REFIID riid
, void **obj
)
299 struct device_manager
*manager
= impl_from_IDirectXVideoProcessorService(iface
);
301 if (IsEqualIID(riid
, &IID_IDirectXVideoProcessorService
) ||
302 IsEqualIID(riid
, &IID_IDirectXVideoAccelerationService
) ||
303 IsEqualIID(riid
, &IID_IUnknown
))
307 else if (IsEqualIID(riid
, &IID_IDirectXVideoDecoderService
))
309 *obj
= &manager
->IDirectXVideoDecoderService_iface
;
313 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
315 return E_NOINTERFACE
;
318 IUnknown_AddRef((IUnknown
*)*obj
);
322 static ULONG WINAPI
device_manager_processor_service_AddRef(IDirectXVideoProcessorService
*iface
)
324 struct device_manager
*manager
= impl_from_IDirectXVideoProcessorService(iface
);
325 return IDirect3DDeviceManager9_AddRef(&manager
->IDirect3DDeviceManager9_iface
);
328 static ULONG WINAPI
device_manager_processor_service_Release(IDirectXVideoProcessorService
*iface
)
330 struct device_manager
*manager
= impl_from_IDirectXVideoProcessorService(iface
);
331 return IDirect3DDeviceManager9_Release(&manager
->IDirect3DDeviceManager9_iface
);
334 static HRESULT WINAPI
device_manager_processor_service_CreateSurface(IDirectXVideoProcessorService
*iface
,
335 UINT width
, UINT height
, UINT backbuffers
, D3DFORMAT format
, D3DPOOL pool
, DWORD usage
, DWORD dxvaType
,
336 IDirect3DSurface9
**surfaces
, HANDLE
*shared_handle
)
338 struct device_manager
*manager
= impl_from_IDirectXVideoProcessorService(iface
);
342 TRACE("%p, %u, %u, %u, %u, %u, %u, %u, %p, %p.\n", iface
, width
, height
, backbuffers
, format
, pool
, usage
, dxvaType
,
343 surfaces
, shared_handle
);
345 if (backbuffers
>= UINT_MAX
)
348 memset(surfaces
, 0, (backbuffers
+ 1) * sizeof(*surfaces
));
350 for (i
= 0; i
< backbuffers
+ 1; ++i
)
352 if (FAILED(hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(manager
->device
, width
, height
, format
,
353 pool
, &surfaces
[i
], NULL
)))
359 for (j
= 0; j
< i
; ++j
)
363 IDirect3DSurface9_Release(surfaces
[j
]);
372 static HRESULT WINAPI
device_manager_processor_service_RegisterVideoProcessorSoftwareDevice(
373 IDirectXVideoProcessorService
*iface
, void *callbacks
)
375 FIXME("%p, %p.\n", iface
, callbacks
);
380 static BOOL
dxva_is_supported_stream_format(const DXVA2_VideoDesc
*video_desc
)
382 return video_desc
->Format
== D3DFMT_A8R8G8B8
||
383 video_desc
->Format
== D3DFMT_X8R8G8B8
||
384 video_desc
->Format
== D3DFMT_YUY2
||
385 video_desc
->Format
== MAKEFOURCC('A','Y','U','V');
388 static HRESULT WINAPI
device_manager_processor_service_GetVideoProcessorDeviceGuids(
389 IDirectXVideoProcessorService
*iface
, const DXVA2_VideoDesc
*video_desc
, UINT
*count
, GUID
**guids
)
391 FIXME("%p, %p, %p, %p semi-stub.\n", iface
, video_desc
, count
, guids
);
395 if (!dxva_is_supported_stream_format(video_desc
))
398 if (!(*guids
= CoTaskMemAlloc(sizeof(**guids
))))
399 return E_OUTOFMEMORY
;
401 memcpy(*guids
, &DXVA2_VideoProcSoftwareDevice
, sizeof(**guids
));
407 static HRESULT WINAPI
device_manager_processor_service_GetVideoProcessorRenderTargets(
408 IDirectXVideoProcessorService
*iface
, REFGUID deviceguid
, const DXVA2_VideoDesc
*video_desc
, UINT
*count
,
411 TRACE("%p, %s, %p, %p, %p.\n", iface
, debugstr_guid(deviceguid
), video_desc
, count
, formats
);
413 if (IsEqualGUID(deviceguid
, &DXVA2_VideoProcSoftwareDevice
))
415 if (!dxva_is_supported_stream_format(video_desc
))
417 WARN("Unsupported content format %#x.\n", video_desc
->Format
);
421 if (!(*formats
= CoTaskMemAlloc(2 * sizeof(**formats
))))
422 return E_OUTOFMEMORY
;
425 (*formats
)[0] = D3DFMT_X8R8G8B8
;
426 (*formats
)[1] = D3DFMT_A8R8G8B8
;
431 FIXME("Unsupported device %s.\n", debugstr_guid(deviceguid
));
436 static HRESULT WINAPI
device_manager_processor_service_GetVideoProcessorSubStreamFormats(
437 IDirectXVideoProcessorService
*iface
, REFGUID deviceguid
, const DXVA2_VideoDesc
*video_desc
,
438 D3DFORMAT rt_format
, UINT
*count
, D3DFORMAT
**formats
)
440 FIXME("%p, %s, %p, %u, %p, %p.\n", iface
, debugstr_guid(deviceguid
), video_desc
, rt_format
, count
, formats
);
445 static HRESULT WINAPI
device_manager_processor_service_GetVideoProcessorCaps(
446 IDirectXVideoProcessorService
*iface
, REFGUID deviceguid
, const DXVA2_VideoDesc
*video_desc
,
447 D3DFORMAT rt_format
, DXVA2_VideoProcessorCaps
*caps
)
449 FIXME("%p, %s, %p, %u, %p.\n", iface
, debugstr_guid(deviceguid
), video_desc
, rt_format
, caps
);
454 static HRESULT WINAPI
device_manager_processor_service_GetProcAmpRange(
455 IDirectXVideoProcessorService
*iface
, REFGUID deviceguid
, const DXVA2_VideoDesc
*video_desc
,
456 D3DFORMAT rt_format
, UINT ProcAmpCap
, DXVA2_ValueRange
*range
)
458 FIXME("%p, %s, %p, %u, %u, %p.\n", iface
, debugstr_guid(deviceguid
), video_desc
, rt_format
, ProcAmpCap
, range
);
463 static HRESULT WINAPI
device_manager_processor_service_GetFilterPropertyRange(
464 IDirectXVideoProcessorService
*iface
, REFGUID deviceguid
, const DXVA2_VideoDesc
*video_desc
,
465 D3DFORMAT rt_format
, UINT filter_setting
, DXVA2_ValueRange
*range
)
467 FIXME("%p, %s, %p, %d, %d, %p.\n", iface
, debugstr_guid(deviceguid
), video_desc
, rt_format
, filter_setting
, range
);
472 static HRESULT WINAPI
device_manager_processor_service_CreateVideoProcessor(IDirectXVideoProcessorService
*iface
,
473 REFGUID device
, const DXVA2_VideoDesc
*video_desc
, D3DFORMAT rt_format
, UINT max_substreams
,
474 IDirectXVideoProcessor
**processor
)
476 struct video_processor
*object
;
478 FIXME("%p, %s, %p, %d, %u, %p.\n", iface
, debugstr_guid(device
), video_desc
, rt_format
, max_substreams
,
481 /* FIXME: validate render target format */
483 if (!(object
= heap_alloc_zero(sizeof(*object
))))
484 return E_OUTOFMEMORY
;
486 object
->IDirectXVideoProcessor_iface
.lpVtbl
= &video_processor_vtbl
;
487 object
->refcount
= 1;
488 object
->service
= iface
;
489 IDirectXVideoProcessorService_AddRef(object
->service
);
490 object
->device
= *device
;
491 object
->video_desc
= *video_desc
;
492 object
->rt_format
= rt_format
;
493 object
->max_substreams
= max_substreams
;
495 *processor
= &object
->IDirectXVideoProcessor_iface
;
500 static const IDirectXVideoProcessorServiceVtbl device_manager_processor_service_vtbl
=
502 device_manager_processor_service_QueryInterface
,
503 device_manager_processor_service_AddRef
,
504 device_manager_processor_service_Release
,
505 device_manager_processor_service_CreateSurface
,
506 device_manager_processor_service_RegisterVideoProcessorSoftwareDevice
,
507 device_manager_processor_service_GetVideoProcessorDeviceGuids
,
508 device_manager_processor_service_GetVideoProcessorRenderTargets
,
509 device_manager_processor_service_GetVideoProcessorSubStreamFormats
,
510 device_manager_processor_service_GetVideoProcessorCaps
,
511 device_manager_processor_service_GetProcAmpRange
,
512 device_manager_processor_service_GetFilterPropertyRange
,
513 device_manager_processor_service_CreateVideoProcessor
,
516 static HRESULT WINAPI
device_manager_decoder_service_QueryInterface(IDirectXVideoDecoderService
*iface
,
517 REFIID riid
, void **obj
)
519 if (IsEqualIID(riid
, &IID_IDirectXVideoDecoderService
) ||
520 IsEqualIID(riid
, &IID_IDirectXVideoAccelerationService
) ||
521 IsEqualIID(riid
, &IID_IUnknown
))
524 IDirectXVideoDecoderService_AddRef(iface
);
528 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
530 return E_NOINTERFACE
;
533 static ULONG WINAPI
device_manager_decoder_service_AddRef(IDirectXVideoDecoderService
*iface
)
535 struct device_manager
*manager
= impl_from_IDirectXVideoDecoderService(iface
);
536 return IDirect3DDeviceManager9_AddRef(&manager
->IDirect3DDeviceManager9_iface
);
539 static ULONG WINAPI
device_manager_decoder_service_Release(IDirectXVideoDecoderService
*iface
)
541 struct device_manager
*manager
= impl_from_IDirectXVideoDecoderService(iface
);
542 return IDirect3DDeviceManager9_Release(&manager
->IDirect3DDeviceManager9_iface
);
545 static HRESULT WINAPI
device_manager_decoder_service_CreateSurface(IDirectXVideoDecoderService
*iface
,
546 UINT width
, UINT height
, UINT backbuffers
, D3DFORMAT format
, D3DPOOL pool
, DWORD usage
, DWORD dxvaType
,
547 IDirect3DSurface9
**surfaces
, HANDLE
*shared_handle
)
549 FIXME("%p, %u, %u, %u, %#x, %d, %d, %d, %p, %p.\n", iface
, width
, height
, backbuffers
, format
, pool
, usage
,
550 dxvaType
, surfaces
, shared_handle
);
555 static HRESULT WINAPI
device_manager_decoder_service_GetDecoderDeviceGuids(IDirectXVideoDecoderService
*iface
,
556 UINT
*count
, GUID
**guids
)
558 FIXME("%p, %p, %p.\n", iface
, count
, guids
);
563 static HRESULT WINAPI
device_manager_decoder_service_GetDecoderRenderTargets(IDirectXVideoDecoderService
*iface
,
564 REFGUID guid
, UINT
*count
, D3DFORMAT
**formats
)
566 FIXME("%p, %s, %p, %p.\n", iface
, debugstr_guid(guid
), count
, formats
);
571 static HRESULT WINAPI
device_manager_decoder_service_GetDecoderConfigurations(IDirectXVideoDecoderService
*iface
,
572 REFGUID guid
, const DXVA2_VideoDesc
*video_desc
, IUnknown
*reserved
, UINT
*count
, DXVA2_ConfigPictureDecode
**configs
)
574 FIXME("%p, %s, %p, %p, %p, %p.\n", iface
, debugstr_guid(guid
), video_desc
, reserved
, count
, configs
);
579 static HRESULT WINAPI
device_manager_decoder_service_CreateVideoDecoder(IDirectXVideoDecoderService
*iface
,
580 REFGUID guid
, const DXVA2_VideoDesc
*video_desc
, DXVA2_ConfigPictureDecode
*config
, IDirect3DSurface9
**rts
,
581 UINT num_surfaces
, IDirectXVideoDecoder
**decoder
)
583 FIXME("%p, %s, %p, %p, %p, %u, %p.\n", iface
, debugstr_guid(guid
), video_desc
, config
, rts
, num_surfaces
,
589 static const IDirectXVideoDecoderServiceVtbl device_manager_decoder_service_vtbl
=
591 device_manager_decoder_service_QueryInterface
,
592 device_manager_decoder_service_AddRef
,
593 device_manager_decoder_service_Release
,
594 device_manager_decoder_service_CreateSurface
,
595 device_manager_decoder_service_GetDecoderDeviceGuids
,
596 device_manager_decoder_service_GetDecoderRenderTargets
,
597 device_manager_decoder_service_GetDecoderConfigurations
,
598 device_manager_decoder_service_CreateVideoDecoder
,
601 static HRESULT WINAPI
device_manager_QueryInterface(IDirect3DDeviceManager9
*iface
, REFIID riid
, void **obj
)
603 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
605 if (IsEqualIID(&IID_IDirect3DDeviceManager9
, riid
) ||
606 IsEqualIID(&IID_IUnknown
, riid
))
609 IDirect3DDeviceManager9_AddRef(iface
);
613 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
615 return E_NOINTERFACE
;
618 static ULONG WINAPI
device_manager_AddRef(IDirect3DDeviceManager9
*iface
)
620 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
621 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
623 TRACE("%p, refcount %u.\n", iface
, refcount
);
628 static ULONG WINAPI
device_manager_Release(IDirect3DDeviceManager9
*iface
)
630 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
631 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
634 TRACE("%p, refcount %u.\n", iface
, refcount
);
639 IDirect3DDevice9_Release(manager
->device
);
640 DeleteCriticalSection(&manager
->cs
);
641 for (i
= 0; i
< manager
->count
; ++i
)
643 if (manager
->handles
[i
].state_block
)
644 IDirect3DStateBlock9_Release(manager
->handles
[i
].state_block
);
646 heap_free(manager
->handles
);
653 static HRESULT WINAPI
device_manager_ResetDevice(IDirect3DDeviceManager9
*iface
, IDirect3DDevice9
*device
,
656 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
659 TRACE("%p, %p, %#x.\n", iface
, device
, token
);
661 if (token
!= manager
->token
)
664 EnterCriticalSection(&manager
->cs
);
667 for (i
= 0; i
< manager
->count
; ++i
)
669 if (manager
->handles
[i
].state_block
)
670 IDirect3DStateBlock9_Release(manager
->handles
[i
].state_block
);
671 manager
->handles
[i
].state_block
= NULL
;
672 manager
->handles
[i
].flags
|= HANDLE_FLAG_INVALID
;
674 manager
->locking_handle
= NULL
;
675 IDirect3DDevice9_Release(manager
->device
);
677 manager
->device
= device
;
678 IDirect3DDevice9_AddRef(manager
->device
);
679 LeaveCriticalSection(&manager
->cs
);
681 WakeAllConditionVariable(&manager
->lock
);
686 static HRESULT WINAPI
device_manager_OpenDeviceHandle(IDirect3DDeviceManager9
*iface
, HANDLE
*hdevice
)
688 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
692 TRACE("%p, %p.\n", iface
, hdevice
);
696 EnterCriticalSection(&manager
->cs
);
697 if (!manager
->device
)
698 hr
= DXVA2_E_NOT_INITIALIZED
;
701 for (i
= 0; i
< manager
->count
; ++i
)
703 if (!(manager
->handles
[i
].flags
& HANDLE_FLAG_OPEN
))
705 manager
->handles
[i
].flags
|= HANDLE_FLAG_OPEN
;
706 *hdevice
= ULongToHandle(i
+ 1);
711 if (dxva_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
712 sizeof(*manager
->handles
)))
714 *hdevice
= ULongToHandle(manager
->count
+ 1);
715 manager
->handles
[manager
->count
].flags
= HANDLE_FLAG_OPEN
;
716 manager
->handles
[manager
->count
].state_block
= NULL
;
722 LeaveCriticalSection(&manager
->cs
);
727 static HRESULT
device_manager_get_handle_index(struct device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
729 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
731 *idx
= (ULONG_PTR
)hdevice
- 1;
735 static HRESULT WINAPI
device_manager_CloseDeviceHandle(IDirect3DDeviceManager9
*iface
, HANDLE hdevice
)
737 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
741 TRACE("%p, %p.\n", iface
, hdevice
);
743 EnterCriticalSection(&manager
->cs
);
744 if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
746 if (manager
->handles
[idx
].flags
& HANDLE_FLAG_OPEN
)
748 if (manager
->locking_handle
== hdevice
)
749 manager
->locking_handle
= NULL
;
750 manager
->handles
[idx
].flags
= 0;
751 if (idx
== manager
->count
- 1)
753 if (manager
->handles
[idx
].state_block
)
754 IDirect3DStateBlock9_Release(manager
->handles
[idx
].state_block
);
755 manager
->handles
[idx
].state_block
= NULL
;
760 LeaveCriticalSection(&manager
->cs
);
762 WakeAllConditionVariable(&manager
->lock
);
767 static HRESULT WINAPI
device_manager_TestDevice(IDirect3DDeviceManager9
*iface
, HANDLE hdevice
)
769 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
773 TRACE("%p, %p.\n", iface
, hdevice
);
775 EnterCriticalSection(&manager
->cs
);
776 if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
778 unsigned int flags
= manager
->handles
[idx
].flags
;
780 if (flags
& HANDLE_FLAG_INVALID
)
781 hr
= DXVA2_E_NEW_VIDEO_DEVICE
;
782 else if (!(flags
& HANDLE_FLAG_OPEN
))
785 LeaveCriticalSection(&manager
->cs
);
790 static HRESULT WINAPI
device_manager_LockDevice(IDirect3DDeviceManager9
*iface
, HANDLE hdevice
,
791 IDirect3DDevice9
**device
, BOOL block
)
793 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
797 TRACE("%p, %p, %p, %d.\n", iface
, hdevice
, device
, block
);
799 EnterCriticalSection(&manager
->cs
);
800 if (!manager
->device
)
801 hr
= DXVA2_E_NOT_INITIALIZED
;
802 else if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
804 if (manager
->locking_handle
&& !block
)
805 hr
= DXVA2_E_VIDEO_DEVICE_LOCKED
;
808 while (manager
->locking_handle
&& block
)
810 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
813 if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
815 if (manager
->handles
[idx
].flags
& HANDLE_FLAG_INVALID
)
816 hr
= DXVA2_E_NEW_VIDEO_DEVICE
;
819 if (manager
->handles
[idx
].state_block
)
821 if (FAILED(IDirect3DStateBlock9_Apply(manager
->handles
[idx
].state_block
)))
822 WARN("Failed to apply state.\n");
823 IDirect3DStateBlock9_Release(manager
->handles
[idx
].state_block
);
824 manager
->handles
[idx
].state_block
= NULL
;
826 *device
= manager
->device
;
827 IDirect3DDevice9_AddRef(*device
);
828 manager
->locking_handle
= hdevice
;
833 LeaveCriticalSection(&manager
->cs
);
838 static HRESULT WINAPI
device_manager_UnlockDevice(IDirect3DDeviceManager9
*iface
, HANDLE hdevice
, BOOL savestate
)
840 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
844 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
846 EnterCriticalSection(&manager
->cs
);
848 if (hdevice
!= manager
->locking_handle
)
850 else if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
852 manager
->locking_handle
= NULL
;
854 IDirect3DDevice9_CreateStateBlock(manager
->device
, D3DSBT_ALL
, &manager
->handles
[idx
].state_block
);
857 LeaveCriticalSection(&manager
->cs
);
859 WakeAllConditionVariable(&manager
->lock
);
864 static HRESULT WINAPI
device_manager_GetVideoService(IDirect3DDeviceManager9
*iface
, HANDLE hdevice
, REFIID riid
,
867 struct device_manager
*manager
= impl_from_IDirect3DDeviceManager9(iface
);
871 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), obj
);
873 EnterCriticalSection(&manager
->cs
);
874 if (SUCCEEDED(hr
= device_manager_get_handle_index(manager
, hdevice
, &idx
)))
876 unsigned int flags
= manager
->handles
[idx
].flags
;
878 if (flags
& HANDLE_FLAG_INVALID
)
879 hr
= DXVA2_E_NEW_VIDEO_DEVICE
;
880 else if (!(flags
& HANDLE_FLAG_OPEN
))
883 hr
= IDirectXVideoProcessorService_QueryInterface(&manager
->IDirectXVideoProcessorService_iface
,
886 LeaveCriticalSection(&manager
->cs
);
891 static const IDirect3DDeviceManager9Vtbl device_manager_vtbl
=
893 device_manager_QueryInterface
,
894 device_manager_AddRef
,
895 device_manager_Release
,
896 device_manager_ResetDevice
,
897 device_manager_OpenDeviceHandle
,
898 device_manager_CloseDeviceHandle
,
899 device_manager_TestDevice
,
900 device_manager_LockDevice
,
901 device_manager_UnlockDevice
,
902 device_manager_GetVideoService
,
905 BOOL WINAPI
CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor
, LPSTR buffer
, DWORD length
)
907 FIXME("(%p, %p, %d): stub\n", monitor
, buffer
, length
);
909 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
913 HRESULT WINAPI
DXVA2CreateDirect3DDeviceManager9(UINT
*token
, IDirect3DDeviceManager9
**manager
)
915 struct device_manager
*object
;
917 TRACE("%p, %p.\n", token
, manager
);
921 if (!(object
= heap_alloc_zero(sizeof(*object
))))
922 return E_OUTOFMEMORY
;
924 object
->IDirect3DDeviceManager9_iface
.lpVtbl
= &device_manager_vtbl
;
925 object
->IDirectXVideoProcessorService_iface
.lpVtbl
= &device_manager_processor_service_vtbl
;
926 object
->IDirectXVideoDecoderService_iface
.lpVtbl
= &device_manager_decoder_service_vtbl
;
927 object
->refcount
= 1;
928 object
->token
= GetTickCount();
929 InitializeCriticalSection(&object
->cs
);
930 InitializeConditionVariable(&object
->lock
);
932 *token
= object
->token
;
933 *manager
= &object
->IDirect3DDeviceManager9_iface
;
938 HRESULT WINAPI
DXVA2CreateVideoService(IDirect3DDevice9
*device
, REFIID riid
, void **obj
)
940 IDirect3DDeviceManager9
*manager
;
945 TRACE("%p, %s, %p.\n", device
, debugstr_guid(riid
), obj
);
947 if (FAILED(hr
= DXVA2CreateDirect3DDeviceManager9(&token
, &manager
)))
950 if (FAILED(hr
= IDirect3DDeviceManager9_ResetDevice(manager
, device
, token
)))
953 if (FAILED(hr
= IDirect3DDeviceManager9_OpenDeviceHandle(manager
, &handle
)))
956 hr
= IDirect3DDeviceManager9_GetVideoService(manager
, handle
, riid
, obj
);
957 IDirect3DDeviceManager9_CloseDeviceHandle(manager
, handle
);
960 IDirect3DDeviceManager9_Release(manager
);
965 BOOL WINAPI
DegaussMonitor( HMONITOR monitor
)
967 FIXME("(%p): stub\n", monitor
);
969 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
973 BOOL WINAPI
DestroyPhysicalMonitor( HMONITOR monitor
)
975 FIXME("(%p): stub\n", monitor
);
977 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
981 BOOL WINAPI
DestroyPhysicalMonitors( DWORD arraySize
, LPPHYSICAL_MONITOR array
)
983 FIXME("(0x%x, %p): stub\n", arraySize
, array
);
985 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
989 BOOL WINAPI
GetCapabilitiesStringLength( HMONITOR monitor
, LPDWORD length
)
991 FIXME("(%p, %p): stub\n", monitor
, length
);
993 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
997 BOOL WINAPI
GetMonitorBrightness( HMONITOR monitor
, LPDWORD minimum
, LPDWORD current
, LPDWORD maximum
)
999 FIXME("(%p, %p, %p, %p): stub\n", monitor
, minimum
, current
, maximum
);
1001 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1005 BOOL WINAPI
GetMonitorCapabilities( HMONITOR monitor
, LPDWORD capabilities
, LPDWORD temperatures
)
1007 FIXME("(%p, %p, %p): stub\n", monitor
, capabilities
, temperatures
);
1009 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1014 BOOL WINAPI
GetMonitorColorTemperature( HMONITOR monitor
, LPMC_COLOR_TEMPERATURE temperature
)
1016 FIXME("(%p, %p): stub\n", monitor
, temperature
);
1018 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1022 BOOL WINAPI
GetMonitorContrast( HMONITOR monitor
, LPDWORD minimum
, LPDWORD current
, LPDWORD maximum
)
1024 FIXME("(%p, %p, %p, %p): stub\n", monitor
, minimum
, current
, maximum
);
1026 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1030 BOOL WINAPI
GetMonitorDisplayAreaPosition( HMONITOR monitor
, MC_POSITION_TYPE type
, LPDWORD minimum
,
1031 LPDWORD current
, LPDWORD maximum
)
1033 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor
, type
, minimum
, current
, maximum
);
1035 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1039 BOOL WINAPI
GetMonitorDisplayAreaSize( HMONITOR monitor
, MC_SIZE_TYPE type
, LPDWORD minimum
,
1040 LPDWORD current
, LPDWORD maximum
)
1042 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor
, type
, minimum
, current
, maximum
);
1044 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1048 BOOL WINAPI
GetMonitorRedGreenOrBlueDrive( HMONITOR monitor
, MC_DRIVE_TYPE type
, LPDWORD minimum
,
1049 LPDWORD current
, LPDWORD maximum
)
1051 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor
, type
, minimum
, current
, maximum
);
1053 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1057 BOOL WINAPI
GetMonitorRedGreenOrBlueGain( HMONITOR monitor
, MC_GAIN_TYPE type
, LPDWORD minimum
,
1058 LPDWORD current
, LPDWORD maximum
)
1060 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor
, type
, minimum
, current
, maximum
);
1062 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1066 BOOL WINAPI
GetMonitorTechnologyType( HMONITOR monitor
, LPMC_DISPLAY_TECHNOLOGY_TYPE type
)
1068 FIXME("(%p, %p): stub\n", monitor
, type
);
1070 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1074 BOOL WINAPI
GetNumberOfPhysicalMonitorsFromHMONITOR( HMONITOR monitor
, LPDWORD number
)
1076 FIXME("(%p, %p): stub\n", monitor
, number
);
1078 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1082 HRESULT WINAPI
GetNumberOfPhysicalMonitorsFromIDirect3DDevice9( IDirect3DDevice9
*device
, LPDWORD number
)
1084 FIXME("(%p, %p): stub\n", device
, number
);
1089 BOOL WINAPI
GetPhysicalMonitorsFromHMONITOR( HMONITOR monitor
, DWORD arraySize
, LPPHYSICAL_MONITOR array
)
1091 FIXME("(%p, 0x%x, %p): stub\n", monitor
, arraySize
, array
);
1093 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1097 HRESULT WINAPI
GetPhysicalMonitorsFromIDirect3DDevice9( IDirect3DDevice9
*device
, DWORD arraySize
, LPPHYSICAL_MONITOR array
)
1099 FIXME("(%p, 0x%x, %p): stub\n", device
, arraySize
, array
);
1104 BOOL WINAPI
GetTimingReport( HMONITOR monitor
, LPMC_TIMING_REPORT timingReport
)
1106 FIXME("(%p, %p): stub\n", monitor
, timingReport
);
1108 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1112 BOOL WINAPI
GetVCPFeatureAndVCPFeatureReply( HMONITOR monitor
, BYTE vcpCode
, LPMC_VCP_CODE_TYPE pvct
,
1113 LPDWORD current
, LPDWORD maximum
)
1115 FIXME("(%p, 0x%02x, %p, %p, %p): stub\n", monitor
, vcpCode
, pvct
, current
, maximum
);
1117 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1121 HRESULT WINAPI
OPMGetVideoOutputsFromHMONITOR( HMONITOR monitor
, /* OPM_VIDEO_OUTPUT_SEMANTICS */ int vos
,
1122 ULONG
*numVideoOutputs
, /* IOPMVideoOutput */ void ***videoOutputs
)
1124 FIXME("(%p, 0x%x, %p, %p): stub\n", monitor
, vos
, numVideoOutputs
, videoOutputs
);
1129 HRESULT WINAPI
OPMGetVideoOutputsFromIDirect3DDevice9Object( IDirect3DDevice9
*device
, /* OPM_VIDEO_OUTPUT_SEMANTICS */ int vos
,
1130 ULONG
*numVideoOutputs
, /* IOPMVideoOutput */ void ***videoOutputs
)
1132 FIXME("(%p, 0x%x, %p, %p): stub\n", device
, vos
, numVideoOutputs
, videoOutputs
);
1137 BOOL WINAPI
RestoreMonitorFactoryColorDefaults( HMONITOR monitor
)
1139 FIXME("(%p): stub\n", monitor
);
1141 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1145 BOOL WINAPI
RestoreMonitorFactoryDefaults( HMONITOR monitor
)
1147 FIXME("(%p): stub\n", monitor
);
1149 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1153 BOOL WINAPI
SaveCurrentMonitorSettings( HMONITOR monitor
)
1155 FIXME("(%p): stub\n", monitor
);
1157 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1161 BOOL WINAPI
SaveCurrentSettings( HMONITOR monitor
)
1163 FIXME("(%p): stub\n", monitor
);
1165 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1169 BOOL WINAPI
SetMonitorBrightness( HMONITOR monitor
, DWORD brightness
)
1171 FIXME("(%p, 0x%x): stub\n", monitor
, brightness
);
1173 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1177 BOOL WINAPI
SetMonitorColorTemperature( HMONITOR monitor
, MC_COLOR_TEMPERATURE temperature
)
1179 FIXME("(%p, 0x%x): stub\n", monitor
, temperature
);
1181 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1185 BOOL WINAPI
SetMonitorContrast( HMONITOR monitor
, DWORD contrast
)
1187 FIXME("(%p, 0x%x): stub\n", monitor
, contrast
);
1189 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1193 BOOL WINAPI
SetMonitorDisplayAreaPosition( HMONITOR monitor
, MC_POSITION_TYPE type
, DWORD position
)
1195 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor
, type
, position
);
1197 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1201 BOOL WINAPI
SetMonitorDisplayAreaSize( HMONITOR monitor
, MC_SIZE_TYPE type
, DWORD size
)
1203 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor
, type
, size
);
1205 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1209 BOOL WINAPI
SetMonitorRedGreenOrBlueDrive( HMONITOR monitor
, MC_DRIVE_TYPE type
, DWORD drive
)
1211 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor
, type
, drive
);
1213 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1217 BOOL WINAPI
SetMonitorRedGreenOrBlueGain( HMONITOR monitor
, MC_GAIN_TYPE type
, DWORD gain
)
1219 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor
, type
, gain
);
1221 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1225 BOOL WINAPI
SetVCPFeature( HMONITOR monitor
, BYTE vcpCode
, DWORD value
)
1227 FIXME("(%p, 0x%02x, 0x%x): stub\n", monitor
, vcpCode
, value
);
1229 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);