Jump to content

ROI and shared state (threading)


politician

Recommended Posts

I'd like to try my hand at porting some image processing algorithms from AForge.NET to Paint.NET plugins, but I'm concerned that the ROI work item segmentation scheme will adversely affect the algorithms (which, due to their complexity, I'd like to minimize changes to). So, for instance, connected components labeling will identify all of the black "blobs" in a black & white (binary) image where white is the background color, but the algorithm relies on building up some shared global state in the form of a disjoint set forest. Before I go down this rabbit hole, I'd like to know if ROI is going to be a showstopper.

My understanding of ROI is limited to (1) Paint.NET segments effects processing into multiple write regions which are scheduled in parallel, and (2) each round has read access to the entire image.

I'm thinking that for connected components labelling (the output of which is rectangles around each blob) that I could just block all but one of the ROI threads (via a Mutex), do the analysis on the one unblocked thread, then unblock/wake the locked threads to render the resulting (clipped) rectangles. I suppose I could host the data structure in the current AppDomain (i.e. as a static variable).

Does that sound reasonable? Am I missing anything (like, preferably, a synchronous PreRender API)?

Let me know if you need more details about what I'm trying to do.

Thanks,

Edited by politician
Link to comment
Share on other sites

Does that sound reasonable?

If you're sane, I suppose you should say, "no, that sounds like a hack," and I would totally agree. So let me ask a slightly different question, does Paint.NET guard its render threads with a timeout?

Link to comment
Share on other sites

When your OnRender() is called for a specific set of rectangles (ROI stands for region of interest, btw), it expects that the rendering for that area is finished by the type you "return;".

However, it doesn't really care if you render things ahead of time -- assuming you don't start until OnSetRenderInfo() is called, however, and that you stop when it tells you do.

There's also a flag in the construct where you can tell it to run single threaded. You will still be fed ROIs, however.

Some of the more interesting plugins out there (e.g. the GPU Blur Pack, and some of Ed Harvey's) do all the rendering at once and then the real OnRender() is mostly a dummy call.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Hey, thank you for the quick response. I didn't expect to hear from the guy this quick.

So, if I understand correctly,

1. In the constructor, I can opt-in to single-threaded processing.

2. When OnSetRenderInfo is invoked, I'm free to access the source surface, create a temporary surface, and render to it.

3. Finally, when OnRender is invoked, I'm supposed to just blit to the destination surface (clipped by the rois, of course).

You will still be fed ROIs, however.

Does this mean that OnRender will be called 1 time with a full list of ROIs, or that OnRender will be called multiple times (sequentially) with partial ROIs?

Although, I suppose it doesn't matter so long as I can just do all the work on OnSetRenderInfo.

Thanks again.

Link to comment
Share on other sites

Does this mean that OnRender will be called 1 time with a full list of ROIs, or that OnRender will be called multiple times (sequentially) with partial ROIs?

OnRender will be called multiple times sequentially with partial ROIs, although if you have a pre-rendered Surface you can just use the code below to copy from your temporary Surface.

dstArgs.Surface.CopySurface(tempSurface, rois); 

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

OnRender will be called multiple times sequentially with partial ROIs, although if you have a pre-rendered Surface you can just use the code below to copy from your temporary Surface.

dstArgs.Surface.CopySurface(tempSurface, rois); 

Works for me. Everyone in this forum is damn helpful. I've gotten like 5 knowledgeable responses from 5 different people on just 2 threads.

Link to comment
Share on other sites

Although, I suppose it doesn't matter so long as I can just do all the work on OnSetRenderInfo.

Yes, you can do that. And then use null54's snippet of code if you are using a temporary surface. In fact, doing all your work in OnSetRenderInfo() will make it much easier to deal with cancellation... you won't have to deal with it, in other words.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...