LCL und Cairo

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: LCL und Cairo

Beitrag von Soner »

Bei Luipack im Cairo-Ordner, dort sind noch mehr Beispiele. Schau einfach im Luipack-Ordner nach, es gibt dort noch mehr Sachen.
Dateianhänge
luipack-cairo.jpg
luipack-cairo.jpg (67.03 KiB) 808 mal betrachtet

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: LCL und Cairo

Beitrag von Mathias »

Ich habe noch ein wenig mit LUIPack probiert. Schlussendlich bleibt auch dies bei dem Printer hängen.
In meinen Augen ein zu grosses Geflick um etwas vernümftiges zu machen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: LCL und Cairo

Beitrag von Mathias »

So nun habe ich es hingekriegt, ein cairo-Bild in der LCL.
Es ist sicher nicht perfekt, aber immerhin es ist etwas sichtbar. Optimierungen sind sicher noch möglich.
Ich habe einen Umweg über TBitmap gemacht.
Einzig, was cairo braucht. ist ein Zeiger auf eine Textur/Bitmap-Daten und dies habe ich bei der TBitmap.RawImage.Data .

https://github.com/sechshelme/Lazarus-D ... /LCL_cairo

Wen es eine LCL-Komponente gibt, bei der man direkt in den Renderpuffer zugreifen kann, müsste da cairo eigentlich auch funktionieren.
Nur kenne ich keine solche Komponente.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Roland Chastain
Beiträge: 156
Registriert: Sa 7. Jul 2012, 21:50
Wohnort: Saargemünd
Kontaktdaten:

Re: LCL und Cairo

Beitrag von Roland Chastain »

Ausgezeichneter Fund! Du hast meine hier gestellte Frage beantwortet.

Ich werde in der Lage sein, meine Beispiele mit Linux kompatibel zu machen. :wink:
Zuletzt geändert von Roland Chastain am Do 9. Feb 2023, 06:04, insgesamt 1-mal geändert.
Petit poisson deviendra grand,
Pourvu que Dieu lui prête vie.

Benutzeravatar
Roland Chastain
Beiträge: 156
Registriert: Sa 7. Jul 2012, 21:50
Wohnort: Saargemünd
Kontaktdaten:

Re: LCL und Cairo

Beitrag von Roland Chastain »

Ich frage mich, ob wir CAIRO_FORMAT_RGB24 oder CAIRO_FORMAT_ARGB32 nehmen sollten.

Bei deinem Beispiel funktioniert beides. :?

Und die Funktion cairo_format_stride_for_width() gibt für beide das gleiche Ergebnis zurück.

Code: Alles auswählen

uses
  Cairo;

var
  stride: integer;
  
begin
  stride := cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, 640);
  WriteLn(stride); // 2560
  stride := cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 640);
  WriteLn(stride); // 2560
end.
Hier soll die Variable stride verwendet werden.

Code: Alles auswählen

  cr_surface := cairo_image_surface_create_for_data(bit.RawImage.Data, {CAIRO_FORMAT_RGB24}CAIRO_FORMAT_ARGB32, bit.Width, bit.Height, {2560}stride);
Petit poisson deviendra grand,
Pourvu que Dieu lui prête vie.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: LCL und Cairo

Beitrag von Mathias »

Eines vorweg, das Testprogramm ist ein Murks, es mischt LCL, GTK und SDL. Aber für einen Benchmark reicht es.
Es werden 3 verschiedene Ccairo-Context auf Geschwindigkeit getestet. In allen 3 Varianten kommt die gleiche Render-Szene vor.
Was mich dabei verwundert, das GTK fast doppelt solange braucht wie die anderen beiden.
Könnte es sein, das SDL und TBitmap ihre Textur-Daten im VRAM hat und GTK im normalen Arbeitsspeicher ?

Dabei bin ich auf folgendes Ergebniss gekommen.

Code: Alles auswählen

GTK:    0.03919
GTK:    0.03918
SDL:    0.02222
SDL:    0.02241
TBitmap:    0.02211
TBitmap:    0.02234
https://github.com/sechshelme/Lazarus-D ... _benchmark

Dies ist die Render-Routine und in dieser hat es keine Plattform spezifischen Sachen.

Code: Alles auswählen

procedure Draw(cr: Pcairo_t; Name: string);
var
  xc: double = 320;
  yc: double = 240;
  radius: double = 200;
  angele1: double = 45 * (pi / 180);
  angele2: double = 180 * (pi / 180);
  startTime: TDateTime;
  i: integer;
begin
  startTime := now;

  for i := 1 to 10000 do begin
    cairo_set_source_rgba(cr, 1, 1, 1, 1.0);
    cairo_rectangle(cr, 0, 0, 640, 480);
    cairo_fill(cr);

    cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
    cairo_set_line_width(cr, 10.0);
    cairo_arc(cr, xc, yc, radius, angele1, angele2);
    cairo_stroke(cr);

    cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
    cairo_set_line_width(cr, 6.0);

    cairo_arc(cr, xc, yc, 10.0, 0, 2 * pi);
    cairo_fill(cr);

    cairo_arc(cr, xc, yc, radius, angele1, angele1);
    cairo_line_to(cr, xc, yc);
    cairo_arc(cr, xc, yc, radius, angele2, angele2);
    cairo_line_to(cr, xc, yc);
    cairo_stroke(cr);
  end;

  WriteLn(Name, ': ', (now - startTime) * 1000: 10: 5);
end;  
Als nächste werde ich mal probieren, bei SDL direkt in der Surface zu rendern ohne Umweg über die Bitmap
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten