Desktop Window Manager & Graphics (DirectX)
Как известно , Desktop Window Manager(DWM) начиная с Vista отрисовывает графический контент на экран. Если в Windows Vista и Windows 7 DWM работал только в Aero, то для Windows 8 работает всегда :). Aero и не Aero это уже не важно.
Про Windows Vista - давнольно печально и вообще не хочу об это. По сути используется DirectX9.
Windows 7 - Использует DirectX 10 и dxgi 1.0.
Устройство создается по D3D10CreateDevice ю
Windows 8 - Использует DirectX 11 и dxgi 1.2.
Устройство создается по D3D11CreateDevice ю
Windows 7
Создания фабрики dxgi
CreateDXGIFactory(REFIID riid,
VOID ** ppFactory
);
Где
riid == __uuidof(IDXGIFactory);
Здесь интересное использование
HRESULT IDXGIFactory::QueryInterface( REFIID riid, VOID** ppvObj )
{
if ( IsEqualIID( riid, __uuidof (IDXGIFactoryDWM) )
{
//DWM получает FactoryDWM, это уже не документированная часть dxgi
}
}
Описание IDXGIFactoryDWM
Методы типо Present, GetBuffer такие как и у IDXGISwapChain да и все остальные методы тоже.
Единственно что здесь не хватает так это еще пару методов , но их DWM не вызывает.
Так стоит отметить , это то что вся текстура хранится в DWM(а точнее backbuffer) хитрым образом. Только реальное обновления будет доступно перед Present, вся остальная часть будет накрыта Alpha каналом.
Windows 8
Тут дела похожи, то есть не которое но.
При обычном дисплеи (Не стерио) используется CreateSwapChainDWMКак известно , Desktop Window Manager(DWM) начиная с Vista отрисовывает графический контент на экран. Если в Windows Vista и Windows 7 DWM работал только в Aero, то для Windows 8 работает всегда :). Aero и не Aero это уже не важно.
Про Windows Vista - давнольно печально и вообще не хочу об это. По сути используется DirectX9.
Windows 7 - Использует DirectX 10 и dxgi 1.0.
Устройство создается по D3D10CreateDevice ю
Windows 8 - Использует DirectX 11 и dxgi 1.2.
Устройство создается по D3D11CreateDevice ю
Windows 7
Создания фабрики dxgi
CreateDXGIFactory(REFIID riid,
VOID ** ppFactory
);
Где
riid == __uuidof(IDXGIFactory);
Здесь интересное использование
HRESULT IDXGIFactory::QueryInterface( REFIID riid, VOID** ppvObj )
{
if ( IsEqualIID( riid, __uuidof (IDXGIFactoryDWM) )
{
//DWM получает FactoryDWM, это уже не документированная часть dxgi
}
}
Описание IDXGIFactoryDWM
struct __declspec(uuid("{713F394E-92CA-47E7-AB81-1159C2791E54}"))
IDXGIFactoryDWM : public IUnknown
{
virtual void STDMETHODCALLTYPE CreateSwapChain(
IUnknown *pDevice,
DXGI_SWAP_CHAIN_DESC *pDesc,
IDXGIOutput *pOutput,
IDXGISwapChainDWM **ppSwapChainDWM ) = 0;
};
IDXGISwapChainDWM - Это SwapChain, чем то похожий на IDXGISwapChain(На самом деле это, только интерфейс к нему другой, но реализует именно он, этот SwapChain ).
struct IDXGISwapChainDWM : public IDXGIDeviceSubObject
{
STDMETHOD(Present)( UINT SyncInterval, UINT Flags ) = 0;
STDMETHOD(GetBuffer)( UINT Buffer, REFIID riid, void **ppSurface) = 0;
STDMETHOD(GetDesc)( DXGI_SWAP_CHAIN_DESC *pDesc ) = 0;
STDMETHOD(ResizeBuffers)( UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags ) = 0;
STDMETHOD(ResizeTarget)( const DXGI_MODE_DESC *pNewTargetParameters ) = 0;
STDMETHOD(GetContainingOutput)( IDXGIOutput **ppOutput ) = 0;
STDMETHOD(GetFrameStatistics)( DXGI_FRAME_STATISTICS *pStats ) = 0;
STDMETHOD(GetLastPresentCount)( UINT *pLastPresentCount ) = 0;
STDMETHOD(SetFullscreenState)( BOOL Fullscreen, IDXGIOutput *pTarget ) = 0;
STDMETHOD(GetFullscreenState)( BOOL *pFullscreen, IDXGIOutput **ppTarget ) = 0;
};
Методы типо Present, GetBuffer такие как и у IDXGISwapChain да и все остальные методы тоже.
Единственно что здесь не хватает так это еще пару методов , но их DWM не вызывает.
Так стоит отметить , это то что вся текстура хранится в DWM(а точнее backbuffer) хитрым образом. Только реальное обновления будет доступно перед Present, вся остальная часть будет накрыта Alpha каналом.
Windows 8
Тут дела похожи, то есть не которое но.
struct __declspec(uuid("{1ddd77aa-9a4a-4cc8-9e55-98c196bafc8f}"))
IDXGIFactoryDWM8 : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE CreateSwapChainDWM(
/* [annotation][in] */
_In_ IUnknown *pDevice,
/* [annotation][in] */
_In_ DXGI_SWAP_CHAIN_DESC1 *pSwapChainDesc1,
/* [annotation][in] */
_In_ DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pSwapChainFullScreenDesc1,
/* [annotation][in] */
_In_ IDXGIOutput * pOutput,
/* [annotation][out] */
_Out_ IDXGISwapChainDWM8 ** ppSwapChainDWM1
) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateSwapChainDDA(
/* [annotation][in] */
_In_ IUnknown *pDevice,
/* [annotation][in] */
_In_ DXGI_SWAP_CHAIN_DESC1 *pSwapChainDesc1,
/* [annotation][in] */
_In_ IDXGIOutput * pOutput,
/* [annotation][out] */
_Out_ IDXGISwapChainDWM8 ** ppSwapChainDWM8
) = 0;
};
Который теперь имеет также расширенный интерфейс
//Undocument interface ( create from IDXGIFactoryDWM1::CreateSwapChain )
struct IDXGISwapChainDWM8 : public IDXGIObject
{
virtual HRESULT STDMETHODCALLTYPE GetDevice(
REFIID riid,
void **ppvObject
) = 0;
virtual HRESULT STDMETHODCALLTYPE Present(
/* [annotation][in] */
_In_ UINT SyncInterval,
/* [annotation][in] */
_In_ UINT Flags
) = 0;
virtual HRESULT STDMETHODCALLTYPE GetBuffer(
/* [annotation][in] */
_In_ UINT Buffer,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][retval][out] */
_Out_ void **ppSurface) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDesc(
/* [annotation][retval][out] */
_Out_ DXGI_SWAP_CHAIN_DESC *pDesc
) = 0;
virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(
/* [annotation][in] */
_In_ UINT BufferCount,
/* [annotation][in] */
_In_ UINT Width,
/* [annotation][in] */
_In_ UINT Height,
/* [annotation][in] */
_In_ DXGI_FORMAT NewFormat,
/* [annotation][in] */
_In_ UINT SwapChainFlags
) = 0;
virtual HRESULT STDMETHODCALLTYPE ResizeTarget(
/* [annotation][in] */
_In_ const DXGI_MODE_DESC *pNewTargetParameters ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(
/* [annotation][retval][out] */
_Out_ IDXGIOutput1 **ppOutput ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
/* [annotation][retval][out] */
_Out_ DXGI_FRAME_STATISTICS *pStats ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(
/* [annotation][retval][out] */
_Out_ UINT *pLastPresentCount ) = 0;
virtual HRESULT STDMETHODCALLTYPE Present1( //equals to : http://msdn.microsoft.com/en-us/library/windows/desktop/hh446797%28v=vs.85%29.aspx
/* [annotation][in] */
_In_ UINT SyncInterval,
/* [annotation][in] */
_In_ UINT Flags,
/* [annotation][in] */
_In_ UINT DirtyRectsCount,
/* [annotation][in] */
_In_ RECT *pDirtyRects,
/* [annotation][in] */
_In_ RECT *pScrollRect,
/* [annotation][in] */
_In_ POINT *pScrollOffset
) = 0;
virtual HRESULT STDMETHODCALLTYPE GetLogicalSurfaceHandle(
LPVOID pVoid
) = 0;
//
//Called by the Desktop Window Manager (DWM) to verify that the user-mode driver supports Direct Flip operations, in which video memory is seamlessly flipped between an application's
//managed primary allocations and the DWM's managed primary allocations.
//
virtual HRESULT STDMETHODCALLTYPE CheckDirectFlipSupport(
ULONG uLong,
IDXGIResource *pResource ,
PULONG puLong
) = 0;
virtual HRESULT STDMETHODCALLTYPE Present2(
/* [annotation][in] */
_In_ UINT SyncInterval,
/* [annotation][in] */
_In_ UINT Flags,
/* [annotation][in] */
_In_ UINT DirtyRectsCount,
/* [annotation][in] */
_In_ RECT *pDirtyRects,
/* [annotation][in] */
_In_ RECT *pScrollRect,
/* [annotation][in] */
_In_ POINT *pScrollOffset,
/* [annotation][in] */
_In_ IDXGIResource * pResource
) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCompositionSurface(
LPVOID* ppVoid
) = 0;
};
Вызывается метод Present2 для отправки контента на экран.
SwapChain содержит так же для буфера . backbuffer(0) и frontbuffer(1).
Интерфейс схож с IDXGISwapChain1.
Только параметры могут передаваться по другому(Случай с Present1).
Если посмотреть описание Present1, то можно увидеть что требуется FrontBuffer.
DWM Использует SwapChainDWM2::GetBuffer(1, __uudof(ID3D10Texture2D), ); Как front, c которого копирует не достоющей части на bacbuffer(SwapChainDWM2::GetBuffer(0, __uudof(ID3D10Texture2D), ))
Их хоть устройство теперь создается через D3D11CreateDevice, большая часть все равно работает как с ID3D10Device1 (ID3D11Device::QueryInterface).
спасибо за инфу, вовремя подвернулась :)
ОтветитьУдалитьА как это использовать для получения быстрого снимка рабочего стола в Windows 7 Aero. Внедряться в процесс и перехватывать вызовы DXGI?
ОтветитьУдалитьПерехватываешь Present. В Present вызов GetBuffer c нулевым индексом и получаешься текстуру. в текстуре будет изображения. Но нужно учитывать такой факт, текстуру будет с Alpha каналом. То и есть часть текстуры будет не видемой. видимая будет только обновлённая area. нужно будет текстуру отрисовать.
ОтветитьУдалитьWhat changes are made on windows 10?
ОтветитьУдалитьa lot of ... A little changes to VTBL for IDXGISwapChainDWM1.
ОтветитьУдалитьAdded several argument to Present method.
from (I don't remember build number ) have special scenario for aspect ratio and no scaling mode when you use not recommended resolution.
Do you have in mind to update the information for windows 10?
ОтветитьУдалитьit would be amazing if you could update it??!?! does it use directx 12?
ОтветитьУдалитьthanks for sharing you knowledge!
Not sure about Windows 10. At current moment I don't have enough time for it. Actually, Microsoft didn't makes big updates for DWM in Win10. But devil as usual in details. All changes related to VTBL and function prototypes. Dependent on Windows 10 build. Also, now DWM can render big texture to low screen resolution.
ОтветитьУдалитьMight be i will have time for it in future
About Dx10, not yet.
Этот комментарий был удален автором.
ОтветитьУдалить