Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Quincey Morris
On Jul 22, 2016, at 19:29 , Graham Cox  wrote:
> 
> If the worker thread is waiting for -performOnMainThread to complete, it 
> *cannot* possibly get a call from the main thread to terminate

I nodded agreement when I first read this, then “but wait!” …

Your logic seems flawed on two counts:

1. The selector performed by the worker thread may still be queued, so the main 
thread is doing something else which may result in an attempt to terminate the 
worker thread.

2. The worker method performed on the main thread may directly or indirectly 
lead to an attempt to terminate the worker thread.

Both scenarios could cause a deadlock. At least, that’s my attempt at logic.

The real problem is that it’s simply a bug to have two threads with mutual, 
synchronous, unconditional waits. Of course that’s going to deadlock eventually.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 23 Jul 2016, at 12:45 AM, Trygve Inda  wrote:
> 
> Because the main thread sometimes needs to ask the worker threads to
> terminate. If it does this after performOnMainThread has been called by a
> worker thread, but before the main thread has processed it, then the main
> thread will block waiting for the worker thread to exit, but the worker
> thread has already blocked when it called performOnMainThread.
> 
> Very rare, but it can happen.


This is wrong thinking.

If the worker thread is waiting for -performOnMainThread to complete, it 
*cannot* possibly get a call from the main thread to terminate, because the 
main thread is dealing with whatever the other thread asked it to do.

If the worker thread performs a copy and doesn’t wait for the main thread to 
perform the drawing, then it’s still “blocked” while it’s performing the copy.

Either your understanding of the bug is wrong, or there’s somethomg whiffy in 
your architecture.

Usually a worker thread just checks a flag on each loop and falls out when it 
gets set (by another thread). That flag should be set atomically. There can 
then be no deadlock.

e.g.

worker thread:

while( self.running )
{
// do work

window.imageRep = myResult; 
// window.imageRep is (atomic, copy)

[performOnMainThread: window.setNeedsDisplay];  // this is 
obviously pseudocode!
}


main thread, when it needs to terminate worker thread:

workerThread.running = NO;


both workerThread.running and window.imageRep are atomic properties.


—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: kCFStreamPropertySSLSettings

2016-07-22 Thread Jens Alfke

> On Jul 22, 2016, at 2:46 AM, Gerriet M. Denkmann  wrote:
> 
> When it gets some streams it will show a panel:
> “MyApp wants to sign using key “something” in your keychain” / “Allow” “Deny”

Presumably this app is either acting as an SSL server, or is sending SSL 
clients. Either of those roles involves signing data using the private key 
associated with the certificate, to prove you own it.  If the app hasn’t 
previously used that private key, the Keychain will ask your permission to let 
the app use it. That’s the alert. Then it updates the key’s access control list 
to remember your app has access. But this access is (usually) invalidated when 
the app binary is modified, so you’ll (usually) see the alert again if you 
modify the app and run it again.

> The problem: sometimes I do NOT get this panel, and the app behaves as if I 
> had clicked “Deny”.

Huh. Had you previously denied the alert? Maybe the security framework hasn’t 
noticed that the app changed and is still using the old Deny permission set 
before.

> Where is this info: < “MyApp is allowed to use key “something”> stored? 

In the Keychain item for that key. You can look at and modify the permissions 
in the Keychain Access app.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Do Debug Apps Expire on iOS?

2016-07-22 Thread Michael David Crawford
Debug it some other way than with Xcode.  Possibly you have a serious
bug, but running under the debugger alters something so that the bug
isn't stimulated.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Alan Snyder
Or better yet, have the termination request come from a thread other than the 
main thread.

> On Jul 22, 2016, at 9:38 AM, Alan Snyder  wrote:
> 
> 
>> On Jul 22, 2016, at 7:45 AM, Trygve Inda  wrote:
>> 
>> Because the main thread sometimes needs to ask the worker threads to
>> terminate. If it does this after performOnMainThread has been called by a
>> worker thread, but before the main thread has processed it, then the main
>> thread will block waiting for the worker thread to exit, but the worker
>> thread has already blocked when it called performOnMainThread.
>> 
>> Very rare, but it can happen.
> 
> This sounds like a bug to me.
> 
> Would this work: The worker thread could set a flag before it calls 
> performOnMainThread and your thread termination code could do something 
> different when this flag is set.
> 


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Alan Snyder

> On Jul 22, 2016, at 7:45 AM, Trygve Inda  wrote:
> 
> Because the main thread sometimes needs to ask the worker threads to
> terminate. If it does this after performOnMainThread has been called by a
> worker thread, but before the main thread has processed it, then the main
> thread will block waiting for the worker thread to exit, but the worker
> thread has already blocked when it called performOnMainThread.
> 
> Very rare, but it can happen.

This sounds like a bug to me.

Would this work: The worker thread could set a flag before it calls 
performOnMainThread and your thread termination code could do something 
different when this flag is set.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Do Debug Apps Expire on iOS?

2016-07-22 Thread Carl Hoefs
Go to Window -> Devices -> View Device Logs

-Carl


> On Jul 22, 2016, at 4:17 AM, Charles Jenkins  wrote:
> 
> Thank you all. I’ll start my research on how to find crash logs.
> 
> On Thu, Jul 21, 2016 at 10:30 AM, Roland King  wrote:
> 
>> 
>>> On 21 Jul 2016, at 22:15, Steve Bird  wrote:
>>> 
>>> 
 On Jul 21, 2016, at 10:05 AM, Eric E. Dolecki 
>> wrote:
 
 I believe that debug apps built directly to hardware have a shelf life
>> of
 one year. At least they did.
>>> 
>>> I don’t know, but I would hope that they would pop up some notice like
>> “This app has expired. Contact the developer for the current version”.
>>> 
>>> That would seem to be the polite thing to do, rather than driving off
>> into the ditch and staying there.
>> 
>> Debug apps expire when your debug provisioning profile expires, which you
>> should know because you renewed your membership.
>> 
>> TestFlight apps have a shorter lifetime to encourage developers to release
>> test versions on a regular basis and stop TestFlight just being an easy
>> mechanism for distributing private apps to your friends for a year at a
>> time.
>> 
>> So the original poster most likely has a bug.
>> 
>> 
>> ___
>> 
>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>> 
>> 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:
>> https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com
>> 
>> This email sent to cejw...@gmail.com
>> 
> 
> 
> 
> -- 
> 
> Charles
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/newslists%40autonomy.caltech.edu
> 
> This email sent to newsli...@autonomy.caltech.edu


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda
 
>> Currently it blocks at this point, but I need to avoid that.
> 
> It’s not really clear why this needs to be avoided. The time to draw the
> pixels should be a few milliseconds, a small fraction of the time your thread
> needs to run, even at its fastest.

Because the main thread sometimes needs to ask the worker threads to
terminate. If it does this after performOnMainThread has been called by a
worker thread, but before the main thread has processed it, then the main
thread will block waiting for the worker thread to exit, but the worker
thread has already blocked when it called performOnMainThread.

Very rare, but it can happen.

>> Since it can't
>> block,
>> the pixels need to be copied to the main thread because as soon as
>> they get handed to the main thread, the worker thread will erase the
>> original pixel buffer to start drawing a new image into it.
> 
> Copying the image is likely to be just as slow/fast as drawing it, so the copy
> isn’t going to help speed up your thread. Both operations have to iterate over
> the pixels; drawing *IS* copying.

Speed isn't really the issue. The issue is changing the code so that the
worker thread never has to block. To do so the pixels need to handed off to
the main thread in such a way that the worker thread can then destroy the
original pixels (by writing over them with new data)

>> The copy needs to exist long enough to be drawn into a window by the main
>> thread and can then be released.
> 
> Understood, but you may as well keep it around until the next version of the
> image is passed across - the previous one will be released at the same time
> when setting the property.

Yup - that's possible too.




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 11:53 PM, Trygve Inda  wrote:
> 
> How can I draw the NSImageRep  directly into a window?


-[NSImageRep drawInRect:fromRect:operation:fraction:respectFlipped:hints:];

i.e. same as NSImage.


> 
> Also, the main pixel buffer is updated slowly (it takes a long time to
> draw). So once the worker thread is done, it needs to pass off those pixels
> to the main thread to be drawn.
> 
> Currently it blocks at this point, but I need to avoid that.

It’s not really clear why this needs to be avoided. The time to draw the pixels 
should be a few milliseconds, a small fraction of the time your thread needs to 
run, even at its fastest.

> Since it can't
> block,
> the pixels need to be copied to the main thread because as soon as
> they get handed to the main thread, the worker thread will erase the
> original pixel buffer to start drawing a new image into it.

Copying the image is likely to be just as slow/fast as drawing it, so the copy 
isn’t going to help speed up your thread. Both operations have to iterate over 
the pixels; drawing *IS* copying.

> The copy needs to exist long enough to be drawn into a window by the main
> thread and can then be released.

Understood, but you may as well keep it around until the next version of the 
image is passed across - the previous one will be released at the same time 
when setting the property.


—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda
> 
>> On 22 Jul 2016, at 4:08 PM, Trygve Inda  wrote:
>> 
>> I don't think the second part will work because of my workflow:
>> 
>> At Launch: Create pixel buffer that is 1000 x 1000 pixels
>> 
>> Looping thread
>> 1. Fill pixel buffer with pixels based on some algorithm
>> 2. create an NSImage with these pixels
>> 3. pass it to the main thread to be drawn in a window
>> Restart the loop with a  slightly modified algorithm
>> 
>> If calling this:
>> [myImage addRepresentation:theBitmapIMadeFirst];
>> 
>> Only causes the NSImage to retain it, then when I change the pixels in the
>> bitmap, they get changed in the NSImage.
>> 
>> I need the NSImage to keep the pixels as they existed when I created it.
> 
> 
> Do you?
> 
> Once the image is drawn into the window, it’s effectively copied to the
> window’s backing store, so there’s already a second copy of the pixels.
> 
> The only situation that might cause a problem is if the window can possibly be
> called upon to redraw at a time when the bitmap is being updated but hasn’t
> yet completed. If the code that fills the buffer is synchronous, that can
> never happen. If the code is asynchronous (e.g. on a second thread), then you
> *might* want a copy of the bitmap, but only if drawing it halfway through
> updating would actually be bad - that depends entirely on what is being drawn.
> If it’s a minor/subtle change, it may not be noticeable.
> 
> 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.

How can I draw the NSImageRep  directly into a window?

Also, the main pixel buffer is updated slowly (it takes a long time to
draw). So once the worker thread is done, it needs to pass off those pixels
to the main thread to be drawn.

Currently it blocks at this point, but I need to avoid that. Since it can't
block, the pixels need to be copied to the main thread because as soon as
they get handed to the main thread, the worker thread will erase the
original pixel buffer to start drawing a new image into it.

The copy needs to exist long enough to be drawn into a window by the main
thread and can then be released.





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda
 
>> This is how it works now, but we are running into a rare deadlock situation
>> where the main thread asks the worker thread to end (and waits until it does
>> so) while the worker thread is waiting for the image to be displayed.
> 
> If the window has a imageRep property that is (atomic, copy) you shouldn’t run
> into a deadlock where the window tries to terminate the thread and it happens
> to be calling that method at the time. If you go with Roland’s suggestion, it
> doesn’t need to be copy, it can simply be strong. But make it atomic, as the
> property will need to be accessed from both the main and the worker threads
> and the rep must be in a viable state at both times.

Ultimately there needs to be more than one copy of the pixels because as
soon as the worker thread is done building the image, it hands it off to the
main thread to be displayed.

Currently it blocks until the main thread displays it, so only one set of
pixels is needed. But to prevent deadlock, the worker thread really needs to
just hand of a copy of the pixels, then erase the original pixels and start
a new image.

[bitmapImageRep copy] might be the best solution here.

T.




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Do Debug Apps Expire on iOS?

2016-07-22 Thread Charles Jenkins
Thank you all. I’ll start my research on how to find crash logs.

On Thu, Jul 21, 2016 at 10:30 AM, Roland King  wrote:

>
> > On 21 Jul 2016, at 22:15, Steve Bird  wrote:
> >
> >
> >> On Jul 21, 2016, at 10:05 AM, Eric E. Dolecki 
> wrote:
> >>
> >> I believe that debug apps built directly to hardware have a shelf life
> of
> >> one year. At least they did.
> >
> > I don’t know, but I would hope that they would pop up some notice like
> “This app has expired. Contact the developer for the current version”.
> >
> > That would seem to be the polite thing to do, rather than driving off
> into the ditch and staying there.
>
> Debug apps expire when your debug provisioning profile expires, which you
> should know because you renewed your membership.
>
> TestFlight apps have a shorter lifetime to encourage developers to release
> test versions on a regular basis and stop TestFlight just being an easy
> mechanism for distributing private apps to your friends for a year at a
> time.
>
> So the original poster most likely has a bug.
>
>
> ___
>
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com
>
> This email sent to cejw...@gmail.com
>



-- 

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

kCFStreamPropertySSLSettings

2016-07-22 Thread Gerriet M. Denkmann
I have an app (macOS 11.6) which uses kCFStreamPropertySSLSettings.

When it gets some streams it will show a panel:

“MyApp wants to sign using key “something” in your keychain” / “Allow” “Deny”

When I click “Deny” the streams get NSOSStatusErrorDomain errSecAuthFailed.
Else (clicked “Allow”) the app proceeds normally.
So far so good.

The problem: sometimes I do NOT get this panel, and the app behaves as if I had 
clicked “Deny”.
Before (11.5) quitting/restarting the app fixed this problem.

But in 11.6 I sometimes have to quit/restart a lot.

Where is this info: < “MyApp is allowed to use key “something”> stored? 
How to reset this (to force the app show the panel)?

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 5:30 PM, Quincey Morris 
>  wrote:
> 
> On Jul 22, 2016, at 00:08 , Graham Cox  wrote:
>> 
>> If the thread building images never goes faster than once per second, the 
>> time to draw the image is a fraction of that - I’m sure 60fps is achievable, 
>> so making the thread wait for the drawing to be done isn’t going to hold it 
>> up significantly. 
> 
> (I’ve done something like this, though it was a couple of years ago, so the 
> same performance characteristics cannot be assumed.)
> 
> With the sequence:
> 
>   worker thread -> NSBitmapImageRep -> main thread -> window
> 
> not even 24 fps was achievable, for anything but fairly small images (say, 
> less than one quarter of a 21-inch non-Retina screen). That’s because a 
> bitmap image rep isn’t the internal representation of anything, so there 
> always a copy or two, along with a possible pixel format translation, and a 
> colorspace mapping.

A possible optimisation there would be to use -[NSView 
bitmapImageRepForCachingDisplayInRect:] which returns a rep that matches the 
backing store format and colorspace, so copying is fast. That might put more 
strain on the renderer code though, which has to deal with the format it finds, 
not one it created.

> OTOH, I’m not sure 60fps is being asked for, unless that comes from your 
> special knowledge of what the app does. It was less than 1 fps per worker 
> thread, and if there are 60+ worker threads, there are likely other 
> performance issues as well.
> 

It’s not being asked for - 1fps is the fastest. But I meant that if the drawing 
time is in the 60fps ballpark, then that part isn’t going to hold up the 1fps 
worker thread significanty. I *think* (correct me if I’m wrong Trygve) that 
there’s only one such worker thread.


> On 22 Jul 2016, at 5:19 PM, Trygve Inda  wrote:
> 
> This is how it works now, but we are running into a rare deadlock situation
> where the main thread asks the worker thread to end (and waits until it does
> so) while the worker thread is waiting for the image to be displayed.

If the window has a imageRep property that is (atomic, copy) you shouldn’t run 
into a deadlock where the window tries to terminate the thread and it happens 
to be calling that method at the time. If you go with Roland’s suggestion, it 
doesn’t need to be copy, it can simply be strong. But make it atomic, as the 
property will need to be accessed from both the main and the worker threads and 
the rep must be in a viable state at both times.

—Graham




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Quincey Morris
On Jul 22, 2016, at 00:08 , Graham Cox  wrote:
> 
> If the thread building images never goes faster than once per second, the 
> time to draw the image is a fraction of that - I’m sure 60fps is achievable, 
> so making the thread wait for the drawing to be done isn’t going to hold it 
> up significantly. 

(I’ve done something like this, though it was a couple of years ago, so the 
same performance characteristics cannot be assumed.)

With the sequence:

worker thread -> NSBitmapImageRep -> main thread -> window

not even 24 fps was achievable, for anything but fairly small images (say, less 
than one quarter of a 21-inch non-Retina screen). That’s because a bitmap image 
rep isn’t the internal representation of anything, so there always a copy or 
two, along with a possible pixel format translation, and a colorspace mapping. 
Plus multithreading overheads like locks. The details will depend on the Mac, 
the OS version and the display.

If something performant is necessary, then the best approach is probably to use 
CVPixelBuffer instead. However, the learning curve for this is pretty 
horrendous, particular when dealing with isolated still images rather than 
video, so I would not suggest going there unless absolutely necessary.

OTOH, I’m not sure 60fps is being asked for, unless that comes from your 
special knowledge of what the app does. It was less than 1 fps per worker 
thread, and if there are 60+ worker threads, there are likely other performance 
issues as well.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda
> 
>> On 22 Jul 2016, at 4:40 PM, Trygve Inda  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 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 think
> you have two choices.

Without naming names, I am sure your hunch is accurate.
 
> 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.

This is how it works now, but we are running into a rare deadlock situation
where the main thread asks the worker thread to end (and waits until it does
so) while the worker thread is waiting for the image to be displayed.

I have never seen it happen here, but I have tracked it down from hang
reports and need to figure out the best way to hand the pixels off to the
main thread in such a way that there are no dependencies on the original
pixel buffer because as soon as the pixels are handed to the main thread,
the worker thread will be changing the pixels in the original buffer.





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 5:00 PM, Roland King  wrote:
> 
> Since you need the data to persist for display whilst you write a new image 
> that means there’s two separate buffers, there has to be

Not sure there HAS to be. Whether it’s the easiest approach is another matter.

If the thread building images never goes faster than once per second, the time 
to draw the image is a fraction of that - I’m sure 60fps is achievable, so 
making the thread wait for the drawing to be done isn’t going to hold it up 
significantly. You’re going to waste exactly the same amount of time doing a 
copy. Your suggestion of making a new buffer is a good one, as there’s no 
wasted time, provided that the worker thread does set every pixel. Otherwise 
it’s going to have to clear it and you’re back to a pass over the pixels which 
takes the same time as the copy/draw, etc.

But is it worth it to save the 4MB per bitmap? Once upon a time the answer 
would definitely be yes, but 4MB isn’t much these days.

—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Roland King

> On 22 Jul 2016, at 14:40, Trygve Inda  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.
> 
> 
> 
> 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’d have said the best way is to create a new image buffer for each new image 
you draw, draw into it and hand it off, then make another new one instead of 
trying to use one single one per thread. Creating them is cheap, it’s basically 
malloc(). Since you need the data to persist for display whilst you write a new 
image that means there’s two separate buffers, there has to be. So either you 
make a copy, which means going through the expense of copying it, or you just 
hand it off and start a new one, which doesn’t. When the main thread has 
finished with it it can dispose of the old buffer. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 4:40 PM, Trygve Inda  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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda

> 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 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?





___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 4:08 PM, Trygve Inda  wrote:
> 
> I don't think the second part will work because of my workflow:
> 
> At Launch: Create pixel buffer that is 1000 x 1000 pixels
> 
> Looping thread
> 1. Fill pixel buffer with pixels based on some algorithm
> 2. create an NSImage with these pixels
> 3. pass it to the main thread to be drawn in a window
> Restart the loop with a  slightly modified algorithm
> 
> If calling this:
> [myImage addRepresentation:theBitmapIMadeFirst];
> 
> Only causes the NSImage to retain it, then when I change the pixels in the
> bitmap, they get changed in the NSImage.
> 
> I need the NSImage to keep the pixels as they existed when I created it.


Do you?

Once the image is drawn into the window, it’s effectively copied to the 
window’s backing store, so there’s already a second copy of the pixels.

The only situation that might cause a problem is if the window can possibly be 
called upon to redraw at a time when the bitmap is being updated but hasn’t yet 
completed. If the code that fills the buffer is synchronous, that can never 
happen. If the code is asynchronous (e.g. on a second thread), then you
*might* want a copy of the bitmap, but only if drawing it halfway through 
updating would actually be bad - that depends entirely on what is being drawn. 
If it’s a minor/subtle change, it may not be noticeable.

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.

—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Ken Thomases
On Jul 22, 2016, at 1:08 AM, Trygve Inda  wrote:
> 
>> But that’s not a great way to do this. You’ve made an image, you’ve encoded 
>> it
>> as TIFF data, then you’ve made a new image, which has decoded the TIFF data 
>> to
>> make a new image rep/bitmap.
>> 
>> You could just add the representation directly to a new NSImage (warning:
>> typed into Mail, check method names):
>> 
>> NSImage* myImage = [[NSImage alloc] initWithSize:NSMakeSize(width,height)];
>> 
>> [myImage addRepresentation:theBitmapIMadeFirst];
>> 
>> [theBitmapIMadeFirst release]; // because NSImage retained it
> 
> 
> I don't think the second part will work because of my workflow:
> 
> At Launch: Create pixel buffer that is 1000 x 1000 pixels
> 
> Looping thread
> 1. Fill pixel buffer with pixels based on some algorithm
> 2. create an NSImage with these pixels
> 3. pass it to the main thread to be drawn in a window
> Restart the loop with a  slightly modified algorithm
> 
> If calling this:
> [myImage addRepresentation:theBitmapIMadeFirst];
> 
> Only causes the NSImage to retain it, then when I change the pixels in the
> bitmap, they get changed in the NSImage.
> 
> I need the NSImage to keep the pixels as they existed when I created it.

Hint: NSBitmapImageRep conforms to the NSCopying protocol.

Regards,
Ken


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Trygve Inda
> 
>> On 22 Jul 2016, at 3:37 PM, Trygve Inda  wrote:
>> 
>> I create an NSBitmapImageRep:
>> 
>> [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
>> pixelsWide:pixelSize.width
>> pixelsHigh:pixelSize.height
>> bitsPerSample:8
>> samplesPerPixel:4
>> hasAlpha:YES
>> isPlanar:NO
>> colorSpaceName:NSDeviceRGBColorSpace
>> bitmapFormat:NSAlphaFirstBitmapFormat
>> bytesPerRow:pixelSize.width * 4
>> bitsPerPixel:32]
>> 
>> I then get the address by sending a "bitmapData" message to the object
>> 
>> After filling it with image data, I call:
>> 
>> NSImage* image =
>> [[NSImage alloc] initWithData:[myImageRep TIFFRepresentation]];
>> 
>> So now I have an NSImage. What happens if I delete/release myImageRep (my
>> NSBitmapImageRep)?
> 
> Nothing. The rep isn’t doing anything after this point; you can release it
> safely.
> 
>> Has the call to NSImage copied my pixels so that they are self-contained
>> within the NSImage?
> 
> Yes.
> 
> But that’s not a great way to do this. You’ve made an image, you’ve encoded it
> as TIFF data, then you’ve made a new image, which has decoded the TIFF data to
> make a new image rep/bitmap.
> 
> You could just add the representation directly to a new NSImage (warning:
> typed into Mail, check method names):
> 
> NSImage* myImage = [[NSImage alloc] initWithSize:NSMakeSize(width,height)];
> 
> [myImage addRepresentation:theBitmapIMadeFirst];
> 
> [theBitmapIMadeFirst release]; // because NSImage retained it


I don't think the second part will work because of my workflow:

At Launch: Create pixel buffer that is 1000 x 1000 pixels

Looping thread
1. Fill pixel buffer with pixels based on some algorithm
2. create an NSImage with these pixels
3. pass it to the main thread to be drawn in a window
Restart the loop with a  slightly modified algorithm

If calling this:
[myImage addRepresentation:theBitmapIMadeFirst];

Only causes the NSImage to retain it, then when I change the pixels in the
bitmap, they get changed in the NSImage.

I need the NSImage to keep the pixels as they existed when I created it.




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Ken Thomases
On Jul 22, 2016, at 12:37 AM, Trygve Inda  wrote:
> 
> I create an NSBitmapImageRep:
> 
> [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
> pixelsWide:pixelSize.width
> pixelsHigh:pixelSize.height
> bitsPerSample:8
> samplesPerPixel:4
> hasAlpha:YES
> isPlanar:NO
> colorSpaceName:NSDeviceRGBColorSpace
> bitmapFormat:NSAlphaFirstBitmapFormat
> bytesPerRow:pixelSize.width * 4
> bitsPerPixel:32]
> 
> I then get the address by sending a "bitmapData" message to the object
> 
> After filling it with image data, I call:
> 
> NSImage* image =
> [[NSImage alloc] initWithData:[myImageRep TIFFRepresentation]];

Aside from your primary question, don't do this.  Use -initWithSize: and then 
directly add the representation to the image using -addRepresentation:.


> So now I have an NSImage. What happens if I delete/release myImageRep (my
> NSBitmapImageRep)?
> 
> Has the call to NSImage copied my pixels so that they are self-contained
> within the NSImage?

The general answer is you don't know and you shouldn't care.  It is the 
responsibility of the framework to do what's necessary.  It may have retained 
the image rep or retained some private NSData object that represented the 
pixels or copied the data or whatever.

The memory management conventions of Cocoa are designed to be local in nature.  
Generally, you do not need to know what other code is doing.  (Exceptions are 
documented.)  You only need to get your part correct, where you retain objects 
if you need to ensure they live beyond the current scope (if you don't already 
have an ownership reference to them, as from +alloc, -copy…, etc.) and you 
release ownership references after you're done with those objects.  You just 
assume that the other parts of the code follow the rules, too, and everything 
works.

You said "delete/release myImageRep".  That "delete" represents incorrect 
thinking on your part.  You only ever release your ownership reference to the 
object.  You can't know whether something else also has an ownership reference 
to it, so you can't know when the object is deleted/deallocated.


In this particular case, you're using -TIFFRepresentation which creates a data 
object of a TIFF image file format.  Since that's not the same format as the 
pixel data you stored via -bitmapData, it's very likely an independent object.  
Also, there's no reason for the image rep to keep any reference to it around.  
For example, you could modify the bitmap data some more and generate a new TIFF 
data object and that would be different from the first.  Surely, it's clear to 
you that such modifications to the bitmap data of the image rep must not modify 
the TIFF data that you created earlier.

Then, -initWithData: decodes the TIFF data and makes a new NSImage with 
whatever representations it needs.  Because of the layers of 
abstraction/conversion that the data went through, it's very unlikely that the 
new NSImage or representations have any references to the original image rep.

Regards,
Ken


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: NSImage from bitmap - then delete bitmap

2016-07-22 Thread Graham Cox

> On 22 Jul 2016, at 3:37 PM, Trygve Inda  wrote:
> 
> I create an NSBitmapImageRep:
> 
> [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
> pixelsWide:pixelSize.width
> pixelsHigh:pixelSize.height
> bitsPerSample:8
> samplesPerPixel:4
> hasAlpha:YES
> isPlanar:NO
> colorSpaceName:NSDeviceRGBColorSpace
> bitmapFormat:NSAlphaFirstBitmapFormat
> bytesPerRow:pixelSize.width * 4
> bitsPerPixel:32]
> 
> I then get the address by sending a "bitmapData" message to the object
> 
> After filling it with image data, I call:
> 
> NSImage* image =
> [[NSImage alloc] initWithData:[myImageRep TIFFRepresentation]];
> 
> So now I have an NSImage. What happens if I delete/release myImageRep (my
> NSBitmapImageRep)?

Nothing. The rep isn’t doing anything after this point; you can release it 
safely.

> Has the call to NSImage copied my pixels so that they are self-contained
> within the NSImage?

Yes.

But that’s not a great way to do this. You’ve made an image, you’ve encoded it 
as TIFF data, then you’ve made a new image, which has decoded the TIFF data to 
make a new image rep/bitmap.

You could just add the representation directly to a new NSImage (warning: typed 
into Mail, check method names):

NSImage* myImage = [[NSImage alloc] initWithSize:NSMakeSize(width,height)];

[myImage addRepresentation:theBitmapIMadeFirst];

[theBitmapIMadeFirst release];  // because NSImage retained it

…

done.



All NSImage is is a “box” in which a bunch of NSImageReps reside. It sometimes 
makes those reps itself from data, etc, but you can make them yourself and add 
them. It’s way more efficient.

—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com