AW: Geht das noch schneller? - Bitmap-Verrechnung
Nach flüchtigem Verfolgen der Diskussion meine ich:
Es geht hier, wie schon anklang, um Alphablending. Da gab es doch 2005 das Thema Alphablending mit MMX / SSE Befehle Aber zur jetzigen Diskussion Wenn man anstatt 255 durch 256 per Shift dividiert, dann geht das nur bei nichnegativem Nenner. Für den Datentyp Int32 kann man den Trick mit der magischen Zahl $8081 zur Division durch 255 verwenden. const Magic: UInt16 = $8081; var n: Integer; Dann ist für -Sqr(255) <= n<=Sqr(255) ( n * Magic) div (1 shl 23) = n div 255 Der Compiler erzeugt für den ersten Ausdruck einen arithmetische Rechtsshift um 23. Müsste mal mit RDTSC timen. Manfred |
AW: Geht das noch schneller? - Bitmap-Verrechnung
nur mit einem Auge das hier verfolgt, aber ist folgender Blog nicht genau das Thema:
http://www.delphifeeds.com/go/f/1217...hiFeeds.com%29 Die haben hier ein VCL Beispiel und hinweise für die Firemonkey Umsetzung |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Zitat:
|
AW: Geht das noch schneller? - Bitmap-Verrechnung
Man muss ja nicht gleich TParallel mit Canvas.Pixel verbinden. Vielleicht muss man auch manuell skalieren, d.h. durch Ausprobieren herausfinden, wo der break even zwischen Bildgröße und Anzahl der Threads ist.
|
AW: Geht das noch schneller? - Bitmap-Verrechnung
Ein Versuch in Vorbereitung einer MMX-Version
Delphi-Quellcode:
procedure Draw32BitToBitmapPreMMX(const BitOben: TBitmap; BitUnten: TBitmap);
const Magic: UInt16 = $8081; var W, x, y: Integer; Stride, ORes: Integer; RowO, RowU, RGBA_Oben, RGBA_Unten: ^TRGBQuad; begin RowU := BitUnten.ScanLine[0]; RowO := BitOben.ScanLine[0]; W := BitUnten.Width; Stride := 4 * W; for y := 0 to BitUnten.Height - 1 do begin RGBA_Unten := RowU; RGBA_Oben := RowO; for x := 0 to W - 1 do begin ORes := RGBA_Oben^.rgbReserved; with RGBA_Unten^ do begin rgbBlue := (ORes * (RGBA_Oben^.rgbBlue - rgbBlue)) * Magic div (1 shl 23) + rgbBlue; rgbGreen := (ORes * (RGBA_Oben^.rgbGreen - rgbGreen)) * Magic div (1 shl 23) + rgbGreen; rgbRed := (ORes * (RGBA_Oben^.rgbRed - rgbRed)) * Magic div (1 shl 23) + rgbRed; rgbReserved := 255; end; Inc(RGBA_Unten); Inc(RGBA_Oben); end; Dec(Cardinal(RowU), Stride); Dec(Cardinal(RowO), Stride); end; end; |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Hier mein letztes Angebot
Delphi-Quellcode:
QUOTE=Harry Stahl;1281742]
unit UAlphaSSE;
{ SSE-Version von Harry Stahls procedure Draw32BitToBitmap(const BitOben: TBitmap; BitUnten: TBitmap); } interface uses Winapi.Windows, Vcl.Graphics; procedure Draw32BitToBitmapSSE(const BitOben: TBitmap; BitUnten: TBitmap); implementation procedure Draw32BitToBitmapSSE(const BitOben: TBitmap; BitUnten: TBitmap); const // bbggrr RGBFF: array[0..1] of UInt64 = ($FF000000, 0); // src bytes ......01......00 ......03......02 UMsk: array[0..1] of UInt64 = ($8080800180808000, $8080800380808002); // res bytes .......... 8 4 0 ................ PMsk: array[0..1] of UInt64 = ($8080808080080400, $8080808080808080); C255: array[0..3] of Single = (1/255, 1/255, 1/255, 0); var BmpO, BmpU: PRGBQuad; N: Integer; begin N := BitOben.Height; BmpO := BitOben.ScanLine[N - 1]; BmpU := BitUnten.ScanLine[N - 1]; N := N * BitOben.Width - 1; // size of bitmap - 1 asm PUSH EBX MOV EAX, BmpO MOV EDX, BmpU MOV ECX, N // XMM7 free LDDQU XMM6, UMsk LDDQU XMM5, PMsk LDDQU XMM4, C255 LDDQU XMM3, RGBFF {$IFOPT O+} DB $66,$90 // 2-Byte-NOP {$ELSE} DB $66,$0F,$1F,$44,0,0 // 6-Byte-NOP {$ENDIF} @Loop: MOVD XMM0, [EAX+4*ECX]// XMM0 = | 0 |α|B|G|R PEXTRW EBX, XMM0, 1 // EBX = α | B SHR EBX, 8 // EBX = 0 | α JZ @LoopEnd // test α ≡ RGBA_O.rgbReserved = 0 ? PSHUFB XMM0, XMM6 // unpack to Int32 CVTDQ2PS XMM0, XMM0 // convert RGB_O to single FP // SHUFPS XMM1, XMM0, $FF // !!! useless result MOVAPD XMM1, XMM0 // copy RGB_O (necessary !) SHUFPS XMM1, XMM1, $FF // XMM1 = α | α | α | α MULPS XMM1, XMM4 // XMM1 = 0 | α/255 | α/255 | α/255 MOVD XMM2,[EDX+4*ECX] // XMM2 = | 0 |α|B|G|R PSHUFB XMM2, XMM6 // unpack to Int32 CVTDQ2PS XMM2, XMM2 // convert RGB_U to single FP SUBPS XMM0, XMM2 // RGB_O - RGB_U MULPS XMM0, XMM1 // α * (RGB_O - RGB_U) / 255 ADDPS XMM0, XMM2 // α * (RGB_O - RGB_U) / 255 + RGB_U CVTPS2DQ XMM0, XMM0 // convert FP to Int32 with rounding PSHUFB XMM0, XMM5 // pack into TRGBQuad POR XMM0, XMM3 // RGB_U.rgbReserved = $FF MOVD [EDX+4*ECX],XMM0 // restore RGB_U @LoopEnd: SUB ECX, 1 JNS @Loop POP EBX end; end; end. Zitat:
Mit anonymen Threads habe ich hier nichts machen können. Sie laufen schön langsam nacheinander auf dem selben Prozessorkern. Könnte vor Wut das CPU-Gatget pulversisieren Manfred |
AW: Geht das noch schneller? - Bitmap-Verrechnung
|
AW: Geht das noch schneller? - Bitmap-Verrechnung
Bitte antworte in vollständigen Sätzen, also: Subjekt, Prädikat, Objekt. Es ist ein wenig dadaistisch, was Du da von Dir gibst und von einfachen Menschen wie mir so nicht zu verstehen.
|
AW: Geht das noch schneller? - Bitmap-Verrechnung
Soll das nur übereinander Angezeigt werden?
Da hätte ich auch ein Beispiel mit GDI+ da rechnet das ja die GPU zusammen? |
AW: Geht das noch schneller? - Bitmap-Verrechnung
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ein Beispiel mit GDI+
Die ganze Unit ist im Anhang incl. drehen und interpolation einfach in ein Package einbinden und ausprobieren Die GDI+ Units sind im XE4 bei mir schon enthalten Einen Geschwindigkeitsvergleich habe ich noch nicht gemacht Mit Transparenten PNG´s klappt das wohl, aber 32Bit BMP´s nicht Kann ich noch Optimieren zb. Ram sparen, wenn ich den Stream Plattmache funktionieren JPG´s nicht mehr
Delphi-Quellcode:
uses GDIPOBJ, GDIPAPI;
... TTestImage = class(TGraphicControl) private { Private declarations } fImageA1: TGPImage; fImageB1: TPicture; fStream1: TMemoryStream; fImageA2: TGPImage; fImageB2: TPicture; fStream2: TMemoryStream; ... procedure TTestImage.Paint; var Graphics: TGPGraphics; begin Graphics := TGPGraphics.Create(Canvas.Handle); try Graphics.DrawImage(fImageA1, 0, 0, Width, Height); Graphics.DrawImage(fImageA2, 0, 0, Width, Height); finally Graphics.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz