AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Multithreaded Zeichnen

Ein Thema von Sherlock · begonnen am 2. Jul 2018 · letzter Beitrag vom 10. Jul 2018
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Multithreaded Zeichnen

  Alt 2. Jul 2018, 20:02
Zitat:
Queue funktioniert hier wohl nicht ....
Ist mir unverständlich warum es nicht gehen sollte.
Ist doch letztendlich nichts anderes als PostMessage!

Kenne mich zwar mit OpenGL aus aber mit FMX habe ich mich nicht beschäftigt da ich das Umfeld nicht habe.

gruss

Geändert von EWeiss ( 2. Jul 2018 um 20:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#2

AW: Multithreaded Zeichnen

  Alt 2. Jul 2018, 23:54
Ich versuche die Zeit zu verkürzen, die meine Applikation einfriert, wenn ich zeichne. Da ab Tokyo Bitmaps threadsicher sein sollen, habe ich das zeichnen auf die Bitmap in einen Thread ausgelagert und möchte die fertige Bitmap per Synchonize an die GUI übergeben.

Im Ergebnis sollte eine Bitmap mit wildem Zickzack einmal pro Sekunde neu gezeichnet werden.

Was mache ich falsch?
Ich habe im Moment leider kein IOS-Gerät im Entwicklungs-Einsatz, kann daher meinen Vorschlag nicht selber testen, muss ich Dir also überlassen.
Deine Variante funktioniert jedenfalls auf einem Android-Device, könnte also ggflls. auch ein spezielles IOS-Problem sein.

"Threadsicher" heißt ab 10.2, dass die Zugriffe mehrerer Threads auf einen Canvas intern von Delphi serialisiert werden. Damit hat sich auch die Art, wann man ein Locking vornimmt, etwas geändert, da bei Dir aber nicht mehrere Threads an einer Grafik arbeiten und Du ja gewollt eine Pause von 1 Sekunde haben willst, ist das hier egal (mehr Infos hierzu bei Bedarf in meinem aktuellen FMX-Buch im Grafik-Kapitel unter 6.4).

Diese Änderung hat aber letztlich auch zur Konsequenz, dass Du das temporäre Bitmap gar nicht mehr brauchst, sondern direkt Image1.bitmap zum zeichnen verwenden kannst (eine extra Synchronisierung entfällt also). Damit sollte auch das Zuweisungsproblem von fBMp an Image1.bitmap entfallen, das aus irgendeinem Grund anscheinend nicht unter IOS funktioniert (wäre zwar ein "umgehen" des Problems, aber eine Lösung, die man mal versuchen könnte, ist ja nicht mehr als copy und paste):

Schlage also mal vor zu testen, ob es so auch auf Deinem IOS-Device funktioniert(unter Windows, Linux, Android geht es):

Delphi-Quellcode:
procedure TPainter.Execute;
var
  myPoint1 : TPoint;
  myPoint2 : TPoint;
  i : integer;
begin
  inherited;
  while not Terminated do
  begin
    myPoint1 := TPoint.Zero;
    if Form15.Image1.bitmap.Canvas.BeginScene then
    begin
      Form15.Image1.bitmap.Canvas.Clear(TAlphaColorRec.Null);
      Form15.Image1.bitmap.Canvas.Stroke.Thickness := 1;
      Form15.Image1.bitmap.Canvas.Stroke.Color := TAlphaColorRec.Black;
      try
        for i := 0 to 1000 do
        begin
          myPoint2 := TPoint.Create(Random(Form15.Image1.Bitmap.Width), Random(Form15.Image1.bitmap.Height));
          Form15.Image1.bitmap.Canvas.DrawLine(myPoint1, myPoint2, 1);
          myPoint1 := myPoint2;
        end;
      finally
        Form15.Image1.bitmap.Canvas.EndScene;
      end;
    end;
    //Synchronize(updateGui); // wird nicht benötigt
    Sleep(1000);
  end;
end;
Image1.bitmap muss irgendwo natürlich noch mit einer sinnvollen Größe vorbelegt werden.
Harry Stahl
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.247 Beiträge
 
Delphi 12 Athens
 
#3

AW: Multithreaded Zeichnen

  Alt 3. Jul 2018, 10:36
Hallo Harry,

ja richtig, in Canvas.BeginScene wird ein Lock gemacht.
Win, OSX, Android funktionieren bei mir auch (nur das Android anscheinend etwas falsch skaliert,
aber das sit ein anderes Thema).
iOS geht bei mir damit leider auch nicht.

Mir ging es darum das mehrere Threads auf einem Bitmap schreiben können, das hatte ich probiert
mit 4 TPainter Klassen, die dann aber beim Schreiben gegenseitig aufeinander Warten müssen.
Funktioniert hat das schon, aber die 4 Painter haben sich ziemlich behindert gegenseitig.
Hatte aber noch externes Lock ausprobiert, mit dem BeginScene Lock hat sich das womöglich überschnitten.

Ich probiere noch ein bischen damit rum.

Rollo
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.247 Beiträge
 
Delphi 12 Athens
 
#4

AW: Multithreaded Zeichnen

  Alt 3. Jul 2018, 11:29
Hab mal ein Testprojekt drangehangen.
Basierend auf der Vorlage von TiGü habe ich das etwas erweitert und "buntisiert" (weil hübscher als schwarz/weiss)

Läuft auf Win mit 4 TPainter-Threads, und dem Vorschlag von Harry immer direkt auf dem Image zu zeichnen.
Win Sample ist so wie gedacht: 4x Taste Drücken 4 separate Bereiche werden gemalt.

Schon OSX hat falsche Skalierungen (finde jetzt nicht so schnell den Fehler), und malt immer
im ganzen Bild statt in einem der 4 Teilbilder.

Android genauso falsch skaliert.

iOS malt im Moment gar nicht, habe ich bei mir bisher auch nicht hinbekommen.
Ich kann aber mit iOS zeichnen, das mache ich auch, ich muss mal checken wo jetzt genau das Problem sein könnte, habe aber gerade keine Zeit mehr dafür.


Rollo
Angehängte Dateien
Dateityp: zip T183_BmpThread.zip (12,8 KB, 2x aufgerufen)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.247 Beiträge
 
Delphi 12 Athens
 
#5

AW: Multithreaded Zeichnen

  Alt 3. Jul 2018, 18:56
Hab noch ein bischen rumgespielt ...

Ich erzeuge 4 Teilbitmps in Threads, diese werden dan in einem Taeget Bitmap zusammengebaut.
Wenn Alle Threads fertig sind wird das komplette Target in das Image geschrieben, mit
Delphi-Quellcode:
procedure DoDrawBitmap(const ACanvasDst : TCanvas;
                       const ADstRc : TRectF;
                       const ASrcBmp : TBitmap);
var
  LDstRc: TRectF;
begin
    if ACanvasDst.BeginScene then
        try
            LDstRc := RectF(0, 0, ADstRc.Width, ADstRc.Width);
            LDstRc.Offset( ADstRc.TopLeft );


            ACanvasDst.DrawBitmap(ASrcBmp, // Src bmp full
                                  RectF(0,0, ASrcBmp.Width, ASrcBmp.Height), // Src rc full
                                  LDstRc, // dst part bmp to dst canvas
                                  1);

        finally
            ACanvasDst.EndScene;
        end;

end;
Wird das Teil-Bmp in das Tgt-Bmp geschrieben.

Funktioniert auf Win, OSX, And, aber noch nicht auf iOS

Sorry, der Code ist noch ein bischen wüst, durch die ganzen Tests, ich hoffe das erkennt man noch wieder
Ob es jetzt Threadmäßig optimal ist wage ich auch zu bezweifeln, mit ging es erstmal drum das
Scaling und Printing überhaupt funktioniert.
Die Performance ist bei mit jedenfalls im Bereich 60-160FPS, je nach Plattform.

Aber wie man das auf eine optimale Performance bringt, vor Allem auch auf allen Platformen, ist noch nicht klar.

Womöglich mit TScene von Eugene, der Teilbereiche bei dem Bildupdate berücksichtigt, während FMX immer das ganze Bild updated.
Vielleicht hat ja noch jemand Ideen dazu.


Rollo
Angehängte Dateien
Dateityp: zip T183_BmpThread.zip (14,3 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Multithreaded Zeichnen

  Alt 3. Jul 2018, 22:46
Hi Leute,

das hat zwar nichts mit IOS zu tun, jedoch mit multithreaded painting sowie mit teilweiser Aktualisierung...
Im Graphics32 Framework findet sich ein schöner Lösungsansatz zu Multithreaded 'Zeichnen', einfach mal so als Grundlage / Anregung.
Siehe TSyntheticImage in GR32_ExtImage.pas
https://graphics32.github.io/Docs/Un...mage/_Body.htm
Peter
Was mache ich, wenn ein Bär meine Frau angreift?
Nichts. Er hat sie angegriffen, soll er doch selber sehen, wie er sich verteidigt.

Geändert von bytecook ( 3. Jul 2018 um 23:53 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.247 Beiträge
 
Delphi 12 Athens
 
#7

AW: Multithreaded Zeichnen

  Alt 4. Jul 2018, 06:30
Hallo bytecook,

ja gute Idee, GR32 für FMX wollte ich schon immer mal Testen.
GR32 war schon immer eine super Lösung

Habe es mir nicht angesehen, aber ich vermute mal da wird noch ein Grafiklayer über den FMX-Layer gelegt.
Macht das wirklich Sinn, und wird das GR32 durch GPU unterstützt ?

Sollte man mal checken, ich kann aber erst nächste Woche weitertesten.

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz