0

the question here merge paint results in thread bitmap painting is derived from using TThread and older versions of DELPHI.

I found now the omnithread library shipped with Delphi XE 7 and can not decide which design pattern should be used for this task while writing this code with the omnithread lib. Is a TBitmap access also restricted using omnithread as it is using TThread and VCL.

To my experience the pen inside the vcl is not threadsafe during parallel Bitmap processing

the current single thread code goes like this :

for i:= 1  to mydatabasetable.recordcount do
begin

     ReadSingleRecordfromTable(aDBrecord);

     BuildViewData(aDBRrcord, aPolygon);

     Paint2Bitmap(aTBitmap, aPolygon);
end;
Community
  • 1
  • 1
user1769184
  • 1,571
  • 1
  • 19
  • 44
  • 1
    My experience is that parallel painting is extremely painful - if not impossible. It doesn't matter whether you use TThread or Parallel library as TBitmap is not threadsafe. – René Hoffmann Sep 25 '15 at 14:54
  • 2
    *Is a TBitmap access also restricted using omnithread as it is using TThread and VCL?* Yes. – David Heffernan Sep 25 '15 at 14:56
  • 5
    If you want truly parallel drawing, what you should probably do is arrange your pixel data *outside* a `TBitmap`. You can do that in parallel by designating certain regions of the bitmap for certain threads. Once all the threads are finished with teir portions of the image, you can, in a single thread, use `CreateDIBSection` and `SetDIBits` to transfer your raw pixel data into a real GDI bitmap. I'd submit this as an answer, but I can't provide any code examples or testimonial that this idea actually works. – Rob Kennedy Sep 25 '15 at 15:14
  • The threading library you use for this task is immaterial. – Rob Kennedy Sep 25 '15 at 15:15
  • TBitmap isn't restricted because of the VCL or TThread, vs OmniThread - it is restricted because *any* parallel access is restricted. The best way is something like @RobKennedy suggests. Or, you could split it up into tiles - say, 512x512 pixel bitmaps - and have one thread draw each of those, then in the main thread assemble them into a larger image. Or anything really - anything that divides the problem up into threads allows you to work *only* in those threads and assemble the result later. – David Sep 25 '15 at 15:51
  • @RobKennedy You don't even have to use a single thread to consolidate the smaller images. Provided you are not writing to the same memory from different threads then there is no problem. We do that all of the time. Once you have finished putting all of the data together then you use `GdipCreateBitmapFromScan0` to create the final bitmap. – Graymatter Sep 25 '15 at 18:20
  • @Graymatter, the idea I intended to convey was that there's only one pixel-data buffer, and each thread is responsible for a certain region or regions of that one buffer. When it's fully populated, then the main GDI thread turns that buffer into a real bitmap. I never meant to suggest there would be any smaller images to consolidate. – Rob Kennedy Sep 25 '15 at 18:29
  • @RobKennedy Ok, understand. I misunderstood. Still using `GdipCreateBitmapFromScan0` is better than `SetDIBits` because there is no copy of the data involved, if I am not mistaken. The GDI bitmap just uses your memory so the final step in the single thread is much faster. – Graymatter Sep 25 '15 at 18:38
  • I would think you still need to serialize access to the buffer when constructing the final bitmap so that threads are not still modifying data while the constructing thread is reading it. Maybe use [`TMREWSync`](http://docwiki.embarcadero.com/Libraries/Seattle/en/System.SysUtils.TMREWSync) or a [Slim Reader/Writer lock](https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx) for that. Despite their names, the creating thread that reads the buffer can be the exclusive locker, and the threads writing the buffer data can be the shared lockers. – Remy Lebeau Sep 25 '15 at 19:36
  • @user1769184 What kind of parallel paintings are you trying to do to your bitmap? Are you interested in composing final bitmap from multiple smaller pictures? Are you perhaps applying some custom algorithm to apply special effects to your bitmap? Providing us with such information we might be able to point you into using of some alternative approaches. For instance if you are interested in applying some custom filtering to your bitmaps then it might be better to use Graphics32 library as it is capable of using your graphics card for manipulating bitmaps so it is much faster. – SilverWarior Sep 25 '15 at 21:00
  • @RemyLebeau Yes, the final action could only take place when all of the threads are finished so some sort of locking would need to be in place. – Graymatter Sep 25 '15 at 21:38
  • I've been looking into this too (see https://code.google.com/p/delphi-shader/), but for small bitmaps or fast rendering algorithms, the overhead of splitting and merging work between threads just slowed things down compared to the single-threaded simple version. I've attempted several things: devide the bitmap in blocks and having multiple threads to calculate upcoming images. If you really want to have parallel processing for your bitmaps, try to code your stuff as a pixel shader, and get a fast graphics card. http://glslsandbox.com/ – Wouter van Nifterick Sep 26 '15 at 01:11
  • @WoutervanNifterick We have seen an increase in speed that matches the number of cores. It helps to have a thread pool so you don't get hit with the overhead. – Graymatter Sep 26 '15 at 04:04
  • @Gray There's still a synchronization overhead. As Wouter says, for small images or fast rendering, the overhead will make parallel methods slower. – David Heffernan Sep 26 '15 at 08:22
  • @SilverWarior / all : i have a set of several 10E6 polgons describing geometrical objects data stored in a database. After the user selected this desired view i need to run through all the polygons , see if they are visible or not , calculate their position in the layout. / bitmap. – user1769184 Sep 29 '15 at 06:45
  • Now I'm a bit confused! Are you trying to render these polygons on your final bitmap or find position of polygons that are already on your existing bitmaps? – SilverWarior Sep 29 '15 at 15:17

0 Answers0