Bei meinem Projekt dreht sich alles um schnelle und geschickte 3D-Stifteingabe mit bis zu 200 Eingabepunkten pro Sekunde.
Software Design Frage: Reicht die Ausgabegeschwindigkeit um jedes Frame ausgeben oder muß ein Fokus auf bestimmte Bildschirmbereiche gelegt werden?
Beim Test der Bildschirmausgabe habe ich einen starken Geschwindigkeitseinbruch bei OpenWindow, OpenWindowedScreen gegenüber OpenScreen.
Sind die Parameter für OpenWindow und OpenWindowedScreen richtig gesetzt um die Hardware-Beschleunigung zu erreichen?
Oder gibt es einen Weg die Adressen und die Schreibrechte vom Videospeicher nach OpenWindowedScreen zu bekommen?
Code: Alles auswählen
; Warum Geschwindigkeits-Test: Schreibe auf den Bildschirm-Buffer hier mit OpenWindowedScreen. Werden mehr als 59 fps erreicht? 
; Erstellt mit PureBasic  5.51 (x64) auf Wacom Cintiq Companion 2 2560x1440xR8G8B8A8@59 Windows 8.1 
; 78619 Zeilen/s 54 fps 98-102% CPU-Auslastung laut Resourcenmanager 
; bei reduzierter Auflösung 1920x1080 111380 Zeilen/s 77 fps  
; offen Stimmen die Aufrufe von OpenWindow und OpenWindowedScreen zur Hardware-Beschleunigung, da nur 21% der OpenScreen Leistung? (Win 8.1 und 7 Pro SP1 aber nicht Vista Home SP2)
; Oder gibt es einen Weg die Adressen und die Schreibrechte vom Videospeicher nach OpenWindowedScreen zu bekommen? 
EnableExplicit
Declare zeile(*wert) ; Procedure gibt Zeilen auf den Bildschirm aus.
Structure Bildschirmtyp : Name.s : Xpixel.w : Ypixel.w : Tiefe.w : fps.f : *Buffer : *Buffer2 : Pitch.l : Pixelformat.w : EndStructure
Dim Bildschirme.Bildschirmtyp(0) ; Im diesem Beispiel gibt es nur einen Bildschirm mit der Nummer 0 
InitSprite(): ExamineScreenModes() 
ExamineDesktops()
Bildschirme(0)\Xpixel=DesktopWidth(0) : Bildschirme(0)\Ypixel=DesktopHeight(0): Bildschirme(0)\fps=DesktopFrequency(0)
Define Fenster=OpenWindow(#PB_Any,
                          0,                       ; Anfängliche x Position des Fensters 
                          0,                       ; Anfängliche y Position des Fensters 
                          Bildschirme(0)\Xpixel ,  ; 2560 Pixel Breite 
                          Bildschirme(0)\Ypixel,   ; 1440 Pixel Höhe 
                          "Geschwindigkeits-TEST", ; Fenstername 
                          #PB_Window_BorderLess|#PB_Window_NoGadgets)   ; Flags keine Ränder - hier könnte etwas fehlen. 
                                                   ; kein ParentWindow
If 0=Fenster : MessageRequester("Fataler Fehler","OpenWindow fehlgeschlagen!") :End :EndIf 
If 0=OpenWindowedScreen(WindowID(Fenster), 
                        0,                      ; x Position 0 links
                        0,                      ; y Position 0 oben 
                        Bildschirme(0)\Xpixel,  ; 2560 Pixel Breite 
                        Bildschirme(0)\Ypixel,  ; 1440 Pixel Höhe
                        #False,                 ; keine Anpassung der Größe 
                        0,                      ; Stetuszeile  RightOffset
                        0,                      ; Statuszeile BottomOffset
                        #PB_Screen_SmartSynchronization) ; FlipModus  - Es scheint nur ein Videobuffer erstellt zu werden.
  MessageRequester("Fataler Fehler ","OpenWindowScreen fehlgeschlagen!")
  End 
EndIf
StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer()  ; Finde die Adresse des  Bildschirmm 
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() 
FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() :StopDrawing() 
Define j=0 
Define i 
Dim *Pufferfeld(Bildschirme(0)\Ypixel) 
*Pufferfeld(0)=AllocateMemory(Bildschirme(0)\Pitch * Bildschirme(0)\Ypixel)
Define *ptr=*Pufferfeld(0) 
For i=0 To Bildschirme(0)\Ypixel-1 ; Für Jede Zeile des *Pufferfeld
  *Pufferfeld(i) = *ptr
  *ptr+Bildschirme(0)\Pitch
  ; Füllte die Zeile mit grünen Punkten unterschiedlicher Helligkeit 
  For j=0 To Bildschirme(0)\Pitch-4 Step 4 :  PokeL(*Pufferfeld(i)+j,RGBA(0,Random(255),0,0)) : Next j 
Next i 
Define fertig=#False
Define fliptime=ElapsedMilliseconds()+16
Define Zeilen=0 
Define Cpus=CountCPUs(#PB_System_ProcessCPUs) :Dim thread(Cpus-1) 
thread(0)=CreateThread(@Zeile(),i) : ThreadPriority(thread(0),17) ; Prio 31 kaum Wirkung 
thread(1)=CreateThread(@Zeile(),i) : ThreadPriority(thread(1),17) ; 2. Thread bringt 10 zusätzliche fps 
; DisableDebugger ; bringt kaum etwas 
Define Startzeit=ElapsedMilliseconds()
Repeat
  Repeat
    Define Event = WindowEvent() ; Windows Event-Abfrage auf ALT-F4 
    If Event = #PB_Event_CloseWindow :  fertig=#True : EndIf
  Until Event = 0
  If ElapsedMilliseconds()>=fliptime ; Nach 16 ms wird ein FlipBuffers ausgelöst 
    FlipBuffers() 
    fliptime=ElapsedMilliseconds()+16 
  Else 
    Delay(1) ; Warte 1 Millisekunde - das Betriebssystems kann sich um die Threads und um anders kümmern 
  EndIf 
Until fertig=#True
EnableDebugger
For i=0 To Cpus-1 : If thread(i)<>0 : KillThread(thread(i)) : EndIf : Next i ; Threads beenden. 
Define Zeit.f=(ElapsedMilliseconds()-Startzeit)/1000 ; Messung ausgeben 
Define ZeilenProSekunde=Zeilen/Zeit
MessageRequester("Messung",
                 StrF(Zeit)+" s Zeilen:"+Str(Zeilen)+" Zeilen/s:"+Str(ZeilenProSekunde)+" fps:"+Str(ZeilenProSekunde/1440)+
                 " "+Bildschirme(0)\Xpixel+"x"+Bildschirme(0)\Ypixel+"@"+Bildschirme(0)\fps+#CRLF$+
                 Hex(Bildschirme(0)\Buffer)+" "+Hex(Bildschirme(0)\Buffer2))
End 
; Thread zur Ausgabe von Zeilen auf dem Bildschirm-Buffer 
Procedure zeile(*wert)
  Shared Zeilen
  Shared *Pufferfeld()
  Shared Bildschirme() 
  Define addzeilen=1  ; Es wird eine Bildschirmzeile ausgegeben 
  Define Laenge=Bildschirme(0)\Pitch*addzeilen ; Bildschirmzeilen in Bytes
  Repeat
    Define *Ziel= Bildschirme(0)\Buffer+Random( Bildschirme(0)\Ypixel-addzeilen) * Bildschirme(0)\Pitch ; zufällige Zeile
    Define *Quelle = *Pufferfeld(Random(Bildschirme(0)\Ypixel-addzeilen))                               ; zufällige Zeile 
    CopyMemory(*Quelle,*Ziel,Laenge) ; hier wird die CPU-Zeit verbraucht 
;    DisableDebugger:EnableASM:Mov rcx,Laenge : Sar rcx,3 : mov rsi, *Quelle : mov rdi, *Ziel : rep movsq :DisableASM:EnableDebugger
    ; x64 nötig - keine Wirkung 
    Zeilen+addzeilen ; Könnte ein Datarace sein? 
  ForEver
EndProcedure
; Geschichte 170101 Es sollte grünes Pixelrasuchen zu sehen sein, vergleichbar TV-Rauschen ohne Empfang. 
Code: Alles auswählen
; Warum Geschwindigkeits-Test: Schreibe auf den Bildschirm-Buffer hier mit OpenScreen. Werden mehr als 59 fps erreicht? 
; Erstellt mit PureBasic  5.51 (x64) auf Wacom Cintiq Companion 2 2560x1440xR8G8B8A8@59 Windows 8.1 
; Zeilen/s:379696 fps:263 
EnableExplicit
Declare zeile(*wert) ; Procedure gibt Zeilen auf den Bildschirm aus.
Structure Bildschirmtyp : Name.s : Xpixel.w : Ypixel.w : Tiefe.w : fps.f : *Buffer : *Buffer2 : Pitch.l : Pixelformat.w : EndStructure
Dim Bildschirme.Bildschirmtyp(0) ; Im diesem Beispiel gibt es nur einen Bildschirm mit der Nummer 0 
InitSprite(): ExamineScreenModes() 
ExamineDesktops()
Bildschirme(0)\Xpixel=DesktopWidth(0) : Bildschirme(0)\Ypixel=DesktopHeight(0): Bildschirme(0)\fps=DesktopFrequency(0)
InitKeyboard() 
Define main_whnd=OpenScreen(Bildschirme(0)\Xpixel,
                            Bildschirme(0)\Ypixel,
                            32,   ; Bildschirme(0)\Tiefe,
                            "Geschwindigkeits-TEST",
                            #PB_Screen_SmartSynchronization)
StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer() ; Finde die Adresse des  Bildschirmm 
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() :FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() ; Finde die 2, Adresse des  Bildschirmm 
Define j=0 
Define i 
Dim *Pufferfeld(Bildschirme(0)\Ypixel) 
*Pufferfeld(0)=AllocateMemory(Bildschirme(0)\Pitch * Bildschirme(0)\Ypixel)
Define *ptr=*Pufferfeld(0) 
For i=0 To Bildschirme(0)\Ypixel-1 ; Für Jede Zeile des *Pufferfeld
  *Pufferfeld(i) = *ptr
  *ptr+Bildschirme(0)\Pitch
  ; Füllte die Zeile mit grünen Punkten unterschiedlicher Helligkeit 
  For j=0 To Bildschirme(0)\Pitch-4 Step 4 :  PokeL(*Pufferfeld(i)+j,RGBA(0,Random(255),0,0)) : Next j 
Next i 
Define fertig=#False
Define fliptime=ElapsedMilliseconds()+16
Define Zeilen=0 
Define Cpus=CountCPUs(#PB_System_ProcessCPUs) :Dim thread(Cpus-1) 
thread(0)=CreateThread(@Zeile(),i) : ThreadPriority(thread(0),17) ; alleine Zeilen/s:347098 fps:241
thread(1)=CreateThread(@Zeile(),i) : ThreadPriority(thread(1),17) 
; DisableDebugger ; bringt kaum etwas 
Define Startzeit=ElapsedMilliseconds()
Repeat
  ExamineKeyboard() ; Prüfe Tasteneingaben ESC-Taste beendet Programm 
Until KeyboardPushed(#PB_Key_Escape) ; 
EnableDebugger
For i=0 To Cpus-1 : If thread(i)<>0 : KillThread(thread(i)) : EndIf : Next i ; Threads beenden. 
CloseScreen()
Define Zeit.f=(ElapsedMilliseconds()-Startzeit)/1000 ; Messung ausgeben 
Define ZeilenProSekunde=Zeilen/Zeit
Debug StrF(Zeit)+" s Zeilen:"+Str(Zeilen)+" Zeilen/s:"+Str(ZeilenProSekunde)+" fps:"+Str(ZeilenProSekunde/1440)+
                 " "+Bildschirme(0)\Xpixel+"x"+Bildschirme(0)\Ypixel+"@"+Bildschirme(0)\fps+#CRLF$+
                 Hex(Bildschirme(0)\Buffer)+" "+Hex(Bildschirme(0)\Buffer2)
End 
; Thread zur Ausgabe von Zeilen auf dem Bildschirm-Buffer 
Procedure zeile(*wert)
  Shared Zeilen
  Shared *Pufferfeld()
  Shared Bildschirme() 
  Define addzeilen=1
  Define Laenge=Bildschirme(0)\Pitch*addzeilen
  Repeat
    Define *Ziel= Bildschirme(0)\Buffer+Random( Bildschirme(0)\Ypixel-addzeilen) * Bildschirme(0)\Pitch
    Define *Quelle = *Pufferfeld(Random(Bildschirme(0)\Ypixel-addzeilen))
    CopyMemory(*Quelle,*Ziel,Laenge)
;    EnableASM : Mov rcx,Laenge : Sar rcx,3 : mov rsi, *Quelle : mov rdi, *Ziel : rep movsq : DisableASM ; x64 nötig - kaum Wirkung 
    Zeilen+addzeilen 
  ForEver
EndProcedure


 
 





