Re: NSImage from bitmap - then delete bitmap
Re: NSImage from bitmap - then delete bitmap
- Subject: Re: NSImage from bitmap - then delete bitmap
- From: Graham Cox <email@hidden>
- Date: Fri, 22 Jul 2016 16:53:33 +1000
> On 22 Jul 2016, at 4:40 PM, Trygve Inda <email@hidden> wrote:
>
>
>> With half an eye on performance, if you *do* strictly need a copy of the
>> bitmap, note that NSBitmapImageRep conforms to NSCopying. You don’t have to
>> turn it into a TIFF and back again.
>>
>> Also, you don’t even need an NSImage - the NSImageRep can be drawn directly.
>
>
> A little deeper discussion of how my app works.
I have an idea I know what this app is, so I understand what you need to do. I won’t name names if you don’t :) I believe I am a registered user.
>
> I have a background worker thread whose purpose is to generate a continuous
> series of NSImages - from one per second to one every 5 minutes or so). I
> may have several of these worker threads working on different images.
>
> The thread starts by making a pixel buffer using:
>
> [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL ......
>
> Then the thread goes into a loop where on each pass it draws the correct
> image into this pixel buffer.
>
> After the image is drawn it need to be handed off to the main thread to be
> drawn into a window.
>
> As soon as it is handed off, the thread starts drawing a new image,
> destroying the pixels used to create the image that was just handed off.
>
> It is likely that the image will not be received by the main thread and
> drawn into the window before the pixels in the NSBitmapImageRep are
> destroyed (because it the thread is now drawing a new image).
>
> So how is the best way to take my NSBitmapImageRep, and hand it off to the
> main thread in such a way that I can destroy the pixels immediately while
> the main thread keeps them?
>
> Would it be best to just call [myImagerep copy], and hand that to the main
> thread, and let the main thread release it once it has draw it into the
> window?
>
I think you have two choices.
You can pass the rep to the window using performSelectorOnMainThread:withObject:waitUntilDone: passing YES for wait until done, in which case your worker thread will be stalled just long enough to draw the image and copy to the backing store. After that you’re free to continue modifying the rep.
Or you can copy the rep and not bother waiting. One way to do that easily is to make the window’s ‘imageRep’ propery ‘copy’ and it’ll do it for you. But you’ll also need to call -setNeedsDisplay: on the main thread, again without waiting. I don’t think there’s any real advantage one way or the other - one will use quite a lot of memory, the other might be ever so slightly slower. Classic tradeoff.
Note that unless you deliberately mark the window as needing display, your window will NEVER draw from the rep, even if the user moves it revealing a covered portion - that will be filled from the backing store.
—Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden