[fpc-pascal] Pixel tricks on arm architech, how can I get more?

lyh1win at hotmail.com lyh1win at hotmail.com
Tue Oct 20 19:22:05 CEST 2009


I am working on a wince game and want to do some fadein/out works on a vga 
screen.
I use alphablt in IDirectDrawSurface, but it only support a  constant 50% 
alpha.
When I blt a 320x240 image on a 480x640 screen, alphablt give me about 12 
fps plus filling a backbuffer black , blt another 320x240 image and blt to 
primary surface.
I found a table look method while googling and doing the same thing on 
device. It can only achieve 8 fps. If pixel is cliped when out of screen, 
the speed increase. About 20 fps if only draw 1/10 of the image on screen.
The numbers is reading from A HTC Touch Pro. A pretty slow device.

The following function is what I am using to blend the pixel on a back 
screen surface to another back screen surface.
Any ideas how can I improve this function to as fast as the alphablt one in 
Directdraw??
It seems arm can do something better then x86 tricks, most operation can 
done in one cycle include mul.

procedure TDirectDrawSurface.drawAlpha(x, y: integer;
  SrcSurface: TDirectDrawSurface;  alpha: integer
  );
var
   SourceTable,DestTable : LookUpLevel;
   SourceTableG,DestTableG : LookUpLevelG;
   DDSURFACEinfoSrc,DDSURFACEinfoDEST : TDDSURFACEDESC;
   SRCbuffer,DESTbuffer,SrcColor,DestColor : ^ushort;
   nPitchDest,nPitchSrc : ushort;
   i,j,xEnd,yEnd,DestLinePos,SrcLinePos, DestWidth, DestHeight,
   SrcWidth,SrcHeight:integer;

   function PackColor(R,G,B : byte) : ushort; inline;
   begin
     result :=  r shl 11 + g shl 5 + b;
   end;

   function UnpackColorR(color : ushort;RBitMask : DWORD) : byte; inline;
   begin
        result := color and RBitMask shr 11;
   end;
   function UnpackColorG(color : ushort;GBitMask : DWORD) : byte; inline;
   begin
        result := color and GBitMask shr 5;
   end;
   function UnpackColorB(color : ushort;BBitMask : DWORD) : byte; inline;
   begin
        result := color and BBitMask;
   end;
begin
  DDSURFACEinfoSrc :=SrcSurface.lock;
  DDSURFACEinfoDEST := lock;

  SourceTable := Alphatable.LookupPointer(Alpha);
  SourceTableG := Alphatable.LookupPointerG(Alpha);
  DestTable := Alphatable.LookupPointer(255 - Alpha);
  DestTableG := Alphatable.LookupPointerG(255 - Alpha);

  SRCbuffer :=  DDSURFACEinfoSRC.lpSurface;
  nPitchSrc  := DDSURFACEinfoSrc.lPitch shr 1;
  DESTbuffer := DDSURFACEinfoDEST.lpSurface;
  nPitchDest := DDSURFACEinfoDest.lPitch shr 1;
  DestWidth := width;
  DestHeight := Height;
  SrcWidth := SrcSurface.width;
  SrcHeight := SrcSurface.Height;

  x := max(0,x);
  y := max(0,y);
  xEnd := min(x+SrcWidth-1,Destwidth-1);
  yEnd := min(y+ SrcHeight-1,DestHeight-1);

  SrcLinePos :=  0;
  DestLinePos := y*nPitchDest;

  for i := y to yEnd do
    begin
    DestColor := @DESTbuffer[DestlinePos+x];
    SrcColor  := @SRCbuffer[SrcLinePos];
    for j := x to xEnd do
     begin
     DESTbuffer[DestlinePos+j] :=
     PackColor(
     DestTable[UnpackColorR(DestColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwRBitMask)]+ 
SourceTable[UnpackColorR(SrcColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwRBitMask)],
     DestTableG[UnpackColorG(DestColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwGBitMask)]+ 
SourceTableG[UnpackColorG(SrcColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwGBitMask)],
     DestTable[UnpackColorB(DestColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwBBitMask)]+ 
SourceTable[UnpackColorB(SrcColor^,DDSURFACEinfoSrc.ddpfPixelFormat._mask.dwBBitMask)]
     );

     inc(DestColor);
     inc(SrcColor);
     end;
    inc(DestlinePos, nPitchDest);
    inc(SrcLinePos, nPitchSrc);
    end;
  SrcSurface.unlock;
  unlock;
end; 




More information about the fpc-pascal mailing list