Recent

Author Topic: Text Rendering to Canvas is very slow on MacOS and Linux  (Read 4480 times)

Superdisk

  • Jr. Member
  • **
  • Posts: 73
Text Rendering to Canvas is very slow on MacOS and Linux
« on: December 24, 2020, 04:58:20 am »
Hello all. I'm developing a program that uses a custom-drawn control. I subclassed TCustomControl and implemented a Paint method. For the control, all graphics are drawn using filled rectangles and extensive use of TextOut.

This works well on Windows, but unfortunately when I build and run on MacOS or Linux, the text-heavy rendering seems to go very, very slow and the control is nearly unusable. I know it is not a general drawing issue, as I have other custom-drawn controls in the project that paint extremely quickly (at real-time speeds).

Is there any recommended way to get better performance out of the text rendering, or will I have to roll my own hack which pre-renders text or uses the font as a spritesheet? I also considered using BGRABitmap, but I'm not sure if that will be any faster.

Handoko

  • Hero Member
  • *****
  • Posts: 5524
  • My goal: build my own game engine using Lazarus
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #1 on: December 24, 2020, 05:54:32 am »
I'm not very sure but it says AggPas has true type font support:
https://wiki.freepascal.org/Graphics_libraries

I also considered using BGRABitmap, but I'm not sure if that will be any faster.

I ever tried to change my simple vertical scrolling shooting game which use TCanvas only to use BGRABitmap, it run a bit slower when using BGRABitmap. BGRABitmap has feature to use OpenGL but that only available if you use certain commands only.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #2 on: December 24, 2020, 08:51:16 am »
Try TGlCanvas. That should be much faster. (Is part of GLScene)
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4695
  • I like bugs.
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #3 on: December 24, 2020, 09:27:02 am »
... I build and run on MacOS or Linux, the text-heavy rendering seems to go very, very slow and the control is nearly unusable.
Normal Canvas should not be very, very slow either. Maybe the Paint method is called too often for some reason.  Place DebugLn calls there and run from console to see how often it triggers.
Add "LazLoggerBase" to uses section.
« Last Edit: December 24, 2020, 09:28:39 am by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

devEric69

  • Hero Member
  • *****
  • Posts: 652
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #4 on: December 24, 2020, 09:59:48 am »
I'm not very sure but it says AggPas has true type font support:
https://wiki.freepascal.org/Graphics_libraries

There are discussions on the forum, notably concerning the use of AggPas with fpGUI, a Pascal Widgetset (custom-drawn controls, sometimes with text) over X11 (so, adapted and compliant MacOS, BSD, or Linux) and GDI (so, adapted and compliant with Windows).
See https://forum.lazarus.freepascal.org/index.php/topic,33232.msg215024.html#msg215024, for example.
« Last Edit: December 24, 2020, 10:27:12 am by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

ps

  • Full Member
  • ***
  • Posts: 136
    • CSS
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #5 on: December 24, 2020, 01:22:00 pm »
Look at this bug https://bugs.freepascal.org/view.php?id=34829 there is something wrong on Cocoa (macos).
Small simple CSS/box model implementation: https://github.com/pst2d/csscontrols/tree/dev

AlexTP

  • Hero Member
  • *****
  • Posts: 2681
    • UVviewsoft
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #6 on: December 24, 2020, 02:36:27 pm »
TCanvas.TextOut is slow wrapper, on linux and macOS. Just took how it's made in the linux gtk2 widgetset... Win32 wrapper is much faster.

Superdisk

  • Jr. Member
  • **
  • Posts: 73
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #7 on: December 25, 2020, 09:32:19 am »
TCanvas.TextOut is slow wrapper, on linux and macOS. Just took how it's made in the linux gtk2 widgetset... Win32 wrapper is much faster.

If TextOut is a slow wrapper then what's the fast way?

I considered using SDL2's font rendering functions since I'm using it in this project anyway, but it would be a hack and I feel like this is a pretty fundamental thing that should not be so slow and broken.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12718
  • FPC developer.
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #8 on: December 25, 2020, 11:09:03 am »
Hello all. I'm developing a program that uses a custom-drawn control. I subclassed TCustomControl and implemented a Paint method. For the control, all graphics are drawn using filled rectangles and extensive use of TextOut.

I'm not sure, but wasn't this what TPaintbox was for?

On OpenGL fonts can be faster, but also not with the default options. Search for "Signed distance fields"

AlexTP

  • Hero Member
  • *****
  • Posts: 2681
    • UVviewsoft
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #9 on: December 25, 2020, 12:37:30 pm »
I don't know what is the fast replacement on gtk2. but look at gtk2 code for TextOut. file gtk2winapi.inc,

Code: Pascal  [Select][+][-]
  1. function TGtk2WidgetSet.TextOut(DC: HDC; X, Y: Integer; Str: Pchar;
  2.   Count: Integer) : Boolean;
  3. var
  4.   DevCtx: TGtkDeviceContext absolute DC;
  5.   DCOrigin: TPoint;
  6.   yOffset: integer;
  7.   BackGroundColor: PGdkColor;
  8. begin
  9.   Result := IsValidDC(DC);
  10.   if not Result then Exit;
  11.   if Count <= 0 then Exit;
  12.  
  13.   if DevCtx.HasTransf then
  14.     DevCtx.TransfPoint(X, Y);
  15.  
  16.   UpdateDCTextMetric(DevCtx);
  17.   DCOrigin := DevCtx.Offset;
  18.  
  19.   with DevCtx.DCTextMetric.TextMetric do
  20.     yOffset := tmHeight-tmDescent-tmAscent;
  21.   if yOffset < 0 then
  22.     yOffset := 0;
  23.    
  24.   DevCtx.SelectedColors := dcscCustom;
  25.   EnsureGCColor(DC, dccCurrentTextColor, True, False);
  26.  
  27.   BackGroundColor := nil;
  28.   if DevCtx.BkMode = OPAQUE then
  29.   begin
  30.     AllocGDIColor(DC, @DevCtx.CurrentBackColor);
  31.     BackGroundColor := @DevCtx.CurrentBackColor.Color;
  32.   end;
  33.  
  34.   DevCtx.DrawTextWithColors(Str, Count,
  35.     X + DCOrigin.X, Y + DCOrigin.Y + yOffset,
  36.     nil, BackGroundColor);
  37. end;
  38.  

and it uses several additional objects (DevCtx...) and funcs (UpdateFCTextMetric....). and "DrawTextWithColors" which uses COLORS. so it is very slow.

wp

  • Hero Member
  • *****
  • Posts: 13422
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #10 on: December 25, 2020, 01:12:19 pm »
This discussion about speed of TextOut can lead you on the wrong track. Your description "all graphics are drawn using filled rectangles and extensive use of TextOut" is far too general to give you precise help. Please publish the source of your component here, and we'll certainly find out what's wrong. Add a demo program to see the slowness.

Superdisk

  • Jr. Member
  • **
  • Posts: 73
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #11 on: December 26, 2020, 12:20:25 am »
This discussion about speed of TextOut can lead you on the wrong track. Your description "all graphics are drawn using filled rectangles and extensive use of TextOut" is far too general to give you precise help. Please publish the source of your component here, and we'll certainly find out what's wrong. Add a demo program to see the slowness.

I've created a cut-down example of the control and attached it to this post. You can drag and select a rectangle, which should be quite snappy on Windows and unusably slow on MacOS and Linux. You can also enter data into the grid with the keyboard. To try it out, please install the included font so the control will render correctly.

The main project this comes from is here. The project has some extra dependencies and is a little more difficult to build though, so my attached example should be much easier to see the problem with.

All the rendering code that uses TextOut is found in TrackerGrid.pas

circular

  • Hero Member
  • *****
  • Posts: 4469
    • Personal webpage
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #12 on: December 26, 2020, 01:04:00 am »
You can use LazFreeType. For this, you need to provide the font files and comes with a drawer for TLazIntfImage.
https://github.com/alrieckert/lazarus/tree/master/examples/lazfreetype

BGRABitmap offers a renderer for it as well in BGRAFreeType unit. You can use it by assigning a TBGRAFreeTypeFontRenderer object to the FontRenderer property.
https://github.com/bgrabitmap/bgrabitmap/blob/master/bgrabitmap/bgrafreetype.pas
https://wiki.freepascal.org/BGRABitmap_tutorial_Font_rendering
Conscience is the debugger of the mind

Superdisk

  • Jr. Member
  • **
  • Posts: 73
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #13 on: December 26, 2020, 01:08:27 am »
BGRABitmap offers a renderer for it as well in BGRAFreeType unit. You can use it by assigning a TBGRAFreeTypeFontRenderer object to the FontRenderer property.
https://github.com/bgrabitmap/bgrabitmap/blob/master/bgrabitmap/bgrafreetype.pas
https://wiki.freepascal.org/BGRABitmap_tutorial_Font_rendering

Cool, this may be just what I need... Ideally I'd like to use the OS's capabilities as much as possible, including for font rendering but this looks promising in the meantime :)

Thanks.

wp

  • Hero Member
  • *****
  • Posts: 13422
Re: Text Rendering to Canvas is very slow on MacOS and Linux
« Reply #14 on: December 26, 2020, 01:12:07 am »
I checked out the demo on LMDE 4 Linux and macOS Mojave 10.14, both in a VM on Win 10 host, and do no noticable delay on this Linux and a slight slowness on mac (which is maybe due to the VM) when dragging the violet rectangle.

Tried to enter some text into the grid, but this was not successful at all although the font was installed. Is this how it is supposed to be?

 

TinyPortal © 2005-2018