|
# Lines |
Arnold Reinders
wrote
on 20-Aug-2009:
I am trying to parallellize bitmap operations. This appears to be well
possible for scanlines. Typical code reads like this:
s := source_bitmap.Scanline [index];
|
29 |
Remy Lebeau (TeamB)
replied
on 20-Aug-2009:
"Arnold Reinders" <✉somewhere.com> wrote in message
news:✉forums.codegear.com...
(snip)
Technically, nothing about it is thread-safe. You should always provide a
lock around multi-threaded access to shared resources. But as long as
neither bitmap is ever being resized or having its underlying handles
|
29 |
Erik Turner
replied
on 21-Aug-2009:
It's not threadsafe at all. I had a similar problem where I was rendering
JPG streams to TBitmaps in a background thread. The problem actually occurs
(near as I can tell) when the form is updated. It trashes any active
TCanvas's after the refresh. Someone had posted a work-around involving
locking the TCanvas, etc but they didn't solve the problem completely. The
|
65 |
Alex Belo
replied
on 21-Aug-2009:
See
Report #: 43020 Status: Reported
TBitmap.Canvas.Lock is a MUST in multithreading applications
http://qc.embarcadero.com/wc/qcmain.aspx?d=43020
Jan Derk:
|
23 |
Arnold Reinders
replied
on 21-Aug-2009:
Hi Alex, Erik, Remy,
Thanks very much for your answers.
Alex Belo wrote:
(snip)
Thanks for the pointer.
(snip)
When I understand Alex and Erik correctly I must be careful not to
|
55 |
Jens Gruschel
replied
on 21-Aug-2009:
(snip)
TBitmap itself is not thread-safe. However the (DIB) pixel data can be accessed
from various threads without problems, after all it's just some memory block. Of
course your algorithm itself must be synchronized, for example if several
threads are accessing the same pixel (it's no problem if each thread works on a
different slice of the pixel data, or if all threads only read from the pixel
|
67 |
David HAROUCHE
replied
on 22-Aug-2009:
Better use a private TBitmap to the thread, and give public access to a
built-shadow TBitmap of it via a property of the Thread....
DH
|
5 |
Jens Gruschel
replied
on 22-Aug-2009:
(snip)
Yes, generally threads using private variables only are easier to handle
(combining their results in a synchronized method). But sometimes there are good
reasons for sharing data among different threads. Let's say a low pass filter,
where each thread generates a separate section of a result image, but needs to
read pixels from the whole area of a shared source image (well, one could
|
29 |
Alex Belo
replied
on 22-Aug-2009:
Arnold Reinders wrote:
(snip)
I don't know _exactly_.
Mr. Bauer, would you please help us.
(snip)
You definitely must do it via Sinchronize.
(snip)
You definitely must do it (any drawing on form) via Sinchronize too. So
|
30 |
Erik Turner
replied
on 23-Aug-2009:
Comments inline.
"Arnold Reinders" <✉somewhere.com> wrote in message
news:✉forums.codegear.com...
(snip)
As another poster mentioned, you MAY be able to get this to work if you
call ScanLine in the main/GUI thread and pass the scan line addresses to
|
58 |
Jan Derk
replied
on 23-Aug-2009:
David HAROUCHE wrote:
(snip)
That is not correct. The really confusing part is that even local TBitmap are
not thread safe unless you lock them.
This is because every TBitmap registers itself to the global BitmapCanvasList
list in graphics.pas. And when the DC garbage collection FreeMemoryContexts()
|
26 |
David HAROUCHE
replied
on 24-Aug-2009:
(snip) This sounds obvious when working with concurrent processes !
DH
✉hotmail.fr
|
8 |
Jan Derk
replied
on 24-Aug-2009:
David HAROUCHE wrote:
(snip)
What I meant is that TBitmaps that are declared private to a thread aren't so
private, because they register themselves in a global list which is accessed by
the garbage collector in the mean thread.
Normally locking is only required if an object can be accessed by multiple
|
32 |
Alex Belo
replied
on 24-Aug-2009:
In the end I would like to know for sure: do I have to do Canvas.Lock
when I use Scanline only, or such the lock is unnecessary?
--
Alex
|
5 |
Jan Derk
replied
on 24-Aug-2009:
Alex Belo wrote:
(snip)
Yes, you have to lock it if you use it in a thread.
Jan Derk
|
8 |
Alex Belo
replied
on 24-Aug-2009:
Jan Derk wrote:
(snip)
Thank you Jan.
--
Alex
|
11 |
Alex Belo
replied
on 24-Aug-2009:
Does the lock affect negatively on other threads?
--
Alex
|
2 |
Jan Derk
replied
on 24-Aug-2009:
Alex Belo wrote:
(snip) No. It just prevents the DC garbage collector from deleting the device context
of the canvas.
Jan Derk
|
7 |
Alex Belo
replied
on 24-Aug-2009:
Jan Derk wrote:
(snip) OK, as I suspected.
Thank you again.
--
Alex.
|
3 |
Sergio Gianezini
replied
on 31-Aug-2009:
TBitmap.Canvas suffer from same issue that I have when trying to use
ShowMessage() - TForm.Canvas - in a multithread application.
This piece of code in dialog.pas causes randomly AV's, 'cause the Canvas DC
get's freed by main thread.
function GetAveCharSize(Canvas: TCanvas): TPoint;
|
53 |
Alex Belo
replied
on 31-Aug-2009:
Sergio Gianezini wrote:
(snip)
ShowMessage dialog is VCL form. So you can't use it in secondary
thread(s). To show your short modal messages use WinAPI dialogs instead.
--
Alex
|
12 |
Jens Gruschel
replied
on 05-Sep-2009:
(snip) Actually you don't have to lock it, if you make sure no canvas is accessed while
your threads are executed. So your main thread should be blocked during your
operation (for example using WaitForMultipleObjects). But it's no problem to
have any number of threads working on one or more bitmaps without locking, if
you are only accessing the memory given by the scanline property.
|
19 |
Alex Belo
replied
on 06-Sep-2009:
Jens Gruschel wrote:
(snip)
So we have 2 different POV on this problem now. :-)
Really, I'd like to see an official POV.
--
Alex
|
9 |
Jens Gruschel
replied
on 06-Sep-2009:
(snip) Officially you have to lock bitmaps, but not if the main thread is blocked :-)
The explanation is simple: you have to lock bitmaps unless you make sure
FreeDeviceContexts is never called, which happens in TWinControl.DestroyWnd and
TWinControl.MainWndProc. But these methods are only executed while the main
(GUI) thread is active (processes messages etc.). I'd also avoid accessing any
|
55 |
Alex Belo
replied
on 07-Sep-2009:
Jens Gruschel wrote:
Thank you Jens for input.
(snip)
....
(snip)
Very special case. Freezing GUI is not acceptable.
---
|
41 |
Jens Gruschel
replied
on 07-Sep-2009:
(snip) It's not so special if you want to execute an image processing operation on a
multi core machine and wait for the result in the main thread, something like
(pseudo code):
StartThreads(GetNumberOfProcessors);
WaitForThreads;
|
19 |
Alex Belo
replied
on 08-Sep-2009:
Jens Gruschel wrote:
(snip)
In other words stop main thread (GUI). As I aldeady said:
(snip)
OK, thank you for explanation.
--
Alex
|
23 |
Earik Beann
replied
on 02-Nov-2009:
Hey Guys,
FYI, I solved my bitmap thread issues by swapping out Graphics::TBitmap for TBitmap32, which is an open source bitmap replacement for Delphi/C++ Builder that doesn't suffer from these issues. www.graphics32.org if you're curious. I spent weeks trying to make it work with the standard class, but just couldn't get it going...
Earik
|
14 |