AGB  ·  Datenschutz  ·  Impressum  







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

Geht das noch schneller? - Bitmap-Verrechnung

Ein Thema von Harry Stahl · begonnen am 22. Nov 2014 · letzter Beitrag vom 5. Jan 2015
 
manfred42

Registriert seit: 23. Nov 2014
Ort: Leipzig
6 Beiträge
 
Delphi 7 Professional
 
#31

AW: Geht das noch schneller? - Bitmap-Verrechnung

  Alt 1. Jan 2015, 21:22
Hier mein letztes Angebot
Delphi-Quellcode:
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.
QUOTE=Harry Stahl;1281742]
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
Nun ja, TParallel hatten wir hier ja auch schon. Der Link zeigt zwar die Parallel-For-Verwendung aber mit canvas.pixel, das ist ja so ziemlich das Langsamste, was man machen kann.[/QUOTE]

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
Manfred Zimmer

Geändert von mkinzler ( 1. Jan 2015 um 21:34 Uhr) Grund: Delphi-Tag gefixt
  Mit Zitat antworten Zitat
 


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 17:46 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