Page 1 of 2
VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 12:38 am
by chris319
I was wondering if FlipBuffers() blocks program execution while waiting for VSync, so I wrote this little program to find out. The answer is yes, it does block program execution while waiting for VSync. By opening the screen in either mode you can see this for yourself.
Two questions: I noticed that it takes a couple of buffer flips for things to synchronize with the display frequency (on my system the display frequency is around 60 Hz). Does anyone know why this is?
By what mechanism does FlipBuffers() know that VSync has arrived?
If anyone has any suggestions for improvements, please feel free to suggest.
Code: Select all
DisableDebugger
Dim duration.f(20)
OpenConsole()
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
;OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization)
OpenScreen(1024, 768, 32, "", #PB_Screen_WaitSynchronization)
;IT MAY TAKE A FEW BUFFER FLIPS TO GET SYNCHRONIZED
For ct = 1 To 20
FlipBuffers()
Next
For ct = 1 To 20
QueryPerformanceCounter_(@then.q)
FlipBuffers()
QueryPerformanceCounter_(@now.q)
duration(ct) = (now - then) / maxFreq
Next
CloseScreen()
For ct = 1 To 20
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,2) + " frames per second")
Next
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 1:05 am
by Demivec
I don't see any patterns.
What do you see in these results?
Code: Select all
15.00 ms 66.66 frames per second
17.88 ms 55.92 frames per second
16.52 ms 60.52 frames per second
17.10 ms 58.47 frames per second
15.49 ms 64.56 frames per second
40.49 ms 24.70 frames per second
12.37 ms 80.83 frames per second
84.72 ms 11.80 frames per second
0.36 ms 2793.91 frames per second
0.02 ms 61706.89 frames per second
15.09 ms 66.28 frames per second
14.51 ms 68.92 frames per second
15.31 ms 65.32 frames per second
16.59 ms 60.29 frames per second
16.68 ms 59.94 frames per second
16.64 ms 60.10 frames per second
16.83 ms 59.41 frames per second
27.94 ms 35.80 frames per second
9.71 ms 102.98 frames per second
12.36 ms 80.88 frames per second
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 1:31 am
by chris319
On my laptop I sometimes get weird values as well. On my desktop with an Nvidia AGP graphics card, after a few warm-up flips it gives 59.xx frames per second consistently. So something is goofy with FlipBuffers (it is not always waiting for VBlank it would seem).
Used to be that you could read the VBlank bit on port $3DA, but if you try to peek that address with PB it causes a crash.
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 2:01 am
by Demivec
Even though the screen is setup to wait for the Vsync, I think you would still need to use SetFrameRate().
Alternatively you can open the screen with smart-synchronization to avoid the program hogging the cpu while it's simply waiting. In this way I think you would be able to take advantage of other threads being able to do something productive during the delay.
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 2:25 am
by chris319
Demivec wrote:Even though the screen is setup to wait for the Vsync, I think you would still need to use SetFrameRate().
Try it!
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 3:06 am
by Demivec
chris319 wrote:Demivec wrote:Even though the screen is setup to wait for the Vsync, I think you would still need to use SetFrameRate().
Try it!
Well, here's the results (information overload

):
Code: Select all
Smart, SetFrameRate(60) Smart, no SetFrameRate
16.40 ms 60.99 fps 56.38 ms 17.74 fps
16.39 ms 61.00 fps 0.05 ms 19037.23 fps
16.40 ms 60.99 fps 9.42 ms 106.15 fps
16.39 ms 61.00 fps 17.84 ms 56.06 fps
16.40 ms 60.99 fps 15.50 ms 64.51 fps
16.39 ms 60.99 fps 17.10 ms 58.46 fps
16.39 ms 61.00 fps 25.63 ms 39.01 fps
16.39 ms 61.00 fps 17.49 ms 57.17 fps
16.40 ms 60.99 fps 7.00 ms 142.85 fps
16.40 ms 60.99 fps 16.65 ms 60.05 fps
18.62 ms 53.72 fps 30.97 ms 32.29 fps
16.39 ms 61.00 fps 15.39 ms 64.99 fps
16.39 ms 60.99 fps 3.32 ms 301.01 fps
16.39 ms 60.99 fps 19.88 ms 50.30 fps
16.39 ms 61.00 fps 13.85 ms 72.21 fps
16.40 ms 60.99 fps 15.15 ms 66.01 fps
16.40 ms 60.99 fps 16.65 ms 60.05 fps
16.39 ms 61.00 fps 17.63 ms 56.71 fps
16.39 ms 61.00 fps 16.95 ms 59.00 fps
16.40 ms 60.99 fps 15.59 ms 64.13 fps
Vsync, SetFrameRate(60) Vsync, no SetFrameRate
16.40 ms 60.99 fps 2.12 ms 471.79 fps
16.39 ms 61.00 fps 15.38 ms 65.02 fps
16.39 ms 60.99 fps 17.95 ms 55.72 fps
16.39 ms 60.99 fps 41.20 ms 24.27 fps
16.39 ms 60.99 fps 9.57 ms 104.54 fps
17.50 ms 57.16 fps 19.04 ms 52.52 fps
16.39 ms 60.99 fps 12.15 ms 82.28 fps
16.39 ms 60.99 fps 17.39 ms 57.50 fps
16.39 ms 61.00 fps 15.91 ms 62.86 fps
16.40 ms 60.99 fps 16.67 ms 59.97 fps
16.40 ms 60.99 fps 16.67 ms 60.00 fps
16.39 ms 61.00 fps 16.69 ms 59.91 fps
16.39 ms 60.99 fps 26.73 ms 37.42 fps
16.39 ms 61.00 fps 11.95 ms 83.68 fps
16.39 ms 60.99 fps 11.39 ms 87.81 fps
16.40 ms 60.99 fps 16.66 ms 60.04 fps
16.40 ms 60.99 fps 16.71 ms 59.84 fps
16.40 ms 60.99 fps 16.61 ms 60.22 fps
16.39 ms 61.00 fps 16.69 ms 59.91 fps
16.40 ms 60.99 fps 16.64 ms 60.09 fps
No Vsync, SetFrameRate(60) No Vsync, no SetFrameRate
16.40 ms 60.99 fps 0.08 ms 12341.38 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 61.00 fps 0.08 ms 12341.38 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 61.00 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
19.11 ms 52.33 fps 0.08 ms 12384.08 fps
16.39 ms 61.00 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.08 ms 12341.38 fps
16.39 ms 60.99 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.09 ms 11325.95 fps
16.39 ms 60.99 fps 0.08 ms 12298.97 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 60.99 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 60.99 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 61.00 fps 0.08 ms 12384.08 fps
16.40 ms 60.99 fps 0.08 ms 12384.08 fps
16.39 ms 61.00 fps 0.08 ms 12384.08 fps
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 4:47 am
by chris319
Here's what I get. Clearly the frame rate must be set regardless.
I am concerned about FlipBuffers() exiting early -- it shouldn't. I can understand why it might exit late if a higher-priority task has the machine tied up.
Code: Select all
Frame rate not set, #PB_Screen_NoSynchronization
0.06 ms 16076.191 frames per second
49.17 ms 20.339 frames per second
0.16 ms 6418.250 frames per second
0.07 ms 14938.052 frames per second
0.06 ms 17583.334 frames per second
0.74 ms 1355.823 frames per second
0.08 ms 12787.879 frames per second
0.07 ms 14938.052 frames per second
0.06 ms 17768.422 frames per second
1.63 ms 614.042 frames per second
0.09 ms 11405.405 frames per second
0.06 ms 15924.529 frames per second
0.10 ms 9590.909 frames per second
0.06 ms 15924.529 frames per second
2.08 ms 481.735 frames per second
0.08 ms 11804.195 frames per second
0.12 ms 8154.589 frames per second
0.06 ms 16880.002 frames per second
0.06 ms 17402.061 frames per second
0.49 ms 2041.112 frames per second
0.07 ms 14184.874 frames per second
0.06 ms 15775.701 frames per second
0.06 ms 17583.334 frames per second
0.35 ms 2846.543 frames per second
0.11 ms 9483.146 frames per second
0.06 ms 17402.061 frames per second
0.30 ms 3296.875 frames per second
0.06 ms 15629.630 frames per second
0.06 ms 17224.488 frames per second
0.68 ms 1466.551 frames per second
Frame rate @60 Hz, #PB_Screen_NoSynchronization
16.40 ms 60.978 frames per second
16.40 ms 60.980 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.980 frames per second
91.66 ms 10.910 frames per second
16.39 ms 60.998 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.983 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.985 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.983 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.980 frames per second
16.40 ms 60.985 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.983 frames per second
16.40 ms 60.985 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.991 frames per second
Frame rate not set, #PB_Screen_WaitSynchronization
16.20 ms 61.716 frames per second
19.17 ms 52.163 frames per second
54.01 ms 18.515 frames per second
0.10 ms 9645.714 frames per second
0.05 ms 21641.025 frames per second
6.44 ms 155.190 frames per second
15.96 ms 62.662 frames per second
15.93 ms 62.763 frames per second
16.03 ms 62.382 frames per second
15.99 ms 62.523 frames per second
15.99 ms 62.553 frames per second
15.98 ms 62.565 frames per second
16.01 ms 62.475 frames per second
15.98 ms 62.593 frames per second
16.00 ms 62.500 frames per second
15.99 ms 62.544 frames per second
16.01 ms 62.479 frames per second
15.98 ms 62.590 frames per second
16.00 ms 62.500 frames per second
15.98 ms 62.567 frames per second
16.01 ms 62.465 frames per second
15.98 ms 62.579 frames per second
16.01 ms 62.475 frames per second
15.99 ms 62.556 frames per second
16.01 ms 62.463 frames per second
15.97 ms 62.602 frames per second
16.01 ms 62.475 frames per second
15.98 ms 62.572 frames per second
16.00 ms 62.509 frames per second
16.00 ms 62.493 frames per second
Frame rate @60 Hz, #PB_Screen_WaitSynchronization
16.40 ms 60.978 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.989 frames per second
16.44 ms 60.840 frames per second
16.39 ms 60.996 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.991 frames per second
16.41 ms 60.954 frames per second
20.55 ms 48.671 frames per second
16.39 ms 61.011 frames per second
16.40 ms 60.994 frames per second
18.18 ms 55.011 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.994 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
Frame rate not set, #PB_Screen_SmartSynchronization
35.14 ms 28.454 frames per second
0.09 ms 10820.513 frames per second
12.74 ms 78.519 frames per second
15.94 ms 62.751 frames per second
19.76 ms 50.616 frames per second
12.35 ms 80.963 frames per second
15.92 ms 62.823 frames per second
15.99 ms 62.544 frames per second
16.02 ms 62.419 frames per second
15.97 ms 62.609 frames per second
15.96 ms 62.672 frames per second
16.03 ms 62.401 frames per second
15.99 ms 62.542 frames per second
15.94 ms 62.735 frames per second
15.97 ms 62.600 frames per second
16.01 ms 62.477 frames per second
15.99 ms 62.558 frames per second
15.99 ms 62.544 frames per second
16.01 ms 62.472 frames per second
15.98 ms 62.590 frames per second
16.00 ms 62.486 frames per second
15.99 ms 62.542 frames per second
16.00 ms 62.493 frames per second
15.98 ms 62.560 frames per second
16.01 ms 62.449 frames per second
15.98 ms 62.576 frames per second
15.99 ms 62.551 frames per second
16.00 ms 62.486 frames per second
15.99 ms 62.535 frames per second
16.00 ms 62.505 frames per second
Frame rate @60 Hz, #PB_Screen_SmartSynchronization
16.40 ms 60.980 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.989 frames per second
16.53 ms 60.500 frames per second
162.39 ms 6.158 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.987 frames per second
16.40 ms 60.991 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.991 frames per second
81.80 ms 12.225 frames per second
16.39 ms 61.005 frames per second
16.40 ms 60.994 frames per second
16.40 ms 60.989 frames per second
16.40 ms 60.987 frames per second
16.39 ms 60.996 frames per second
16.40 ms 60.991 frames per second
16.39 ms 60.996 frames per second
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 5:47 am
by chris319
It gets worse. I created a procedure which draws a box on the screen and it messes up the timing beyond belief. If the StartDrawing() function is moved to line 27 (outside the loop) and disabled inside the procedure, the box is not drawn at all.
Code: Select all
Procedure DrawScreen(null)
StartDrawing(ScreenOutput())
Box(0,0,400,400, $00ffff)
StopDrawing()
EndProcedure
DisableDebugger
Dim duration.f(100)
OpenConsole()
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
OpenScreen(1024, 768, 32, "", #PB_Screen_WaitSynchronization)
;OpenScreen(1024, 768, 32, "", #PB_Screen_SmartSynchronization)
SetFrameRate(60) ;MUST BE SET
;IT MAY TAKE A FEW BUFFER FLIPS TO GET SYNCHRONIZED
For ct = 1 To 20
FlipBuffers()
Next
;StartDrawing(ScreenOutput())
For ct = 1 To 30
DrawScreen(null)
QueryPerformanceCounter_(@then.q)
FlipBuffers()
QueryPerformanceCounter_(@now.q)
duration(ct) = (now - then) / maxFreq
Next
;StopDrawing()
CloseScreen()
For ct = 1 To 30
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,3) + " frames per second")
Next
;PrintN(Str(PeekA($3DA))) ;, 8
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 8:51 am
by Demivec
chris319 wrote:It gets worse. I created a procedure which draws a box on the screen and it messes up the timing beyond belief. If the StartDrawing() function is moved to line 27 (outside the loop) and disabled inside the procedure, the box is not drawn at all.
That is because the FlipBuffers would then be inside the StartDrawing()/StopDrawing() block! You can't flip a screen that is still being drawn (and see it).
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 1:50 pm
by chris319
The timing is better behaved using a windowed screen. The flip mode used when opening the windowed screen seems to have no meaning. The program relies instead on SetFrameRate().
A fly in the ointment is that FlipBuffers() doesn't work inside a procedure. I have left in my Flip() procedure to demonstrate this. My idea was to flip buffers in a separate thread. In pseudo code it would work thus:
1. Draw graphics
2. Signal external thread to flip buffers
3. External thread sets a shared "busy" flag
4. While external thread is waiting for the next VBlank, main thread begins drawing next frame
5. When finished drawing graphics, main thread waits for "busy" flag to be cleared and signals external thread for next frame. This is to make sure the main (drawing) thread does not get ahead of the screen flipping. This scheme should buy the main thread extra time to draw while the external thread is waiting for VBlank. For this to work, the graphics MUST finish rendering within a period of one frame (about 16.6 ms at 60 fps). In my real application I am doing image processing so the graphics routine is the same for each frame; I am basically reading and rewriting pixels.
Thoughts? How can I flip buffers within a procedure?
Code: Select all
Global now.q, then.q, maxFreq.q, ct, null = 0: Global Dim duration.f(100)
Procedure Flip(null)
QueryPerformanceCounter_(@then.q)
FlipBuffers()
QueryPerformanceCounter_(@now.q)
duration(ct) = (now - then) / maxFreq
EndProcedure
DisableDebugger
OpenConsole()
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
;OpenWindowedScreen(0,0,0,1024, 768, #False, 0, 0,#PB_Screen_WaitSynchronization)
OpenWindowedScreen(0,0,0,1024, 768, #False, 0, 0,#PB_Screen_NoSynchronization)
;OpenWindowedScreen(0,0,0,1024, 768, #False, 0, 0,#PB_Screen_SmartSynchronization)
SetFrameRate(60) ;MUST BE SET
;GET SYNCHRONIZED
FlipBuffers()
For ct = 1 To 20
StartDrawing(WindowOutput(0))
Box(0,0,400,400, $00ffff)
StopDrawing()
;Flip(null)
QueryPerformanceCounter_(@then.q)
FlipBuffers()
QueryPerformanceCounter_(@now.q)
duration(ct) = (now - then) / maxFreq
Next
Delay(2000)
CloseWindow(0)
For ct = 1 To 20
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,2) + " frames per second")
Next
;PrintN(Str(PeekA($3DA))) ;, 8
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End
Re: VSync and FlipBuffers(), and Questions
Posted: Tue Oct 02, 2012 10:18 pm
by chris319
Back to regular screens. The following incorporates some of djes' excellent code found here:
http://www.purebasic.fr/english/viewtop ... ers+thread
Note that the thread containing FlipBuffers() has a higher priority than the main thread. Note also how the timing has been implemented in the Flip() procedure to help prevent early returns.
Code: Select all
Global now.q, then.q, maxFreq.q, ct, null = 0, threadID1, semaphore1, readyFlag
Global Dim duration.f(100)
Global frameDur.f = (1/(60 / 1)) * 1000
Structure D3DRaster_STATUS
InVBlank.l
ScanLine.l
EndStructure
Define.D3DRaster_STATUS Raster
Define.IDirect3DDevice9 D3DDeviceInterface
Procedure Flip(null)
Shared D3DDeviceInterface, Raster
Repeat
WaitSemaphore(semaphore1)
D3DDeviceInterface\GetRasterStatus(0, @Raster)
If Raster\InVBlank = #True
Repeat
D3DDeviceInterface\GetRasterStatus(0, @Raster)
Until Raster\InVBlank = #False
EndIf
Repeat
D3DDeviceInterface\GetRasterStatus(0, @Raster)
Until Raster\InVBlank = #True
FlipBuffers()
Repeat
QueryPerformanceCounter_(@n.q)
dur.f = (n.q - then.q) / maxFreq
Until dur.f >= frameDur
readyFlag = #True
ForEver
EndProcedure
OpenConsole()
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization) ;, 60)
;SetFrameRate(60)
!extrn _PB_Screen_Direct3DDevice
!MOV dword EAX, [_PB_Screen_Direct3DDevice]
!MOV dword [v_D3DDeviceInterface],EAX
semaphore1 = CreateSemaphore()
threadID1 = CreateThread(@Flip(), null)
SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
SetThreadPriority_(GetCurrentThread_(), #THREAD_PRIORITY_ABOVE_NORMAL)
SetThreadPriority_(ThreadID(threadID1), #THREAD_PRIORITY_HIGHEST)
For ct = 1 To 30
QueryPerformanceCounter_(@then.q)
readyFlag = #False
SignalSemaphore(semaphore1)
StartDrawing(ScreenOutput())
Box(0,0,400,400, $00ffff)
StopDrawing()
While readyFlag = #False: Wend
QueryPerformanceCounter_(@now.q)
duration(ct) = (now - then) / maxFreq
Next
SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
SetThreadPriority_(GetCurrentThread_(), #THREAD_PRIORITY_NORMAL)
SetThreadPriority_(ThreadID(threadID1), #THREAD_PRIORITY_NORMAL)
KillThread(threadID1)
CloseScreen()
For ct = 1 To 30
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,2) + " frames per second")
Next
;PrintN(Str(PeekA($3DA))) ;, 8
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End
Re: VSync and FlipBuffers(), and Questions
Posted: Thu Oct 04, 2012 6:24 pm
by chris319
This gets us a little closer to perfection.
Code: Select all
Global now.q, then.q, maxFreq.q, ct, null = 0, threadID1, readyFlag
Global Dim duration.f(100)
Structure D3DRaster_STATUS
InVBlank.l
ScanLine.l
EndStructure
Define.D3DRaster_STATUS Raster
Define.IDirect3DDevice9 D3DDeviceInterface
Procedure Flip(null)
Shared D3DDeviceInterface, Raster, readyFlag
ct = 0
Repeat
QueryPerformanceCounter_(@then.q)
D3DDeviceInterface\GetRasterStatus(0, @Raster)
If Raster\InVBlank = #True ;IN CASE WE COME PARTWAY INTO A VBLANKING INTERVAL
Repeat
D3DDeviceInterface\GetRasterStatus(0, @Raster)
Until Raster\InVBlank = #False
EndIf
Repeat
Delay(2) ;SAVE THE CPU
D3DDeviceInterface\GetRasterStatus(0, @Raster)
Until Raster\InVBlank = #True
FlipBuffers()
; D3DDeviceInterface\GetRasterStatus(0, @Raster)
; If Raster\InVBlank = #True
; Repeat
; D3DDeviceInterface\GetRasterStatus(0, @Raster)
; Until Raster\InVBlank = #False
; EndIf
QueryPerformanceCounter_(@n.q)
dur.f = (n.q - then.q) / maxFreq
If ct < 30 And readyFlag = #True
duration(ct) = dur ;(n - then) / maxFreq
ct + 1
Else
SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
SetThreadPriority_(ThreadID(threadID1), #THREAD_PRIORITY_NORMAL)
EndIf
ForEver
EndProcedure
readyFlag = #False
OpenConsole()
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization) ;, 60)
;SetFrameRate(60)
StartDrawing(ScreenOutput())
Box(0,0,400,400, $00ffff)
StopDrawing()
FlipBuffers()
StartDrawing(ScreenOutput())
Box(0,0,400,400, $00ffff)
StopDrawing()
!extrn _PB_Screen_Direct3DDevice
!MOV dword EAX, [_PB_Screen_Direct3DDevice]
!MOV dword [v_D3DDeviceInterface],EAX
threadID1 = CreateThread(@Flip(), null)
SetPriorityClass_(GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
SetThreadPriority_(ThreadID(threadID1), #THREAD_PRIORITY_TIME_CRITICAL)
Delay(500)
readyFlag = #True
While ct < 30: Wend
SetThreadPriority_(GetCurrentThread_(), #THREAD_PRIORITY_NORMAL)
KillThread(threadID1)
SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
CloseScreen()
For ct = 1 To 30
If duration(ct) <> 0
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,2) + " fps")
EndIf
Next
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End
Re: VSync and FlipBuffers(), and Questions
Posted: Thu Oct 04, 2012 10:47 pm
by PMV
PureBasic Help - Threads wrote:Note: Don't use DirectX inside threads (MS Windows limitation)! If you need to display graphics in threads use Images and 2DDrawing instead.
PureBasic Help - KillThread() wrote:Imediately kills the specified thread, which had previously been created with CreateThread(). This is a very dangerous function, and should only be used rarely. The problem is that the thread is killed immediately and has no chance to perform any cleanup code (for example, freeing memory, releasing items, de-allocating its own stack).
If possible, a flag like a global variable should be used to tell the thread to quit itself (which does the needed cleanup) and this function should only be used if this is not possible for some reason.
I have not any problems in my game or any other game. Maybe Flipbuffers() is able to
see, that there is nothing changed and returns immediately. What i know is, that you
doesn't need to worry about Flipbuffers()! Just make your game.
It will need enough time to do that.
And of course Flipbuffer() blocks if VSync is activated, that is what VSync is for. It is
just DX on windows behind all the Sprite and Screen functions ... so there is no special
behind that functions. Because i have PB i don't know what the DX-Function name is called.
MFG PMV
Re: VSync and FlipBuffers(), and Questions
Posted: Fri Oct 05, 2012 12:20 am
by chris319
Just make your game.

Where do you get the idea that it's a game? It's an image-processing program for video which must process an entire frame within 1/60 second.
Note: Don't use DirectX inside threads (MS Windows limitation)! If you need to display graphics in threads use Images and 2DDrawing instead.
So far no problem reading the vertical blanking information and calling FlipBuffers(). As you can see from earlier posts in this thread, the synchronization bits used with open screen aren't dependable.
Maybe Flipbuffers() is able to
see, that there is nothing changed and returns immediately.
That's making quite a big assumption about FlipBuffers().
Imediately kills the specified thread, which had previously been created with CreateThread(). This is a very dangerous function, and should only be used rarely. The problem is that the thread is killed immediately and has no chance to perform any cleanup code (for example, freeing memory, releasing items, de-allocating its own stack).
If possible, a flag like a global variable should be used to tell the thread to quit itself (which does the needed cleanup) and this function should only be used if this is not possible for some reason.
Good point and easily changed.
Re: VSync and FlipBuffers(), and Questions
Posted: Fri Oct 05, 2012 12:48 am
by PMV
Ah sorry, had read that you want to make image-processing program
just forgotted

.
I have read your post a little bit more carfully and now i got what
you want to get with your little Flip()-Procedure. To be direct, that
will have no effect, i still don't think that Flipbuffers() is allowed in
a thread ... but additional, Flipbuffers() doesn't do that much. You
do the same thing (and more) as Flipbuffers() will do alone. Waits
until the next possible time to swap and get back to work for the
next frame.
And if you write to the Screen before it is flipped, you will write
to the false buffer. So you need to wait until the flip is finished.
It can be just possible, that you could write onto a sprite while
waiting for the flip and until the sprite is finished and the flip is
done, write the sprite to the screen, start waiting for the next
flip and draw the next frame onto the sprite. That would be
something like a dripple buffer. By the way, OpenGL has such an
Option ... maybe you could use OpenGL directly instead of
DX and PB. Could be, that OpenGL is more Threadsafe, too
MFG PMV