Blocking Canvas


I have a form of my app that can have up to 1000 visual components, in which I draw each one once using Canvas of a bitmap, and save this bitmap of each component (a kind of double buffered), because each operation takes 20 ms.

I’m using threads to paint the bitmaps and send notifications with this bitmap to the MainThread, to refresh the visual components, the UI.

Theoretically, it would have to have a fluid form opening with the components being displayed as their bitmaps were painted in the threads, but in practice it was not fluid. I decided to take a look at the delphi’s TCanvas and I noticed something staggering:

class var // <<<<<<<<<<<<<<<<<<<<<<<<<<<< class var
FLock: TObject;

function TCanvas.BeginScene(AClipRects: PClipRects = nil; AContextHandle: THandle = 0): Boolean;


procedure TCanvas.EndScene;


class procedure TCanvas.Lock;

class procedure TCanvas.Unlock;

This definitely does not seem right. Why does the embarcadero make it impossible to work with TCanvas simultaneously in different threads? It’s no use creating 10 threads to be doing bitmap drawings since everything will be processed 1 at a time…

Why does this exist?
Is there any workaround? What can happen if I make my version of
FMX.Graphics with only local monitors for each TCanvas?
Is there any third party lib with it own TCanvas?

I know that many will advise me to use native classes, JCanvas in android and CGContextRef in iOS, but I wanted a solution with TCanvas, because its job is to be a wrapper for drawing functions of all platforms, and to be easy to use.

============= @EDIT =============

I changed the Lock and Unlock of the TCanvas in the FMX.Graphics unit to use local instead of global monitors, as well as the BeginScene and EndScene of TContext3D in the FMX.Types3D unit.
I’m very apprehensive about this change but apparently the app is working normal, the biggest job was recompile the entire FMX.

Comments are closed.