我想知道使用 a 是否更优化局部功能(在下面的例子中_drawBitmap
)只需要3个参数 and 无法内联因为该函数访问一些所有者过程变量,或者使用可以内联的全局函数(但它真的会内联吗?)这需要5个参数.
也不知道这是否重要,但是这段代码主要用于 android/ios 编译
具有本地功能的代码:
procedure TMyObject.onPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
function _drawBitmap(const aBitmap: {$IFDEF _USE_TEXTURE}TTexture{$ELSE}Tbitmap{$ENDIF}; const aTopLeft: TpointF; Const aOpacity: Single): boolean;
var aDestRect: TrectF;
begin
Result := False;
if aBitmap <> nil then begin
//calculate aDestRect
aDestRect := canvas.AlignToPixel(
TRectF.Create(
aTopLeft,
aBitmap.Width/ScreenScale,
aBitmap.Height/ScreenScale));
//if the aBitmap is visible
if ARect.IntersectsWith(aDestRect) then begin
Result := True;
{$IFDEF _USE_TEXTURE}
TCustomCanvasGpu(Canvas).DrawTexture(aDestRect, // ATexRect
TRectF.Create(0,
0,
aBitmap.Width,
aBitmap.Height), // ARect
ALPrepareColor(TCustomCanvasGpu.ModulateColor, aOpacity * AbsoluteOpacity), // https://quality.embarcadero.com/browse/RSP-15432
aBitmap);
{$ELSE}
Canvas.DrawBitmap(aBitmap, // ABitmap
TRectF.Create(0,
0,
aBitmap.Width,
aBitmap.Height), // SrcRect
aDestRect, // DstRect
aOpacity * AbsoluteOpacity, // AOpacity
samevalue(aDestRect.Width, aBitmap.Width, Tepsilon.Position) and
samevalue(aDestRect.height, aBitmap.height, Tepsilon.Position)); // HighSpeed - set interpolation to none
{$ENDIF};
end;
end;
end;
begin
_drawBitmap(aBitmap, aPos, 1);
end;
ASM :
MyObject.pas.2632: _drawBitmap(fBtnFilterBitmap, // aBitmap
00B97511 55 push ebp
00B97512 680000803F push $3f800000
00B97517 8B45F8 mov eax,[ebp-$08]
00B9751A 8D90C4050000 lea edx,[eax+$000005c4]
00B97520 8B45F8 mov eax,[ebp-$08]
00B97523 8B80A8040000 mov eax,[eax+$000004a8]
00B97529 E882FDFFFF call _drawBitmap
00B9752E 59 pop ecx
MyObject.pas.2562: begin
00B972B0 55 push ebp
00B972B1 8BEC mov ebp,esp
00B972B3 83C4A0 add esp,-$60
00B972B6 53 push ebx
00B972B7 56 push esi
00B972B8 57 push edi
00B972B9 8955FC mov [ebp-$04],edx
00B972BC 8BF0 mov esi,eax
MyObject.pas.2563: Result := False;
00B972BE 33DB xor ebx,ebx
MyObject.pas.2564: if aBitmap <> nil then begin
00B972C0 85F6 test esi,esi
00B972C2 0F84B4010000 jz $00b9747c
MyObject.pas.2567: aDestRect := canvas.AlignToPixel(
00B972C8 8B450C mov eax,[ebp+$0c]
00B972CB 8B78FC mov edi,[eax-$04]
00B972CE 8BC6 mov eax,esi
00B972D0 E88F559BFF call TBitmap.GetWidth
...
并具有全局功能:
function drawBitmap(const Canvas: TCanvas; const ARect: TRectF; const aBitmap: {$IFDEF _USE_TEXTURE}TTexture{$ELSE}Tbitmap{$ENDIF}; const aTopLeft: TpointF; Const aOpacity: Single): boolean; inline;
var aDestRect: TrectF;
begin
Result := False;
if aBitmap <> nil then begin
//calculate aDestRect
aDestRect := canvas.AlignToPixel(
TRectF.Create(
aTopLeft,
aBitmap.Width/ScreenScale,
aBitmap.Height/ScreenScale));
//if the aBitmap is visible
if ARect.IntersectsWith(aDestRect) then begin
Result := True;
{$IFDEF _USE_TEXTURE}
TCustomCanvasGpu(Canvas).DrawTexture(aDestRect, // ATexRect
TRectF.Create(0,
0,
aBitmap.Width,
aBitmap.Height), // ARect
ALPrepareColor(TCustomCanvasGpu.ModulateColor, aOpacity * AbsoluteOpacity), // https://quality.embarcadero.com/browse/RSP-15432
aBitmap);
{$ELSE}
Canvas.DrawBitmap(aBitmap, // ABitmap
TRectF.Create(0,
0,
aBitmap.Width,
aBitmap.Height), // SrcRect
aDestRect, // DstRect
aOpacity * AbsoluteOpacity, // AOpacity
samevalue(aDestRect.Width, aBitmap.Width, Tepsilon.Position) and
samevalue(aDestRect.height, aBitmap.height, Tepsilon.Position)); // HighSpeed - set interpolation to none
{$ENDIF};
end;
end;
end;
procedure TMyObject.onPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
drawBitmap(aBitmap, aPos, 1);
end;
ASM:
MyObject.pas.2636: drawBitmap(Canvas, aRect, fBtnFilterBitmap, // aBitmap
00B98F6D 8BFB mov edi,ebx
00B98F6F 8B83A8040000 mov eax,[ebx+$000004a8]
00B98F75 8945F0 mov [ebp-$10],eax
00B98F78 8D83C4050000 lea eax,[ebx+$000005c4]
00B98F7E 8945EC mov [ebp-$14],eax
00B98F81 C645EB00 mov byte ptr [ebp-$15],$00
00B98F85 8B75F0 mov esi,[ebp-$10]
00B98F88 85F6 test esi,esi
00B98F8A 0F840A020000 jz $00b9919a
00B98F90 8BC6 mov eax,esi
00B98F92 E8CD389BFF call TBitmap.GetWidth
...