Suboptimal performance in TQtWidgetSet.DCSetPixel for bitmap based cancases
Original Reporter info from Mantis: mm7
-
Reporter name: Mark Malakanov
Original Reporter info from Mantis: mm7
- Reporter name: Mark Malakanov
Description:
TQtWidgetSet.DCSetPixel uses QPainter_drawPoint for all canvases, even for those that are bitmap based (have vImage, Fot example, in FPC/Lazarus it can be TBitmap.Canvas).
Performance is not perfect because of it.
Also, it uses current Painter's Pen, just changes its color, but does not change other properties like Width etc.
Steps to reproduce:
Create bitmap from TBitmap.
call bitmap.pixels[,y]:=aColor.
Additional information:
I propose to use QT setPixel for bitmap backed canvases. It works at least 4 times faster, and does not depend on Painters Pen, neither changes it.
Also, for screen base d canvases (that in QT have only Painter), it will use specific pen for SetPixel, independent current Painter's pen, and not changing it.current.
file qtobject.inc
class TQtWidgetSet...
...
FPenForSetPixel: QPenH;
...
procedure TQtWidgetSet.DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor);
var
ColorRef: TColorRef;
Painter: QPainterH;
Pen:QPenH;
Rgb:QRgb;
Color: QColorH;
begin
if IsValidDC(CanvasHandle) then
begin
// WriteLn('TQtWidgetSet.DCSetPixel X=',X,' Y=',Y, ' AColor=',dbghex(AColor),' rgb ? ',dbgHex(ColorToRGB(AColor)));
if (TQtDeviceContext(CanvasHandle).vImage <> nil) then
begin
ColorRef := TColorRef(ColorToRGB(AColor));
try
Color:=QColor_create(Red(ColorRef), Green(ColorRef), Blue(ColorRef));
Rgb:=QColor_rgba(Color);
QImage_setPixel(TQtDeviceContext(CanvasHandle).vImage.Handle, X,Y, Rgb);
finally
QColor_destroy(Color);
end;
end
else if (TQtDeviceContext(CanvasHandle).Widget <> nil) then
// It is not bitmap. Fallback to Painter drawPoint.
begin
Painter := TQtDeviceContext(CanvasHandle).Widget;
{Save current pen.Better save copy of pen instead of
using painter save/restore, or saved Pen in devicecontext which
may be null. Issue #27620}
Pen := QPen_create(QPainter_pen(Painter)); //save current pen
{Create pen for SetPixel from scratch to prevent inheriting Width
and other Pen properties from Painter current Pen.}
if FPenForSetPixel = nil then
FPenForSetPixel := QPen_create;
try
ColorRef := TColorRef(ColorToRGB(AColor));
QColor_fromRgb(@Color, Red(ColorRef), Green(ColorRef), Blue(ColorRef));
QPen_setColor(FPenForSetPixel, @Color);
QPainter_setPen(Painter, FPenForSetPixel);
QPainter_drawPoint(Painter, X,Y);
finally
QPainter_setPen(Painter, Pen); //restore saved pen
QPen_destroy(Pen); //destroy the saved pen.
end;
end
else
begin
raise Exception.CreateFmt('TQtDeviceContext(CanvasHandle) %u : does not have vImage or Widget',[PtrUInt(CanvasHandle)]);
end;
end;
end;
Mantis conversion info:
- Mantis ID: 29277
- OS: linux
- OS Build: 3.13
- Platform: amd64
- Version: 1.4.4
- Fixed in revision: 62839 (#1a5015dc)