Vista and Windows 7 DWM, Get refresh and enabled status.

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Vista and Windows 7 DWM, Get refresh and enabled status.

Post by Rescator »

DWM refresh: 80.5167399278
DX refresh: 57.8264191820
DWM Composition: Enabled
This source will let you get the refresh rate of the DWM buffer and the DirectX buffer, and also let you check if DWM composition is currently enabled.

Be aware that the DWM refresh and DX refresh rates vary.
in my case it hovers around 80 Hz (or is this fps?) for DWM refresh and 57.8 for DirectX refresh.
My LCD is set to 60Hz, I got a 2nd monitor that is a CRT at 85Hz, changing it's refresh did not affect the refresh info.
It's likely that DWM uses the lowest common denominator, and that while my LCD and Desktop is at 60Hz it's possible my GFX card uses 57.8 internally for DX for some reason.
The fact that the DWM refresh is higher than the hardware refresh makes sense, as this ensures that lost frames are at a minimum if a update is too early or late for the vblank.

Code: Select all

EnableExplicit

Structure UNSIGNED_RATIO
 uiNumerator.l
 uiDenominator.l
EndStructure

Structure DWM_TIMING_INFO
 cbSize.l
 rateRefresh.UNSIGNED_RATIO
 qpcRefreshPeriod.q
 rateCompose.UNSIGNED_RATIO
 qpcVBlank.q
 cRefresh.q
 cDXRefresh.l
 qpcCompose.q
 cFrame.q
 cDXPresent.l
 cRefreshFrame.q
 cFrameSubmitted.q
 cDXPresentSubmitted.l
 cFrameConfirmed.q
 cDXPresentConfirmed.l
 cRefreshConfirmed.q
 cDXRefreshConfirmed.l
 cFramesLate.q
 cFramesOutstanding.l
 cFrameDisplayed.q
 qpcFrameDisplayed.q
 cRefreshFrameDisplayed.q
 cFrameComplete.q
 qpcFrameComplete.q
 cFramePending.q
 qpcFramePending.q
 cFramesDisplayed.q
 cFramesComplete.q
 cFramesPending.q
 cFramesAvailable.q
 cFramesDropped.q
 cFramesMissed.q
 cRefreshNextDisplayed.q
 cRefreshNextPresented.q
 cRefreshesDisplayed.q
 cRefreshesPresented.q
 cRefreshStarted.q
 cPixelsReceived.q
 cPixelsDrawn.q
 cBuffersEmpty.q
EndStructure

Prototype.l DwmGetCompositionTimingInfo(hwnd.i,*pTimingInfo.DWM_TIMING_INFO)
Global DwmGetCompositionTimingInfo.DwmGetCompositionTimingInfo
Prototype.l DwmIsCompositionEnabled(*pfEnabled.l)
Global DwmIsCompositionEnabled.DwmIsCompositionEnabled

Procedure.i dwmap_dll_init(init.i)
 Static dwmapi_dll.i
 Protected result.i=#True
 If init And Not dwmapi_dll
  dwmapi_dll=OpenLibrary(#PB_Any,"dwmapi.dll")
  If dwmapi_dll
   DwmGetCompositionTimingInfo=GetFunction(dwmapi_dll,"DwmGetCompositionTimingInfo")
   If Not DwmGetCompositionTimingInfo
    result=#False
   EndIf
   DwmIsCompositionEnabled=GetFunction(dwmapi_dll,"DwmIsCompositionEnabled")
   If Not DwmIsCompositionEnabled
    result=#False
   EndIf
  Else
   result=#False
  EndIf
  If Not result
   CloseLibrary(dwmapi_dll)
   dwmapi_dll=#Null
  EndIf
 ElseIf Not init And dwmapi_dll
  CloseLibrary(dwmapi_dll)
  dwmapi_dll=#Null
 EndIf
 ProcedureReturn dwmapi_dll
EndProcedure

Define.i event,quit,fEnabled.l
If OpenWindow(0,100,200,195,260,"PureBasic Window",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)

 If dwmap_dll_init(#True) ;init lib and return OpenLibrary id, if allready opened it returns the id.
  Define TimingInfo.DWM_TIMING_INFO
  TimingInfo\cbSize=SizeOf(DWM_TIMING_INFO)
  If DwmGetCompositionTimingInfo(#Null,TimingInfo)=#S_OK
   Debug "DWM refresh: "+StrD(TimingInfo\cRefresh/TimingInfo\qpcRefreshPeriod)
   Debug "DX refresh: "+StrD(TimingInfo\cDXRefresh/TimingInfo\qpcRefreshPeriod)
  Else
   Debug "Unable to get DWM Composition timing info!"
  EndIf
  DwmIsCompositionEnabled(@fEnabled)
  If fEnabled
   Debug "DWM Composition: Enabled"
  Else
   Debug "DWM Composition: Disabled"
  EndIf
 Else
  Debug "Failed to open dwmapi.dll or find needed functions!"
 EndIf

 Repeat
  event=WaitWindowEvent()
  If event=#PB_Event_CloseWindow
   quit=1
  EndIf
 Until quit=1
EndIf

Debug dwmap_dll_init(#False) ;returns #Null if library was closed.
Last edited by Rescator on Tue Aug 11, 2009 3:17 am, edited 1 time in total.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

In Windows 7 Ultimate 32 bit mine shows:

DWM refresh: 104.9049998988
DX refresh: 104.8696910220

My LCD wide screen monitor is at 60 Hz max. Its the refresh rate in Hz not FPS that DWM and DirectX is capable of with your computer. The monitor refresh rate doesn't figure into it. And...if I comment out the open window stuff in your code the rates increases to :

DWM refresh: 105.4964283546
DX refresh: 105.4609142603

and if I look at it when an actual diredctX window (a game) is open it increases to:

DWM refresh: 108.5425178833
DX refresh: 108.5061947268

Nice stuff, thank you very much. :)
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Ok, FPS not Hz gotcha. That does make more sense due to the fluctuating numbers.

I wonder why the fps is so different between us.
Mine almost seems semi-synced with some arbitrary relation to my LCD's refresh rate. While yours seem to be, not sure really.
It's almost like mine is vblank synced, which is very odd since I do not have that forced.

I got a GF8800GT card btw.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Rescator wrote: I got a GF8800GT card btw.
I've got an ATI HD 4890 with 1GB VRam, that might be the difference.

Theres a small typo in your code:

Code: Select all

Define.i event,quit,i.i,fEnabled.l

at quit, you have quit,i.i < you have a comma here instead of a period and an extra .i
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Fixed. the i.i was a leftover from some testing.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Post by idle »

that will come in handy, cheers
Post Reply