mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 16:31:40 +02:00
LCL-CustomDrawn: Further improves the painting performance by checking if a control is completely covered by other ones, this improves the magnifier painting speed by 20%, from 790ms to 630ms, although it is still way too high
git-svn-id: trunk@36437 -
This commit is contained in:
parent
439347c67b
commit
1dad086508
@ -710,7 +710,7 @@ var
|
|||||||
AImage: TLazIntfImage;
|
AImage: TLazIntfImage;
|
||||||
ACanvas: TLazCanvas;
|
ACanvas: TLazCanvas;
|
||||||
{$IFDEF VerboseCDPaintProfiler}
|
{$IFDEF VerboseCDPaintProfiler}
|
||||||
lTimeStart: TDateTime;
|
lTimeStart, lNativeStart: TDateTime;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerboseCDPaintProfiler}
|
{$IFDEF VerboseCDPaintProfiler}
|
||||||
@ -732,13 +732,19 @@ begin
|
|||||||
// Draw the form
|
// Draw the form
|
||||||
RenderForm(WindowHandle.Image, WindowHandle.Canvas, WindowHandle.LCLForm);
|
RenderForm(WindowHandle.Image, WindowHandle.Canvas, WindowHandle.LCLForm);
|
||||||
|
|
||||||
|
{$IFDEF VerboseCDPaintProfiler}
|
||||||
|
lNativeStart := NowUTC();
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
// Now render it into the control
|
// Now render it into the control
|
||||||
WindowHandle.Image.GetRawImage(lRawImage);
|
WindowHandle.Image.GetRawImage(lRawImage);
|
||||||
Cocoa_RawImage_CreateBitmaps(lRawImage, lBitmap, lMask, True);
|
Cocoa_RawImage_CreateBitmaps(lRawImage, lBitmap, lMask, True);
|
||||||
Context.DrawBitmap(0, 0, TCocoaBitmap(lBitmap));
|
Context.DrawBitmap(0, 0, TCocoaBitmap(lBitmap));
|
||||||
end;
|
end;
|
||||||
{$IFDEF VerboseCDPaintProfiler}
|
{$IFDEF VerboseCDPaintProfiler}
|
||||||
DebugLn(Format('[TCocoaCustomControl.Draw] Paint duration: %d ms', [DateTimeToMilliseconds(NowUTC() - lTimeStart)]));
|
DebugLn(Format('[TCocoaCustomControl.Draw] Paint LCL-CustomDrawn: %d ms Native: %d ms',
|
||||||
|
[DateTimeToMilliseconds(lNativeStart - lTimeStart),
|
||||||
|
DateTimeToMilliseconds(NowUTC() - lNativeStart)]));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ type
|
|||||||
FProps: TStringList;
|
FProps: TStringList;
|
||||||
function GetProps(AnIndex: String): pointer;
|
function GetProps(AnIndex: String): pointer;
|
||||||
procedure SetProps(AnIndex: String; AValue: pointer);
|
procedure SetProps(AnIndex: String; AValue: pointer);
|
||||||
|
protected
|
||||||
|
FWinControl: TWinControl;
|
||||||
public
|
public
|
||||||
Children: TFPList; // of TCDWinControl;
|
Children: TFPList; // of TCDWinControl;
|
||||||
// For scrolling a control
|
// For scrolling a control
|
||||||
@ -54,8 +56,9 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure IncInvalidateCount;
|
procedure IncInvalidateCount;
|
||||||
function AdjustCoordinatesForScrolling(AX, AY: Integer): TPoint;
|
function AdjustCoordinatesForScrolling(AX, AY: Integer): TPoint;
|
||||||
property Props[AnIndex:String]:pointer read GetProps write SetProps;
|
|
||||||
procedure UpdateImageAndCanvas; virtual;
|
procedure UpdateImageAndCanvas; virtual;
|
||||||
|
function IsControlBackgroundVisible: Boolean; virtual;
|
||||||
|
property Props[AnIndex:String]:pointer read GetProps write SetProps;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCDWinControl }
|
{ TCDWinControl }
|
||||||
@ -67,6 +70,7 @@ type
|
|||||||
CDControl: TCDControl;
|
CDControl: TCDControl;
|
||||||
CDControlInjected: Boolean;
|
CDControlInjected: Boolean;
|
||||||
procedure UpdateImageAndCanvas; override;
|
procedure UpdateImageAndCanvas; override;
|
||||||
|
function IsControlBackgroundVisible: Boolean; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCDForm }
|
{ TCDForm }
|
||||||
@ -90,6 +94,7 @@ type
|
|||||||
function GetFormVirtualHeight(AScreenHeight: Integer): Integer;
|
function GetFormVirtualHeight(AScreenHeight: Integer): Integer;
|
||||||
procedure SanityCheckScrollPos();
|
procedure SanityCheckScrollPos();
|
||||||
procedure UpdateImageAndCanvas; override;
|
procedure UpdateImageAndCanvas; override;
|
||||||
|
function IsControlBackgroundVisible: Boolean; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCDNonNativeForm = class(TCDForm)
|
TCDNonNativeForm = class(TCDForm)
|
||||||
@ -554,7 +559,8 @@ procedure RenderWinControlAndChildren(var AImage: TLazIntfImage;
|
|||||||
var ACanvas: TLazCanvas; ACDWinControl: TCDWinControl; ACDForm: TCDForm);
|
var ACanvas: TLazCanvas; ACDWinControl: TCDWinControl; ACDForm: TCDForm);
|
||||||
begin
|
begin
|
||||||
// Draw the control
|
// Draw the control
|
||||||
if not RenderWinControl(AImage, ACanvas, ACDWinControl, ACDForm) then Exit;
|
if ACDWinControl.IsControlBackgroundVisible() then
|
||||||
|
if not RenderWinControl(AImage, ACanvas, ACDWinControl, ACDForm) then Exit;
|
||||||
|
|
||||||
// Now Draw all sub-controls
|
// Now Draw all sub-controls
|
||||||
if ACDWinControl.Children <> nil then
|
if ACDWinControl.Children <> nil then
|
||||||
@ -570,6 +576,10 @@ var
|
|||||||
lFormCanvas: TLazCanvas;
|
lFormCanvas: TLazCanvas;
|
||||||
begin
|
begin
|
||||||
lWindowHandle := TCDForm(AForm.Handle);
|
lWindowHandle := TCDForm(AForm.Handle);
|
||||||
|
|
||||||
|
if lWindowHandle.IsControlBackgroundVisible() then
|
||||||
|
begin
|
||||||
|
|
||||||
{$ifndef CD_BufferFormImage}
|
{$ifndef CD_BufferFormImage}
|
||||||
DrawFormBackground(AImage, ACanvas);
|
DrawFormBackground(AImage, ACanvas);
|
||||||
{$endif}
|
{$endif}
|
||||||
@ -608,6 +618,7 @@ begin
|
|||||||
ACanvas.CanvasCopyRect(lWindowHandle.ControlCanvas, 0, 0, 0, 0,
|
ACanvas.CanvasCopyRect(lWindowHandle.ControlCanvas, 0, 0, 0, 0,
|
||||||
AForm.ClientWidth, AForm.ClientHeight);
|
AForm.ClientWidth, AForm.ClientHeight);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
// Now paint all child win controls
|
// Now paint all child win controls
|
||||||
RenderChildWinControls(AImage, ACanvas, GetCDWinControlList(AForm), lWindowHandle);
|
RenderChildWinControls(AImage, ACanvas, GetCDWinControlList(AForm), lWindowHandle);
|
||||||
@ -953,6 +964,12 @@ begin
|
|||||||
WinControl.Width, WinControl.Height, clfARGB32);
|
WinControl.Width, WinControl.Height, clfARGB32);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCDWinControl.IsControlBackgroundVisible: Boolean;
|
||||||
|
begin
|
||||||
|
FWinControl := WinControl;
|
||||||
|
Result:=inherited IsControlBackgroundVisible;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCDBitmap }
|
{ TCDBitmap }
|
||||||
|
|
||||||
destructor TCDBitmap.Destroy;
|
destructor TCDBitmap.Destroy;
|
||||||
@ -1026,6 +1043,39 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// This is utilized for optimizing the painting. If we figure out that there is
|
||||||
|
// nothing visible from a control, just give up drawing it completely
|
||||||
|
//
|
||||||
|
// What usually happens is that child controls might completely cover their
|
||||||
|
// parent controls
|
||||||
|
//
|
||||||
|
// We should watch out for alpha-blending, however
|
||||||
|
function TCDBaseControl.IsControlBackgroundVisible: Boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
lChild: TControl;
|
||||||
|
lWinChild: TWinControl;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
if FWinControl = nil then Exit;
|
||||||
|
for i := 0 to FWinControl.ControlCount-1 do
|
||||||
|
begin
|
||||||
|
lChild := FWinControl.Controls[i];
|
||||||
|
if not (lChild is TWinControl) then Continue;
|
||||||
|
lWinChild := TWinControl(lChild);
|
||||||
|
|
||||||
|
// ToDo: Ignore alpha blended controls
|
||||||
|
|
||||||
|
// Basic case: alClient
|
||||||
|
if lWinChild.Align = alClient then Exit(False);
|
||||||
|
|
||||||
|
// Another case: coordinates match
|
||||||
|
if (lWinChild.Left = 0) and (lWinChild.Top = 0) and
|
||||||
|
(lWinChild.Width = FWinControl.Width) and (lWinChild.Height = FWinControl.Height) then
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCDForm }
|
{ TCDForm }
|
||||||
|
|
||||||
constructor TCDForm.Create;
|
constructor TCDForm.Create;
|
||||||
@ -1067,5 +1117,11 @@ begin
|
|||||||
LCLForm.ClientWIdth, LCLForm.ClientHeight, clfARGB32);
|
LCLForm.ClientWIdth, LCLForm.ClientHeight, clfARGB32);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCDForm.IsControlBackgroundVisible: Boolean;
|
||||||
|
begin
|
||||||
|
FWinControl := LCLForm;
|
||||||
|
Result:=inherited IsControlBackgroundVisible;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user